Merge branch 'mc1.20.1/flywheel-upgrade' into mc1.20.1/dev

# Conflicts:
#	build.gradle
#	gradle.properties
#	src/main/java/com/simibubi/create/content/contraptions/actors/roller/RollerMovementBehaviour.java
#	src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainRenderer.java
#	src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java
#	src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmRenderer.java
#	src/main/java/com/simibubi/create/content/kinetics/waterwheel/WaterWheelRenderer.java
#	src/main/java/com/simibubi/create/content/trains/schedule/hat/TrainHatArmorLayer.java
#	src/main/resources/META-INF/mods.toml
#	src/main/resources/create.mixins.json
This commit is contained in:
Jozufozu 2024-09-03 11:51:18 -05:00
commit 14c93e590c
517 changed files with 9401 additions and 8059 deletions

View file

@ -1,32 +1,16 @@
buildscript {
repositories {
maven { url = 'https://maven.minecraftforge.net' }
mavenCentral()
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
}
dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:${forgegradle_version}"
classpath "org.spongepowered:mixingradle:${mixingradle_version}"
classpath "org.parchmentmc:librarian:${librarian_version}"
}
}
plugins { plugins {
id 'eclipse'
id 'idea'
id 'maven-publish'
id 'net.minecraftforge.gradle' version "${forgegradle_version}"
id 'org.parchmentmc.librarian.forgegradle' version "${librarian_version}"
id 'org.spongepowered.mixin' version "${mixingradle_version}"
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}" id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
} }
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.parchmentmc.librarian.forgegradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: 'org.spongepowered.mixin'
jarJar.enable() jarJar.enable()
boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equals('false'); boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equals('false');
// jozu: I use a gradle workspace with both projects.
// The project is named Flywheel-Forge, but sub-projects are named by folder.
boolean inWorkspace = findProject(':Flywheel') != null
ext.buildNumber = System.getenv('BUILD_NUMBER') ext.buildNumber = System.getenv('BUILD_NUMBER')
@ -38,8 +22,27 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(17)
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
mixin {
add sourceSets.main, 'create.refmap.json'
config 'flywheel.backend.mixins.json'
config 'flywheel.impl.mixins.json'
config 'flywheel.impl.sodium.mixins.json'
config 'create.mixins.json'
debug.verbose = true
debug.export = true
}
idea {
module {
downloadJavadoc = true
downloadSources = true
}
}
minecraft { minecraft {
if (Boolean.parseBoolean(project.use_parchment)) { if (Boolean.parseBoolean(use_parchment)) {
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}" mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
} else { } else {
mappings channel: 'official', version: "${minecraft_version}" mappings channel: 'official', version: "${minecraft_version}"
@ -48,64 +51,39 @@ minecraft {
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs { runs {
client { configureEach {
workingDirectory project.file('run') property 'forge.logging.markers', ''
arg '-mixin.config=create.mixins.json'
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling
//jvmArgs '-XX:+IgnoreUnrecognizedVMOptions', '-XX:+AllowEnhancedClassRedefinition' // uncomment with jbr
property 'forge.logging.console.level', 'info' property 'forge.logging.console.level', 'info'
property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
//jvmArgs '-XX:+IgnoreUnrecognizedVMOptions', '-XX:+AllowEnhancedClassRedefinition' // uncomment with jbr
mods { mods {
create { create {
source sourceSets.main source sourceSets.main
} }
if (inWorkspace) {
flywheel {
source project(":Flywheel").sourceSets.main
}
}
} }
} }
client {
workingDirectory project.file('run')
}
server { server {
workingDirectory project.file('run/server') workingDirectory project.file('run/server')
arg '-mixin.config=create.mixins.json'
property 'forge.logging.console.level', 'info'
mods {
create {
source sourceSets.main
}
}
} }
data { data {
workingDirectory project.file('run') workingDirectory project.file('run')
arg '-mixin.config=create.mixins.json'
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP' property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
args '--mod', 'create', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources') args '--mod', 'create', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources')
mods {
create {
source sourceSets.main
}
if (inWorkspace) {
flywheel {
source project(":Flywheel").sourceSets.main
}
}
}
} }
gameTestServer { gameTestServer {
workingDirectory project.file('run/gametest') workingDirectory project.file('run/gametest')
arg '-mixin.config=create.mixins.json'
property 'forge.logging.console.level', 'info'
mods {
create {
source sourceSets.main
}
}
// setForceExit false <- FIXME 1.20 // setForceExit false <- FIXME 1.20
} }
} }
@ -156,6 +134,7 @@ repositories {
} }
} }
mavenCentral()
mavenLocal() mavenLocal()
flatDir { flatDir {
dirs 'libs' dirs 'libs'
@ -168,17 +147,14 @@ dependencies {
jarJar("com.tterrag.registrate:Registrate:${registrate_version}") { jarJar("com.tterrag.registrate:Registrate:${registrate_version}") {
jarJar.ranged(it, '[MC1.19.3-1.1.10,)') jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
} }
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { jarJar("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
jarJar.ranged(it, '[0.6.11,)') jarJar.ranged(it, '[1.0,2.0)')
} }
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}") implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
if (inWorkspace) { compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${flywheel_minecraft_version}:${flywheel_version}")
implementation project(':Flywheel') runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
} else {
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
}
compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-common-api:${jei_version}") compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-common-api:${jei_version}")
compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge-api:${jei_version}") compileOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}-forge-api:${jei_version}")
@ -252,10 +228,6 @@ sourceSets.main.resources {
exclude '.cache/' exclude '.cache/'
} }
mixin {
add sourceSets.main, 'create.refmap.json'
}
// Workaround for SpongePowered/MixinGradle#38 // Workaround for SpongePowered/MixinGradle#38
afterEvaluate { afterEvaluate {
tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava) tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava)

View file

@ -8,22 +8,22 @@ mod_version = 0.5.1.h
artifact_minecraft_version = 1.20.1 artifact_minecraft_version = 1.20.1
minecraft_version = 1.20.1 minecraft_version = 1.20.1
forge_version = 47.1.43 forge_version = 47.2.6
# build dependency versions # build dependency versions
forgegradle_version = 6.0.6 forgegradle_version = [6.0.16,6.2)
mixingradle_version = 0.7-SNAPSHOT mixingradle_version = 0.7.+
mixin_version = 0.8.5 mixin_version = 0.8.5
librarian_version = 1.+ librarian_version = 1.+
cursegradle_version = 1.4.0 cursegradle_version = 1.4.0
parchment_version = 2023.06.26 parchment_version = 2023.09.03
use_parchment = true use_parchment = true
# dependency versions # dependency versions
registrate_version = MC1.20-1.3.3 registrate_version = MC1.20-1.3.3
flywheel_minecraft_version = 1.20.1 flywheel_minecraft_version = 1.20.1
flywheel_version = 0.6.11-13 flywheel_version = 1.0.0-beta-113
jei_minecraft_version = 1.20.1 jei_minecraft_version = 1.20.1
jei_version = 15.10.0.39 jei_version = 15.10.0.39
curios_minecraft_version = 1.20.1 curios_minecraft_version = 1.20.1

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

11
gradlew vendored
View file

@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -144,7 +141,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -152,7 +149,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in # shell script including quotes and variable substitutions, so put them in

View file

@ -1 +1,18 @@
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven {
name = 'MinecraftForge'
url = 'https://maven.minecraftforge.net/'
}
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
}
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}
rootProject.name = 'Create' rootProject.name = 'Create'

View file

@ -7,34 +7,34 @@ import com.simibubi.create.content.contraptions.actors.contraptionControls.Contr
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsRenderer; import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsRenderer;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterBlockEntity; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterBlockEntity;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer;
import com.simibubi.create.content.contraptions.actors.psi.PSIInstance; import com.simibubi.create.content.contraptions.actors.psi.PSIVisual;
import com.simibubi.create.content.contraptions.actors.psi.PortableFluidInterfaceBlockEntity; import com.simibubi.create.content.contraptions.actors.psi.PortableFluidInterfaceBlockEntity;
import com.simibubi.create.content.contraptions.actors.psi.PortableItemInterfaceBlockEntity; import com.simibubi.create.content.contraptions.actors.psi.PortableItemInterfaceBlockEntity;
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceRenderer; import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceRenderer;
import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity; import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity;
import com.simibubi.create.content.contraptions.actors.roller.RollerRenderer; import com.simibubi.create.content.contraptions.actors.roller.RollerRenderer;
import com.simibubi.create.content.contraptions.bearing.BearingInstance;
import com.simibubi.create.content.contraptions.bearing.BearingRenderer; import com.simibubi.create.content.contraptions.bearing.BearingRenderer;
import com.simibubi.create.content.contraptions.bearing.BearingVisual;
import com.simibubi.create.content.contraptions.bearing.ClockworkBearingBlockEntity; import com.simibubi.create.content.contraptions.bearing.ClockworkBearingBlockEntity;
import com.simibubi.create.content.contraptions.bearing.MechanicalBearingBlockEntity; import com.simibubi.create.content.contraptions.bearing.MechanicalBearingBlockEntity;
import com.simibubi.create.content.contraptions.bearing.WindmillBearingBlockEntity; import com.simibubi.create.content.contraptions.bearing.WindmillBearingBlockEntity;
import com.simibubi.create.content.contraptions.chassis.ChassisBlockEntity; import com.simibubi.create.content.contraptions.chassis.ChassisBlockEntity;
import com.simibubi.create.content.contraptions.chassis.StickerBlockEntity; import com.simibubi.create.content.contraptions.chassis.StickerBlockEntity;
import com.simibubi.create.content.contraptions.chassis.StickerInstance;
import com.simibubi.create.content.contraptions.chassis.StickerRenderer; import com.simibubi.create.content.contraptions.chassis.StickerRenderer;
import com.simibubi.create.content.contraptions.chassis.StickerVisual;
import com.simibubi.create.content.contraptions.elevator.ElevatorContactBlockEntity; import com.simibubi.create.content.contraptions.elevator.ElevatorContactBlockEntity;
import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyBlockEntity; import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyBlockEntity;
import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyRenderer; import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyRenderer;
import com.simibubi.create.content.contraptions.gantry.GantryCarriageBlockEntity; import com.simibubi.create.content.contraptions.gantry.GantryCarriageBlockEntity;
import com.simibubi.create.content.contraptions.gantry.GantryCarriageInstance;
import com.simibubi.create.content.contraptions.gantry.GantryCarriageRenderer; import com.simibubi.create.content.contraptions.gantry.GantryCarriageRenderer;
import com.simibubi.create.content.contraptions.gantry.GantryCarriageVisual;
import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity; import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity;
import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlockEntity; import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlockEntity;
import com.simibubi.create.content.contraptions.piston.MechanicalPistonRenderer; import com.simibubi.create.content.contraptions.piston.MechanicalPistonRenderer;
import com.simibubi.create.content.contraptions.pulley.HosePulleyInstance; import com.simibubi.create.content.contraptions.pulley.HosePulleyVisual;
import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity; import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity;
import com.simibubi.create.content.contraptions.pulley.PulleyRenderer; import com.simibubi.create.content.contraptions.pulley.PulleyRenderer;
import com.simibubi.create.content.contraptions.pulley.RopePulleyInstance; import com.simibubi.create.content.contraptions.pulley.RopePulleyVisual;
import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity;
import com.simibubi.create.content.decoration.placard.PlacardBlockEntity; import com.simibubi.create.content.decoration.placard.PlacardBlockEntity;
import com.simibubi.create.content.decoration.placard.PlacardRenderer; import com.simibubi.create.content.decoration.placard.PlacardRenderer;
@ -43,13 +43,13 @@ import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorRenderer;
import com.simibubi.create.content.decoration.steamWhistle.WhistleBlockEntity; import com.simibubi.create.content.decoration.steamWhistle.WhistleBlockEntity;
import com.simibubi.create.content.decoration.steamWhistle.WhistleRenderer; import com.simibubi.create.content.decoration.steamWhistle.WhistleRenderer;
import com.simibubi.create.content.equipment.armor.BacktankBlockEntity; import com.simibubi.create.content.equipment.armor.BacktankBlockEntity;
import com.simibubi.create.content.equipment.armor.BacktankInstance;
import com.simibubi.create.content.equipment.armor.BacktankRenderer; import com.simibubi.create.content.equipment.armor.BacktankRenderer;
import com.simibubi.create.content.equipment.armor.BacktankVisual;
import com.simibubi.create.content.equipment.bell.BellRenderer; import com.simibubi.create.content.equipment.bell.BellRenderer;
import com.simibubi.create.content.equipment.bell.HauntedBellBlockEntity; import com.simibubi.create.content.equipment.bell.HauntedBellBlockEntity;
import com.simibubi.create.content.equipment.bell.PeculiarBellBlockEntity; import com.simibubi.create.content.equipment.bell.PeculiarBellBlockEntity;
import com.simibubi.create.content.equipment.clipboard.ClipboardBlockEntity; import com.simibubi.create.content.equipment.clipboard.ClipboardBlockEntity;
import com.simibubi.create.content.equipment.toolbox.ToolBoxInstance; import com.simibubi.create.content.equipment.toolbox.ToolBoxVisual;
import com.simibubi.create.content.equipment.toolbox.ToolboxBlockEntity; import com.simibubi.create.content.equipment.toolbox.ToolboxBlockEntity;
import com.simibubi.create.content.equipment.toolbox.ToolboxRenderer; import com.simibubi.create.content.equipment.toolbox.ToolboxRenderer;
import com.simibubi.create.content.fluids.drain.ItemDrainBlockEntity; import com.simibubi.create.content.fluids.drain.ItemDrainBlockEntity;
@ -61,99 +61,98 @@ import com.simibubi.create.content.fluids.pipes.SmartFluidPipeBlockEntity;
import com.simibubi.create.content.fluids.pipes.StraightPipeBlockEntity; import com.simibubi.create.content.fluids.pipes.StraightPipeBlockEntity;
import com.simibubi.create.content.fluids.pipes.TransparentStraightPipeRenderer; import com.simibubi.create.content.fluids.pipes.TransparentStraightPipeRenderer;
import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlockEntity; import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlockEntity;
import com.simibubi.create.content.fluids.pipes.valve.FluidValveInstance;
import com.simibubi.create.content.fluids.pipes.valve.FluidValveRenderer; import com.simibubi.create.content.fluids.pipes.valve.FluidValveRenderer;
import com.simibubi.create.content.fluids.pipes.valve.FluidValveVisual;
import com.simibubi.create.content.fluids.pump.PumpBlockEntity; import com.simibubi.create.content.fluids.pump.PumpBlockEntity;
import com.simibubi.create.content.fluids.pump.PumpCogInstance; import com.simibubi.create.content.fluids.pump.PumpCogVisual;
import com.simibubi.create.content.fluids.pump.PumpRenderer; import com.simibubi.create.content.fluids.pump.PumpRenderer;
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity; import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
import com.simibubi.create.content.fluids.spout.SpoutRenderer; import com.simibubi.create.content.fluids.spout.SpoutRenderer;
import com.simibubi.create.content.fluids.tank.CreativeFluidTankBlockEntity; import com.simibubi.create.content.fluids.tank.CreativeFluidTankBlockEntity;
import com.simibubi.create.content.fluids.tank.FluidTankBlockEntity; import com.simibubi.create.content.fluids.tank.FluidTankBlockEntity;
import com.simibubi.create.content.fluids.tank.FluidTankRenderer; import com.simibubi.create.content.fluids.tank.FluidTankRenderer;
import com.simibubi.create.content.kinetics.base.CutoutRotatingInstance; import com.simibubi.create.content.kinetics.base.HalfShaftVisual;
import com.simibubi.create.content.kinetics.base.HalfShaftInstance; import com.simibubi.create.content.kinetics.base.HorizontalHalfShaftVisual;
import com.simibubi.create.content.kinetics.base.HorizontalHalfShaftInstance;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.base.ShaftInstance;
import com.simibubi.create.content.kinetics.base.ShaftRenderer; import com.simibubi.create.content.kinetics.base.ShaftRenderer;
import com.simibubi.create.content.kinetics.base.SingleRotatingInstance; import com.simibubi.create.content.kinetics.base.ShaftVisual;
import com.simibubi.create.content.kinetics.base.SingleRotatingVisual;
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity; import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
import com.simibubi.create.content.kinetics.belt.BeltInstance;
import com.simibubi.create.content.kinetics.belt.BeltRenderer; import com.simibubi.create.content.kinetics.belt.BeltRenderer;
import com.simibubi.create.content.kinetics.belt.BeltVisual;
import com.simibubi.create.content.kinetics.chainDrive.ChainGearshiftBlockEntity; import com.simibubi.create.content.kinetics.chainDrive.ChainGearshiftBlockEntity;
import com.simibubi.create.content.kinetics.clock.CuckooClockBlockEntity; import com.simibubi.create.content.kinetics.clock.CuckooClockBlockEntity;
import com.simibubi.create.content.kinetics.clock.CuckooClockRenderer; import com.simibubi.create.content.kinetics.clock.CuckooClockRenderer;
import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterBlockEntity; import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterBlockEntity;
import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterRenderer; import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterRenderer;
import com.simibubi.create.content.kinetics.crafter.ShaftlessCogwheelInstance; import com.simibubi.create.content.kinetics.crafter.ShaftlessCogwheelVisual;
import com.simibubi.create.content.kinetics.crank.HandCrankBlockEntity; import com.simibubi.create.content.kinetics.crank.HandCrankBlockEntity;
import com.simibubi.create.content.kinetics.crank.HandCrankInstance;
import com.simibubi.create.content.kinetics.crank.HandCrankRenderer; import com.simibubi.create.content.kinetics.crank.HandCrankRenderer;
import com.simibubi.create.content.kinetics.crank.HandCrankVisual;
import com.simibubi.create.content.kinetics.crank.ValveHandleBlockEntity; import com.simibubi.create.content.kinetics.crank.ValveHandleBlockEntity;
import com.simibubi.create.content.kinetics.crusher.CrushingWheelBlockEntity; import com.simibubi.create.content.kinetics.crusher.CrushingWheelBlockEntity;
import com.simibubi.create.content.kinetics.crusher.CrushingWheelControllerBlockEntity; import com.simibubi.create.content.kinetics.crusher.CrushingWheelControllerBlockEntity;
import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity; import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity;
import com.simibubi.create.content.kinetics.deployer.DeployerInstance;
import com.simibubi.create.content.kinetics.deployer.DeployerRenderer; import com.simibubi.create.content.kinetics.deployer.DeployerRenderer;
import com.simibubi.create.content.kinetics.deployer.DeployerVisual;
import com.simibubi.create.content.kinetics.drill.DrillBlockEntity; import com.simibubi.create.content.kinetics.drill.DrillBlockEntity;
import com.simibubi.create.content.kinetics.drill.DrillInstance;
import com.simibubi.create.content.kinetics.drill.DrillRenderer; import com.simibubi.create.content.kinetics.drill.DrillRenderer;
import com.simibubi.create.content.kinetics.drill.DrillVisual;
import com.simibubi.create.content.kinetics.fan.EncasedFanBlockEntity; import com.simibubi.create.content.kinetics.fan.EncasedFanBlockEntity;
import com.simibubi.create.content.kinetics.fan.EncasedFanRenderer; import com.simibubi.create.content.kinetics.fan.EncasedFanRenderer;
import com.simibubi.create.content.kinetics.fan.FanInstance; import com.simibubi.create.content.kinetics.fan.FanVisual;
import com.simibubi.create.content.kinetics.fan.NozzleBlockEntity; import com.simibubi.create.content.kinetics.fan.NozzleBlockEntity;
import com.simibubi.create.content.kinetics.flywheel.FlywheelBlockEntity; import com.simibubi.create.content.kinetics.flywheel.FlywheelBlockEntity;
import com.simibubi.create.content.kinetics.flywheel.FlywheelInstance;
import com.simibubi.create.content.kinetics.flywheel.FlywheelRenderer; import com.simibubi.create.content.kinetics.flywheel.FlywheelRenderer;
import com.simibubi.create.content.kinetics.flywheel.FlywheelVisual;
import com.simibubi.create.content.kinetics.gantry.GantryShaftBlockEntity; import com.simibubi.create.content.kinetics.gantry.GantryShaftBlockEntity;
import com.simibubi.create.content.kinetics.gauge.GaugeInstance;
import com.simibubi.create.content.kinetics.gauge.GaugeRenderer; import com.simibubi.create.content.kinetics.gauge.GaugeRenderer;
import com.simibubi.create.content.kinetics.gauge.GaugeVisual;
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity; import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity; import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
import com.simibubi.create.content.kinetics.gearbox.GearboxBlockEntity; import com.simibubi.create.content.kinetics.gearbox.GearboxBlockEntity;
import com.simibubi.create.content.kinetics.gearbox.GearboxInstance;
import com.simibubi.create.content.kinetics.gearbox.GearboxRenderer; import com.simibubi.create.content.kinetics.gearbox.GearboxRenderer;
import com.simibubi.create.content.kinetics.gearbox.GearboxVisual;
import com.simibubi.create.content.kinetics.mechanicalArm.ArmBlockEntity; import com.simibubi.create.content.kinetics.mechanicalArm.ArmBlockEntity;
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInstance;
import com.simibubi.create.content.kinetics.mechanicalArm.ArmRenderer; import com.simibubi.create.content.kinetics.mechanicalArm.ArmRenderer;
import com.simibubi.create.content.kinetics.mechanicalArm.ArmVisual;
import com.simibubi.create.content.kinetics.millstone.MillstoneBlockEntity; import com.simibubi.create.content.kinetics.millstone.MillstoneBlockEntity;
import com.simibubi.create.content.kinetics.millstone.MillstoneCogInstance; import com.simibubi.create.content.kinetics.millstone.MillstoneCogVisual;
import com.simibubi.create.content.kinetics.millstone.MillstoneRenderer; import com.simibubi.create.content.kinetics.millstone.MillstoneRenderer;
import com.simibubi.create.content.kinetics.mixer.MechanicalMixerBlockEntity; import com.simibubi.create.content.kinetics.mixer.MechanicalMixerBlockEntity;
import com.simibubi.create.content.kinetics.mixer.MechanicalMixerRenderer; import com.simibubi.create.content.kinetics.mixer.MechanicalMixerRenderer;
import com.simibubi.create.content.kinetics.mixer.MixerInstance; import com.simibubi.create.content.kinetics.mixer.MixerVisual;
import com.simibubi.create.content.kinetics.motor.CreativeMotorBlockEntity; import com.simibubi.create.content.kinetics.motor.CreativeMotorBlockEntity;
import com.simibubi.create.content.kinetics.motor.CreativeMotorRenderer; import com.simibubi.create.content.kinetics.motor.CreativeMotorRenderer;
import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity; import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity;
import com.simibubi.create.content.kinetics.press.MechanicalPressRenderer; import com.simibubi.create.content.kinetics.press.MechanicalPressRenderer;
import com.simibubi.create.content.kinetics.press.PressInstance; import com.simibubi.create.content.kinetics.press.PressVisual;
import com.simibubi.create.content.kinetics.saw.SawBlockEntity; import com.simibubi.create.content.kinetics.saw.SawBlockEntity;
import com.simibubi.create.content.kinetics.saw.SawInstance;
import com.simibubi.create.content.kinetics.saw.SawRenderer; import com.simibubi.create.content.kinetics.saw.SawRenderer;
import com.simibubi.create.content.kinetics.saw.SawVisual;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityInstance;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityVisual;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity; import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogInstance;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogRenderer; import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogVisual;
import com.simibubi.create.content.kinetics.speedController.SpeedControllerBlockEntity; import com.simibubi.create.content.kinetics.speedController.SpeedControllerBlockEntity;
import com.simibubi.create.content.kinetics.speedController.SpeedControllerRenderer; import com.simibubi.create.content.kinetics.speedController.SpeedControllerRenderer;
import com.simibubi.create.content.kinetics.steamEngine.PoweredShaftBlockEntity; import com.simibubi.create.content.kinetics.steamEngine.PoweredShaftBlockEntity;
import com.simibubi.create.content.kinetics.steamEngine.SteamEngineBlockEntity; import com.simibubi.create.content.kinetics.steamEngine.SteamEngineBlockEntity;
import com.simibubi.create.content.kinetics.steamEngine.SteamEngineInstance;
import com.simibubi.create.content.kinetics.steamEngine.SteamEngineRenderer; import com.simibubi.create.content.kinetics.steamEngine.SteamEngineRenderer;
import com.simibubi.create.content.kinetics.steamEngine.SteamEngineVisual;
import com.simibubi.create.content.kinetics.transmission.ClutchBlockEntity; import com.simibubi.create.content.kinetics.transmission.ClutchBlockEntity;
import com.simibubi.create.content.kinetics.transmission.GearshiftBlockEntity; import com.simibubi.create.content.kinetics.transmission.GearshiftBlockEntity;
import com.simibubi.create.content.kinetics.transmission.SplitShaftInstance;
import com.simibubi.create.content.kinetics.transmission.SplitShaftRenderer; import com.simibubi.create.content.kinetics.transmission.SplitShaftRenderer;
import com.simibubi.create.content.kinetics.transmission.SplitShaftVisual;
import com.simibubi.create.content.kinetics.transmission.sequencer.SequencedGearshiftBlockEntity; import com.simibubi.create.content.kinetics.transmission.sequencer.SequencedGearshiftBlockEntity;
import com.simibubi.create.content.kinetics.turntable.TurntableBlockEntity; import com.simibubi.create.content.kinetics.turntable.TurntableBlockEntity;
import com.simibubi.create.content.kinetics.waterwheel.LargeWaterWheelBlockEntity; import com.simibubi.create.content.kinetics.waterwheel.LargeWaterWheelBlockEntity;
import com.simibubi.create.content.kinetics.waterwheel.WaterWheelBlockEntity; import com.simibubi.create.content.kinetics.waterwheel.WaterWheelBlockEntity;
import com.simibubi.create.content.kinetics.waterwheel.WaterWheelInstance;
import com.simibubi.create.content.kinetics.waterwheel.WaterWheelRenderer; import com.simibubi.create.content.kinetics.waterwheel.WaterWheelRenderer;
import com.simibubi.create.content.kinetics.waterwheel.WaterWheelVisual;
import com.simibubi.create.content.logistics.chute.ChuteBlockEntity; import com.simibubi.create.content.logistics.chute.ChuteBlockEntity;
import com.simibubi.create.content.logistics.chute.ChuteRenderer; import com.simibubi.create.content.logistics.chute.ChuteRenderer;
import com.simibubi.create.content.logistics.chute.SmartChuteBlockEntity; import com.simibubi.create.content.logistics.chute.SmartChuteBlockEntity;
@ -162,25 +161,26 @@ import com.simibubi.create.content.logistics.crate.CreativeCrateBlockEntity;
import com.simibubi.create.content.logistics.depot.DepotBlockEntity; import com.simibubi.create.content.logistics.depot.DepotBlockEntity;
import com.simibubi.create.content.logistics.depot.DepotRenderer; import com.simibubi.create.content.logistics.depot.DepotRenderer;
import com.simibubi.create.content.logistics.depot.EjectorBlockEntity; import com.simibubi.create.content.logistics.depot.EjectorBlockEntity;
import com.simibubi.create.content.logistics.depot.EjectorInstance;
import com.simibubi.create.content.logistics.depot.EjectorRenderer; import com.simibubi.create.content.logistics.depot.EjectorRenderer;
import com.simibubi.create.content.logistics.depot.EjectorVisual;
import com.simibubi.create.content.logistics.funnel.FunnelBlockEntity; import com.simibubi.create.content.logistics.funnel.FunnelBlockEntity;
import com.simibubi.create.content.logistics.funnel.FunnelInstance;
import com.simibubi.create.content.logistics.funnel.FunnelRenderer; import com.simibubi.create.content.logistics.funnel.FunnelRenderer;
import com.simibubi.create.content.logistics.funnel.FunnelVisual;
import com.simibubi.create.content.logistics.tunnel.BeltTunnelBlockEntity; import com.simibubi.create.content.logistics.tunnel.BeltTunnelBlockEntity;
import com.simibubi.create.content.logistics.tunnel.BeltTunnelInstance;
import com.simibubi.create.content.logistics.tunnel.BeltTunnelRenderer; import com.simibubi.create.content.logistics.tunnel.BeltTunnelRenderer;
import com.simibubi.create.content.logistics.tunnel.BeltTunnelVisual;
import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity; import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity;
import com.simibubi.create.content.logistics.vault.ItemVaultBlockEntity; import com.simibubi.create.content.logistics.vault.ItemVaultBlockEntity;
import com.simibubi.create.content.processing.basin.BasinBlockEntity; import com.simibubi.create.content.processing.basin.BasinBlockEntity;
import com.simibubi.create.content.processing.basin.BasinRenderer; import com.simibubi.create.content.processing.basin.BasinRenderer;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity; import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity;
import com.simibubi.create.content.processing.burner.BlazeBurnerRenderer; import com.simibubi.create.content.processing.burner.BlazeBurnerRenderer;
import com.simibubi.create.content.processing.burner.BlazeBurnerVisual;
import com.simibubi.create.content.redstone.analogLever.AnalogLeverBlockEntity; import com.simibubi.create.content.redstone.analogLever.AnalogLeverBlockEntity;
import com.simibubi.create.content.redstone.analogLever.AnalogLeverInstance;
import com.simibubi.create.content.redstone.analogLever.AnalogLeverRenderer; import com.simibubi.create.content.redstone.analogLever.AnalogLeverRenderer;
import com.simibubi.create.content.redstone.diodes.BrassDiodeInstance; import com.simibubi.create.content.redstone.analogLever.AnalogLeverVisual;
import com.simibubi.create.content.redstone.diodes.BrassDiodeRenderer; import com.simibubi.create.content.redstone.diodes.BrassDiodeRenderer;
import com.simibubi.create.content.redstone.diodes.BrassDiodeVisual;
import com.simibubi.create.content.redstone.diodes.PulseExtenderBlockEntity; import com.simibubi.create.content.redstone.diodes.PulseExtenderBlockEntity;
import com.simibubi.create.content.redstone.diodes.PulseRepeaterBlockEntity; import com.simibubi.create.content.redstone.diodes.PulseRepeaterBlockEntity;
import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockEntity; import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockEntity;
@ -195,8 +195,8 @@ import com.simibubi.create.content.redstone.nixieTube.NixieTubeRenderer;
import com.simibubi.create.content.redstone.smartObserver.SmartObserverBlockEntity; import com.simibubi.create.content.redstone.smartObserver.SmartObserverBlockEntity;
import com.simibubi.create.content.redstone.thresholdSwitch.ThresholdSwitchBlockEntity; import com.simibubi.create.content.redstone.thresholdSwitch.ThresholdSwitchBlockEntity;
import com.simibubi.create.content.schematics.cannon.SchematicannonBlockEntity; import com.simibubi.create.content.schematics.cannon.SchematicannonBlockEntity;
import com.simibubi.create.content.schematics.cannon.SchematicannonInstance;
import com.simibubi.create.content.schematics.cannon.SchematicannonRenderer; import com.simibubi.create.content.schematics.cannon.SchematicannonRenderer;
import com.simibubi.create.content.schematics.cannon.SchematicannonVisual;
import com.simibubi.create.content.schematics.table.SchematicTableBlockEntity; import com.simibubi.create.content.schematics.table.SchematicTableBlockEntity;
import com.simibubi.create.content.trains.bogey.BogeyBlockEntityRenderer; import com.simibubi.create.content.trains.bogey.BogeyBlockEntityRenderer;
import com.simibubi.create.content.trains.bogey.StandardBogeyBlockEntity; import com.simibubi.create.content.trains.bogey.StandardBogeyBlockEntity;
@ -210,9 +210,9 @@ import com.simibubi.create.content.trains.station.StationBlockEntity;
import com.simibubi.create.content.trains.station.StationRenderer; import com.simibubi.create.content.trains.station.StationRenderer;
import com.simibubi.create.content.trains.track.FakeTrackBlockEntity; import com.simibubi.create.content.trains.track.FakeTrackBlockEntity;
import com.simibubi.create.content.trains.track.TrackBlockEntity; import com.simibubi.create.content.trains.track.TrackBlockEntity;
import com.simibubi.create.content.trains.track.TrackInstance;
import com.simibubi.create.content.trains.track.TrackMaterial; import com.simibubi.create.content.trains.track.TrackMaterial;
import com.simibubi.create.content.trains.track.TrackRenderer; import com.simibubi.create.content.trains.track.TrackRenderer;
import com.simibubi.create.content.trains.track.TrackVisual;
import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer;
import com.tterrag.registrate.util.entry.BlockEntityEntry; import com.tterrag.registrate.util.entry.BlockEntityEntry;
@ -221,7 +221,7 @@ public class AllBlockEntityTypes {
// Schematics // Schematics
public static final BlockEntityEntry<SchematicannonBlockEntity> SCHEMATICANNON = REGISTRATE public static final BlockEntityEntry<SchematicannonBlockEntity> SCHEMATICANNON = REGISTRATE
.blockEntity("schematicannon", SchematicannonBlockEntity::new) .blockEntity("schematicannon", SchematicannonBlockEntity::new)
.instance(() -> SchematicannonInstance::new) .visual(() -> SchematicannonVisual::new)
.validBlocks(AllBlocks.SCHEMATICANNON) .validBlocks(AllBlocks.SCHEMATICANNON)
.renderer(() -> SchematicannonRenderer::new) .renderer(() -> SchematicannonRenderer::new)
.register(); .register();
@ -234,28 +234,28 @@ public class AllBlockEntityTypes {
// Kinetics // Kinetics
public static final BlockEntityEntry<BracketedKineticBlockEntity> BRACKETED_KINETIC = REGISTRATE public static final BlockEntityEntry<BracketedKineticBlockEntity> BRACKETED_KINETIC = REGISTRATE
.blockEntity("simple_kinetic", BracketedKineticBlockEntity::new) .blockEntity("simple_kinetic", BracketedKineticBlockEntity::new)
.instance(() -> BracketedKineticBlockEntityInstance::new, false) .visual(() -> BracketedKineticBlockEntityVisual::new, false)
.validBlocks(AllBlocks.SHAFT, AllBlocks.COGWHEEL, AllBlocks.LARGE_COGWHEEL) .validBlocks(AllBlocks.SHAFT, AllBlocks.COGWHEEL, AllBlocks.LARGE_COGWHEEL)
.renderer(() -> BracketedKineticBlockEntityRenderer::new) .renderer(() -> BracketedKineticBlockEntityRenderer::new)
.register(); .register();
public static final BlockEntityEntry<CreativeMotorBlockEntity> MOTOR = REGISTRATE public static final BlockEntityEntry<CreativeMotorBlockEntity> MOTOR = REGISTRATE
.blockEntity("motor", CreativeMotorBlockEntity::new) .blockEntity("motor", CreativeMotorBlockEntity::new)
.instance(() -> HalfShaftInstance::new, false) .visual(() -> HalfShaftVisual::new, false)
.validBlocks(AllBlocks.CREATIVE_MOTOR) .validBlocks(AllBlocks.CREATIVE_MOTOR)
.renderer(() -> CreativeMotorRenderer::new) .renderer(() -> CreativeMotorRenderer::new)
.register(); .register();
public static final BlockEntityEntry<GearboxBlockEntity> GEARBOX = REGISTRATE public static final BlockEntityEntry<GearboxBlockEntity> GEARBOX = REGISTRATE
.blockEntity("gearbox", GearboxBlockEntity::new) .blockEntity("gearbox", GearboxBlockEntity::new)
.instance(() -> GearboxInstance::new, false) .visual(() -> GearboxVisual::new, false)
.validBlocks(AllBlocks.GEARBOX) .validBlocks(AllBlocks.GEARBOX)
.renderer(() -> GearboxRenderer::new) .renderer(() -> GearboxRenderer::new)
.register(); .register();
public static final BlockEntityEntry<KineticBlockEntity> ENCASED_SHAFT = REGISTRATE public static final BlockEntityEntry<KineticBlockEntity> ENCASED_SHAFT = REGISTRATE
.blockEntity("encased_shaft", KineticBlockEntity::new) .blockEntity("encased_shaft", KineticBlockEntity::new)
.instance(() -> ShaftInstance::new, false) .visual(() -> ShaftVisual::new, false)
.validBlocks(AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT, AllBlocks.ENCASED_CHAIN_DRIVE, .validBlocks(AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT, AllBlocks.ENCASED_CHAIN_DRIVE,
AllBlocks.METAL_GIRDER_ENCASED_SHAFT) AllBlocks.METAL_GIRDER_ENCASED_SHAFT)
.renderer(() -> ShaftRenderer::new) .renderer(() -> ShaftRenderer::new)
@ -263,28 +263,28 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<SimpleKineticBlockEntity> ENCASED_COGWHEEL = REGISTRATE public static final BlockEntityEntry<SimpleKineticBlockEntity> ENCASED_COGWHEEL = REGISTRATE
.blockEntity("encased_cogwheel", SimpleKineticBlockEntity::new) .blockEntity("encased_cogwheel", SimpleKineticBlockEntity::new)
.instance(() -> EncasedCogInstance::small, false) .visual(() -> EncasedCogVisual::small, false)
.validBlocks(AllBlocks.ANDESITE_ENCASED_COGWHEEL, AllBlocks.BRASS_ENCASED_COGWHEEL) .validBlocks(AllBlocks.ANDESITE_ENCASED_COGWHEEL, AllBlocks.BRASS_ENCASED_COGWHEEL)
.renderer(() -> EncasedCogRenderer::small) .renderer(() -> EncasedCogRenderer::small)
.register(); .register();
public static final BlockEntityEntry<SimpleKineticBlockEntity> ENCASED_LARGE_COGWHEEL = REGISTRATE public static final BlockEntityEntry<SimpleKineticBlockEntity> ENCASED_LARGE_COGWHEEL = REGISTRATE
.blockEntity("encased_large_cogwheel", SimpleKineticBlockEntity::new) .blockEntity("encased_large_cogwheel", SimpleKineticBlockEntity::new)
.instance(() -> EncasedCogInstance::large, false) .visual(() -> EncasedCogVisual::large, false)
.validBlocks(AllBlocks.ANDESITE_ENCASED_LARGE_COGWHEEL, AllBlocks.BRASS_ENCASED_LARGE_COGWHEEL) .validBlocks(AllBlocks.ANDESITE_ENCASED_LARGE_COGWHEEL, AllBlocks.BRASS_ENCASED_LARGE_COGWHEEL)
.renderer(() -> EncasedCogRenderer::large) .renderer(() -> EncasedCogRenderer::large)
.register(); .register();
public static final BlockEntityEntry<ChainGearshiftBlockEntity> ADJUSTABLE_CHAIN_GEARSHIFT = REGISTRATE public static final BlockEntityEntry<ChainGearshiftBlockEntity> ADJUSTABLE_CHAIN_GEARSHIFT = REGISTRATE
.blockEntity("adjustable_chain_gearshift", ChainGearshiftBlockEntity::new) .blockEntity("adjustable_chain_gearshift", ChainGearshiftBlockEntity::new)
.instance(() -> ShaftInstance::new, false) .visual(() -> ShaftVisual::new, false)
.validBlocks(AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT) .validBlocks(AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT)
.renderer(() -> ShaftRenderer::new) .renderer(() -> ShaftRenderer::new)
.register(); .register();
public static final BlockEntityEntry<EncasedFanBlockEntity> ENCASED_FAN = REGISTRATE public static final BlockEntityEntry<EncasedFanBlockEntity> ENCASED_FAN = REGISTRATE
.blockEntity("encased_fan", EncasedFanBlockEntity::new) .blockEntity("encased_fan", EncasedFanBlockEntity::new)
.instance(() -> FanInstance::new, false) .visual(() -> FanVisual::new, false)
.validBlocks(AllBlocks.ENCASED_FAN) .validBlocks(AllBlocks.ENCASED_FAN)
.renderer(() -> EncasedFanRenderer::new) .renderer(() -> EncasedFanRenderer::new)
.register(); .register();
@ -297,35 +297,35 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<ClutchBlockEntity> CLUTCH = REGISTRATE public static final BlockEntityEntry<ClutchBlockEntity> CLUTCH = REGISTRATE
.blockEntity("clutch", ClutchBlockEntity::new) .blockEntity("clutch", ClutchBlockEntity::new)
.instance(() -> SplitShaftInstance::new, false) .visual(() -> SplitShaftVisual::new, false)
.validBlocks(AllBlocks.CLUTCH) .validBlocks(AllBlocks.CLUTCH)
.renderer(() -> SplitShaftRenderer::new) .renderer(() -> SplitShaftRenderer::new)
.register(); .register();
public static final BlockEntityEntry<GearshiftBlockEntity> GEARSHIFT = REGISTRATE public static final BlockEntityEntry<GearshiftBlockEntity> GEARSHIFT = REGISTRATE
.blockEntity("gearshift", GearshiftBlockEntity::new) .blockEntity("gearshift", GearshiftBlockEntity::new)
.instance(() -> SplitShaftInstance::new, false) .visual(() -> SplitShaftVisual::new, false)
.validBlocks(AllBlocks.GEARSHIFT) .validBlocks(AllBlocks.GEARSHIFT)
.renderer(() -> SplitShaftRenderer::new) .renderer(() -> SplitShaftRenderer::new)
.register(); .register();
public static final BlockEntityEntry<TurntableBlockEntity> TURNTABLE = REGISTRATE public static final BlockEntityEntry<TurntableBlockEntity> TURNTABLE = REGISTRATE
.blockEntity("turntable", TurntableBlockEntity::new) .blockEntity("turntable", TurntableBlockEntity::new)
.instance(() -> SingleRotatingInstance::new, false) .visual(() -> SingleRotatingVisual::new, false)
.validBlocks(AllBlocks.TURNTABLE) .validBlocks(AllBlocks.TURNTABLE)
.renderer(() -> KineticBlockEntityRenderer::new) .renderer(() -> KineticBlockEntityRenderer::new)
.register(); .register();
public static final BlockEntityEntry<HandCrankBlockEntity> HAND_CRANK = REGISTRATE public static final BlockEntityEntry<HandCrankBlockEntity> HAND_CRANK = REGISTRATE
.blockEntity("hand_crank", HandCrankBlockEntity::new) .blockEntity("hand_crank", HandCrankBlockEntity::new)
.instance(() -> HandCrankInstance::new) .visual(() -> HandCrankVisual::new)
.validBlocks(AllBlocks.HAND_CRANK) .validBlocks(AllBlocks.HAND_CRANK)
.renderer(() -> HandCrankRenderer::new) .renderer(() -> HandCrankRenderer::new)
.register(); .register();
public static final BlockEntityEntry<ValveHandleBlockEntity> VALVE_HANDLE = REGISTRATE public static final BlockEntityEntry<ValveHandleBlockEntity> VALVE_HANDLE = REGISTRATE
.blockEntity("valve_handle", ValveHandleBlockEntity::new) .blockEntity("valve_handle", ValveHandleBlockEntity::new)
.instance(() -> HandCrankInstance::new) .visual(() -> HandCrankVisual::new)
.validBlocks(AllBlocks.COPPER_VALVE_HANDLE) .validBlocks(AllBlocks.COPPER_VALVE_HANDLE)
.validBlocks(AllBlocks.DYED_VALVE_HANDLES.toArray()) .validBlocks(AllBlocks.DYED_VALVE_HANDLES.toArray())
.renderer(() -> HandCrankRenderer::new) .renderer(() -> HandCrankRenderer::new)
@ -333,28 +333,28 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<CuckooClockBlockEntity> CUCKOO_CLOCK = REGISTRATE public static final BlockEntityEntry<CuckooClockBlockEntity> CUCKOO_CLOCK = REGISTRATE
.blockEntity("cuckoo_clock", CuckooClockBlockEntity::new) .blockEntity("cuckoo_clock", CuckooClockBlockEntity::new)
.instance(() -> HorizontalHalfShaftInstance::new) .visual(() -> HorizontalHalfShaftVisual::new)
.validBlocks(AllBlocks.CUCKOO_CLOCK, AllBlocks.MYSTERIOUS_CUCKOO_CLOCK) .validBlocks(AllBlocks.CUCKOO_CLOCK, AllBlocks.MYSTERIOUS_CUCKOO_CLOCK)
.renderer(() -> CuckooClockRenderer::new) .renderer(() -> CuckooClockRenderer::new)
.register(); .register();
public static final BlockEntityEntry<GantryShaftBlockEntity> GANTRY_SHAFT = REGISTRATE public static final BlockEntityEntry<GantryShaftBlockEntity> GANTRY_SHAFT = REGISTRATE
.blockEntity("gantry_shaft", GantryShaftBlockEntity::new) .blockEntity("gantry_shaft", GantryShaftBlockEntity::new)
.instance(() -> SingleRotatingInstance::new, false) .visual(() -> SingleRotatingVisual::new, false)
.validBlocks(AllBlocks.GANTRY_SHAFT) .validBlocks(AllBlocks.GANTRY_SHAFT)
.renderer(() -> KineticBlockEntityRenderer::new) .renderer(() -> KineticBlockEntityRenderer::new)
.register(); .register();
public static final BlockEntityEntry<GantryCarriageBlockEntity> GANTRY_PINION = REGISTRATE public static final BlockEntityEntry<GantryCarriageBlockEntity> GANTRY_PINION = REGISTRATE
.blockEntity("gantry_pinion", GantryCarriageBlockEntity::new) .blockEntity("gantry_pinion", GantryCarriageBlockEntity::new)
.instance(() -> GantryCarriageInstance::new) .visual(() -> GantryCarriageVisual::new)
.validBlocks(AllBlocks.GANTRY_CARRIAGE) .validBlocks(AllBlocks.GANTRY_CARRIAGE)
.renderer(() -> GantryCarriageRenderer::new) .renderer(() -> GantryCarriageRenderer::new)
.register(); .register();
public static final BlockEntityEntry<PumpBlockEntity> MECHANICAL_PUMP = REGISTRATE public static final BlockEntityEntry<PumpBlockEntity> MECHANICAL_PUMP = REGISTRATE
.blockEntity("mechanical_pump", PumpBlockEntity::new) .blockEntity("mechanical_pump", PumpBlockEntity::new)
.instance(() -> PumpCogInstance::new) .visual(() -> PumpCogVisual::new)
.validBlocks(AllBlocks.MECHANICAL_PUMP) .validBlocks(AllBlocks.MECHANICAL_PUMP)
.renderer(() -> PumpRenderer::new) .renderer(() -> PumpRenderer::new)
.register(); .register();
@ -383,7 +383,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<FluidValveBlockEntity> FLUID_VALVE = REGISTRATE public static final BlockEntityEntry<FluidValveBlockEntity> FLUID_VALVE = REGISTRATE
.blockEntity("fluid_valve", FluidValveBlockEntity::new) .blockEntity("fluid_valve", FluidValveBlockEntity::new)
.instance(() -> FluidValveInstance::new) .visual(() -> FluidValveVisual::new)
.validBlocks(AllBlocks.FLUID_VALVE) .validBlocks(AllBlocks.FLUID_VALVE)
.renderer(() -> FluidValveRenderer::new) .renderer(() -> FluidValveRenderer::new)
.register(); .register();
@ -402,7 +402,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<HosePulleyBlockEntity> HOSE_PULLEY = REGISTRATE public static final BlockEntityEntry<HosePulleyBlockEntity> HOSE_PULLEY = REGISTRATE
.blockEntity("hose_pulley", HosePulleyBlockEntity::new) .blockEntity("hose_pulley", HosePulleyBlockEntity::new)
.instance(() -> HosePulleyInstance::new) .visual(() -> HosePulleyVisual::new)
.validBlocks(AllBlocks.HOSE_PULLEY) .validBlocks(AllBlocks.HOSE_PULLEY)
.renderer(() -> HosePulleyRenderer::new) .renderer(() -> HosePulleyRenderer::new)
.register(); .register();
@ -421,7 +421,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<BeltBlockEntity> BELT = REGISTRATE public static final BlockEntityEntry<BeltBlockEntity> BELT = REGISTRATE
.blockEntity("belt", BeltBlockEntity::new) .blockEntity("belt", BeltBlockEntity::new)
.instance(() -> BeltInstance::new, BeltBlockEntity::shouldRenderNormally) .visual(() -> BeltVisual::new, BeltBlockEntity::shouldRenderNormally)
.validBlocks(AllBlocks.BELT) .validBlocks(AllBlocks.BELT)
.renderer(() -> BeltRenderer::new) .renderer(() -> BeltRenderer::new)
.register(); .register();
@ -440,21 +440,21 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<BeltTunnelBlockEntity> ANDESITE_TUNNEL = REGISTRATE public static final BlockEntityEntry<BeltTunnelBlockEntity> ANDESITE_TUNNEL = REGISTRATE
.blockEntity("andesite_tunnel", BeltTunnelBlockEntity::new) .blockEntity("andesite_tunnel", BeltTunnelBlockEntity::new)
.instance(() -> BeltTunnelInstance::new) .visual(() -> BeltTunnelVisual::new)
.validBlocks(AllBlocks.ANDESITE_TUNNEL) .validBlocks(AllBlocks.ANDESITE_TUNNEL)
.renderer(() -> BeltTunnelRenderer::new) .renderer(() -> BeltTunnelRenderer::new)
.register(); .register();
public static final BlockEntityEntry<BrassTunnelBlockEntity> BRASS_TUNNEL = REGISTRATE public static final BlockEntityEntry<BrassTunnelBlockEntity> BRASS_TUNNEL = REGISTRATE
.blockEntity("brass_tunnel", BrassTunnelBlockEntity::new) .blockEntity("brass_tunnel", BrassTunnelBlockEntity::new)
.instance(() -> BeltTunnelInstance::new) .visual(() -> BeltTunnelVisual::new)
.validBlocks(AllBlocks.BRASS_TUNNEL) .validBlocks(AllBlocks.BRASS_TUNNEL)
.renderer(() -> BeltTunnelRenderer::new) .renderer(() -> BeltTunnelRenderer::new)
.register(); .register();
public static final BlockEntityEntry<ArmBlockEntity> MECHANICAL_ARM = REGISTRATE public static final BlockEntityEntry<ArmBlockEntity> MECHANICAL_ARM = REGISTRATE
.blockEntity("mechanical_arm", ArmBlockEntity::new) .blockEntity("mechanical_arm", ArmBlockEntity::new)
.instance(() -> ArmInstance::new) .visual(() -> ArmVisual::new)
.validBlocks(AllBlocks.MECHANICAL_ARM) .validBlocks(AllBlocks.MECHANICAL_ARM)
.renderer(() -> ArmRenderer::new) .renderer(() -> ArmRenderer::new)
.register(); .register();
@ -466,35 +466,35 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<MechanicalPistonBlockEntity> MECHANICAL_PISTON = REGISTRATE public static final BlockEntityEntry<MechanicalPistonBlockEntity> MECHANICAL_PISTON = REGISTRATE
.blockEntity("mechanical_piston", MechanicalPistonBlockEntity::new) .blockEntity("mechanical_piston", MechanicalPistonBlockEntity::new)
.instance(() -> ShaftInstance::new, false) .visual(() -> ShaftVisual::new, false)
.validBlocks(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON) .validBlocks(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON)
.renderer(() -> MechanicalPistonRenderer::new) .renderer(() -> MechanicalPistonRenderer::new)
.register(); .register();
public static final BlockEntityEntry<WindmillBearingBlockEntity> WINDMILL_BEARING = REGISTRATE public static final BlockEntityEntry<WindmillBearingBlockEntity> WINDMILL_BEARING = REGISTRATE
.blockEntity("windmill_bearing", WindmillBearingBlockEntity::new) .blockEntity("windmill_bearing", WindmillBearingBlockEntity::new)
.instance(() -> BearingInstance::new) .visual(() -> BearingVisual::new)
.validBlocks(AllBlocks.WINDMILL_BEARING) .validBlocks(AllBlocks.WINDMILL_BEARING)
.renderer(() -> BearingRenderer::new) .renderer(() -> BearingRenderer::new)
.register(); .register();
public static final BlockEntityEntry<MechanicalBearingBlockEntity> MECHANICAL_BEARING = REGISTRATE public static final BlockEntityEntry<MechanicalBearingBlockEntity> MECHANICAL_BEARING = REGISTRATE
.blockEntity("mechanical_bearing", MechanicalBearingBlockEntity::new) .blockEntity("mechanical_bearing", MechanicalBearingBlockEntity::new)
.instance(() -> BearingInstance::new) .visual(() -> BearingVisual::new)
.validBlocks(AllBlocks.MECHANICAL_BEARING) .validBlocks(AllBlocks.MECHANICAL_BEARING)
.renderer(() -> BearingRenderer::new) .renderer(() -> BearingRenderer::new)
.register(); .register();
public static final BlockEntityEntry<ClockworkBearingBlockEntity> CLOCKWORK_BEARING = REGISTRATE public static final BlockEntityEntry<ClockworkBearingBlockEntity> CLOCKWORK_BEARING = REGISTRATE
.blockEntity("clockwork_bearing", ClockworkBearingBlockEntity::new) .blockEntity("clockwork_bearing", ClockworkBearingBlockEntity::new)
.instance(() -> BearingInstance::new) .visual(() -> BearingVisual::new)
.validBlocks(AllBlocks.CLOCKWORK_BEARING) .validBlocks(AllBlocks.CLOCKWORK_BEARING)
.renderer(() -> BearingRenderer::new) .renderer(() -> BearingRenderer::new)
.register(); .register();
public static final BlockEntityEntry<PulleyBlockEntity> ROPE_PULLEY = REGISTRATE public static final BlockEntityEntry<PulleyBlockEntity> ROPE_PULLEY = REGISTRATE
.blockEntity("rope_pulley", PulleyBlockEntity::new) .blockEntity("rope_pulley", PulleyBlockEntity::new)
.instance(() -> RopePulleyInstance::new, false) .visual(() -> RopePulleyVisual::new, false)
.validBlocks(AllBlocks.ROPE_PULLEY) .validBlocks(AllBlocks.ROPE_PULLEY)
.renderer(() -> PulleyRenderer::new) .renderer(() -> PulleyRenderer::new)
.register(); .register();
@ -519,7 +519,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<StickerBlockEntity> STICKER = REGISTRATE public static final BlockEntityEntry<StickerBlockEntity> STICKER = REGISTRATE
.blockEntity("sticker", StickerBlockEntity::new) .blockEntity("sticker", StickerBlockEntity::new)
.instance(() -> StickerInstance::new, false) .visual(() -> StickerVisual::new, false)
.validBlocks(AllBlocks.STICKER) .validBlocks(AllBlocks.STICKER)
.renderer(() -> StickerRenderer::new) .renderer(() -> StickerRenderer::new)
.register(); .register();
@ -532,14 +532,14 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<DrillBlockEntity> DRILL = REGISTRATE public static final BlockEntityEntry<DrillBlockEntity> DRILL = REGISTRATE
.blockEntity("drill", DrillBlockEntity::new) .blockEntity("drill", DrillBlockEntity::new)
.instance(() -> DrillInstance::new, false) .visual(() -> DrillVisual::new, false)
.validBlocks(AllBlocks.MECHANICAL_DRILL) .validBlocks(AllBlocks.MECHANICAL_DRILL)
.renderer(() -> DrillRenderer::new) .renderer(() -> DrillRenderer::new)
.register(); .register();
public static final BlockEntityEntry<SawBlockEntity> SAW = REGISTRATE public static final BlockEntityEntry<SawBlockEntity> SAW = REGISTRATE
.blockEntity("saw", SawBlockEntity::new) .blockEntity("saw", SawBlockEntity::new)
.instance(() -> SawInstance::new) .visual(() -> SawVisual::new)
.validBlocks(AllBlocks.MECHANICAL_SAW) .validBlocks(AllBlocks.MECHANICAL_SAW)
.renderer(() -> SawRenderer::new) .renderer(() -> SawRenderer::new)
.register(); .register();
@ -559,7 +559,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<PortableItemInterfaceBlockEntity> PORTABLE_STORAGE_INTERFACE = public static final BlockEntityEntry<PortableItemInterfaceBlockEntity> PORTABLE_STORAGE_INTERFACE =
REGISTRATE REGISTRATE
.blockEntity("portable_storage_interface", PortableItemInterfaceBlockEntity::new) .blockEntity("portable_storage_interface", PortableItemInterfaceBlockEntity::new)
.instance(() -> PSIInstance::new) .visual(() -> PSIVisual::new)
.validBlocks(AllBlocks.PORTABLE_STORAGE_INTERFACE) .validBlocks(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.renderer(() -> PortableStorageInterfaceRenderer::new) .renderer(() -> PortableStorageInterfaceRenderer::new)
.register(); .register();
@ -567,14 +567,14 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<PortableFluidInterfaceBlockEntity> PORTABLE_FLUID_INTERFACE = public static final BlockEntityEntry<PortableFluidInterfaceBlockEntity> PORTABLE_FLUID_INTERFACE =
REGISTRATE REGISTRATE
.blockEntity("portable_fluid_interface", PortableFluidInterfaceBlockEntity::new) .blockEntity("portable_fluid_interface", PortableFluidInterfaceBlockEntity::new)
.instance(() -> PSIInstance::new) .visual(() -> PSIVisual::new)
.validBlocks(AllBlocks.PORTABLE_FLUID_INTERFACE) .validBlocks(AllBlocks.PORTABLE_FLUID_INTERFACE)
.renderer(() -> PortableStorageInterfaceRenderer::new) .renderer(() -> PortableStorageInterfaceRenderer::new)
.register(); .register();
public static final BlockEntityEntry<SteamEngineBlockEntity> STEAM_ENGINE = REGISTRATE public static final BlockEntityEntry<SteamEngineBlockEntity> STEAM_ENGINE = REGISTRATE
.blockEntity("steam_engine", SteamEngineBlockEntity::new) .blockEntity("steam_engine", SteamEngineBlockEntity::new)
.instance(() -> SteamEngineInstance::new, false) .visual(() -> SteamEngineVisual::new, false)
.validBlocks(AllBlocks.STEAM_ENGINE) .validBlocks(AllBlocks.STEAM_ENGINE)
.renderer(() -> SteamEngineRenderer::new) .renderer(() -> SteamEngineRenderer::new)
.register(); .register();
@ -587,28 +587,28 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<PoweredShaftBlockEntity> POWERED_SHAFT = REGISTRATE public static final BlockEntityEntry<PoweredShaftBlockEntity> POWERED_SHAFT = REGISTRATE
.blockEntity("powered_shaft", PoweredShaftBlockEntity::new) .blockEntity("powered_shaft", PoweredShaftBlockEntity::new)
.instance(() -> SingleRotatingInstance::new, false) .visual(() -> SingleRotatingVisual::new, false)
.validBlocks(AllBlocks.POWERED_SHAFT) .validBlocks(AllBlocks.POWERED_SHAFT)
.renderer(() -> KineticBlockEntityRenderer::new) .renderer(() -> KineticBlockEntityRenderer::new)
.register(); .register();
public static final BlockEntityEntry<FlywheelBlockEntity> FLYWHEEL = REGISTRATE public static final BlockEntityEntry<FlywheelBlockEntity> FLYWHEEL = REGISTRATE
.blockEntity("flywheel", FlywheelBlockEntity::new) .blockEntity("flywheel", FlywheelBlockEntity::new)
.instance(() -> FlywheelInstance::new, false) .visual(() -> FlywheelVisual::new, false)
.validBlocks(AllBlocks.FLYWHEEL) .validBlocks(AllBlocks.FLYWHEEL)
.renderer(() -> FlywheelRenderer::new) .renderer(() -> FlywheelRenderer::new)
.register(); .register();
public static final BlockEntityEntry<MillstoneBlockEntity> MILLSTONE = REGISTRATE public static final BlockEntityEntry<MillstoneBlockEntity> MILLSTONE = REGISTRATE
.blockEntity("millstone", MillstoneBlockEntity::new) .blockEntity("millstone", MillstoneBlockEntity::new)
.instance(() -> MillstoneCogInstance::new, false) .visual(() -> MillstoneCogVisual::new, false)
.validBlocks(AllBlocks.MILLSTONE) .validBlocks(AllBlocks.MILLSTONE)
.renderer(() -> MillstoneRenderer::new) .renderer(() -> MillstoneRenderer::new)
.register(); .register();
public static final BlockEntityEntry<CrushingWheelBlockEntity> CRUSHING_WHEEL = REGISTRATE public static final BlockEntityEntry<CrushingWheelBlockEntity> CRUSHING_WHEEL = REGISTRATE
.blockEntity("crushing_wheel", CrushingWheelBlockEntity::new) .blockEntity("crushing_wheel", CrushingWheelBlockEntity::new)
.instance(() -> CutoutRotatingInstance::new, false) .visual(() -> SingleRotatingVisual::new, false)
.validBlocks(AllBlocks.CRUSHING_WHEEL) .validBlocks(AllBlocks.CRUSHING_WHEEL)
.renderer(() -> KineticBlockEntityRenderer::new) .renderer(() -> KineticBlockEntityRenderer::new)
.register(); .register();
@ -622,35 +622,35 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<WaterWheelBlockEntity> WATER_WHEEL = REGISTRATE public static final BlockEntityEntry<WaterWheelBlockEntity> WATER_WHEEL = REGISTRATE
.blockEntity("water_wheel", WaterWheelBlockEntity::new) .blockEntity("water_wheel", WaterWheelBlockEntity::new)
.instance(() -> WaterWheelInstance::standard, false) .visual(() -> WaterWheelVisual::standard, false)
.validBlocks(AllBlocks.WATER_WHEEL) .validBlocks(AllBlocks.WATER_WHEEL)
.renderer(() -> WaterWheelRenderer::standard) .renderer(() -> WaterWheelRenderer::standard)
.register(); .register();
public static final BlockEntityEntry<LargeWaterWheelBlockEntity> LARGE_WATER_WHEEL = REGISTRATE public static final BlockEntityEntry<LargeWaterWheelBlockEntity> LARGE_WATER_WHEEL = REGISTRATE
.blockEntity("large_water_wheel", LargeWaterWheelBlockEntity::new) .blockEntity("large_water_wheel", LargeWaterWheelBlockEntity::new)
.instance(() -> WaterWheelInstance::large, false) .visual(() -> WaterWheelVisual::large, false)
.validBlocks(AllBlocks.LARGE_WATER_WHEEL) .validBlocks(AllBlocks.LARGE_WATER_WHEEL)
.renderer(() -> WaterWheelRenderer::large) .renderer(() -> WaterWheelRenderer::large)
.register(); .register();
public static final BlockEntityEntry<MechanicalPressBlockEntity> MECHANICAL_PRESS = REGISTRATE public static final BlockEntityEntry<MechanicalPressBlockEntity> MECHANICAL_PRESS = REGISTRATE
.blockEntity("mechanical_press", MechanicalPressBlockEntity::new) .blockEntity("mechanical_press", MechanicalPressBlockEntity::new)
.instance(() -> PressInstance::new) .visual(() -> PressVisual::new)
.validBlocks(AllBlocks.MECHANICAL_PRESS) .validBlocks(AllBlocks.MECHANICAL_PRESS)
.renderer(() -> MechanicalPressRenderer::new) .renderer(() -> MechanicalPressRenderer::new)
.register(); .register();
public static final BlockEntityEntry<MechanicalMixerBlockEntity> MECHANICAL_MIXER = REGISTRATE public static final BlockEntityEntry<MechanicalMixerBlockEntity> MECHANICAL_MIXER = REGISTRATE
.blockEntity("mechanical_mixer", MechanicalMixerBlockEntity::new) .blockEntity("mechanical_mixer", MechanicalMixerBlockEntity::new)
.instance(() -> MixerInstance::new) .visual(() -> MixerVisual::new)
.validBlocks(AllBlocks.MECHANICAL_MIXER) .validBlocks(AllBlocks.MECHANICAL_MIXER)
.renderer(() -> MechanicalMixerRenderer::new) .renderer(() -> MechanicalMixerRenderer::new)
.register(); .register();
public static final BlockEntityEntry<DeployerBlockEntity> DEPLOYER = REGISTRATE public static final BlockEntityEntry<DeployerBlockEntity> DEPLOYER = REGISTRATE
.blockEntity("deployer", DeployerBlockEntity::new) .blockEntity("deployer", DeployerBlockEntity::new)
.instance(() -> DeployerInstance::new) .visual(() -> DeployerVisual::new)
.validBlocks(AllBlocks.DEPLOYER) .validBlocks(AllBlocks.DEPLOYER)
.renderer(() -> DeployerRenderer::new) .renderer(() -> DeployerRenderer::new)
.register(); .register();
@ -663,52 +663,53 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<BlazeBurnerBlockEntity> HEATER = REGISTRATE public static final BlockEntityEntry<BlazeBurnerBlockEntity> HEATER = REGISTRATE
.blockEntity("blaze_heater", BlazeBurnerBlockEntity::new) .blockEntity("blaze_heater", BlazeBurnerBlockEntity::new)
.visual(() -> BlazeBurnerVisual::new, false)
.validBlocks(AllBlocks.BLAZE_BURNER) .validBlocks(AllBlocks.BLAZE_BURNER)
.renderer(() -> BlazeBurnerRenderer::new) .renderer(() -> BlazeBurnerRenderer::new)
.register(); .register();
public static final BlockEntityEntry<MechanicalCrafterBlockEntity> MECHANICAL_CRAFTER = REGISTRATE public static final BlockEntityEntry<MechanicalCrafterBlockEntity> MECHANICAL_CRAFTER = REGISTRATE
.blockEntity("mechanical_crafter", MechanicalCrafterBlockEntity::new) .blockEntity("mechanical_crafter", MechanicalCrafterBlockEntity::new)
.instance(() -> ShaftlessCogwheelInstance::new) .visual(() -> ShaftlessCogwheelVisual::new)
.validBlocks(AllBlocks.MECHANICAL_CRAFTER) .validBlocks(AllBlocks.MECHANICAL_CRAFTER)
.renderer(() -> MechanicalCrafterRenderer::new) .renderer(() -> MechanicalCrafterRenderer::new)
.register(); .register();
public static final BlockEntityEntry<SequencedGearshiftBlockEntity> SEQUENCED_GEARSHIFT = REGISTRATE public static final BlockEntityEntry<SequencedGearshiftBlockEntity> SEQUENCED_GEARSHIFT = REGISTRATE
.blockEntity("sequenced_gearshift", SequencedGearshiftBlockEntity::new) .blockEntity("sequenced_gearshift", SequencedGearshiftBlockEntity::new)
.instance(() -> SplitShaftInstance::new, false) .visual(() -> SplitShaftVisual::new, false)
.validBlocks(AllBlocks.SEQUENCED_GEARSHIFT) .validBlocks(AllBlocks.SEQUENCED_GEARSHIFT)
.renderer(() -> SplitShaftRenderer::new) .renderer(() -> SplitShaftRenderer::new)
.register(); .register();
public static final BlockEntityEntry<SpeedControllerBlockEntity> ROTATION_SPEED_CONTROLLER = REGISTRATE public static final BlockEntityEntry<SpeedControllerBlockEntity> ROTATION_SPEED_CONTROLLER = REGISTRATE
.blockEntity("rotation_speed_controller", SpeedControllerBlockEntity::new) .blockEntity("rotation_speed_controller", SpeedControllerBlockEntity::new)
.instance(() -> ShaftInstance::new) .visual(() -> ShaftVisual::new)
.validBlocks(AllBlocks.ROTATION_SPEED_CONTROLLER) .validBlocks(AllBlocks.ROTATION_SPEED_CONTROLLER)
.renderer(() -> SpeedControllerRenderer::new) .renderer(() -> SpeedControllerRenderer::new)
.register(); .register();
public static final BlockEntityEntry<SpeedGaugeBlockEntity> SPEEDOMETER = REGISTRATE public static final BlockEntityEntry<SpeedGaugeBlockEntity> SPEEDOMETER = REGISTRATE
.blockEntity("speedometer", SpeedGaugeBlockEntity::new) .blockEntity("speedometer", SpeedGaugeBlockEntity::new)
.instance(() -> GaugeInstance.Speed::new) .visual(() -> GaugeVisual.Speed::new)
.validBlocks(AllBlocks.SPEEDOMETER) .validBlocks(AllBlocks.SPEEDOMETER)
.renderer(() -> GaugeRenderer::speed) .renderer(() -> GaugeRenderer::speed)
.register(); .register();
public static final BlockEntityEntry<StressGaugeBlockEntity> STRESSOMETER = REGISTRATE public static final BlockEntityEntry<StressGaugeBlockEntity> STRESSOMETER = REGISTRATE
.blockEntity("stressometer", StressGaugeBlockEntity::new) .blockEntity("stressometer", StressGaugeBlockEntity::new)
.instance(() -> GaugeInstance.Stress::new) .visual(() -> GaugeVisual.Stress::new)
.validBlocks(AllBlocks.STRESSOMETER) .validBlocks(AllBlocks.STRESSOMETER)
.renderer(() -> GaugeRenderer::stress) .renderer(() -> GaugeRenderer::stress)
.register(); .register();
public static final BlockEntityEntry<AnalogLeverBlockEntity> ANALOG_LEVER = REGISTRATE public static final BlockEntityEntry<AnalogLeverBlockEntity> ANALOG_LEVER = REGISTRATE
.blockEntity("analog_lever", AnalogLeverBlockEntity::new) .blockEntity("analog_lever", AnalogLeverBlockEntity::new)
.instance(() -> AnalogLeverInstance::new, false) .visual(() -> AnalogLeverVisual::new, false)
.validBlocks(AllBlocks.ANALOG_LEVER) .validBlocks(AllBlocks.ANALOG_LEVER)
.renderer(() -> AnalogLeverRenderer::new) .renderer(() -> AnalogLeverRenderer::new)
.register(); .register();
public static final BlockEntityEntry<PlacardBlockEntity> PLACARD = REGISTRATE public static final BlockEntityEntry<PlacardBlockEntity> PLACARD = REGISTRATE
.blockEntity("placard", PlacardBlockEntity::new) .blockEntity("placard", PlacardBlockEntity::new)
.validBlocks(AllBlocks.PLACARD) .validBlocks(AllBlocks.PLACARD)
@ -763,14 +764,14 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<EjectorBlockEntity> WEIGHTED_EJECTOR = REGISTRATE public static final BlockEntityEntry<EjectorBlockEntity> WEIGHTED_EJECTOR = REGISTRATE
.blockEntity("weighted_ejector", EjectorBlockEntity::new) .blockEntity("weighted_ejector", EjectorBlockEntity::new)
.instance(() -> EjectorInstance::new) .visual(() -> EjectorVisual::new)
.validBlocks(AllBlocks.WEIGHTED_EJECTOR) .validBlocks(AllBlocks.WEIGHTED_EJECTOR)
.renderer(() -> EjectorRenderer::new) .renderer(() -> EjectorRenderer::new)
.register(); .register();
public static final BlockEntityEntry<FunnelBlockEntity> FUNNEL = REGISTRATE public static final BlockEntityEntry<FunnelBlockEntity> FUNNEL = REGISTRATE
.blockEntity("funnel", FunnelBlockEntity::new) .blockEntity("funnel", FunnelBlockEntity::new)
.instance(() -> FunnelInstance::new) .visual(() -> FunnelVisual::new)
.validBlocks(AllBlocks.BRASS_FUNNEL, AllBlocks.BRASS_BELT_FUNNEL, AllBlocks.ANDESITE_FUNNEL, .validBlocks(AllBlocks.BRASS_FUNNEL, AllBlocks.BRASS_BELT_FUNNEL, AllBlocks.ANDESITE_FUNNEL,
AllBlocks.ANDESITE_BELT_FUNNEL) AllBlocks.ANDESITE_BELT_FUNNEL)
.renderer(() -> FunnelRenderer::new) .renderer(() -> FunnelRenderer::new)
@ -784,14 +785,14 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<PulseExtenderBlockEntity> PULSE_EXTENDER = REGISTRATE public static final BlockEntityEntry<PulseExtenderBlockEntity> PULSE_EXTENDER = REGISTRATE
.blockEntity("pulse_extender", PulseExtenderBlockEntity::new) .blockEntity("pulse_extender", PulseExtenderBlockEntity::new)
.instance(() -> BrassDiodeInstance::new, false) .visual(() -> BrassDiodeVisual::new, false)
.validBlocks(AllBlocks.PULSE_EXTENDER) .validBlocks(AllBlocks.PULSE_EXTENDER)
.renderer(() -> BrassDiodeRenderer::new) .renderer(() -> BrassDiodeRenderer::new)
.register(); .register();
public static final BlockEntityEntry<PulseRepeaterBlockEntity> PULSE_REPEATER = REGISTRATE public static final BlockEntityEntry<PulseRepeaterBlockEntity> PULSE_REPEATER = REGISTRATE
.blockEntity("pulse_repeater", PulseRepeaterBlockEntity::new) .blockEntity("pulse_repeater", PulseRepeaterBlockEntity::new)
.instance(() -> BrassDiodeInstance::new, false) .visual(() -> BrassDiodeVisual::new, false)
.validBlocks(AllBlocks.PULSE_REPEATER) .validBlocks(AllBlocks.PULSE_REPEATER)
.renderer(() -> BrassDiodeRenderer::new) .renderer(() -> BrassDiodeRenderer::new)
.register(); .register();
@ -805,7 +806,7 @@ public class AllBlockEntityTypes {
// Curiosities // Curiosities
public static final BlockEntityEntry<BacktankBlockEntity> BACKTANK = REGISTRATE public static final BlockEntityEntry<BacktankBlockEntity> BACKTANK = REGISTRATE
.blockEntity("backtank", BacktankBlockEntity::new) .blockEntity("backtank", BacktankBlockEntity::new)
.instance(() -> BacktankInstance::new) .visual(() -> BacktankVisual::new)
.validBlocks(AllBlocks.COPPER_BACKTANK, AllBlocks.NETHERITE_BACKTANK) .validBlocks(AllBlocks.COPPER_BACKTANK, AllBlocks.NETHERITE_BACKTANK)
.renderer(() -> BacktankRenderer::new) .renderer(() -> BacktankRenderer::new)
.register(); .register();
@ -824,18 +825,18 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<ToolboxBlockEntity> TOOLBOX = REGISTRATE public static final BlockEntityEntry<ToolboxBlockEntity> TOOLBOX = REGISTRATE
.blockEntity("toolbox", ToolboxBlockEntity::new) .blockEntity("toolbox", ToolboxBlockEntity::new)
.instance(() -> ToolBoxInstance::new, false) .visual(() -> ToolBoxVisual::new, false)
.validBlocks(AllBlocks.TOOLBOXES.toArray()) .validBlocks(AllBlocks.TOOLBOXES.toArray())
.renderer(() -> ToolboxRenderer::new) .renderer(() -> ToolboxRenderer::new)
.register(); .register();
public static final BlockEntityEntry<TrackBlockEntity> TRACK = REGISTRATE public static final BlockEntityEntry<TrackBlockEntity> TRACK = REGISTRATE
.blockEntity("track", TrackBlockEntity::new) .blockEntity("track", TrackBlockEntity::new)
.instance(() -> TrackInstance::new) .visual(() -> TrackVisual::new)
.validBlocksDeferred(TrackMaterial::allBlocks) .validBlocksDeferred(TrackMaterial::allBlocks)
.renderer(() -> TrackRenderer::new) .renderer(() -> TrackRenderer::new)
.register(); .register();
public static final BlockEntityEntry<FakeTrackBlockEntity> FAKE_TRACK = REGISTRATE public static final BlockEntityEntry<FakeTrackBlockEntity> FAKE_TRACK = REGISTRATE
.blockEntity("fake_track", FakeTrackBlockEntity::new) .blockEntity("fake_track", FakeTrackBlockEntity::new)
.validBlocks(AllBlocks.FAKE_TRACK) .validBlocks(AllBlocks.FAKE_TRACK)
@ -867,7 +868,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<FlapDisplayBlockEntity> FLAP_DISPLAY = REGISTRATE public static final BlockEntityEntry<FlapDisplayBlockEntity> FLAP_DISPLAY = REGISTRATE
.blockEntity("flap_display", FlapDisplayBlockEntity::new) .blockEntity("flap_display", FlapDisplayBlockEntity::new)
.instance(() -> ShaftlessCogwheelInstance::new) .visual(() -> ShaftlessCogwheelVisual::new)
.renderer(() -> FlapDisplayRenderer::new) .renderer(() -> FlapDisplayRenderer::new)
.validBlocks(AllBlocks.DISPLAY_BOARD) .validBlocks(AllBlocks.DISPLAY_BOARD)
.register(); .register();
@ -883,7 +884,7 @@ public class AllBlockEntityTypes {
.renderer(() -> TrackObserverRenderer::new) .renderer(() -> TrackObserverRenderer::new)
.validBlocks(AllBlocks.TRACK_OBSERVER) .validBlocks(AllBlocks.TRACK_OBSERVER)
.register(); .register();
public static final BlockEntityEntry<ClipboardBlockEntity> CLIPBOARD = REGISTRATE public static final BlockEntityEntry<ClipboardBlockEntity> CLIPBOARD = REGISTRATE
.blockEntity("clipboard", ClipboardBlockEntity::new) .blockEntity("clipboard", ClipboardBlockEntity::new)
.validBlocks(AllBlocks.CLIPBOARD) .validBlocks(AllBlocks.CLIPBOARD)

View file

@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.gantry.GantryContraptionEntity;
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.glue.SuperGlueRenderer; import com.simibubi.create.content.contraptions.glue.SuperGlueRenderer;
import com.simibubi.create.content.contraptions.render.ContraptionEntityRenderer; import com.simibubi.create.content.contraptions.render.ContraptionEntityRenderer;
import com.simibubi.create.content.contraptions.render.ContraptionVisual;
import com.simibubi.create.content.contraptions.render.OrientedContraptionEntityRenderer; import com.simibubi.create.content.contraptions.render.OrientedContraptionEntityRenderer;
import com.simibubi.create.content.equipment.blueprint.BlueprintEntity; import com.simibubi.create.content.equipment.blueprint.BlueprintEntity;
import com.simibubi.create.content.equipment.blueprint.BlueprintRenderer; import com.simibubi.create.content.equipment.blueprint.BlueprintRenderer;
@ -15,7 +16,7 @@ import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileEntity
import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileRenderer; import com.simibubi.create.content.equipment.potatoCannon.PotatoProjectileRenderer;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntityRenderer; import com.simibubi.create.content.trains.entity.CarriageContraptionEntityRenderer;
import com.simibubi.create.content.trains.entity.CarriageContraptionInstance; import com.simibubi.create.content.trains.entity.CarriageContraptionVisual;
import com.simibubi.create.foundation.data.CreateEntityBuilder; import com.simibubi.create.foundation.data.CreateEntityBuilder;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.tterrag.registrate.util.entry.EntityEntry; import com.tterrag.registrate.util.entry.EntityEntry;
@ -33,15 +34,22 @@ import net.minecraft.world.entity.MobCategory;
public class AllEntityTypes { public class AllEntityTypes {
public static final EntityEntry<OrientedContraptionEntity> ORIENTED_CONTRAPTION = contraption("contraption", public static final EntityEntry<OrientedContraptionEntity> ORIENTED_CONTRAPTION = contraption("contraption",
OrientedContraptionEntity::new, () -> OrientedContraptionEntityRenderer::new, 5, 3, true).register(); OrientedContraptionEntity::new, () -> OrientedContraptionEntityRenderer::new, 5, 3, true)
.visual(() -> ContraptionVisual::new)
.register();
public static final EntityEntry<ControlledContraptionEntity> CONTROLLED_CONTRAPTION = public static final EntityEntry<ControlledContraptionEntity> CONTROLLED_CONTRAPTION =
contraption("stationary_contraption", ControlledContraptionEntity::new, () -> ContraptionEntityRenderer::new, contraption("stationary_contraption", ControlledContraptionEntity::new, () -> ContraptionEntityRenderer::new,
20, 40, false).register(); 20, 40, false)
.visual(() -> ContraptionVisual::new)
.register();
public static final EntityEntry<GantryContraptionEntity> GANTRY_CONTRAPTION = contraption("gantry_contraption", public static final EntityEntry<GantryContraptionEntity> GANTRY_CONTRAPTION = contraption("gantry_contraption",
GantryContraptionEntity::new, () -> ContraptionEntityRenderer::new, 10, 40, false).register(); GantryContraptionEntity::new, () -> ContraptionEntityRenderer::new, 10, 40, false)
.visual(() -> ContraptionVisual::new)
.register();
public static final EntityEntry<CarriageContraptionEntity> CARRIAGE_CONTRAPTION = public static final EntityEntry<CarriageContraptionEntity> CARRIAGE_CONTRAPTION =
contraption("carriage_contraption", CarriageContraptionEntity::new, contraption("carriage_contraption", CarriageContraptionEntity::new,
() -> CarriageContraptionEntityRenderer::new, 15, 3, true).instance(() -> CarriageContraptionInstance::new) () -> CarriageContraptionEntityRenderer::new, 15, 3, true)
.visual(() -> CarriageContraptionVisual::new)
.register(); .register();
public static final EntityEntry<SuperGlueEntity> SUPER_GLUE = public static final EntityEntry<SuperGlueEntity> SUPER_GLUE =

View file

@ -6,12 +6,12 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.content.fluids.FluidTransportBehaviour; import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
@ -58,7 +58,7 @@ public class AllPartialModels {
ANALOG_LEVER_INDICATOR = block("analog_lever/indicator"), FUNNEL_FLAP = block("funnel/flap"), ANALOG_LEVER_INDICATOR = block("analog_lever/indicator"), FUNNEL_FLAP = block("funnel/flap"),
BELT_FUNNEL_FLAP = block("belt_funnel/flap"), BELT_TUNNEL_FLAP = block("belt_tunnel/flap"), BELT_FUNNEL_FLAP = block("belt_funnel/flap"), BELT_TUNNEL_FLAP = block("belt_tunnel/flap"),
FLEXPEATER_INDICATOR = block("diodes/indicator"), FLEXPEATER_INDICATOR = block("diodes/indicator"),
ROLLER_WHEEL = block("mechanical_roller/wheel"), ROLLER_WHEEL = block("mechanical_roller/wheel"),
ROLLER_FRAME = block("mechanical_roller/frame"), ROLLER_FRAME = block("mechanical_roller/frame"),
@ -67,7 +67,7 @@ public class AllPartialModels {
CUCKOO_PIG = block("cuckoo_clock/pig"), CUCKOO_CREEPER = block("cuckoo_clock/creeper"), CUCKOO_PIG = block("cuckoo_clock/pig"), CUCKOO_CREEPER = block("cuckoo_clock/creeper"),
GANTRY_COGS = block("gantry_carriage/wheels"), GANTRY_COGS = block("gantry_carriage/wheels"),
ROPE_COIL = block("rope_pulley/rope_coil"), ROPE_HALF = block("rope_pulley/rope_half"), ROPE_COIL = block("rope_pulley/rope_coil"), ROPE_HALF = block("rope_pulley/rope_half"),
ROPE_HALF_MAGNET = block("rope_pulley/rope_half_magnet"), ROPE_HALF_MAGNET = block("rope_pulley/rope_half_magnet"),
@ -208,7 +208,7 @@ public class AllPartialModels {
METAL_GIRDER_BRACKETS.put(d, block("metal_girder/bracket_" + Lang.asId(d.name()))); METAL_GIRDER_BRACKETS.put(d, block("metal_girder/bracket_" + Lang.asId(d.name())));
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
CONTRAPTION_CONTROLS_INDICATOR.add(block("contraption_controls/indicator_" + i)); CONTRAPTION_CONTROLS_INDICATOR.add(block("contraption_controls/indicator_" + i));
putFoldingDoor("andesite_door"); putFoldingDoor("andesite_door");
putFoldingDoor("copper_door"); putFoldingDoor("copper_door");
} }
@ -219,11 +219,11 @@ public class AllPartialModels {
} }
private static PartialModel block(String path) { private static PartialModel block(String path) {
return new PartialModel(Create.asResource("block/" + path)); return PartialModel.of(Create.asResource("block/" + path));
} }
private static PartialModel entity(String path) { private static PartialModel entity(String path) {
return new PartialModel(Create.asResource("entity/" + path)); return PartialModel.of(Create.asResource("entity/" + path));
} }
public static void init() { public static void init() {

View file

@ -1,8 +1,8 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.content.contraptions.glue.SuperGlueSelectionHandler; import com.simibubi.create.content.contraptions.glue.SuperGlueSelectionHandler;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfo;
import com.simibubi.create.content.contraptions.render.SBBContraptionManager; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfoManager;
import com.simibubi.create.content.decoration.encasing.CasingConnectivity; import com.simibubi.create.content.decoration.encasing.CasingConnectivity;
import com.simibubi.create.content.equipment.bell.SoulPulseEffectHandler; import com.simibubi.create.content.equipment.bell.SoulPulseEffectHandler;
import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonRenderHandler; import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonRenderHandler;
@ -18,8 +18,9 @@ import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsClient;
import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.outliner.Outliner; import com.simibubi.create.foundation.outliner.Outliner;
import com.simibubi.create.foundation.ponder.element.WorldSectionElement; import com.simibubi.create.foundation.ponder.element.WorldSectionElement;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.CreateContexts; import com.simibubi.create.foundation.render.StitchedSprite;
import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.ModelSwapper; import com.simibubi.create.foundation.utility.ModelSwapper;
@ -62,8 +63,10 @@ public class CreateClient {
public static void onCtorClient(IEventBus modEventBus, IEventBus forgeEventBus) { public static void onCtorClient(IEventBus modEventBus, IEventBus forgeEventBus) {
modEventBus.addListener(CreateClient::clientInit); modEventBus.addListener(CreateClient::clientInit);
modEventBus.addListener(AllParticleTypes::registerFactories); modEventBus.addListener(AllParticleTypes::registerFactories);
modEventBus.addListener(CreateContexts::flwInit);
modEventBus.addListener(ContraptionRenderDispatcher::gatherContext); modEventBus.addListener(StitchedSprite::onTextureStitchPost);
AllInstanceTypes.init();
MODEL_SWAPPER.registerListeners(modEventBus); MODEL_SWAPPER.registerListeners(modEventBus);
@ -77,7 +80,7 @@ public class CreateClient {
BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL); BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL);
BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK); BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK);
BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL); BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL);
BUFFER_CACHE.registerCompartment(SBBContraptionManager.CONTRAPTION, 20); BUFFER_CACHE.registerCompartment(ContraptionRenderInfo.CONTRAPTION, 20);
BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20); BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20);
AllPartialModels.init(); AllPartialModels.init();
@ -92,7 +95,7 @@ public class CreateClient {
BUFFER_CACHE.invalidate(); BUFFER_CACHE.invalidate();
SCHEMATIC_HANDLER.updateRenderers(); SCHEMATIC_HANDLER.updateRenderers();
ContraptionRenderDispatcher.reset(); ContraptionRenderInfoManager.resetAll();
} }
public static void checkGraphicsFanciness() { public static void checkGraphicsFanciness() {

View file

@ -29,20 +29,20 @@ public class GhostIngredientHandler<T extends GhostItemMenu<?>>
boolean doStart) { boolean doStart) {
boolean isAttributeFilter = gui instanceof AttributeFilterScreen; boolean isAttributeFilter = gui instanceof AttributeFilterScreen;
List<Target<I>> targets = new LinkedList<>(); List<Target<I>> targets = new LinkedList<>();
if (ingredient.getType() == VanillaTypes.ITEM_STACK) { if (ingredient.getType() == VanillaTypes.ITEM_STACK) {
for (int i = 36; i < gui.getMenu().slots.size(); i++) { for (int i = 36; i < gui.getMenu().slots.size(); i++) {
if (gui.getMenu().slots.get(i) if (gui.getMenu().slots.get(i)
.isActive()) .isActive())
targets.add(new GhostTarget<>(gui, i - 36, isAttributeFilter)); targets.add(new GhostTarget<>(gui, i - 36, isAttributeFilter));
// Only accept items in 1st slot. 2nd is used for functionality, don't wanna // Only accept items in 1st slot. 2nd is used for functionality, don't wanna
// override that one // override that one
if (isAttributeFilter) if (isAttributeFilter)
break; break;
} }
} }
return targets; return targets;
} }

View file

@ -1,8 +1,6 @@
package com.simibubi.create.compat.jei.category.animations; package com.simibubi.create.compat.jei.category.animations;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
@ -12,10 +10,10 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -84,14 +82,10 @@ public class AnimatedBlazeBurner extends AnimatedKinetics {
uScroll = uScroll - Math.floor(uScroll); uScroll = uScroll - Math.floor(uScroll);
uScroll = uScroll * spriteWidth / 2; uScroll = uScroll * spriteWidth / 2;
Minecraft mc = Minecraft.getInstance();
MultiBufferSource.BufferSource buffer = mc.renderBuffers()
.bufferSource();
VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped());
CachedBufferer.partial(AllPartialModels.BLAZE_BURNER_FLAME, Blocks.AIR.defaultBlockState()) CachedBufferer.partial(AllPartialModels.BLAZE_BURNER_FLAME, Blocks.AIR.defaultBlockState())
.shiftUVScrolling(spriteShift, (float) uScroll, (float) vScroll) .shiftUVScrolling(spriteShift, (float) uScroll, (float) vScroll)
.light(LightTexture.FULL_BRIGHT) .light(LightTexture.FULL_BRIGHT)
.renderInto(matrixStack, vb); .renderInto(matrixStack, graphics.bufferSource().getBuffer(RenderType.cutoutMipped()));
matrixStack.popPose(); matrixStack.popPose();
} }

View file

@ -1,10 +1,10 @@
package com.simibubi.create.compat.jei.category.animations; package com.simibubi.create.compat.jei.category.animations;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
public class AnimatedCrafter extends AnimatedKinetics { public class AnimatedCrafter extends AnimatedKinetics {
@ -17,9 +17,9 @@ public class AnimatedCrafter extends AnimatedKinetics {
AllGuiTextures.JEI_SHADOW.render(graphics, -16, 13); AllGuiTextures.JEI_SHADOW.render(graphics, -16, 13);
matrixStack.translate(3, 16, 0); matrixStack.translate(3, 16, 0);
TransformStack.cast(matrixStack) TransformStack.of(matrixStack)
.rotateX(-12.5f) .rotateXDegrees(-12.5f)
.rotateY(-22.5f); .rotateYDegrees(-22.5f);
int scale = 22; int scale = 22;
blockElement(cogwheel()) blockElement(cogwheel())

View file

@ -1,6 +1,5 @@
package com.simibubi.create.compat.jei.category.animations; package com.simibubi.create.compat.jei.category.animations;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.gui.CustomLightingSettings; import com.simibubi.create.foundation.gui.CustomLightingSettings;
@ -8,13 +7,14 @@ import com.simibubi.create.foundation.gui.ILightingSettings;
import com.simibubi.create.foundation.gui.element.GuiGameElement; import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public abstract class AnimatedKinetics implements IDrawable { public abstract class AnimatedKinetics implements IDrawable {
public int offset = 0; public int offset = 0;
public static final ILightingSettings DEFAULT_LIGHTING = CustomLightingSettings.builder() public static final ILightingSettings DEFAULT_LIGHTING = CustomLightingSettings.builder()

View file

@ -28,7 +28,7 @@ import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption; import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.mounted.MountedContraption; import com.simibubi.create.content.contraptions.mounted.MountedContraption;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfo;
import com.simibubi.create.content.contraptions.sync.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.sync.ContraptionSeatMappingPacket;
import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock; import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock;
import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.CarriageContraption;
@ -383,7 +383,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
if (!contraption.deferInvalidate) if (!contraption.deferInvalidate)
return; return;
contraption.deferInvalidate = false; contraption.deferInvalidate = false;
ContraptionRenderDispatcher.invalidate(contraption); ContraptionRenderInfo.invalidate(contraption);
}); });
if (!(level() instanceof ServerLevelAccessor sl)) if (!(level() instanceof ServerLevelAccessor sl))

View file

@ -18,6 +18,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -55,8 +56,6 @@ import com.simibubi.create.content.contraptions.pulley.PulleyBlock;
import com.simibubi.create.content.contraptions.pulley.PulleyBlock.MagnetBlock; import com.simibubi.create.content.contraptions.pulley.PulleyBlock.MagnetBlock;
import com.simibubi.create.content.contraptions.pulley.PulleyBlock.RopeBlock; import com.simibubi.create.content.contraptions.pulley.PulleyBlock.RopeBlock;
import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity; import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.content.contraptions.render.EmptyLighter;
import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock; import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.IRotate;
@ -121,8 +120,6 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.ModelData; import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
@ -162,8 +159,7 @@ public abstract class Contraption {
// Client // Client
public Map<BlockPos, ModelData> modelData; public Map<BlockPos, ModelData> modelData;
public Map<BlockPos, BlockEntity> presentBlockEntities; public Map<BlockPos, BlockEntity> presentBlockEntities;
public List<BlockEntity> maybeInstancedBlockEntities; public List<BlockEntity> renderedBlockEntities;
public List<BlockEntity> specialRenderedBlockEntities;
protected ContraptionWorld world; protected ContraptionWorld world;
public boolean deferInvalidate; public boolean deferInvalidate;
@ -180,8 +176,7 @@ public abstract class Contraption {
glueToRemove = new HashSet<>(); glueToRemove = new HashSet<>();
initialPassengers = new HashMap<>(); initialPassengers = new HashMap<>();
presentBlockEntities = new HashMap<>(); presentBlockEntities = new HashMap<>();
maybeInstancedBlockEntities = new ArrayList<>(); renderedBlockEntities = new ArrayList<>();
specialRenderedBlockEntities = new ArrayList<>();
pendingSubContraptions = new ArrayList<>(); pendingSubContraptions = new ArrayList<>();
stabilizedSubContraptions = new HashMap<>(); stabilizedSubContraptions = new HashMap<>();
simplifiedEntityColliders = Optional.empty(); simplifiedEntityColliders = Optional.empty();
@ -709,7 +704,7 @@ public abstract class Contraption {
public void readNBT(Level world, CompoundTag nbt, boolean spawnData) { public void readNBT(Level world, CompoundTag nbt, boolean spawnData) {
blocks.clear(); blocks.clear();
presentBlockEntities.clear(); presentBlockEntities.clear();
specialRenderedBlockEntities.clear(); renderedBlockEntities.clear();
Tag blocks = nbt.get("Blocks"); Tag blocks = nbt.get("Blocks");
// used to differentiate between the 'old' and the paletted serialization // used to differentiate between the 'old' and the paletted serialization
@ -942,20 +937,17 @@ public abstract class Contraption {
if (be == null) if (be == null)
return; return;
be.setLevel(world); be.setLevel(world);
modelData.put(info.pos(), be.getModelData());
if (be instanceof KineticBlockEntity kbe) if (be instanceof KineticBlockEntity kbe)
kbe.setSpeed(0); kbe.setSpeed(0);
be.getBlockState(); be.getBlockState();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state());
if (movementBehaviour == null || !movementBehaviour.hasSpecialInstancedRendering())
maybeInstancedBlockEntities.add(be);
if (movementBehaviour != null && !movementBehaviour.renderAsNormalBlockEntity())
return;
presentBlockEntities.put(info.pos(), be); presentBlockEntities.put(info.pos(), be);
specialRenderedBlockEntities.add(be); modelData.put(info.pos(), be.getModelData());
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state());
if (movementBehaviour == null || !movementBehaviour.disableBlockEntityRendering()) {
renderedBlockEntities.add(be);
}
}); });
} }
@ -1385,12 +1377,6 @@ public abstract class Contraption {
return interactors; return interactors;
} }
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
// TODO: move lighters to registry
return new EmptyLighter(this);
}
public void invalidateColliders() { public void invalidateColliders() {
simplifiedEntityColliders = Optional.empty(); simplifiedEntityColliders = Optional.empty();
gatherBBsOffThread(); gatherBBsOffThread();
@ -1458,12 +1444,18 @@ public abstract class Contraption {
return storage.getFluids(); return storage.getFluids();
} }
public Collection<StructureBlockInfo> getRenderedBlocks() { public RenderedBlocks getRenderedBlocks() {
return blocks.values(); return new RenderedBlocks(pos -> {
StructureBlockInfo info = blocks.get(pos);
if (info == null) {
return Blocks.AIR.defaultBlockState();
}
return info.state();
}, blocks.keySet());
} }
public Collection<BlockEntity> getSpecialRenderedBEs() { public Collection<BlockEntity> getRenderedBEs() {
return specialRenderedBlockEntities; return renderedBlockEntities;
} }
public boolean isHiddenInPortal(BlockPos localPos) { public boolean isHiddenInPortal(BlockPos localPos) {
@ -1511,4 +1503,7 @@ public abstract class Contraption {
return false; return false;
} }
public record RenderedBlocks(Function<BlockPos, BlockState> lookup, Iterable<BlockPos> positions) {
}
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions;
import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp; import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllEntityTypes; import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.content.contraptions.bearing.BearingContraption; import com.simibubi.create.content.contraptions.bearing.BearingContraption;
@ -11,6 +10,7 @@ import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
@ -51,7 +51,7 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
entity.setContraption(contraption); entity.setContraption(contraption);
return entity; return entity;
} }
@Override @Override
public void setPos(double x, double y, double z) { public void setPos(double x, double y, double z) {
super.setPos(x, y, z); super.setPos(x, y, z);
@ -246,10 +246,12 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
float angle = getAngle(partialTicks); float angle = getAngle(partialTicks);
Axis axis = getRotationAxis(); Axis axis = getRotationAxis();
TransformStack.cast(matrixStack) if (axis != null) {
.nudge(getId()) TransformStack.of(matrixStack)
.centre() .nudge(getId())
.rotate(angle, axis) .center()
.unCentre(); .rotateDegrees(angle, axis)
.uncenter();
}
} }
} }

View file

@ -2,11 +2,11 @@ package com.simibubi.create.content.contraptions;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.blockEntity.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
@ -27,8 +27,8 @@ public class DirectionalExtenderScrollOptionSlot extends CenteredSideValueBoxTra
@Override @Override
public void rotate(BlockState state, PoseStack ms) { public void rotate(BlockState state, PoseStack ms) {
if (!getSide().getAxis().isHorizontal()) if (!getSide().getAxis().isHorizontal())
TransformStack.cast(ms) TransformStack.of(ms)
.rotateY(AngleHelper.horizontalAngle(state.getValue(BlockStateProperties.FACING)) + 180); .rotateYDegrees(AngleHelper.horizontalAngle(state.getValue(BlockStateProperties.FACING)) + 180);
super.rotate(state, ms); super.rotate(state, ms);
} }
} }

View file

@ -8,7 +8,6 @@ import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllEntityTypes; import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.content.contraptions.bearing.StabilizedContraption; import com.simibubi.create.content.contraptions.bearing.StabilizedContraption;
@ -23,6 +22,7 @@ import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -539,13 +539,13 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
repositionOnContraption(matrixStack, partialTicks, ridingEntity); repositionOnContraption(matrixStack, partialTicks, ridingEntity);
} }
TransformStack.cast(matrixStack) TransformStack.of(matrixStack)
.nudge(getId()) .nudge(getId())
.centre() .center()
.rotateY(angleYaw) .rotateYDegrees(angleYaw)
.rotateZ(anglePitch) .rotateZDegrees(anglePitch)
.rotateY(angleInitialYaw) .rotateYDegrees(angleInitialYaw)
.unCentre(); .uncenter();
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)

View file

@ -0,0 +1,88 @@
package com.simibubi.create.content.contraptions.actors;
import org.joml.Quaternionf;
import org.joml.Quaternionfc;
import org.joml.Vector3f;
import dev.engine_room.flywheel.api.instance.InstanceHandle;
import dev.engine_room.flywheel.api.instance.InstanceType;
import dev.engine_room.flywheel.lib.instance.AbstractInstance;
import net.minecraft.core.BlockPos;
public class ActorInstance extends AbstractInstance {
public float x;
public float y;
public float z;
public byte blockLight;
public byte skyLight;
public float rotationOffset;
public byte rotationAxisX;
public byte rotationAxisY;
public byte rotationAxisZ;
public Quaternionf rotation = new Quaternionf();
public byte rotationCenterX = 64;
public byte rotationCenterY = 64;
public byte rotationCenterZ = 64;
public float speed;
public ActorInstance(InstanceType<?> type, InstanceHandle handle) {
super(type, handle);
}
public ActorInstance setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public ActorInstance setBlockLight(int blockLight) {
this.blockLight = (byte) blockLight;
return this;
}
public ActorInstance setSkyLight(int skyLight) {
this.skyLight = (byte) skyLight;
return this;
}
public ActorInstance setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
return this;
}
public ActorInstance setSpeed(float speed) {
this.speed = speed;
return this;
}
public ActorInstance setRotationAxis(Vector3f axis) {
setRotationAxis(axis.x(), axis.y(), axis.z());
return this;
}
public ActorInstance setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127);
return this;
}
public ActorInstance setRotationCenter(Vector3f axis) {
setRotationCenter(axis.x(), axis.y(), axis.z());
return this;
}
public ActorInstance setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) {
this.rotationCenterX = (byte) (rotationCenterX * 127);
this.rotationCenterY = (byte) (rotationCenterY * 127);
this.rotationCenterZ = (byte) (rotationCenterZ * 127);
return this;
}
public ActorInstance setLocalRotation(Quaternionfc q) {
this.rotation.set(q);
return this;
}
}

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.actors.contraptionControls;
import java.util.List; import java.util.List;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllTags.AllItemTags; import com.simibubi.create.AllTags.AllItemTags;
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock; import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock;
@ -17,6 +16,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
@ -135,9 +135,9 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity {
public void rotate(BlockState state, PoseStack ms) { public void rotate(BlockState state, PoseStack ms) {
Direction facing = state.getValue(ControlsBlock.FACING); Direction facing = state.getValue(ControlsBlock.FACING);
float yRot = AngleHelper.horizontalAngle(facing); float yRot = AngleHelper.horizontalAngle(facing);
TransformStack.cast(ms) TransformStack.of(ms)
.rotateY(yRot + 180) .rotateYDegrees(yRot + 180)
.rotateX(67.5f); .rotateXDegrees(67.5f);
} }
@Override @Override

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.actors.contraptionControls; package com.simibubi.create.content.contraptions.actors.contraptionControls;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
@ -11,6 +10,7 @@ import com.simibubi.create.foundation.utility.IntAttached;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -138,11 +138,6 @@ public class ContraptionControlsMovement implements MovementBehaviour {
.string(); .string();
} }
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext ctx, VirtualRenderWorld renderWorld, ContraptionMatrices matrices, public void renderInContraption(MovementContext ctx, VirtualRenderWorld renderWorld, ContraptionMatrices matrices,

View file

@ -2,8 +2,6 @@ package com.simibubi.create.content.contraptions.actors.contraptionControls;
import java.util.Random; import java.util.Random;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
@ -20,7 +18,9 @@ import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.DyeHelper; import com.simibubi.create.foundation.utility.DyeHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
@ -93,14 +93,14 @@ public class ContraptionControlsRenderer extends SmartBlockEntityRenderer<Contra
String text = efs.currentShortName; String text = efs.currentShortName;
String description = efs.currentLongName; String description = efs.currentLongName;
PoseStack ms = matrices.getViewProjection(); PoseStack ms = matrices.getViewProjection();
TransformStack msr = TransformStack.cast(ms); var msr = TransformStack.of(ms);
ms.pushPose(); ms.pushPose();
msr.translate(ctx.localPos); msr.translate(ctx.localPos);
msr.rotateCentered(Direction.UP, msr.rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(ctx.state.getValue(ContraptionControlsBlock.FACING))),
AngleHelper.rad(AngleHelper.horizontalAngle(ctx.state.getValue(ContraptionControlsBlock.FACING)))); Direction.UP);
ms.translate(0.275f + 0.125f, 1, 0.5f); ms.translate(0.275f + 0.125f, 1, 0.5f);
msr.rotate(Direction.WEST, AngleHelper.rad(67.5f)); msr.rotate(AngleHelper.rad(67.5f), Direction.WEST);
float buttondepth = -.25f; float buttondepth = -.25f;
if (ctx.contraption.presentBlockEntities.get(ctx.localPos) instanceof ContraptionControlsBlockEntity cbe) if (ctx.contraption.presentBlockEntities.get(ctx.localPos) instanceof ContraptionControlsBlockEntity cbe)
@ -140,4 +140,4 @@ public class ContraptionControlsRenderer extends SmartBlockEntityRenderer<Contra
} }
} }

View file

@ -1,96 +0,0 @@
package com.simibubi.create.content.contraptions.actors.flwdata;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import com.jozufozu.flywheel.api.InstanceData;
import net.minecraft.core.BlockPos;
public class ActorData extends InstanceData {
float x;
float y;
float z;
byte blockLight;
byte skyLight;
float rotationOffset;
byte rotationAxisX;
byte rotationAxisY;
byte rotationAxisZ;
float qX;
float qY;
float qZ;
float qW;
byte rotationCenterX = 64;
byte rotationCenterY = 64;
byte rotationCenterZ = 64;
float speed;
public ActorData setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
markDirty();
return this;
}
public ActorData setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
markDirty();
return this;
}
public ActorData setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
markDirty();
return this;
}
public ActorData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
markDirty();
return this;
}
public ActorData setSpeed(float speed) {
this.speed = speed;
markDirty();
return this;
}
public ActorData setRotationAxis(Vector3f axis) {
setRotationAxis(axis.x(), axis.y(), axis.z());
return this;
}
public ActorData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127);
markDirty();
return this;
}
public ActorData setRotationCenter(Vector3f axis) {
setRotationCenter(axis.x(), axis.y(), axis.z());
return this;
}
public ActorData setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) {
this.rotationCenterX = (byte) (rotationCenterX * 127);
this.rotationCenterY = (byte) (rotationCenterY * 127);
this.rotationCenterZ = (byte) (rotationCenterZ * 127);
markDirty();
return this;
}
public ActorData setLocalRotation(Quaternionf q) {
this.qX = q.x();
this.qY = q.y();
this.qZ = q.z();
this.qW = q.w();
markDirty();
return this;
}
}

View file

@ -1,39 +0,0 @@
package com.simibubi.create.content.contraptions.actors.flwdata;
import com.jozufozu.flywheel.api.struct.Batched;
import com.jozufozu.flywheel.api.struct.Instanced;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.model.ModelTransformer;
import com.simibubi.create.foundation.render.AllInstanceFormats;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import net.minecraft.resources.ResourceLocation;
public class ActorType implements Instanced<ActorData>, Batched<ActorData> {
@Override
public ActorData create() {
return new ActorData();
}
@Override
public BufferLayout getLayout() {
return AllInstanceFormats.ACTOR;
}
@Override
public StructWriter<ActorData> getWriter(VecBuffer backing) {
return new UnsafeActorWriter(backing, this);
}
@Override
public ResourceLocation getProgramSpec() {
return AllProgramSpecs.ACTOR;
}
@Override
public void transform(ActorData d, ModelTransformer.Params b) {
}
}

View file

@ -1,35 +0,0 @@
package com.simibubi.create.content.contraptions.actors.flwdata;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter;
public class UnsafeActorWriter extends UnsafeBufferWriter<ActorData> {
public UnsafeActorWriter(VecBuffer backingBuffer, StructType<ActorData> vertexType) {
super(backingBuffer, vertexType);
}
@Override
protected void writeInternal(ActorData d) {
long addr = writePointer;
MemoryUtil.memPutFloat(addr, d.x);
MemoryUtil.memPutFloat(addr + 4, d.y);
MemoryUtil.memPutFloat(addr + 8, d.z);
MemoryUtil.memPutByte(addr + 12, d.blockLight);
MemoryUtil.memPutByte(addr + 13, d.skyLight);
MemoryUtil.memPutFloat(addr + 14, d.rotationOffset);
MemoryUtil.memPutByte(addr + 18, d.rotationAxisX);
MemoryUtil.memPutByte(addr + 19, d.rotationAxisY);
MemoryUtil.memPutByte(addr + 20, d.rotationAxisZ);
MemoryUtil.memPutFloat(addr + 21, d.qX);
MemoryUtil.memPutFloat(addr + 25, d.qY);
MemoryUtil.memPutFloat(addr + 29, d.qZ);
MemoryUtil.memPutFloat(addr + 33, d.qW);
MemoryUtil.memPutByte(addr + 37, d.rotationCenterX);
MemoryUtil.memPutByte(addr + 38, d.rotationCenterY);
MemoryUtil.memPutByte(addr + 39, d.rotationCenterZ);
MemoryUtil.memPutFloat(addr + 40, d.speed);
}
}

View file

@ -1,6 +0,0 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
package com.simibubi.create.content.contraptions.actors.flwdata;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;

View file

@ -1,28 +1,28 @@
package com.simibubi.create.content.contraptions.actors.harvester; package com.simibubi.create.content.contraptions.actors.harvester;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class HarvesterActorInstance extends ActorInstance { public class HarvesterActorVisual extends ActorVisual {
static float originOffset = 1 / 16f; static float originOffset = 1 / 16f;
static Vec3 rotOffset = new Vec3(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); static Vec3 rotOffset = new Vec3(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
protected ModelData harvester; protected TransformedInstance harvester;
private Direction facing; private Direction facing;
protected float horizontalAngle; protected float horizontalAngle;
@ -30,31 +30,30 @@ public class HarvesterActorInstance extends ActorInstance {
private double rotation; private double rotation;
private double previousRotation; private double previousRotation;
public HarvesterActorInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, MovementContext context) { public HarvesterActorVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, MovementContext movementContext) {
super(materialManager, simulationWorld, context); super(visualizationContext, simulationWorld, movementContext);
Material<ModelData> material = materialManager.defaultCutout() BlockState state = movementContext.state;
.material(Materials.TRANSFORMED);
BlockState state = context.state;
facing = state.getValue(BlockStateProperties.HORIZONTAL_FACING); facing = state.getValue(BlockStateProperties.HORIZONTAL_FACING);
harvester = material.getModel(getRollingPartial(), state).createInstance(); harvester = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(getRollingPartial()))
.createInstance();
horizontalAngle = facing.toYRot() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0); horizontalAngle = facing.toYRot() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0);
harvester.setBlockLight(localBlockLight()); harvester.light(localBlockLight(), 0);
harvester.setChanged();
} }
protected PartialModel getRollingPartial() { protected PartialModel getRollingPartial() {
return AllPartialModels.HARVESTER_BLADE; return AllPartialModels.HARVESTER_BLADE;
} }
protected Vec3 getRotationOffset() { protected Vec3 getRotationOffset() {
return rotOffset; return rotOffset;
} }
protected double getRadius() { protected double getRadius() {
return 6.5; return 6.5;
} }
@ -84,17 +83,23 @@ public class HarvesterActorInstance extends ActorInstance {
@Override @Override
public void beginFrame() { public void beginFrame() {
harvester.loadIdentity() harvester.setIdentityTransform()
.translate(context.localPos) .translate(context.localPos)
.centre() .center()
.rotateY(horizontalAngle) .rotateYDegrees(horizontalAngle)
.unCentre() .uncenter()
.translate(getRotationOffset()) .translate(getRotationOffset())
.rotateX(getRotation()) .rotateXDegrees((float) getRotation())
.translateBack(getRotationOffset()); .translateBack(getRotationOffset())
.setChanged();
} }
protected double getRotation() { @Override
protected void _delete() {
harvester.delete();
}
protected double getRotation() {
return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation); return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation);
} }
} }

View file

@ -4,18 +4,18 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
@ -45,25 +45,6 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.getOpposite()); .getOpposite());
} }
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
return new HarvesterActorInstance(materialManager, simulationWorld, context);
}
@Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!ContraptionRenderDispatcher.canInstance())
HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers);
}
@Override @Override
public Vec3 getActiveAreaOffset(MovementContext context) { public Vec3 getActiveAreaOffset(MovementContext context) {
return Vec3.atLowerCornerOf(context.state.getValue(HarvesterBlock.FACING) return Vec3.atLowerCornerOf(context.state.getValue(HarvesterBlock.FACING)
@ -218,4 +199,23 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.createLegacyBlock(); .createLegacyBlock();
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!VisualizationManager.supportsVisualization(context.world))
HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers);
}
@Nullable
@Override
public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new HarvesterActorVisual(visualizationContext, simulationWorld, movementContext);
}
} }

View file

@ -2,19 +2,19 @@ package com.simibubi.create.content.contraptions.actors.harvester;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING; import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -53,8 +53,8 @@ public class HarvesterRenderer extends SafeBlockEntityRenderer<HarvesterBlockEnt
superBuffer.transform(matrices.getModel()); superBuffer.transform(matrices.getModel());
transform(context.world, facing, superBuffer, speed, PIVOT); transform(context.world, facing, superBuffer, speed, PIVOT);
superBuffer superBuffer.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffers.getBuffer(RenderType.cutoutMipped())); .renderInto(matrices.getViewProjection(), buffers.getBuffer(RenderType.cutoutMipped()));
} }
@ -64,9 +64,9 @@ public class HarvesterRenderer extends SafeBlockEntityRenderer<HarvesterBlockEnt
float time = AnimationTickHolder.getRenderTime(world) / 20; float time = AnimationTickHolder.getRenderTime(world) / 20;
float angle = (time * speed) % 360; float angle = (time * speed) % 360;
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing))) superBuffer.rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(facing)), Direction.UP)
.translate(rotOffset.x, rotOffset.y, rotOffset.z) .translate(rotOffset.x, rotOffset.y, rotOffset.z)
.rotate(Direction.WEST, AngleHelper.rad(angle)) .rotate(AngleHelper.rad(angle), Direction.WEST)
.translate(-rotOffset.x, -rotOffset.y, -rotOffset.z); .translate(-rotOffset.x, -rotOffset.y, -rotOffset.z);
} }
} }

View file

@ -1,27 +1,31 @@
package com.simibubi.create.content.contraptions.actors.psi; package com.simibubi.create.content.contraptions.actors.psi;
import com.jozufozu.flywheel.api.MaterialManager; import java.util.function.Consumer;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.instance.InstancerProvider;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
public class PIInstance { public class PIInstance {
private final MaterialManager materialManager; private final InstancerProvider instancerProvider;
private final BlockState blockState; private final BlockState blockState;
private final BlockPos instancePos; private final BlockPos instancePos;
private final float angleX; private final float angleX;
private final float angleY; private final float angleY;
private boolean lit; private boolean lit;
ModelData middle; TransformedInstance middle;
ModelData top; TransformedInstance top;
public PIInstance(MaterialManager materialManager, BlockState blockState, BlockPos instancePos) { public PIInstance(InstancerProvider instancerProvider, BlockState blockState, BlockPos instancePos) {
this.materialManager = materialManager; this.instancerProvider = instancerProvider;
this.blockState = blockState; this.blockState = blockState;
this.instancePos = instancePos; this.instancePos = instancePos;
Direction facing = blockState.getValue(PortableStorageInterfaceBlock.FACING); Direction facing = blockState.getValue(PortableStorageInterfaceBlock.FACING);
@ -31,42 +35,38 @@ public class PIInstance {
public void init(boolean lit) { public void init(boolean lit) {
this.lit = lit; this.lit = lit;
middle = materialManager.defaultSolid() middle = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit)))
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
.createInstance(); .createInstance();
top = materialManager.defaultSolid() top = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getTopForState(blockState)))
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getTopForState(blockState), blockState)
.createInstance(); .createInstance();
} }
public void beginFrame(float progress) { public void beginFrame(float progress) {
middle.loadIdentity() middle.setIdentityTransform()
.translate(instancePos) .translate(instancePos)
.centre() .center()
.rotateY(angleY) .rotateYDegrees(angleY)
.rotateX(angleX) .rotateXDegrees(angleX)
.unCentre(); .uncenter();
top.loadIdentity() top.setIdentityTransform()
.translate(instancePos) .translate(instancePos)
.centre() .center()
.rotateY(angleY) .rotateYDegrees(angleY)
.rotateX(angleX) .rotateXDegrees(angleX)
.unCentre(); .uncenter();
middle.translate(0, progress * 0.5f + 0.375f, 0); middle.translate(0, progress * 0.5f + 0.375f, 0);
top.translate(0, progress, 0); top.translate(0, progress, 0);
middle.setChanged();
top.setChanged();
} }
public void tick(boolean lit) { public void tick(boolean lit) {
if (this.lit != lit) { if (this.lit != lit) {
this.lit = lit; this.lit = lit;
materialManager.defaultSolid() instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit)))
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
.stealInstance(middle); .stealInstance(middle);
} }
} }
@ -75,4 +75,9 @@ public class PIInstance {
middle.delete(); middle.delete();
top.delete(); top.delete();
} }
public void collectCrumblingInstances(Consumer<Instance> consumer) {
consumer.accept(middle);
consumer.accept(top);
}
} }

View file

@ -1,31 +0,0 @@
package com.simibubi.create.content.contraptions.actors.psi;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
public class PSIActorInstance extends ActorInstance {
private final PIInstance instance;
public PSIActorInstance(MaterialManager materialManager, VirtualRenderWorld world, MovementContext context) {
super(materialManager, world, context);
instance = new PIInstance(materialManager, context.state, context.localPos);
instance.init(false);
instance.middle.setBlockLight(localBlockLight());
instance.top.setBlockLight(localBlockLight());
}
@Override
public void beginFrame() {
LerpedFloat lf = PortableStorageInterfaceMovement.getAnimation(context);
instance.tick(lf.settled());
instance.beginFrame(lf.getValue(AnimationTickHolder.getPartialTicks()));
}
}

View file

@ -0,0 +1,36 @@
package com.simibubi.create.content.contraptions.actors.psi;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
public class PSIActorVisual extends ActorVisual {
private final PIInstance instance;
public PSIActorVisual(VisualizationContext context, VirtualRenderWorld world, MovementContext movementContext) {
super(context, world, movementContext);
instance = new PIInstance(context.instancerProvider(), movementContext.state, movementContext.localPos);
instance.init(false);
instance.middle.light(localBlockLight(), 0);
instance.top.light(localBlockLight(), 0);
}
@Override
public void beginFrame() {
LerpedFloat lf = PortableStorageInterfaceMovement.getAnimation(context);
instance.tick(lf.settled());
instance.beginFrame(lf.getValue(AnimationTickHolder.getPartialTicks()));
}
@Override
protected void _delete() {
instance.remove();
}
}

View file

@ -1,48 +0,0 @@
package com.simibubi.create.content.contraptions.actors.psi;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
public class PSIInstance extends BlockEntityInstance<PortableStorageInterfaceBlockEntity> implements DynamicInstance, TickableInstance {
private final PIInstance instance;
public PSIInstance(MaterialManager materialManager, PortableStorageInterfaceBlockEntity blockEntity) {
super(materialManager, blockEntity);
instance = new PIInstance(materialManager, blockState, getInstancePosition());
}
@Override
public void init() {
instance.init(isLit());
}
@Override
public void tick() {
instance.tick(isLit());
}
@Override
public void beginFrame() {
instance.beginFrame(blockEntity.getExtensionDistance(AnimationTickHolder.getPartialTicks()));
}
@Override
public void updateLight() {
relight(pos, instance.middle, instance.top);
}
@Override
public void remove() {
instance.remove();
}
private boolean isLit() {
return blockEntity.isConnected();
}
}

View file

@ -0,0 +1,53 @@
package com.simibubi.create.content.contraptions.actors.psi;
import java.util.function.Consumer;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visual.TickableVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual;
public class PSIVisual extends AbstractBlockEntityVisual<PortableStorageInterfaceBlockEntity> implements SimpleDynamicVisual, SimpleTickableVisual {
private final PIInstance instance;
public PSIVisual(VisualizationContext visualizationContext, PortableStorageInterfaceBlockEntity blockEntity, float partialTick) {
super(visualizationContext, blockEntity, partialTick);
instance = new PIInstance(visualizationContext.instancerProvider(), blockState, getVisualPosition());
instance.init(isLit());
}
@Override
public void tick(TickableVisual.Context ctx) {
instance.tick(isLit());
}
@Override
public void beginFrame(DynamicVisual.Context ctx) {
instance.beginFrame(blockEntity.getExtensionDistance(ctx.partialTick()));
}
@Override
public void updateLight(float partialTick) {
relight(instance.middle, instance.top);
}
@Override
protected void _delete() {
instance.remove();
}
private boolean isLit() {
return blockEntity.isConnected();
}
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
instance.collectCrumblingInstances(consumer);
}
}

View file

@ -4,18 +4,18 @@ import java.util.Optional;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.CarriageContraption;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -40,22 +40,22 @@ public class PortableStorageInterfaceMovement implements MovementBehaviour {
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { public boolean disableBlockEntityRendering() {
return true; return true;
} }
@Nullable @Nullable
@Override @Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext context) { MovementContext movementContext) {
return new PSIActorInstance(materialManager, simulationWorld, context); return new PSIActorVisual(visualizationContext, simulationWorld, movementContext);
} }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) { ContraptionMatrices matrices, MultiBufferSource buffer) {
if (!ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer); PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer);
} }

View file

@ -2,23 +2,23 @@ package com.simibubi.create.content.contraptions.actors.psi;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -35,7 +35,7 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
@Override @Override
protected void renderSafe(PortableStorageInterfaceBlockEntity be, float partialTicks, PoseStack ms, protected void renderSafe(PortableStorageInterfaceBlockEntity be, float partialTicks, PoseStack ms,
MultiBufferSource buffer, int light, int overlay) { MultiBufferSource buffer, int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) if (VisualizationManager.supportsVisualization(be.getLevel()))
return; return;
BlockState blockState = be.getBlockState(); BlockState blockState = be.getBlockState();
@ -55,8 +55,8 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
float progress = animation.getValue(renderPartialTicks); float progress = animation.getValue(renderPartialTicks);
boolean lit = animation.settled(); boolean lit = animation.settled();
render(blockState, lit, progress, matrices.getModel(), render(blockState, lit, progress, matrices.getModel(),
sbb -> sbb sbb -> sbb.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), vb)); .renderInto(matrices.getViewProjection(), vb));
} }
@ -80,10 +80,10 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
} }
private static void rotateToFacing(SuperByteBuffer buffer, Direction facing) { private static void rotateToFacing(SuperByteBuffer buffer, Direction facing) {
buffer.centre() buffer.center()
.rotateY(AngleHelper.horizontalAngle(facing)) .rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) .rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.unCentre(); .uncenter();
} }
static PortableStorageInterfaceBlockEntity getTargetPSI(MovementContext context) { static PortableStorageInterfaceBlockEntity getTargetPSI(MovementContext context) {

View file

@ -1,64 +0,0 @@
package com.simibubi.create.content.contraptions.actors.roller;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterActorInstance;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import net.minecraft.world.phys.Vec3;
public class RollerActorInstance extends HarvesterActorInstance {
ModelData frame;
public RollerActorInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
super(materialManager, simulationWorld, context);
Material<ModelData> material = materialManager.defaultCutout()
.material(Materials.TRANSFORMED);
frame = material.getModel(AllPartialModels.ROLLER_FRAME, context.state)
.createInstance();
frame.setBlockLight(localBlockLight());
}
@Override
public void beginFrame() {
harvester.loadIdentity()
.translate(context.localPos)
.centre()
.rotateY(horizontalAngle)
.unCentre()
.translate(0, -.25, 17 / 16f)
.rotateX(getRotation())
.translate(0, -.5, .5)
.rotateY(90);
frame.loadIdentity()
.translate(context.localPos)
.centre()
.rotateY(horizontalAngle + 180)
.unCentre();
}
@Override
protected PartialModel getRollingPartial() {
return AllPartialModels.ROLLER_WHEEL;
}
@Override
protected Vec3 getRotationOffset() {
return Vec3.ZERO;
}
@Override
protected double getRadius() {
return 16.5;
}
}

View file

@ -0,0 +1,70 @@
package com.simibubi.create.content.contraptions.actors.roller;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterActorVisual;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.world.phys.Vec3;
public class RollerActorVisual extends HarvesterActorVisual {
TransformedInstance frame;
public RollerActorVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
super(visualizationContext, simulationWorld, movementContext);
frame = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROLLER_FRAME))
.createInstance();
frame.light(localBlockLight(), 0);
}
@Override
public void beginFrame() {
harvester.setIdentityTransform()
.translate(context.localPos)
.center()
.rotateYDegrees(horizontalAngle)
.uncenter()
.translate(0, -.25, 17 / 16f)
.rotateXDegrees((float) getRotation())
.translate(0, -.5, .5)
.rotateYDegrees(90)
.setChanged();
frame.setIdentityTransform()
.translate(context.localPos)
.center()
.rotateYDegrees(horizontalAngle + 180)
.uncenter()
.setChanged();
}
@Override
protected PartialModel getRollingPartial() {
return AllPartialModels.ROLLER_WHEEL;
}
@Override
protected Vec3 getRotationOffset() {
return Vec3.ZERO;
}
@Override
protected double getRadius() {
return 16.5;
}
@Override
protected void _delete() {
super._delete();
frame.delete();
}
}

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.actors.roller;
import java.util.List; import java.util.List;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
@ -16,6 +15,7 @@ import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
@ -182,11 +182,11 @@ public class RollerBlockEntity extends SmartBlockEntity {
public void rotate(BlockState state, PoseStack ms) { public void rotate(BlockState state, PoseStack ms) {
Direction facing = state.getValue(RollerBlock.FACING); Direction facing = state.getValue(RollerBlock.FACING);
float yRot = AngleHelper.horizontalAngle(facing) + 180; float yRot = AngleHelper.horizontalAngle(facing) + 180;
TransformStack.cast(ms) TransformStack.of(ms)
.rotateY(yRot) .rotateYDegrees(yRot)
.rotateX(90); .rotateXDegrees(90);
} }
@Override @Override
public boolean testHit(BlockState state, Vec3 localHit) { public boolean testHit(BlockState state, Vec3 localHit) {
Vec3 offset = getLocalOffset(state); Vec3 offset = getLocalOffset(state);

View file

@ -9,15 +9,13 @@ import java.util.function.BiConsumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllTags; import com.simibubi.create.AllTags;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode; import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.pulley.PulleyContraption; import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
import com.simibubi.create.content.contraptions.render.ActorInstance; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.content.logistics.filter.FilterItemStack; import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.trains.bogey.StandardBogeyBlock; import com.simibubi.create.content.trains.bogey.StandardBogeyBlock;
@ -37,8 +35,11 @@ import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -70,21 +71,21 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { public boolean disableBlockEntityRendering() {
return true; return true;
} }
@Nullable @Nullable
@Override @Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext context) { MovementContext movementContext) {
return new RollerActorInstance(materialManager, simulationWorld, context); return new RollerActorVisual(visualizationContext, simulationWorld, movementContext);
} }
@Override @Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) { ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
RollerRenderer.renderInContraption(context, renderWorld, matrices, buffers); RollerRenderer.renderInContraption(context, renderWorld, matrices, buffers);
} }

View file

@ -2,19 +2,20 @@ package com.simibubi.create.content.contraptions.actors.roller;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING; import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
@ -34,6 +35,7 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
super.renderSafe(be, partialTicks, ms, buffer, light, overlay); super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
BlockState blockState = be.getBlockState(); BlockState blockState = be.getBlockState();
VertexConsumer vc = buffer.getBuffer(RenderType.cutoutMipped());
ms.pushPose(); ms.pushPose();
ms.translate(0, -0.25, 0); ms.translate(0, -0.25, 0);
@ -43,21 +45,22 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
.scale(17 / 16f)); .scale(17 / 16f));
HarvesterRenderer.transform(be.getLevel(), facing, superBuffer, be.getAnimatedSpeed(), Vec3.ZERO); HarvesterRenderer.transform(be.getLevel(), facing, superBuffer, be.getAnimatedSpeed(), Vec3.ZERO);
superBuffer.translate(0, -.5, .5) superBuffer.translate(0, -.5, .5)
.rotateY(90) .rotateYDegrees(90)
.light(light) .light(light)
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped())); .renderInto(ms, vc);
ms.popPose(); ms.popPose();
CachedBufferer.partial(AllPartialModels.ROLLER_FRAME, blockState) CachedBufferer.partial(AllPartialModels.ROLLER_FRAME, blockState)
.rotateCentered(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180)) .rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180), Direction.UP)
.light(light) .light(light)
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped())); .renderInto(ms, vc);
} }
public static void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public static void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) { ContraptionMatrices matrices, MultiBufferSource buffers) {
BlockState blockState = context.state; BlockState blockState = context.state;
Direction facing = blockState.getValue(HORIZONTAL_FACING); Direction facing = blockState.getValue(HORIZONTAL_FACING);
VertexConsumer vc = buffers.getBuffer(RenderType.cutoutMipped());
SuperByteBuffer superBuffer = CachedBufferer.partial(AllPartialModels.ROLLER_WHEEL, blockState); SuperByteBuffer superBuffer = CachedBufferer.partial(AllPartialModels.ROLLER_WHEEL, blockState);
float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()) float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())
? context.getAnimationSpeed() ? context.getAnimationSpeed()
@ -73,18 +76,20 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
PoseStack viewProjection = matrices.getViewProjection(); PoseStack viewProjection = matrices.getViewProjection();
viewProjection.pushPose(); viewProjection.pushPose();
viewProjection.translate(0, -.25, 0); viewProjection.translate(0, -.25, 0);
int contraptionWorldLight = ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld); int contraptionWorldLight = LevelRenderer.getLightColor(renderWorld, context.localPos);
superBuffer.translate(0, -.5, .5) superBuffer.translate(0, -.5, .5)
.rotateY(90) .rotateYDegrees(90)
.light(matrices.getWorld(), contraptionWorldLight) .light(contraptionWorldLight)
.renderInto(viewProjection, buffers.getBuffer(RenderType.cutoutMipped())); .useLevelLight(context.world, matrices.getWorld())
.renderInto(viewProjection, vc);
viewProjection.popPose(); viewProjection.popPose();
CachedBufferer.partial(AllPartialModels.ROLLER_FRAME, blockState) CachedBufferer.partial(AllPartialModels.ROLLER_FRAME, blockState)
.transform(matrices.getModel()) .transform(matrices.getModel())
.rotateCentered(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180)) .rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180), Direction.UP)
.light(matrices.getWorld(), contraptionWorldLight) .light(contraptionWorldLight)
.renderInto(viewProjection, buffers.getBuffer(RenderType.cutoutMipped())); .useLevelLight(context.world, matrices.getWorld())
.renderInto(viewProjection, vc);
} }
} }

View file

@ -101,7 +101,7 @@ public class TrackPaverV2 {
Map<Pair<Integer, Integer>, Double> yLevels = new HashMap<>(); Map<Pair<Integer, Integer>, Double> yLevels = new HashMap<>();
Map<Pair<Integer, Integer>, Double> tLevels = new HashMap<>(); Map<Pair<Integer, Integer>, Double> tLevels = new HashMap<>();
BlockPos tePosition = bc.tePositions.getFirst(); BlockPos bePosition = bc.bePositions.getFirst();
double radius = -task.getHorizontalInterval() double radius = -task.getHorizontalInterval()
.getFirst(); .getFirst();
double r1 = radius - .575; double r1 = radius - .575;
@ -109,10 +109,10 @@ public class TrackPaverV2 {
double handleLength = bc.getHandleLength(); double handleLength = bc.getHandleLength();
Vec3 start = bc.starts.getFirst() Vec3 start = bc.starts.getFirst()
.subtract(Vec3.atLowerCornerOf(tePosition)) .subtract(Vec3.atLowerCornerOf(bePosition))
.add(0, 3 / 16f, 0); .add(0, 3 / 16f, 0);
Vec3 end = bc.starts.getSecond() Vec3 end = bc.starts.getSecond()
.subtract(Vec3.atLowerCornerOf(tePosition)) .subtract(Vec3.atLowerCornerOf(bePosition))
.add(0, 3 / 16f, 0); .add(0, 3 / 16f, 0);
Vec3 startHandle = bc.axes.getFirst() Vec3 startHandle = bc.axes.getFirst()
.scale(handleLength) .scale(handleLength)
@ -190,7 +190,7 @@ public class TrackPaverV2 {
BlockPos targetPos = new BlockPos(entry.getKey() BlockPos targetPos = new BlockPos(entry.getKey()
.getFirst(), floor, .getFirst(), floor,
entry.getKey() entry.getKey()
.getSecond()).offset(tePosition); .getSecond()).offset(bePosition);
task.put(targetPos.getX(), targetPos.getZ(), targetPos.getY() + (yValue - floor >= .5 ? .5f : 0)); task.put(targetPos.getX(), targetPos.getZ(), targetPos.getY() + (yValue - floor >= .5 ? .5f : 0));
} }
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.actors.trainControls;
import java.util.Collection; import java.util.Collection;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
@ -11,6 +10,7 @@ import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -32,7 +32,7 @@ public class ControlsMovementBehaviour implements MovementBehaviour {
public ItemStack canBeDisabledVia(MovementContext context) { public ItemStack canBeDisabledVia(MovementContext context) {
return null; return null;
} }
@Override @Override
public void stopMoving(MovementContext context) { public void stopMoving(MovementContext context) {
context.contraption.entity.stopControlling(context.localPos); context.contraption.entity.stopControlling(context.localPos);

View file

@ -1,17 +1,17 @@
package com.simibubi.create.content.contraptions.actors.trainControls; package com.simibubi.create.content.contraptions.actors.trainControls;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -29,30 +29,32 @@ public class ControlsRenderer {
float hAngle = 180 + AngleHelper.horizontalAngle(facing); float hAngle = 180 + AngleHelper.horizontalAngle(facing);
PoseStack ms = matrices.getModel(); PoseStack ms = matrices.getModel();
cover.transform(ms) cover.transform(ms)
.centre() .center()
.rotateY(hAngle) .rotateYDegrees(hAngle)
.unCentre() .uncenter()
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped()));
double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f); double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f);
for (boolean first : Iterate.trueAndFalse) { for (boolean first : Iterate.trueAndFalse) {
float vAngle = (float) Mth.clamp(first ? firstLever * 70 - 25 : secondLever * 15, -45, 45); float vAngle = Mth.clamp(first ? firstLever * 70 - 25 : secondLever * 15, -45, 45);
SuperByteBuffer lever = CachedBufferer.partial(AllPartialModels.TRAIN_CONTROLS_LEVER, state); SuperByteBuffer lever = CachedBufferer.partial(AllPartialModels.TRAIN_CONTROLS_LEVER, state);
ms.pushPose(); ms.pushPose();
TransformStack.cast(ms) TransformStack.of(ms)
.centre() .center()
.rotateY(hAngle) .rotateYDegrees(hAngle)
.translate(0, 0, 4 / 16f) .translate(0, 0, 4 / 16f)
.rotateX(vAngle - 45) .rotateXDegrees(vAngle - 45)
.translate(0, yOffset, 0) .translate(0, yOffset, 0)
.rotateX(45) .rotateXDegrees(45)
.unCentre() .uncenter()
.translate(0, -2 / 16f, -3 / 16f) .translate(0, -2 / 16f, -3 / 16f)
.translate(first ? 0 : 6 / 16f, 0, 0); .translate(first ? 0 : 6 / 16f, 0, 0);
lever.transform(ms) lever.transform(ms)
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
ms.popPose(); ms.popPose();
} }

View file

@ -1,19 +0,0 @@
package com.simibubi.create.content.contraptions.bearing;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
public class AnchoredLighter extends ContraptionLighter<Contraption> {
public AnchoredLighter(Contraption contraption) {
super(contraption);
}
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bb = GridAlignedBB.from(contraption.bounds);
bb.translate(contraption.anchor);
return bb;
}
}

View file

@ -7,7 +7,6 @@ import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.content.contraptions.AssemblyException; import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
@ -18,8 +17,6 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class BearingContraption extends Contraption { public class BearingContraption extends Contraption {
@ -104,9 +101,4 @@ public class BearingContraption extends Contraption {
return facing.getAxis() == this.facing.getAxis(); return facing.getAxis() == this.facing.getAxis();
} }
@OnlyIn(Dist.CLIENT)
@Override
public ContraptionLighter<?> makeLighter() {
return new AnchoredLighter(this);
}
} }

View file

@ -1,75 +0,0 @@
package com.simibubi.create.content.contraptions.bearing;
import org.joml.Quaternionf;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.BackHalfShaftInstance;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class BearingInstance<B extends KineticBlockEntity & IBearingBlockEntity> extends BackHalfShaftInstance<B> implements DynamicInstance {
final OrientedData topInstance;
final Axis rotationAxis;
final Quaternionf blockOrientation;
public BearingInstance(MaterialManager materialManager, B blockEntity) {
super(materialManager, blockEntity);
Direction facing = blockState.getValue(BlockStateProperties.FACING);
rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, axis).step());
blockOrientation = getBlockStateOrientation(facing);
PartialModel top =
blockEntity.isWoodenTop() ? AllPartialModels.BEARING_TOP_WOODEN : AllPartialModels.BEARING_TOP;
topInstance = getOrientedMaterial().getModel(top, blockState).createInstance();
topInstance.setPosition(getInstancePosition()).setRotation(blockOrientation);
}
@Override
public void beginFrame() {
float interpolatedAngle = blockEntity.getInterpolatedAngle(AnimationTickHolder.getPartialTicks() - 1);
Quaternionf rot = rotationAxis.rotationDegrees(interpolatedAngle);
rot.mul(blockOrientation);
topInstance.setRotation(rot);
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, topInstance);
}
@Override
public void remove() {
super.remove();
topInstance.delete();
}
static Quaternionf getBlockStateOrientation(Direction facing) {
Quaternionf orientation;
if (facing.getAxis().isHorizontal()) {
orientation = Axis.YP.rotationDegrees(AngleHelper.horizontalAngle(facing.getOpposite()));
} else {
orientation = new Quaternionf();
}
orientation.mul(Axis.XP.rotationDegrees(-90 - AngleHelper.verticalAngle(facing)));
return orientation;
}
}

View file

@ -1,7 +1,5 @@
package com.simibubi.create.content.contraptions.bearing; package com.simibubi.create.content.contraptions.bearing;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -10,6 +8,8 @@ import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -27,7 +27,7 @@ public class BearingRenderer<T extends KineticBlockEntity & IBearingBlockEntity>
protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer, protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) { int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) return; if (VisualizationManager.supportsVisualization(be.getLevel())) return;
super.renderSafe(be, partialTicks, ms, buffer, light, overlay); super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
@ -42,9 +42,9 @@ public class BearingRenderer<T extends KineticBlockEntity & IBearingBlockEntity>
if (facing.getAxis() if (facing.getAxis()
.isHorizontal()) .isHorizontal())
superBuffer.rotateCentered(Direction.UP, superBuffer.rotateCentered(
AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite()))); AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite())), Direction.UP);
superBuffer.rotateCentered(Direction.EAST, AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing))); superBuffer.rotateCentered(AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing)), Direction.EAST);
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.solid())); superBuffer.renderInto(ms, buffer.getBuffer(RenderType.solid()));
} }

View file

@ -0,0 +1,90 @@
package com.simibubi.create.content.contraptions.bearing;
import java.util.function.Consumer;
import org.joml.Quaternionf;
import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.BackHalfShaftVisual;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class BearingVisual<B extends KineticBlockEntity & IBearingBlockEntity> extends BackHalfShaftVisual<B> implements SimpleDynamicVisual {
final OrientedInstance topInstance;
final Axis rotationAxis;
final Quaternionf blockOrientation;
public BearingVisual(VisualizationContext context, B blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
Direction facing = blockState.getValue(BlockStateProperties.FACING);
rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, axis).step());
blockOrientation = getBlockStateOrientation(facing);
PartialModel top =
blockEntity.isWoodenTop() ? AllPartialModels.BEARING_TOP_WOODEN : AllPartialModels.BEARING_TOP;
topInstance = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(top))
.createInstance();
topInstance.position(getVisualPosition())
.rotation(blockOrientation)
.setChanged();
}
@Override
public void beginFrame(DynamicVisual.Context ctx) {
float interpolatedAngle = blockEntity.getInterpolatedAngle(ctx.partialTick() - 1);
Quaternionf rot = rotationAxis.rotationDegrees(interpolatedAngle);
rot.mul(blockOrientation);
topInstance.rotation(rot)
.setChanged();
}
@Override
public void updateLight(float partialTick) {
super.updateLight(partialTick);
relight(topInstance);
}
@Override
protected void _delete() {
super._delete();
topInstance.delete();
}
static Quaternionf getBlockStateOrientation(Direction facing) {
Quaternionf orientation;
if (facing.getAxis().isHorizontal()) {
orientation = Axis.YP.rotationDegrees(AngleHelper.horizontalAngle(facing.getOpposite()));
} else {
orientation = new Quaternionf();
}
orientation.mul(Axis.XP.rotationDegrees(-90 - AngleHelper.verticalAngle(facing)));
return orientation;
}
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
super.collectCrumblingInstances(consumer);
consumer.accept(topInstance);
}
}

View file

@ -9,15 +9,12 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.content.contraptions.AssemblyException; import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class ClockworkContraption extends Contraption { public class ClockworkContraption extends Contraption {
@ -132,9 +129,4 @@ public class ClockworkContraption extends Contraption {
HOUR, MINUTE HOUR, MINUTE
} }
@Override
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new AnchoredLighter(this);
}
} }

View file

@ -1,70 +0,0 @@
package com.simibubi.create.content.contraptions.bearing;
import org.joml.Quaternionf;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance;
import com.simibubi.create.content.kinetics.base.flwdata.RotatingData;
import com.simibubi.create.foundation.render.AllMaterialSpecs;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class StabilizedBearingInstance extends ActorInstance {
final OrientedData topInstance;
final RotatingData shaft;
final Direction facing;
final Axis rotationAxis;
final Quaternionf blockOrientation;
public StabilizedBearingInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, MovementContext context) {
super(materialManager, simulationWorld, context);
BlockState blockState = context.state;
facing = blockState.getValue(BlockStateProperties.FACING);
rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, facing.getAxis()).step());
blockOrientation = BearingInstance.getBlockStateOrientation(facing);
topInstance = materialManager.defaultSolid()
.material(Materials.ORIENTED)
.getModel(AllPartialModels.BEARING_TOP, blockState)
.createInstance();
int blockLight = localBlockLight();
topInstance.setPosition(context.localPos)
.setRotation(blockOrientation)
.setBlockLight(blockLight);
shaft = materialManager.defaultSolid()
.material(AllMaterialSpecs.ROTATING)
.getModel(AllPartialModels.SHAFT_HALF, blockState, blockState.getValue(BlockStateProperties.FACING).getOpposite())
.createInstance();
// not rotating so no need to set speed, axis, etc.
shaft.setPosition(context.localPos)
.setBlockLight(blockLight);
}
@Override
public void beginFrame() {
float counterRotationAngle = StabilizedBearingMovementBehaviour.getCounterRotationAngle(context, facing, AnimationTickHolder.getPartialTicks());
Quaternionf rotation = rotationAxis.rotationDegrees(counterRotationAngle);
rotation.mul(blockOrientation);
topInstance.setRotation(rotation);
}
}

View file

@ -4,9 +4,6 @@ import javax.annotation.Nullable;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
@ -14,13 +11,17 @@ import com.simibubi.create.content.contraptions.ControlledContraptionEntity;
import com.simibubi.create.content.contraptions.OrientedContraptionEntity; import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -35,12 +36,17 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
public ItemStack canBeDisabledVia(MovementContext context) { public ItemStack canBeDisabledVia(MovementContext context) {
return null; return null;
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) { ContraptionMatrices matrices, MultiBufferSource buffer) {
if (ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
return; return;
Direction facing = context.state.getValue(BlockStateProperties.FACING); Direction facing = context.state.getValue(BlockStateProperties.FACING);
@ -49,7 +55,7 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
float renderPartialTicks = AnimationTickHolder.getPartialTicks(); float renderPartialTicks = AnimationTickHolder.getPartialTicks();
// rotate to match blockstate // rotate to match blockstate
Quaternionf orientation = BearingInstance.getBlockStateOrientation(facing); Quaternionf orientation = BearingVisual.getBlockStateOrientation(facing);
// rotate against parent // rotate against parent
float angle = getCounterRotationAngle(context, facing, renderPartialTicks) * facing.getAxisDirection() float angle = getCounterRotationAngle(context, facing, renderPartialTicks) * facing.getAxisDirection()
@ -66,21 +72,16 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
superBuffer.rotateCentered(orientation); superBuffer.rotateCentered(orientation);
// render // render
superBuffer superBuffer.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
} }
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable @Nullable
@Override @Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext context) { MovementContext movementContext) {
return new StabilizedBearingInstance(materialManager, simulationWorld, context); return new StabilizedBearingVisual(visualizationContext, simulationWorld, movementContext);
} }
static float getCounterRotationAngle(MovementContext context, Direction facing, float renderPartialTicks) { static float getCounterRotationAngle(MovementContext context, Direction facing, float renderPartialTicks) {

View file

@ -0,0 +1,73 @@
package com.simibubi.create.content.contraptions.bearing;
import org.joml.Quaternionf;
import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.kinetics.base.RotatingInstance;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class StabilizedBearingVisual extends ActorVisual {
final OrientedInstance topInstance;
final RotatingInstance shaft;
final Direction facing;
final Axis rotationAxis;
final Quaternionf blockOrientation;
public StabilizedBearingVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, MovementContext movementContext) {
super(visualizationContext, simulationWorld, movementContext);
BlockState blockState = movementContext.state;
facing = blockState.getValue(BlockStateProperties.FACING);
rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, facing.getAxis()).step());
blockOrientation = BearingVisual.getBlockStateOrientation(facing);
topInstance = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.BEARING_TOP))
.createInstance();
int blockLight = localBlockLight();
topInstance.position(movementContext.localPos)
.rotation(blockOrientation)
.light(blockLight, 0);
shaft = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF, blockState.getValue(BlockStateProperties.FACING).getOpposite()))
.createInstance();
// not rotating so no need to set speed, axis, etc.
shaft.setPosition(movementContext.localPos)
.light(blockLight, 0);
}
@Override
public void beginFrame() {
float counterRotationAngle = StabilizedBearingMovementBehaviour.getCounterRotationAngle(context, facing, AnimationTickHolder.getPartialTicks());
Quaternionf rotation = rotationAxis.rotationDegrees(counterRotationAngle);
rotation.mul(blockOrientation);
topInstance.rotation(rotation);
}
@Override
protected void _delete() {
topInstance.delete();
shaft.delete();
}
}

View file

@ -3,15 +3,11 @@ package com.simibubi.create.content.contraptions.bearing;
import com.simibubi.create.content.contraptions.AssemblyException; import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.content.contraptions.render.NonStationaryLighter;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class StabilizedContraption extends Contraption { public class StabilizedContraption extends Contraption {
@ -66,9 +62,4 @@ public class StabilizedContraption extends Contraption {
return facing; return facing;
} }
@Override
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new NonStationaryLighter<>(this);
}
} }

View file

@ -11,12 +11,6 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class BellMovementBehaviour implements MovementBehaviour { public class BellMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public boolean isActive(MovementContext context) { public boolean isActive(MovementContext context) {
return MovementBehaviour.super.isActive(context) && !(context.contraption instanceof CarriageContraption); return MovementBehaviour.super.isActive(context) && !(context.contraption instanceof CarriageContraption);

View file

@ -5,11 +5,6 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.CampfireBlock; import net.minecraft.world.level.block.CampfireBlock;
public class CampfireMovementBehaviour implements MovementBehaviour { public class CampfireMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public void tick(MovementContext context) { public void tick(MovementContext context) {
if (context.world == null || !context.world.isClientSide || context.position == null if (context.world == null || !context.world.isClientSide || context.position == null

View file

@ -2,12 +2,12 @@ package com.simibubi.create.content.contraptions.behaviour;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.MaterialManager; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.render.ActorInstance;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
@ -41,11 +41,11 @@ public interface MovementBehaviour {
return null; return null;
return new ItemStack(block); return new ItemStack(block);
} }
default void onDisabledByControls(MovementContext context) { default void onDisabledByControls(MovementContext context) {
cancelStall(context); cancelStall(context);
} }
default boolean mustTickWhileDisabled() { default boolean mustTickWhileDisabled() {
return false; return false;
} }
@ -63,7 +63,7 @@ public interface MovementBehaviour {
Vec3 vec = context.position; Vec3 vec = context.position;
if (vec == null) if (vec == null)
return; return;
ItemEntity itemEntity = new ItemEntity(context.world, vec.x, vec.y, vec.z, remainder); ItemEntity itemEntity = new ItemEntity(context.world, vec.x, vec.y, vec.z, remainder);
itemEntity.setDeltaMovement(context.motion.add(0, 0.5f, 0) itemEntity.setDeltaMovement(context.motion.add(0, 0.5f, 0)
.scale(context.world.random.nextFloat() * .3f)); .scale(context.world.random.nextFloat() * .3f));
@ -73,18 +73,14 @@ public interface MovementBehaviour {
default void onSpeedChanged(MovementContext context, Vec3 oldMotion, Vec3 motion) {} default void onSpeedChanged(MovementContext context, Vec3 oldMotion, Vec3 motion) {}
default void stopMoving(MovementContext context) {} default void stopMoving(MovementContext context) {}
default void cancelStall(MovementContext context) { default void cancelStall(MovementContext context) {
context.stall = false; context.stall = false;
} }
default void writeExtraData(MovementContext context) {} default void writeExtraData(MovementContext context) {}
default boolean renderAsNormalBlockEntity() { default boolean disableBlockEntityRendering() {
return false;
}
default boolean hasSpecialInstancedRendering() {
return false; return false;
} }
@ -94,8 +90,8 @@ public interface MovementBehaviour {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Nullable @Nullable
default ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, default ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext context) { MovementContext movementContext) {
return null; return null;
} }
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.chassis;
import java.util.List; import java.util.List;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
@ -12,6 +11,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -70,7 +70,7 @@ public class StickerBlockEntity extends SmartBlockEntity {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false));
piston.chase(target, .4f, Chaser.LINEAR); piston.chase(target, .4f, Chaser.LINEAR);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> VisualizationHelper.queueUpdate(this));
} }
public boolean isAttachedToBlock() { public boolean isAttachedToBlock() {
@ -85,7 +85,7 @@ public class StickerBlockEntity extends SmartBlockEntity {
protected void write(CompoundTag tag, boolean clientPacket) { protected void write(CompoundTag tag, boolean clientPacket) {
super.write(tag, clientPacket); super.write(tag, clientPacket);
} }
@Override @Override
protected void read(CompoundTag compound, boolean clientPacket) { protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket); super.read(compound, clientPacket);

View file

@ -1,71 +0,0 @@
package com.simibubi.create.content.contraptions.chassis;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
public class StickerInstance extends BlockEntityInstance<StickerBlockEntity> implements DynamicInstance {
float lastOffset = Float.NaN;
final Direction facing;
final boolean fakeWorld;
final int offset;
private final ModelData head;
public StickerInstance(MaterialManager materialManager, StickerBlockEntity blockEntity) {
super(materialManager, blockEntity);
head = getTransformMaterial().getModel(AllPartialModels.STICKER_HEAD, blockState).createInstance();
fakeWorld = blockEntity.getLevel() != Minecraft.getInstance().level;
facing = blockState.getValue(StickerBlock.FACING);
offset = blockState.getValue(StickerBlock.EXTENDED) ? 1 : 0;
animateHead(offset);
}
@Override
public void beginFrame() {
float offset = blockEntity.piston.getValue(AnimationTickHolder.getPartialTicks());
if (fakeWorld)
offset = this.offset;
if (Mth.equal(offset, lastOffset))
return;
animateHead(offset);
lastOffset = offset;
}
private void animateHead(float offset) {
head.loadIdentity()
.translate(getInstancePosition())
.nudge(blockEntity.hashCode())
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing) + 90)
.unCentre()
.translate(0, (offset * offset) * 4 / 16f, 0);
}
@Override
public void updateLight() {
relight(pos, head);
}
@Override
public void remove() {
head.delete();
}
}

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.chassis; package com.simibubi.create.content.contraptions.chassis;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
@ -9,6 +8,7 @@ import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
@ -25,7 +25,7 @@ public class StickerRenderer extends SafeBlockEntityRenderer<StickerBlockEntity>
protected void renderSafe(StickerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, protected void renderSafe(StickerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) { int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) return; if (VisualizationManager.supportsVisualization(be.getLevel())) return;
BlockState state = be.getBlockState(); BlockState state = be.getBlockState();
SuperByteBuffer head = CachedBufferer.partial(AllPartialModels.STICKER_HEAD, state); SuperByteBuffer head = CachedBufferer.partial(AllPartialModels.STICKER_HEAD, state);
@ -36,10 +36,10 @@ public class StickerRenderer extends SafeBlockEntityRenderer<StickerBlockEntity>
Direction facing = state.getValue(StickerBlock.FACING); Direction facing = state.getValue(StickerBlock.FACING);
head.nudge(be.hashCode()) head.nudge(be.hashCode())
.centre() .center()
.rotateY(AngleHelper.horizontalAngle(facing)) .rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing) + 90) .rotateXDegrees(AngleHelper.verticalAngle(facing) + 90)
.unCentre() .uncenter()
.translate(0, (offset * offset) * 4 / 16f, 0); .translate(0, (offset * offset) * 4 / 16f, 0);
head.light(light) head.light(light)

View file

@ -0,0 +1,82 @@
package com.simibubi.create.content.contraptions.chassis;
import java.util.function.Consumer;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
public class StickerVisual extends AbstractBlockEntityVisual<StickerBlockEntity> implements SimpleDynamicVisual {
float lastOffset = Float.NaN;
final Direction facing;
final boolean fakeWorld;
final int offset;
private final TransformedInstance head;
public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
head = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance();
fakeWorld = blockEntity.getLevel() != Minecraft.getInstance().level;
facing = blockState.getValue(StickerBlock.FACING);
offset = blockState.getValue(StickerBlock.EXTENDED) ? 1 : 0;
animateHead(offset);
}
@Override
public void beginFrame(DynamicVisual.Context ctx) {
float offset = blockEntity.piston.getValue(ctx.partialTick());
if (fakeWorld)
offset = this.offset;
if (Mth.equal(offset, lastOffset))
return;
animateHead(offset);
lastOffset = offset;
}
private void animateHead(float offset) {
head.setIdentityTransform()
.translate(getVisualPosition())
.nudge(blockEntity.hashCode())
.center()
.rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateXDegrees(AngleHelper.verticalAngle(facing) + 90)
.uncenter()
.translate(0, (offset * offset) * 4 / 16f, 0)
.setChanged();
}
@Override
public void updateLight(float partialTick) {
relight(head);
}
@Override
protected void _delete() {
head.delete();
}
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
consumer.accept(head);
}
}

View file

@ -1,24 +0,0 @@
package com.simibubi.create.content.contraptions.elevator;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.light.TickingLightListener;
import com.simibubi.create.content.kinetics.base.ShaftInstance;
// TODO
public class ElevatorPulleyInstance extends ShaftInstance<ElevatorPulleyBlockEntity> implements DynamicInstance, TickingLightListener {
public ElevatorPulleyInstance(MaterialManager materialManager, ElevatorPulleyBlockEntity blockEntity) {
super(materialManager, blockEntity);
}
@Override
public boolean tickLightListener() {
return false;
}
@Override
public void beginFrame() {
}
}

View file

@ -30,14 +30,13 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
protected void renderSafe(ElevatorPulleyBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, protected void renderSafe(ElevatorPulleyBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) { int light, int overlay) {
// if (Backend.canUseInstancing(be.getLevel())) // if (VisualizationManager.supportsVisualization(be.getLevel()))
// return; // return;
// from KBE. replace with super call when flw instance is implemented // from KBE. replace with super call when flw visual is implemented
BlockState state = getRenderedBlockState(be); BlockState state = getRenderedBlockState(be);
RenderType type = getRenderType(be, state); RenderType type = getRenderType(be, state);
if (type != null) renderRotatingBuffer(be, getRotatedModel(be, state), ms, buffer.getBuffer(type), light);
renderRotatingBuffer(be, getRotatedModel(be, state), ms, buffer.getBuffer(type), light);
// //
float offset = PulleyRenderer.getBlockEntityOffset(partialTicks, be); float offset = PulleyRenderer.getBlockEntityOffset(partialTicks, be);
@ -55,9 +54,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
SuperByteBuffer magnet = CachedBufferer.partial(AllPartialModels.ELEVATOR_MAGNET, blockState); SuperByteBuffer magnet = CachedBufferer.partial(AllPartialModels.ELEVATOR_MAGNET, blockState);
if (running || offset == 0) if (running || offset == 0)
AbstractPulleyRenderer.renderAt(world, magnet.centre() AbstractPulleyRenderer.renderAt(world, magnet.center()
.rotateY(blockStateAngle) .rotateYDegrees(blockStateAngle)
.unCentre(), offset, pos, ms, vb); .uncenter(), offset, pos, ms, vb);
SuperByteBuffer rotatedCoil = getRotatedCoil(be); SuperByteBuffer rotatedCoil = getRotatedCoil(be);
if (offset == 0) { if (offset == 0) {
@ -83,9 +82,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
float f = offset % 1; float f = offset % 1;
if (f < .25f || f > .75f) { if (f < .25f || f > .75f) {
halfRope.centre() halfRope.center()
.rotateY(blockStateAngle) .rotateYDegrees(blockStateAngle)
.unCentre(); .uncenter();
AbstractPulleyRenderer.renderAt(world, AbstractPulleyRenderer.renderAt(world,
halfRope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), f > .75f ? f - 1 : f, pos, ms, halfRope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), f > .75f ? f - 1 : f, pos, ms,
vb); vb);
@ -95,9 +94,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
return; return;
for (int i = 0; i < offset - .25f; i++) { for (int i = 0; i < offset - .25f; i++) {
rope.centre() rope.center()
.rotateY(blockStateAngle) .rotateYDegrees(blockStateAngle)
.unCentre(); .uncenter();
AbstractPulleyRenderer.renderAt(world, rope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), AbstractPulleyRenderer.renderAt(world, rope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize),
offset - i, pos, ms, vb); offset - i, pos, ms, vb);
} }

View file

@ -0,0 +1,20 @@
package com.simibubi.create.content.contraptions.elevator;
import com.simibubi.create.content.kinetics.base.ShaftVisual;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
// TODO
public class ElevatorPulleyVisual extends ShaftVisual<ElevatorPulleyBlockEntity> implements SimpleDynamicVisual {
public ElevatorPulleyVisual(VisualizationContext context, ElevatorPulleyBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
}
@Override
public void beginFrame(DynamicVisual.Context ctx) {
}
}

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.gantry; package com.simibubi.create.content.contraptions.gantry;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
@ -11,6 +10,7 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -31,7 +31,7 @@ public class GantryCarriageRenderer extends KineticBlockEntityRenderer<GantryCar
int light, int overlay) { int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay); super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel())) return; if (VisualizationManager.supportsVisualization(be.getLevel())) return;
BlockState state = be.getBlockState(); BlockState state = be.getBlockState();
Direction facing = state.getValue(GantryCarriageBlock.FACING); Direction facing = state.getValue(GantryCarriageBlock.FACING);
@ -55,14 +55,14 @@ public class GantryCarriageRenderer extends KineticBlockEntityRenderer<GantryCar
angleForBE *= -1; angleForBE *= -1;
SuperByteBuffer cogs = CachedBufferer.partial(AllPartialModels.GANTRY_COGS, state); SuperByteBuffer cogs = CachedBufferer.partial(AllPartialModels.GANTRY_COGS, state);
cogs.centre() cogs.center()
.rotateY(AngleHelper.horizontalAngle(facing)) .rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) .rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateY(alongFirst ^ facing.getAxis() == Axis.X ? 0 : 90) .rotateYDegrees(alongFirst ^ facing.getAxis() == Axis.X ? 0 : 90)
.translate(0, -9 / 16f, 0) .translate(0, -9 / 16f, 0)
.rotateX(-angleForBE) .rotateXDegrees(-angleForBE)
.translate(0, 9 / 16f, 0) .translate(0, 9 / 16f, 0)
.unCentre(); .uncenter();
cogs.light(light) cogs.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.solid())); .renderInto(ms, buffer.getBuffer(RenderType.solid()));

View file

@ -1,21 +1,27 @@
package com.simibubi.create.content.contraptions.gantry; package com.simibubi.create.content.contraptions.gantry;
import com.jozufozu.flywheel.api.MaterialManager; import java.util.function.Consumer;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.base.ShaftInstance; import com.simibubi.create.content.kinetics.base.ShaftVisual;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEntity> implements DynamicInstance { public class GantryCarriageVisual extends ShaftVisual<GantryCarriageBlockEntity> implements SimpleDynamicVisual {
private final ModelData gantryCogs; private final TransformedInstance gantryCogs;
final Direction facing; final Direction facing;
final Boolean alongFirst; final Boolean alongFirst;
@ -25,11 +31,10 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
private float lastAngle = Float.NaN; private float lastAngle = Float.NaN;
public GantryCarriageInstance(MaterialManager materialManager, GantryCarriageBlockEntity blockEntity) { public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity, float partialTick) {
super(materialManager, blockEntity); super(context, blockEntity, partialTick);
gantryCogs = getTransformMaterial() gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS))
.getModel(AllPartialModels.GANTRY_COGS, blockState)
.createInstance(); .createInstance();
facing = blockState.getValue(GantryCarriageBlock.FACING); facing = blockState.getValue(GantryCarriageBlock.FACING);
@ -46,7 +51,7 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
} }
@Override @Override
public void beginFrame() { public void beginFrame(DynamicVisual.Context ctx) {
float cogAngle = getCogAngle(); float cogAngle = getCogAngle();
if (Mth.equal(cogAngle, lastAngle)) return; if (Mth.equal(cogAngle, lastAngle)) return;
@ -59,16 +64,17 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
} }
private void animateCogs(float cogAngle) { private void animateCogs(float cogAngle) {
gantryCogs.loadIdentity() gantryCogs.setIdentityTransform()
.translate(getInstancePosition()) .translate(getVisualPosition())
.centre() .center()
.rotateY(AngleHelper.horizontalAngle(facing)) .rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) .rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateY(alongFirst ^ facing.getAxis() == Direction.Axis.X ? 0 : 90) .rotateYDegrees(alongFirst ^ facing.getAxis() == Direction.Axis.X ? 0 : 90)
.translate(0, -9 / 16f, 0) .translate(0, -9 / 16f, 0)
.rotateX(-cogAngle) .rotateXDegrees(-cogAngle)
.translate(0, 9 / 16f, 0) .translate(0, 9 / 16f, 0)
.unCentre(); .uncenter()
.setChanged();
} }
static float getRotationMultiplier(Direction.Axis gantryAxis, Direction facing) { static float getRotationMultiplier(Direction.Axis gantryAxis, Direction facing) {
@ -92,13 +98,19 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
} }
@Override @Override
public void updateLight() { public void updateLight(float partialTick) {
relight(pos, gantryCogs, rotatingModel); relight(gantryCogs, rotatingModel);
} }
@Override @Override
public void remove() { protected void _delete() {
super.remove(); super._delete();
gantryCogs.delete(); gantryCogs.delete();
} }
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
super.collectCrumblingInstances(consumer);
consumer.accept(gantryCogs);
}
} }

View file

@ -4,16 +4,12 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.AssemblyException; import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.TranslatingContraption; import com.simibubi.create.content.contraptions.TranslatingContraption;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.content.contraptions.render.NonStationaryLighter;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class GantryContraption extends TranslatingContraption { public class GantryContraption extends TranslatingContraption {
@ -65,9 +61,4 @@ public class GantryContraption extends TranslatingContraption {
return super.shouldUpdateAfterMovement(info) && !AllBlocks.GANTRY_CARRIAGE.has(info.state()); return super.shouldUpdateAfterMovement(info) && !AllBlocks.GANTRY_CARRIAGE.has(info.state());
} }
@Override
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new NonStationaryLighter<>(this);
}
} }

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.minecart;
import static net.minecraft.util.Mth.lerp; import static net.minecraft.util.Mth.lerp;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
@ -16,6 +15,7 @@ import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
@ -79,7 +79,7 @@ public class CouplingRenderer {
double connectorPitch = Math.atan2(endPointDiff.y, endPointDiff.multiply(1, 0, 1) double connectorPitch = Math.atan2(endPointDiff.y, endPointDiff.multiply(1, 0, 1)
.length()) * 180 / Math.PI; .length()) * 180 / Math.PI;
TransformStack msr = TransformStack.cast(ms); var msr = TransformStack.of(ms);
carts.forEachWithContext((cart, isFirst) -> { carts.forEachWithContext((cart, isFirst) -> {
CartEndpoint cartTransform = transforms.get(isFirst); CartEndpoint cartTransform = transforms.get(isFirst);
@ -87,7 +87,7 @@ public class CouplingRenderer {
cartTransform.apply(ms, camera); cartTransform.apply(ms, camera);
attachment.light(lightValues.get(isFirst)) attachment.light(lightValues.get(isFirst))
.renderInto(ms, builder); .renderInto(ms, builder);
msr.rotateY(connectorYaw - cartTransform.yaw); msr.rotateYDegrees((float) connectorYaw - cartTransform.yaw);
ring.light(lightValues.get(isFirst)) ring.light(lightValues.get(isFirst))
.renderInto(ms, builder); .renderInto(ms, builder);
ms.popPose(); ms.popPose();
@ -100,8 +100,8 @@ public class CouplingRenderer {
ms.pushPose(); ms.pushPose();
msr.translate(firstEndpoint.subtract(camera)) msr.translate(firstEndpoint.subtract(camera))
.rotateY(connectorYaw) .rotateYDegrees((float) connectorYaw)
.rotateZ(connectorPitch); .rotateZDegrees((float) connectorPitch);
ms.scale((float) endPointDiff.length(), 1, 1); ms.scale((float) endPointDiff.length(), 1, 1);
connector.light(meanSkyLight << 20 | meanBlockLight << 4) connector.light(meanSkyLight << 20 | meanBlockLight << 4)
@ -201,14 +201,14 @@ public class CouplingRenderer {
} }
public void apply(PoseStack ms, Vec3 camera) { public void apply(PoseStack ms, Vec3 camera) {
TransformStack.cast(ms) TransformStack.of(ms)
.translate(camera.scale(-1) .translate(camera.scale(-1)
.add(x, y, z)) .add(x, y, z))
.rotateY(yaw) .rotateYDegrees(yaw)
.rotateZ(pitch) .rotateZDegrees(pitch)
.rotateX(roll) .rotateXDegrees(roll)
.translate(offset, 0, 0) .translate(offset, 0, 0)
.rotateY(flip ? 180 : 0); .rotateYDegrees(flip ? 180 : 0);
} }
} }

View file

@ -11,8 +11,6 @@ import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity.CartMovementMode; import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity.CartMovementMode;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.content.contraptions.render.NonStationaryLighter;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -32,8 +30,6 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.RailShape; import net.minecraft.world.level.block.state.properties.RailShape;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.wrapper.InvWrapper; import net.minecraftforge.items.wrapper.InvWrapper;
public class MountedContraption extends Contraption { public class MountedContraption extends Contraption {
@ -159,10 +155,5 @@ public class MountedContraption extends Contraption {
if (cart instanceof Container container) if (cart instanceof Container container)
storage.attachExternal(new ContraptionInvWrapper(true, new InvWrapper(container))); storage.attachExternal(new ContraptionInvWrapper(true, new InvWrapper(container)));
} }
@Override
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new NonStationaryLighter<>(this);
}
} }

View file

@ -19,7 +19,6 @@ import com.simibubi.create.content.contraptions.BlockMovementChecks;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.TranslatingContraption; import com.simibubi.create.content.contraptions.TranslatingContraption;
import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlock.PistonState;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.AllConfigs;
@ -36,8 +35,6 @@ import net.minecraft.world.level.block.state.properties.PistonType;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class PistonContraption extends TranslatingContraption { public class PistonContraption extends TranslatingContraption {
@ -244,9 +241,4 @@ public class PistonContraption extends TranslatingContraption {
return tag; return tag;
} }
@OnlyIn(Dist.CLIENT)
@Override
public ContraptionLighter<?> makeLighter() {
return new PistonLighter(this);
}
} }

View file

@ -1,35 +0,0 @@
package com.simibubi.create.content.contraptions.piston;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import net.minecraft.core.Vec3i;
public class PistonLighter extends ContraptionLighter<PistonContraption> {
public PistonLighter(PistonContraption contraption) {
super(contraption);
}
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds);
bounds.translate(contraption.anchor);
int length = contraption.extensionLength;
Vec3i direction = contraption.orientation.getNormal();
int shift = length / 2;
int shiftX = direction.getX() * shift;
int shiftY = direction.getY() * shift;
int shiftZ = direction.getZ() * shift;
bounds.translate(shiftX, shiftY, shiftZ);
int grow = (length + 1) / 2;
int extendX = Math.abs(direction.getX() * grow);
int extendY = Math.abs(direction.getY() * grow);
int extendZ = Math.abs(direction.getZ() * grow);
bounds.grow(extendX, extendY, extendZ);
return bounds;
}
}

View file

@ -1,195 +0,0 @@
package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.instancing.ConditionalInstance;
import com.jozufozu.flywheel.core.instancing.GroupInstance;
import com.jozufozu.flywheel.core.instancing.SelectInstance;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.jozufozu.flywheel.light.LightPacking;
import com.jozufozu.flywheel.light.LightVolume;
import com.jozufozu.flywheel.light.TickingLightListener;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
import com.mojang.math.Axis;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.ShaftInstance;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.LightLayer;
public abstract class AbstractPulleyInstance<T extends KineticBlockEntity> extends ShaftInstance<T> implements DynamicInstance, TickingLightListener {
final OrientedData coil;
final SelectInstance<OrientedData> magnet;
final GroupInstance<OrientedData> rope;
final ConditionalInstance<OrientedData> halfRope;
protected float offset;
protected final Direction rotatingAbout;
protected final Axis rotationAxis;
private final GridAlignedBB volume = new GridAlignedBB();
private final LightVolume light;
public AbstractPulleyInstance(MaterialManager dispatcher, T blockEntity) {
super(dispatcher, blockEntity);
rotatingAbout = Direction.get(Direction.AxisDirection.POSITIVE, axis);
rotationAxis = Axis.of(rotatingAbout.step());
coil = getCoilModel().createInstance()
.setPosition(getInstancePosition());
magnet = new SelectInstance<>(this::getMagnetModelIndex);
magnet.addModel(getMagnetModel())
.addModel(getHalfMagnetModel());
rope = new GroupInstance<>(getRopeModel());
halfRope = new ConditionalInstance<>(getHalfRopeModel()).withCondition(this::shouldRenderHalfRope);
updateOffset();
updateVolume();
light = new LightVolume(world, volume);
light.initialize();
}
@Override
public void beginFrame() {
updateOffset();
coil.setRotation(rotationAxis.rotationDegrees(offset * 180));
int neededRopeCount = getNeededRopeCount();
rope.resize(neededRopeCount);
magnet.update()
.get()
.ifPresent(data -> {
int i = Math.max(0, Mth.floor(offset));
short packed = light.getPackedLight(pos.getX(), pos.getY() - i, pos.getZ());
data.setPosition(getInstancePosition())
.nudge(0, -offset, 0)
.setBlockLight(LightPacking.getBlock(packed))
.setSkyLight(LightPacking.getSky(packed));
});
halfRope.update()
.get()
.ifPresent(rope1 -> {
float f = offset % 1;
float halfRopeNudge = f > .75f ? f - 1 : f;
short packed = light.getPackedLight(pos.getX(), pos.getY(), pos.getZ());
rope1.setPosition(getInstancePosition())
.nudge(0, -halfRopeNudge, 0)
.setBlockLight(LightPacking.getBlock(packed))
.setSkyLight(LightPacking.getSky(packed));
});
if (isRunning()) {
int size = rope.size();
int bottomY = pos.getY() - size;
for (int i = 0; i < size; i++) {
short packed = light.getPackedLight(pos.getX(), bottomY + i, pos.getZ());
rope.get(i)
.setPosition(getInstancePosition())
.nudge(0, -offset + i + 1, 0)
.setBlockLight(LightPacking.getBlock(packed))
.setSkyLight(LightPacking.getSky(packed));
}
} else {
rope.clear();
}
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, coil);
}
@Override
public void remove() {
super.remove();
coil.delete();
magnet.delete();
rope.clear();
halfRope.delete();
light.delete();
}
protected abstract Instancer<OrientedData> getRopeModel();
protected abstract Instancer<OrientedData> getMagnetModel();
protected abstract Instancer<OrientedData> getHalfMagnetModel();
protected abstract Instancer<OrientedData> getCoilModel();
protected abstract Instancer<OrientedData> getHalfRopeModel();
protected abstract float getOffset();
protected abstract boolean isRunning();
@Override
public boolean tickLightListener() {
if (updateVolume()) {
light.move(volume);
return true;
}
return false;
}
private boolean updateVolume() {
int length = Mth.ceil(offset) + 2;
if (volume.sizeY() < length) {
volume.assign(pos.below(length), pos)
.fixMinMax();
return true;
}
return false;
}
private void updateOffset() {
offset = getOffset();
}
private int getNeededRopeCount() {
return Math.max(0, Mth.ceil(offset - 1.25f));
}
private boolean shouldRenderHalfRope() {
float f = offset % 1;
return offset > .75f && (f < .25f || f > .75f);
}
private int getMagnetModelIndex() {
if (isRunning() || offset == 0) {
return offset > .25f ? 0 : 1;
} else {
return -1;
}
}
@Override
public boolean decreaseFramerateWithDistance() {
return false;
}
@Override
public ImmutableBox getVolume() {
return volume;
}
@Override
public void onLightUpdate(LightLayer type, ImmutableBox changed) {
super.onLightUpdate(type, changed);
light.onLightUpdate(type, changed);
}
}

View file

@ -1,7 +1,5 @@
package com.simibubi.create.content.contraptions.pulley; package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.IRotate;
@ -11,6 +9,8 @@ import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
@ -44,7 +44,7 @@ public abstract class AbstractPulleyRenderer<T extends KineticBlockEntity> exten
protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer, protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) { int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) if (VisualizationManager.supportsVisualization(be.getLevel()))
return; return;
super.renderSafe(be, partialTicks, ms, buffer, light, overlay); super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
@ -53,8 +53,9 @@ public abstract class AbstractPulleyRenderer<T extends KineticBlockEntity> exten
Axis rotationAxis = ((IRotate) be.getBlockState() Axis rotationAxis = ((IRotate) be.getBlockState()
.getBlock()).getRotationAxis(be.getBlockState()); .getBlock()).getRotationAxis(be.getBlockState());
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
kineticRotationTransform(getRotatedCoil(be), be, rotationAxis, AngleHelper.rad(offset * 180), light) kineticRotationTransform(getRotatedCoil(be), be, rotationAxis, AngleHelper.rad(offset * 180), light)
.renderInto(ms, buffer.getBuffer(RenderType.solid())); .renderInto(ms, vb);
Level world = be.getLevel(); Level world = be.getLevel();
BlockState blockState = be.getBlockState(); BlockState blockState = be.getBlockState();
@ -65,7 +66,6 @@ public abstract class AbstractPulleyRenderer<T extends KineticBlockEntity> exten
SuperByteBuffer magnet = renderMagnet(be); SuperByteBuffer magnet = renderMagnet(be);
SuperByteBuffer rope = renderRope(be); SuperByteBuffer rope = renderRope(be);
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
if (running || offset == 0) if (running || offset == 0)
renderAt(world, offset > .25f ? magnet : halfMagnet, offset, pos, ms, vb); renderAt(world, offset > .25f ? magnet : halfMagnet, offset, pos, ms, vb);
@ -85,7 +85,7 @@ public abstract class AbstractPulleyRenderer<T extends KineticBlockEntity> exten
BlockPos actualPos = pulleyPos.below((int) offset); BlockPos actualPos = pulleyPos.below((int) offset);
int light = LevelRenderer.getLightColor(world, world.getBlockState(actualPos), actualPos); int light = LevelRenderer.getLightColor(world, world.getBlockState(actualPos), actualPos);
partial.translate(0, -offset, 0) partial.translate(0, -offset, 0)
.light(light) .light(light)
.renderInto(ms, buffer); .renderInto(ms, buffer);
} }

View file

@ -0,0 +1,235 @@
package com.simibubi.create.content.contraptions.pulley;
import java.util.function.Consumer;
import com.mojang.math.Axis;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.ShaftVisual;
import com.simibubi.create.foundation.render.ConditionalInstance;
import com.simibubi.create.foundation.render.GroupInstance;
import com.simibubi.create.foundation.render.SelectInstance;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.math.MoreMath;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.bytes.ByteList;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import net.minecraft.world.level.LightLayer;
public abstract class AbstractPulleyVisual<T extends KineticBlockEntity> extends ShaftVisual<T> implements SimpleDynamicVisual {
private final OrientedInstance coil;
private final SelectInstance<OrientedInstance> magnet;
private final GroupInstance<OrientedInstance> rope;
private final ConditionalInstance<OrientedInstance> halfRope;
protected final Direction rotatingAbout;
protected final Axis rotationAxis;
private final LightCache lightCache = new LightCache();
private float offset;
public AbstractPulleyVisual(VisualizationContext dispatcher, T blockEntity, float partialTick) {
super(dispatcher, blockEntity, partialTick);
rotatingAbout = Direction.get(Direction.AxisDirection.POSITIVE, axis);
rotationAxis = Axis.of(rotatingAbout.step());
coil = getCoilModel().createInstance()
.position(getVisualPosition());
coil.setChanged();
magnet = new SelectInstance<>(this::getMagnetModelIndex);
magnet.addModel(getMagnetModel())
.addModel(getHalfMagnetModel());
rope = new GroupInstance<>(getRopeModel());
halfRope = new ConditionalInstance<>(getHalfRopeModel()).withCondition(this::shouldRenderHalfRope);
updateOffset(partialTick);
}
@Override
public void setSectionCollector(SectionCollector sectionCollector) {
super.setSectionCollector(sectionCollector);
lightCache.updateSections();
}
protected abstract Instancer<OrientedInstance> getRopeModel();
protected abstract Instancer<OrientedInstance> getMagnetModel();
protected abstract Instancer<OrientedInstance> getHalfMagnetModel();
protected abstract Instancer<OrientedInstance> getCoilModel();
protected abstract Instancer<OrientedInstance> getHalfRopeModel();
protected abstract float getOffset(float pt);
protected abstract boolean isRunning();
@Override
public void beginFrame(DynamicVisual.Context ctx) {
updateOffset(ctx.partialTick());
coil.rotation(rotationAxis.rotationDegrees(offset * 180))
.setChanged();
int neededRopeCount = getNeededRopeCount();
rope.resize(neededRopeCount);
magnet.update()
.get()
.ifPresent(data -> {
int i = Math.max(0, Mth.floor(offset));
int light = lightCache.getPackedLight(i);
data.position(getVisualPosition())
.translatePosition(0, -offset, 0)
.light(light)
.setChanged();
});
halfRope.update()
.get()
.ifPresent(rope1 -> {
float f = offset % 1;
float halfRopeNudge = f > .75f ? f - 1 : f;
int light = lightCache.getPackedLight(0);
rope1.position(getVisualPosition())
.translatePosition(0, -halfRopeNudge, 0)
.light(light)
.setChanged();
});
if (isRunning()) {
int size = rope.size();
for (int i = 0; i < size; i++) {
int light = lightCache.getPackedLight(size - 1 - i);
rope.get(i)
.position(getVisualPosition())
.translatePosition(0, -offset + i + 1, 0)
.light(light)
.setChanged();
}
} else {
rope.clear();
}
}
@Override
public void updateLight(float partialTick) {
super.updateLight(partialTick);
relight(coil);
lightCache.update();
}
private void updateOffset(float pt) {
offset = getOffset(pt);
lightCache.setSize(Mth.ceil(offset) + 2);
}
private int getNeededRopeCount() {
return Math.max(0, Mth.ceil(offset - 1.25f));
}
private boolean shouldRenderHalfRope() {
float f = offset % 1;
return offset > .75f && (f < .25f || f > .75f);
}
private int getMagnetModelIndex() {
if (isRunning() || offset == 0) {
return offset > .25f ? 0 : 1;
} else {
return -1;
}
}
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
super.collectCrumblingInstances(consumer);
consumer.accept(coil);
magnet.forEach(consumer);
rope.forEach(consumer);
halfRope.forEach(consumer);
}
@Override
protected void _delete() {
super._delete();
coil.delete();
magnet.delete();
rope.clear();
halfRope.delete();
}
private class LightCache {
private final ByteList data = new ByteArrayList();
private final LongSet sections = new LongOpenHashSet();
private final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
private int sectionCount;
public void setSize(int size) {
if (size != data.size()) {
data.size(size);
int sectionCount = MoreMath.ceilingDiv(size + 15 - pos.getY() + pos.getY() / 4 * 4, SectionPos.SECTION_SIZE);
if (sectionCount != this.sectionCount) {
this.sectionCount = sectionCount;
sections.clear();
int sectionX = SectionPos.blockToSectionCoord(pos.getX());
int sectionY = SectionPos.blockToSectionCoord(pos.getY());
int sectionZ = SectionPos.blockToSectionCoord(pos.getZ());
for (int i = 0; i < sectionCount; i++) {
sections.add(SectionPos.asLong(sectionX, sectionY - i, sectionZ));
}
// Will be null during initialization
if (lightSections != null) {
updateSections();
}
}
}
}
public void updateSections() {
lightSections.sections(sections);
}
public void update() {
mutablePos.set(pos);
for (int i = 0; i < data.size(); i++) {
int blockLight = level.getBrightness(LightLayer.BLOCK, mutablePos);
int skyLight = level.getBrightness(LightLayer.SKY, mutablePos);
int light = ((skyLight << 4) & 0xF) | (blockLight & 0xF);
data.set(i, (byte) light);
mutablePos.move(Direction.DOWN);
}
}
public int getPackedLight(int offset) {
if (offset < 0 || offset >= data.size()) {
return 0;
}
int light = Byte.toUnsignedInt(data.getByte(offset));
int blockLight = light & 0xF;
int skyLight = (light >>> 4) & 0xF;
return LightTexture.pack(blockLight, skyLight);
}
}
}

View file

@ -1,48 +0,0 @@
package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.fluids.hosePulley.HosePulleyBlockEntity;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
public class HosePulleyInstance extends AbstractPulleyInstance<HosePulleyBlockEntity> {
public HosePulleyInstance(MaterialManager dispatcher, HosePulleyBlockEntity blockEntity) {
super(dispatcher, blockEntity);
}
protected Instancer<OrientedData> getRopeModel() {
return getOrientedMaterial().getModel(AllPartialModels.HOSE, blockState);
}
protected Instancer<OrientedData> getMagnetModel() {
return materialManager.defaultCutout()
.material(Materials.ORIENTED)
.getModel(AllPartialModels.HOSE_MAGNET, blockState);
}
protected Instancer<OrientedData> getHalfMagnetModel() {
return materialManager.defaultCutout()
.material(Materials.ORIENTED)
.getModel(AllPartialModels.HOSE_HALF_MAGNET, blockState);
}
protected Instancer<OrientedData> getCoilModel() {
return getOrientedMaterial().getModel(AllPartialModels.HOSE_COIL, blockState, rotatingAbout);
}
protected Instancer<OrientedData> getHalfRopeModel() {
return getOrientedMaterial().getModel(AllPartialModels.HOSE_HALF, blockState);
}
protected float getOffset() {
return blockEntity.getInterpolatedOffset(AnimationTickHolder.getPartialTicks());
}
protected boolean isRunning() {
return true;
}
}

View file

@ -0,0 +1,51 @@
package com.simibubi.create.content.contraptions.pulley;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.fluids.hosePulley.HosePulleyBlockEntity;
import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.model.Models;
public class HosePulleyVisual extends AbstractPulleyVisual<HosePulleyBlockEntity> {
public HosePulleyVisual(VisualizationContext dispatcher, HosePulleyBlockEntity blockEntity, float partialTick) {
super(dispatcher, blockEntity, partialTick);
}
@Override
protected Instancer<OrientedInstance> getRopeModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE));
}
@Override
protected Instancer<OrientedInstance> getMagnetModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_MAGNET));
}
@Override
protected Instancer<OrientedInstance> getHalfMagnetModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET));
}
@Override
protected Instancer<OrientedInstance> getCoilModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_COIL, rotatingAbout));
}
@Override
protected Instancer<OrientedInstance> getHalfRopeModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF));
}
@Override
protected float getOffset(float pt) {
return blockEntity.getInterpolatedOffset(pt);
}
@Override
protected boolean isRunning() {
return true;
}
}

View file

@ -3,18 +3,15 @@ package com.simibubi.create.content.contraptions.pulley;
import com.simibubi.create.content.contraptions.AssemblyException; import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.ContraptionType; import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.TranslatingContraption; import com.simibubi.create.content.contraptions.TranslatingContraption;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class PulleyContraption extends TranslatingContraption { public class PulleyContraption extends TranslatingContraption {
int initialOffset; int initialOffset;
@Override @Override
public ContraptionType getType() { public ContraptionType getType() {
return ContraptionType.PULLEY; return ContraptionType.PULLEY;
@ -57,13 +54,7 @@ public class PulleyContraption extends TranslatingContraption {
super.readNBT(world, nbt, spawnData); super.readNBT(world, nbt, spawnData);
} }
@Override public int getInitialOffset() {
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new PulleyLighter(this);
}
public int getInitialOffset() {
return initialOffset; return initialOffset;
} }
} }

View file

@ -1,30 +0,0 @@
package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
public class PulleyLighter extends ContraptionLighter<PulleyContraption> {
public PulleyLighter(PulleyContraption contraption) {
super(contraption);
}
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds);
Level world = contraption.entity.level();
BlockPos.MutableBlockPos pos = contraption.anchor.mutable();
while (!AllBlocks.ROPE_PULLEY.has(world.getBlockState(pos)) && pos.getY() < world.getMaxBuildHeight())
pos.move(0, 1, 0);
bounds.translate(pos);
bounds.setMinY(world.getMinBuildHeight());
return bounds;
}
}

View file

@ -1,12 +1,12 @@
package com.simibubi.create.content.contraptions.pulley; package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -64,10 +64,10 @@ public class PulleyRenderer extends AbstractPulleyRenderer<PulleyBlockEntity> {
return offset; return offset;
} }
@Override @Override
public int getViewDistance() { public int getViewDistance() {
return 128; return 128;
} }
} }

View file

@ -1,44 +0,0 @@
package com.simibubi.create.content.contraptions.pulley;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
public class RopePulleyInstance extends AbstractPulleyInstance<PulleyBlockEntity> {
public RopePulleyInstance(MaterialManager materialManager, PulleyBlockEntity blockEntity) {
super(materialManager, blockEntity);
}
protected Instancer<OrientedData> getRopeModel() {
return getOrientedMaterial().getModel(AllBlocks.ROPE.getDefaultState());
}
protected Instancer<OrientedData> getMagnetModel() {
return getOrientedMaterial().getModel(AllBlocks.PULLEY_MAGNET.getDefaultState());
}
protected Instancer<OrientedData> getHalfMagnetModel() {
return getOrientedMaterial().getModel(AllPartialModels.ROPE_HALF_MAGNET, blockState);
}
protected Instancer<OrientedData> getCoilModel() {
return getOrientedMaterial().getModel(AllPartialModels.ROPE_COIL, blockState, rotatingAbout);
}
protected Instancer<OrientedData> getHalfRopeModel() {
return getOrientedMaterial().getModel(AllPartialModels.ROPE_HALF, blockState);
}
protected float getOffset() {
float partialTicks = AnimationTickHolder.getPartialTicks();
return PulleyRenderer.getBlockEntityOffset(partialTicks, blockEntity);
}
protected boolean isRunning() {
return PulleyRenderer.isPulleyRunning(blockEntity);
}
}

View file

@ -0,0 +1,53 @@
package com.simibubi.create.content.contraptions.pulley;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import dev.engine_room.flywheel.api.instance.Instancer;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.OrientedInstance;
import dev.engine_room.flywheel.lib.model.Models;
public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
public RopePulleyVisual(VisualizationContext context, PulleyBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
}
@Override
protected Instancer<OrientedInstance> getRopeModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState()));
}
@Override
protected Instancer<OrientedInstance> getMagnetModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState()));
}
@Override
protected Instancer<OrientedInstance> getHalfMagnetModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET));
}
@Override
protected Instancer<OrientedInstance> getCoilModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_COIL, rotatingAbout));
}
@Override
protected Instancer<OrientedInstance> getHalfRopeModel() {
return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF));
}
@Override
protected float getOffset(float pt) {
return PulleyRenderer.getBlockEntityOffset(pt, blockEntity);
}
@Override
protected boolean isRunning() {
return PulleyRenderer.isPulleyRunning(blockEntity);
}
}

View file

@ -1,27 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import net.minecraft.world.level.LightLayer;
public abstract class ActorInstance {
protected final MaterialManager materialManager;
protected final VirtualRenderWorld simulationWorld;
protected final MovementContext context;
public ActorInstance(MaterialManager materialManager, VirtualRenderWorld world, MovementContext context) {
this.materialManager = materialManager;
this.simulationWorld = world;
this.context = context;
}
public void tick() { }
public void beginFrame() { }
protected int localBlockLight() {
return simulationWorld.getBrightness(LightLayer.BLOCK, context.localPos);
}
}

View file

@ -0,0 +1,49 @@
package com.simibubi.create.content.contraptions.render;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import dev.engine_room.flywheel.api.instance.InstancerProvider;
import dev.engine_room.flywheel.api.visual.Visual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.LightLayer;
public abstract class ActorVisual implements Visual {
protected final VisualizationContext visualizationContext;
protected final InstancerProvider instancerProvider;
protected final BlockAndTintGetter simulationWorld;
protected final MovementContext context;
private boolean deleted;
public ActorVisual(VisualizationContext visualizationContext, BlockAndTintGetter world, MovementContext context) {
this.visualizationContext = visualizationContext;
this.instancerProvider = visualizationContext.instancerProvider();
this.simulationWorld = world;
this.context = context;
}
public void tick() { }
public void beginFrame() { }
protected int localBlockLight() {
return simulationWorld.getBrightness(LightLayer.BLOCK, context.localPos);
}
@Override
public void update(float partialTick) {
}
protected abstract void _delete();
@Override
public final void delete() {
if (deleted) {
return;
}
_delete();
deleted = true;
}
}

View file

@ -1,17 +1,30 @@
package com.simibubi.create.content.contraptions.render; package com.simibubi.create.content.contraptions.render;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> { public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> {
public ContraptionEntityRenderer(EntityRendererProvider.Context context) { public ContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context); super(context);
} }
@ -22,7 +35,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
} }
@Override @Override
public boolean shouldRender(C entity, Frustum clippingHelper, double cameraX, double cameraY, public boolean shouldRender(C entity, Frustum frustum, double cameraX, double cameraY,
double cameraZ) { double cameraZ) {
if (entity.getContraption() == null) if (entity.getContraption() == null)
return false; return false;
@ -31,18 +44,71 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
if (!entity.isReadyForRender()) if (!entity.isReadyForRender())
return false; return false;
return super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ); return super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ);
} }
@Override @Override
public void render(C entity, float yaw, float partialTicks, PoseStack ms, MultiBufferSource buffers, public void render(C entity, float yaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffers,
int overlay) { int overlay) {
super.render(entity, yaw, partialTicks, ms, buffers, overlay); super.render(entity, yaw, partialTicks, poseStack, buffers, overlay);
Contraption contraption = entity.getContraption(); Contraption contraption = entity.getContraption();
if (contraption != null) { if (contraption == null) {
ContraptionRenderDispatcher.renderFromEntity(entity, contraption, buffers); return;
} }
Level level = entity.level();
ContraptionRenderInfo renderInfo = ContraptionRenderInfo.get(contraption);
VirtualRenderWorld renderWorld = renderInfo.getRenderWorld();
ContraptionMatrices matrices = renderInfo.getMatrices();
matrices.setup(poseStack, entity);
if (!VisualizationManager.supportsVisualization(level)) {
for (RenderType renderType : RenderType.chunkBufferLayers()) {
SuperByteBuffer sbb = renderInfo.getBuffer(renderType);
if (!sbb.isEmpty()) {
VertexConsumer vc = buffers.getBuffer(renderType);
sbb.transform(matrices.getModel())
.useLevelLight(level, matrices.getWorld())
.renderInto(poseStack, vc);
}
}
}
renderBlockEntities(level, renderWorld, contraption, matrices, buffers);
renderActors(level, renderWorld, contraption, matrices, buffers);
matrices.clear();
} }
private static void renderBlockEntities(Level level, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
BlockEntityRenderHelper.renderBlockEntities(level, renderWorld, c.getRenderedBEs(),
matrices.getModelViewProjection(), matrices.getLight(), buffer);
}
private static void renderActors(Level level, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
PoseStack m = matrices.getModel();
for (Pair<StructureTemplate.StructureBlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = level;
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour != null) {
if (c.isHiddenInPortal(blockInfo.pos()))
continue;
m.pushPose();
TransformStack.of(m)
.translate(blockInfo.pos());
movementBehaviour.renderInContraption(context, renderWorld, matrices, buffer);
m.popPose();
}
}
}
} }

View file

@ -1,26 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterialGroup;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import net.minecraft.client.renderer.RenderType;
public class ContraptionGroup<P extends ContraptionProgram> extends InstancedMaterialGroup<P> {
private final FlwContraption contraption;
public ContraptionGroup(FlwContraption contraption, InstancingEngine<P> owner, RenderType type) {
super(owner, type);
this.contraption = contraption;
}
@Override
protected void setup(P program) {
contraption.setup(program);
}
public static <P extends ContraptionProgram> InstancingEngine.GroupFactory<P> forContraption(FlwContraption c) {
return (materialManager, type) -> new ContraptionGroup<>(c, materialManager, type);
}
}

View file

@ -1,84 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import java.util.ArrayList;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import net.minecraft.client.Camera;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
public class ContraptionInstanceManager extends BlockEntityInstanceManager {
protected ArrayList<ActorInstance> actors = new ArrayList<>();
private final VirtualRenderWorld renderWorld;
private Contraption contraption;
ContraptionInstanceManager(MaterialManager materialManager, VirtualRenderWorld renderWorld, Contraption contraption) {
super(materialManager);
this.renderWorld = renderWorld;
this.contraption = contraption;
}
public void tick() {
actors.forEach(ActorInstance::tick);
}
@Override
protected boolean canCreateInstance(BlockEntity blockEntity) {
return !contraption.isHiddenInPortal(blockEntity.getBlockPos());
}
@Override
public void beginFrame(TaskEngine taskEngine, Camera info) {
super.beginFrame(taskEngine, info);
actors.forEach(ActorInstance::beginFrame);
}
@Override
protected void updateInstance(DynamicInstance dyn, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
dyn.beginFrame();
}
@Nullable
public ActorInstance createActor(Pair<StructureBlockInfo, MovementContext> actor) {
StructureBlockInfo blockInfo = actor.getLeft();
MovementContext context = actor.getRight();
if (contraption.isHiddenInPortal(context.localPos))
return null;
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) {
ActorInstance instance = movementBehaviour.createInstance(materialManager, renderWorld, context);
actors.add(instance);
return instance;
}
return null;
}
@Override
public void detachLightListeners() {
// noop, no light updater for contraption levels
}
}

View file

@ -1,67 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.light.GPULightVolume;
import com.jozufozu.flywheel.light.LightListener;
import com.jozufozu.flywheel.light.LightUpdater;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
import com.simibubi.create.content.contraptions.Contraption;
import net.minecraft.world.level.LightLayer;
public abstract class ContraptionLighter<C extends Contraption> implements LightListener {
protected final C contraption;
public final GPULightVolume lightVolume;
protected final LightUpdater lightUpdater;
protected final GridAlignedBB bounds;
protected boolean scheduleRebuild;
protected ContraptionLighter(C contraption) {
this.contraption = contraption;
lightUpdater = LightUpdater.get(contraption.entity.level());
bounds = getContraptionBounds();
growBoundsForEdgeData(bounds);
lightVolume = new GPULightVolume(contraption.entity.level(), bounds);
lightVolume.initialize();
scheduleRebuild = true;
lightUpdater.addListener(this);
}
public abstract GridAlignedBB getContraptionBounds();
@Override
public boolean isListenerInvalid() {
return lightVolume.isListenerInvalid();
}
@Override
public void onLightUpdate(LightLayer type, ImmutableBox changed) {
lightVolume.onLightUpdate(type, changed);
}
@Override
public void onLightPacket(int chunkX, int chunkZ) {
lightVolume.onLightPacket(chunkX, chunkZ);
}
protected static void growBoundsForEdgeData(GridAlignedBB bounds) {
// so we have at least enough data on the edges to avoid artifacts and have smooth lighting
bounds.grow(2);
}
@Override
public ImmutableBox getVolume() {
return bounds;
}
public void delete() {
lightUpdater.removeListener(this);
lightVolume.delete();
}
}

View file

@ -22,9 +22,7 @@ public class ContraptionMatrices {
private final Matrix4f world = new Matrix4f(); private final Matrix4f world = new Matrix4f();
private final Matrix4f light = new Matrix4f(); private final Matrix4f light = new Matrix4f();
private boolean ready; void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
public void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
float partialTicks = AnimationTickHolder.getPartialTicks(); float partialTicks = AnimationTickHolder.getPartialTicks();
this.viewProjection.pushPose(); this.viewProjection.pushPose();
@ -41,17 +39,14 @@ public class ContraptionMatrices {
light.set(world); light.set(world);
light.mul(model.last() light.mul(model.last()
.pose()); .pose());
ready = true;
} }
public void clear() { void clear() {
clearStack(modelViewProjection); clearStack(modelViewProjection);
clearStack(viewProjection); clearStack(viewProjection);
clearStack(model); clearStack(model);
world.identity(); world.identity();
light.identity(); light.identity();
ready = false;
} }
public PoseStack getModelViewProjection() { public PoseStack getModelViewProjection() {
@ -74,10 +69,6 @@ public class ContraptionMatrices {
return light; return light;
} }
public boolean isReady() {
return ready;
}
public static void transform(PoseStack ms, PoseStack transform) { public static void transform(PoseStack ms, PoseStack transform) {
ms.last() ms.last()
.pose() .pose()

View file

@ -1,39 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.AABB;
public class ContraptionProgram extends WorldProgram {
protected final int uLightBoxSize;
protected final int uLightBoxMin;
protected final int uModel;
protected int uLightVolume;
public ContraptionProgram(ResourceLocation name, int handle) {
super(name, handle);
uLightBoxSize = getUniformLocation("uLightBoxSize");
uLightBoxMin = getUniformLocation("uLightBoxMin");
uModel = getUniformLocation("uModel");
}
@Override
protected void registerSamplers() {
super.registerSamplers();
uLightVolume = setSamplerBinding("uLightVolume", 4);
}
public void bind(Matrix4f model, AABB lightVolume) {
double sizeX = lightVolume.maxX - lightVolume.minX;
double sizeY = lightVolume.maxY - lightVolume.minY;
double sizeZ = lightVolume.maxZ - lightVolume.minZ;
GL20.glUniform3f(uLightBoxSize, (float) sizeX, (float) sizeY, (float) sizeZ);
GL20.glUniform3f(uLightBoxMin, (float) lightVolume.minX, (float) lightVolume.minY, (float) lightVolume.minZ);
uploadMatrixUniform(uModel, model);
}
}

View file

@ -1,216 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import java.util.Collection;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.error.GlError;
import com.jozufozu.flywheel.config.BackendType;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData;
import com.jozufozu.flywheel.core.model.WorldModelBuilder;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.GatherContextEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.jozufozu.flywheel.util.WorldAttached;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(Dist.CLIENT)
public class ContraptionRenderDispatcher {
private static WorldAttached<ContraptionRenderingWorld<?>> WORLDS = new WorldAttached<>(SBBContraptionManager::new);
/**
* Reset a contraption's renderer.
*
* @param contraption The contraption to invalidate.
* @return true if there was a renderer associated with the given contraption.
*/
public static boolean invalidate(Contraption contraption) {
Level level = contraption.entity.level();
return WORLDS.get(level)
.invalidate(contraption);
}
public static void tick(Level world) {
if (Minecraft.getInstance()
.isPaused())
return;
WORLDS.get(world)
.tick();
}
@SubscribeEvent
public static void beginFrame(BeginFrameEvent event) {
WORLDS.get(event.getWorld())
.beginFrame(event);
}
@SubscribeEvent
public static void renderLayer(RenderLayerEvent event) {
WORLDS.get(event.getWorld())
.renderLayer(event);
GlError.pollAndThrow(() -> "contraption layer: " + event.getLayer());
}
@SubscribeEvent
public static void onRendererReload(ReloadRenderersEvent event) {
reset();
}
public static void gatherContext(GatherContextEvent e) {
reset();
}
public static void renderFromEntity(AbstractContraptionEntity entity, Contraption contraption,
MultiBufferSource buffers) {
Level world = entity.level();
ContraptionRenderInfo renderInfo = WORLDS.get(world)
.getRenderInfo(contraption);
ContraptionMatrices matrices = renderInfo.getMatrices();
// something went wrong with the other rendering
if (!matrices.isReady())
return;
VirtualRenderWorld renderWorld = renderInfo.renderWorld;
renderBlockEntities(world, renderWorld, contraption, matrices, buffers);
if (buffers instanceof MultiBufferSource.BufferSource)
((MultiBufferSource.BufferSource) buffers).endBatch();
renderActors(world, renderWorld, contraption, matrices, buffers);
}
public static VirtualRenderWorld setupRenderWorld(Level world, Contraption c) {
ContraptionWorld contraptionWorld = c.getContraptionWorld();
BlockPos origin = c.anchor;
int minBuildHeight = contraptionWorld.getMinBuildHeight();
int height = contraptionWorld.getHeight();
VirtualRenderWorld renderWorld = new VirtualRenderWorld(world, minBuildHeight, height, origin) {
@Override
public boolean supportsFlywheel() {
return canInstance();
}
};
renderWorld.setBlockEntities(c.presentBlockEntities.values());
for (StructureTemplate.StructureBlockInfo info : c.getBlocks()
.values())
// Skip individual lighting updates to prevent lag with large contraptions
// FIXME 1.20 this '0' used to be Block.UPDATE_SUPPRESS_LIGHT, yet VirtualRenderWorld didn't actually parse the flags at all
renderWorld.setBlock(info.pos(), info.state(), 0);
renderWorld.runLightEngine();
return renderWorld;
}
public static void renderBlockEntities(Level world, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
BlockEntityRenderHelper.renderBlockEntities(world, renderWorld, c.getSpecialRenderedBEs(),
matrices.getModelViewProjection(), matrices.getLight(), buffer);
}
protected static void renderActors(Level world, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
PoseStack m = matrices.getModel();
for (Pair<StructureTemplate.StructureBlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = world;
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour != null) {
if (c.isHiddenInPortal(blockInfo.pos()))
continue;
m.pushPose();
TransformStack.cast(m)
.translate(blockInfo.pos());
movementBehaviour.renderInContraption(context, renderWorld, matrices, buffer);
m.popPose();
}
}
}
public static SuperByteBuffer buildStructureBuffer(VirtualRenderWorld renderWorld, Contraption c,
RenderType layer) {
Collection<StructureTemplate.StructureBlockInfo> values = c.getRenderedBlocks();
ShadeSeparatedBufferedData data = new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withBlocks(values)
.withModelData(c.modelData)
.build();
SuperByteBuffer sbb = new SuperByteBuffer(data);
data.release();
return sbb;
}
public static int getLight(Level world, float lx, float ly, float lz) {
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
float block = 0, sky = 0;
float offset = 1 / 8f;
for (float zOffset = offset; zOffset >= -offset; zOffset -= 2 * offset)
for (float yOffset = offset; yOffset >= -offset; yOffset -= 2 * offset)
for (float xOffset = offset; xOffset >= -offset; xOffset -= 2 * offset) {
pos.set(lx + xOffset, ly + yOffset, lz + zOffset);
block += world.getBrightness(LightLayer.BLOCK, pos) / 8f;
sky += world.getBrightness(LightLayer.SKY, pos) / 8f;
}
return LightTexture.pack((int) block, (int) sky);
}
public static int getContraptionWorldLight(MovementContext context, VirtualRenderWorld renderWorld) {
return LevelRenderer.getLightColor(renderWorld, context.localPos);
}
public static void reset() {
WORLDS.empty(ContraptionRenderingWorld::delete);
if (Backend.isOn()) {
WORLDS = new WorldAttached<>(FlwContraptionManager::new);
} else {
WORLDS = new WorldAttached<>(SBBContraptionManager::new);
}
}
public static boolean canInstance() {
return Backend.getBackendType() == BackendType.INSTANCING;
}
}

View file

@ -1,77 +1,144 @@
package com.simibubi.create.content.contraptions.render; package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld; import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.util.Mth; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
import com.simibubi.create.content.contraptions.ContraptionWorld;
import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.model.ModelUtil;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.client.model.data.ModelData;
public class ContraptionRenderInfo { public class ContraptionRenderInfo {
public final Contraption contraption; public static final SuperByteBufferCache.Compartment<Pair<Contraption, RenderType>> CONTRAPTION = new SuperByteBufferCache.Compartment<>();
public final VirtualRenderWorld renderWorld; private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
private final Contraption contraption;
private final VirtualRenderWorld renderWorld;
private final ContraptionMatrices matrices = new ContraptionMatrices(); private final ContraptionMatrices matrices = new ContraptionMatrices();
private boolean visible;
public ContraptionRenderInfo(Contraption contraption, VirtualRenderWorld renderWorld) { ContraptionRenderInfo(Level level, Contraption contraption) {
this.contraption = contraption; this.contraption = contraption;
this.renderWorld = renderWorld; this.renderWorld = setupRenderWorld(level, contraption);
} }
public int getEntityId() { public static ContraptionRenderInfo get(Contraption contraption) {
return contraption.entity.getId(); return ContraptionRenderInfoManager.MANAGERS.get(contraption.entity.level()).getRenderInfo(contraption);
}
/**
* Reset a contraption's renderer.
*
* @param contraption The contraption to invalidate.
* @return true if there was a renderer associated with the given contraption.
*/
public static boolean invalidate(Contraption contraption) {
return ContraptionRenderInfoManager.MANAGERS.get(contraption.entity.level()).invalidate(contraption);
} }
public boolean isDead() { public boolean isDead() {
return !contraption.entity.isAliveOrStale(); return !contraption.entity.isAliveOrStale();
} }
public void beginFrame(BeginFrameEvent event) { public Contraption getContraption() {
matrices.clear(); return contraption;
AbstractContraptionEntity entity = contraption.entity;
visible = event.getFrustum()
.isVisible(entity.getBoundingBoxForCulling()
.inflate(2));
} }
public boolean isVisible() { public VirtualRenderWorld getRenderWorld() {
return visible && contraption.entity.isAliveOrStale() && contraption.entity.isReadyForRender(); return renderWorld;
} }
/**
* Need to call this during RenderLayerEvent.
*/
public void setupMatrices(PoseStack viewProjection, double camX, double camY, double camZ) {
if (!matrices.isReady()) {
AbstractContraptionEntity entity = contraption.entity;
viewProjection.pushPose();
double x = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.xOld, entity.getX()) - camX;
double y = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.yOld, entity.getY()) - camY;
double z = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.zOld, entity.getZ()) - camZ;
viewProjection.translate(x, y, z);
matrices.setup(viewProjection, entity);
viewProjection.popPose();
}
}
/**
* If #setupMatrices is called correctly, the returned matrices will be ready
*/
public ContraptionMatrices getMatrices() { public ContraptionMatrices getMatrices() {
return matrices; return matrices;
} }
public void invalidate() { public SuperByteBuffer getBuffer(RenderType renderType) {
return CreateClient.BUFFER_CACHE.get(CONTRAPTION, Pair.of(contraption, renderType), () -> buildStructureBuffer(renderType));
}
public void invalidate() {
for (RenderType renderType : RenderType.chunkBufferLayers()) {
CreateClient.BUFFER_CACHE.invalidate(CONTRAPTION, Pair.of(contraption, renderType));
}
}
public static VirtualRenderWorld setupRenderWorld(Level level, Contraption c) {
ContraptionWorld contraptionWorld = c.getContraptionWorld();
BlockPos origin = c.anchor;
int minBuildHeight = contraptionWorld.getMinBuildHeight();
int height = contraptionWorld.getHeight();
VirtualRenderWorld renderWorld = new VirtualRenderWorld(level, minBuildHeight, height, origin) {
@Override
public boolean supportsVisualization() {
return VisualizationManager.supportsVisualization(level);
}
};
renderWorld.setBlockEntities(c.presentBlockEntities.values());
for (StructureTemplate.StructureBlockInfo info : c.getBlocks()
.values())
renderWorld.setBlock(info.pos(), info.state(), 0);
renderWorld.runLightEngine();
return renderWorld;
}
private SuperByteBuffer buildStructureBuffer(RenderType layer) {
BlockRenderDispatcher dispatcher = ModelUtil.VANILLA_RENDERER;
ModelBlockRenderer renderer = dispatcher.getModelRenderer();
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
PoseStack poseStack = objects.poseStack;
RandomSource random = objects.random;
RenderedBlocks blocks = contraption.getRenderedBlocks();
ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder;
sbbBuilder.begin();
ModelBlockRenderer.enableCaching();
for (BlockPos pos : blocks.positions()) {
BlockState state = blocks.lookup().apply(pos);
if (state.getRenderShape() == RenderShape.MODEL) {
BakedModel model = dispatcher.getBlockModel(state);
ModelData modelData = contraption.modelData.getOrDefault(pos, ModelData.EMPTY);
modelData = model.getModelData(renderWorld, pos, state, modelData);
long randomSeed = state.getSeed(pos);
random.setSeed(randomSeed);
if (model.getRenderTypes(state, random, modelData).contains(layer)) {
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, sbbBuilder, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
}
}
}
ModelBlockRenderer.clearCache();
return sbbBuilder.end();
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder();
} }
} }

View file

@ -0,0 +1,84 @@
package com.simibubi.create.content.contraptions.render;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.utility.WorldAttached;
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(Dist.CLIENT)
public class ContraptionRenderInfoManager {
static final WorldAttached<ContraptionRenderInfoManager> MANAGERS = new WorldAttached<>(ContraptionRenderInfoManager::new);
private final Level level;
private final Int2ObjectMap<ContraptionRenderInfo> renderInfos = new Int2ObjectOpenHashMap<>();
private int removalTimer;
private ContraptionRenderInfoManager(LevelAccessor level) {
this.level = (Level) level;
}
public static void tickFor(Level level) {
if (Minecraft.getInstance()
.isPaused())
return;
MANAGERS.get(level)
.tick();
}
public static void resetAll() {
MANAGERS.empty(ContraptionRenderInfoManager::delete);
}
@SubscribeEvent
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
resetAll();
}
ContraptionRenderInfo getRenderInfo(Contraption contraption) {
int entityId = contraption.entity.getId();
ContraptionRenderInfo renderInfo = renderInfos.get(entityId);
if (renderInfo == null) {
renderInfo = new ContraptionRenderInfo(level, contraption);
renderInfos.put(entityId, renderInfo);
}
return renderInfo;
}
boolean invalidate(Contraption contraption) {
int entityId = contraption.entity.getId();
ContraptionRenderInfo renderInfo = renderInfos.remove(entityId);
if (renderInfo != null) {
renderInfo.invalidate();
return true;
}
return false;
}
private void tick() {
if (removalTimer >= 20) {
renderInfos.values().removeIf(ContraptionRenderInfo::isDead);
removalTimer = 0;
}
removalTimer++;
}
private void delete() {
for (ContraptionRenderInfo renderer : renderInfos.values()) {
renderer.invalidate();
}
renderInfos.clear();
}
}

View file

@ -1,116 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import java.lang.ref.Reference;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionHandler;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
public abstract class ContraptionRenderingWorld<C extends ContraptionRenderInfo> {
protected final Level world;
private int removalTimer;
protected final Int2ObjectMap<C> renderInfos = new Int2ObjectOpenHashMap<>();
protected final List<C> visible = new ObjectArrayList<>();
public ContraptionRenderingWorld(LevelAccessor world) {
this.world = (Level) world;
}
public boolean invalidate(Contraption contraption) {
int entityId = contraption.entity.getId();
C removed = renderInfos.remove(entityId);
if (removed != null) {
removed.invalidate();
visible.remove(removed);
return true;
}
return false;
}
public void renderLayer(RenderLayerEvent event) {
for (C c : visible) {
c.setupMatrices(event.stack, event.camX, event.camY, event.camZ);
}
}
protected abstract C create(Contraption c);
public void tick() {
removalTimer++;
if (removalTimer >= 20) {
removeDeadRenderers();
removalTimer = 0;
}
ContraptionHandler.loadedContraptions.get(world)
.values()
.stream()
.map(Reference::get)
.filter(Objects::nonNull)
.map(AbstractContraptionEntity::getContraption)
.filter(Objects::nonNull) // contraptions that are too large will not be synced, and un-synced contraptions will be null
.forEach(this::getRenderInfo);
}
public void beginFrame(BeginFrameEvent event) {
renderInfos.int2ObjectEntrySet()
.stream()
.map(Map.Entry::getValue)
.forEach(renderInfo -> renderInfo.beginFrame(event));
collectVisible();
}
protected void collectVisible() {
visible.clear();
renderInfos.int2ObjectEntrySet()
.stream()
.map(Map.Entry::getValue)
.filter(ContraptionRenderInfo::isVisible)
.forEach(visible::add);
}
public C getRenderInfo(Contraption c) {
int entityId = c.entity.getId();
C renderInfo = renderInfos.get(entityId);
if (renderInfo == null) {
renderInfo = create(c);
renderInfos.put(entityId, renderInfo);
}
return renderInfo;
}
public void delete() {
for (C renderer : renderInfos.values()) {
renderer.invalidate();
}
renderInfos.clear();
}
/**
* Remove all render infos associated with dead/removed contraptions.
*/
public void removeDeadRenderers() {
renderInfos.values().removeIf(ContraptionRenderInfo::isDead);
}
}

View file

@ -0,0 +1,282 @@
package com.simibubi.create.content.contraptions.render;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.tuple.MutablePair;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.utility.worldWrappers.WrappedBlockAndTintGetter;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.api.visual.BlockEntityVisual;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visual.LightUpdatedVisual;
import dev.engine_room.flywheel.api.visual.ShaderLightVisual;
import dev.engine_room.flywheel.api.visual.TickableVisual;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import dev.engine_room.flywheel.api.visualization.VisualEmbedding;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.api.visualization.VisualizerRegistry;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.baked.ForgeMultiBlockModelBuilder;
import dev.engine_room.flywheel.lib.task.ForEachPlan;
import dev.engine_room.flywheel.lib.task.NestedPlan;
import dev.engine_room.flywheel.lib.task.PlanMap;
import dev.engine_room.flywheel.lib.task.RunnablePlan;
import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Vec3i;
import net.minecraft.util.Mth;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.client.model.data.ModelData;
public class ContraptionVisual<E extends AbstractContraptionEntity> extends AbstractEntityVisual<E> implements DynamicVisual, TickableVisual, LightUpdatedVisual, ShaderLightVisual {
protected static final int LIGHT_PADDING = 1;
protected final VisualEmbedding embedding;
protected final List<BlockEntityVisual<?>> children = new ArrayList<>();
protected final List<ActorVisual> actors = new ArrayList<>();
protected final PlanMap<DynamicVisual, DynamicVisual.Context> dynamicVisuals = new PlanMap<>();
protected final PlanMap<TickableVisual, TickableVisual.Context> tickableVisuals = new PlanMap<>();
protected VirtualRenderWorld virtualRenderWorld;
protected Model model;
protected TransformedInstance structure;
protected SectionCollector sectionCollector;
protected long minSection, maxSection;
protected long minBlock, maxBlock;
private final PoseStack contraptionMatrix = new PoseStack();
public ContraptionVisual(VisualizationContext ctx, E entity, float partialTick) {
super(ctx, entity, partialTick);
embedding = ctx.createEmbedding(Vec3i.ZERO);
init(partialTick);
}
protected void init(float partialTick) {
setEmbeddingMatrices(partialTick);
Contraption contraption = entity.getContraption();
virtualRenderWorld = ContraptionRenderInfo.setupRenderWorld(level, contraption);
RenderedBlocks blocks = contraption.getRenderedBlocks();
BlockAndTintGetter modelWorld = new WrappedBlockAndTintGetter(virtualRenderWorld) {
@Override
public BlockState getBlockState(BlockPos pos) {
return blocks.lookup().apply(pos);
}
};
model = new ForgeMultiBlockModelBuilder(modelWorld, blocks.positions())
.modelDataLookup(pos -> contraption.modelData.getOrDefault(pos, ModelData.EMPTY))
.build();
structure = embedding.instancerProvider()
.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance();
for (BlockEntity be : contraption.getRenderedBEs()) {
setupVisualizer(be, partialTick);
}
for (var actor : contraption.getActors()) {
setupActor(actor, partialTick);
}
}
@SuppressWarnings("unchecked")
protected <T extends BlockEntity> void setupVisualizer(T be, float partialTicks) {
BlockEntityVisualizer<? super T> visualizer = (BlockEntityVisualizer<? super T>) VisualizerRegistry.getVisualizer(be.getType());
if (visualizer == null) {
return;
}
Level level = be.getLevel();
be.setLevel(virtualRenderWorld);
BlockEntityVisual<? super T> visual = visualizer.createVisual(this.embedding, be, partialTicks);
children.add(visual);
if (visual instanceof DynamicVisual dynamic) {
dynamicVisuals.add(dynamic, dynamic.planFrame());
}
if (visual instanceof TickableVisual tickable) {
tickableVisuals.add(tickable, tickable.planTick());
}
be.setLevel(level);
}
private void setupActor(MutablePair<StructureTemplate.StructureBlockInfo, MovementContext> actor, float partialTick) {
MovementContext context = actor.getRight();
if (context == null) {
return;
}
if (context.world == null) {
context.world = level;
}
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour == null) {
return;
}
var visual = movementBehaviour.createVisual(this.embedding, virtualRenderWorld, context);
if (visual == null) {
return;
}
actors.add(visual);
}
@Override
public Plan<TickableVisual.Context> planTick() {
return NestedPlan.of(
ForEachPlan.of(() -> actors, ActorVisual::tick),
tickableVisuals
);
}
@Override
public Plan<DynamicVisual.Context> planFrame() {
return NestedPlan.of(
RunnablePlan.of(this::beginFrame),
ForEachPlan.of(() -> actors, ActorVisual::beginFrame),
dynamicVisuals
);
}
protected void beginFrame(DynamicVisual.Context context) {
var partialTick = context.partialTick();
setEmbeddingMatrices(partialTick);
if (hasMovedSections()) {
sectionCollector.sections(collectLightSections());
}
if (hasMovedBlocks()) {
updateLight(partialTick);
}
}
private void setEmbeddingMatrices(float partialTick) {
double x = Mth.lerp(partialTick, entity.xOld, entity.getX());
double y = Mth.lerp(partialTick, entity.yOld, entity.getY());
double z = Mth.lerp(partialTick, entity.zOld, entity.getZ());
contraptionMatrix.setIdentity();
contraptionMatrix.translate(x, y, z);
entity.applyLocalTransforms(contraptionMatrix, partialTick);
embedding.transforms(contraptionMatrix.last().pose(), contraptionMatrix.last().normal());
}
@Override
public void updateLight(float partialTick) {
}
public LongSet collectLightSections() {
var boundingBox = entity.getBoundingBox();
var minSectionX = minLightSection(boundingBox.minX);
var minSectionY = minLightSection(boundingBox.minY);
var minSectionZ = minLightSection(boundingBox.minZ);
int maxSectionX = maxLightSection(boundingBox.maxX);
int maxSectionY = maxLightSection(boundingBox.maxY);
int maxSectionZ = maxLightSection(boundingBox.maxZ);
minSection = SectionPos.asLong(minSectionX, minSectionY, minSectionZ);
maxSection = SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ);
LongSet longSet = new LongArraySet();
for (int x = 0; x <= maxSectionX - minSectionX; x++) {
for (int y = 0; y <= maxSectionY - minSectionY; y++) {
for (int z = 0; z <= maxSectionZ - minSectionZ; z++) {
longSet.add(SectionPos.offset(minSection, x, y, z));
}
}
}
return longSet;
}
protected boolean hasMovedBlocks() {
var boundingBox = entity.getBoundingBox();
int minX = minLight(boundingBox.minX);
int minY = minLight(boundingBox.minY);
int minZ = minLight(boundingBox.minZ);
int maxX = maxLight(boundingBox.maxX);
int maxY = maxLight(boundingBox.maxY);
int maxZ = maxLight(boundingBox.maxZ);
return minBlock != BlockPos.asLong(minX, minY, minZ) || maxBlock != BlockPos.asLong(maxX, maxY, maxZ);
}
protected boolean hasMovedSections() {
var boundingBox = entity.getBoundingBox();
var minSectionX = minLightSection(boundingBox.minX);
var minSectionY = minLightSection(boundingBox.minY);
var minSectionZ = minLightSection(boundingBox.minZ);
int maxSectionX = maxLightSection(boundingBox.maxX);
int maxSectionY = maxLightSection(boundingBox.maxY);
int maxSectionZ = maxLightSection(boundingBox.maxZ);
return minSection != SectionPos.asLong(minSectionX, minSectionY, minSectionZ) || maxSection != SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ);
}
@Override
public void setSectionCollector(SectionCollector collector) {
this.sectionCollector = collector;
}
@Override
protected void _delete() {
children.forEach(BlockEntityVisual::delete);
actors.forEach(ActorVisual::delete);
if (structure != null) {
structure.delete();
}
}
public static int minLight(double aabbPos) {
return Mth.floor(aabbPos) - LIGHT_PADDING;
}
public static int maxLight(double aabbPos) {
return Mth.ceil(aabbPos) + LIGHT_PADDING;
}
public static int minLightSection(double aabbPos) {
return SectionPos.blockToSectionCoord(minLight(aabbPos));
}
public static int maxLightSection(double aabbPos) {
return SectionPos.blockToSectionCoord(maxLight(aabbPos));
}
}

View file

@ -1,16 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.simibubi.create.content.contraptions.Contraption;
// so other contraptions don't crash before they have a lighter
public class EmptyLighter extends ContraptionLighter<Contraption> {
public EmptyLighter(Contraption contraption) {
super(contraption);
}
@Override
public GridAlignedBB getContraptionBounds() {
return new GridAlignedBB(0, 0, 0, 1, 1, 1);
}
}

View file

@ -1,214 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joml.Matrix4f;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine;
import com.jozufozu.flywheel.backend.instancing.batching.BatchingEngine;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import com.jozufozu.flywheel.backend.model.ArrayModelRenderer;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.model.WorldModelBuilder;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.render.CreateContexts;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class FlwContraption extends ContraptionRenderInfo {
private final ContraptionLighter<?> lighter;
private final Map<RenderType, ArrayModelRenderer> renderLayers = new HashMap<>();
private final Matrix4f modelViewPartial = new Matrix4f();
private final ContraptionInstanceWorld instanceWorld;
private boolean modelViewPartialReady;
// floats because we upload this to the gpu
private AABB lightBox;
public FlwContraption(Contraption contraption, VirtualRenderWorld renderWorld) {
super(contraption, renderWorld);
this.lighter = contraption.makeLighter();
instanceWorld = new ContraptionInstanceWorld(this);
var restoreState = GlStateTracker.getRestoreState();
buildLayers();
if (ContraptionRenderDispatcher.canInstance()) {
buildInstancedBlockEntities();
buildActors();
}
restoreState.restore();
}
public ContraptionLighter<?> getLighter() {
return lighter;
}
public void renderStructureLayer(RenderType layer, ContraptionProgram shader) {
ArrayModelRenderer structure = renderLayers.get(layer);
if (structure != null) {
setup(shader);
structure.draw();
}
}
public void renderInstanceLayer(RenderLayerEvent event) {
event.stack.pushPose();
float partialTicks = AnimationTickHolder.getPartialTicks();
AbstractContraptionEntity entity = contraption.entity;
double x = Mth.lerp(partialTicks, entity.xOld, entity.getX());
double y = Mth.lerp(partialTicks, entity.yOld, entity.getY());
double z = Mth.lerp(partialTicks, entity.zOld, entity.getZ());
event.stack.translate(x - event.camX, y - event.camY, z - event.camZ);
ContraptionMatrices.transform(event.stack, getMatrices().getModel());
instanceWorld.engine.render(SerialTaskEngine.INSTANCE, event);
event.stack.popPose();
}
public void beginFrame(BeginFrameEvent event) {
super.beginFrame(event);
modelViewPartial.identity();
modelViewPartialReady = false;
if (!isVisible()) return;
instanceWorld.blockEntityInstanceManager.beginFrame(SerialTaskEngine.INSTANCE, event.getCamera());
Vec3 cameraPos = event.getCameraPos();
lightBox = lighter.lightVolume.toAABB()
.move(-cameraPos.x, -cameraPos.y, -cameraPos.z);
}
@Override
public void setupMatrices(PoseStack viewProjection, double camX, double camY, double camZ) {
super.setupMatrices(viewProjection, camX, camY, camZ);
if (!modelViewPartialReady) {
setupModelViewPartial(modelViewPartial, getMatrices().getModel().last().pose(), contraption.entity, camX, camY, camZ, AnimationTickHolder.getPartialTicks());
modelViewPartialReady = true;
}
}
void setup(ContraptionProgram shader) {
if (!modelViewPartialReady || lightBox == null) return;
shader.bind(modelViewPartial, lightBox);
lighter.lightVolume.bind();
}
public void invalidate() {
for (ArrayModelRenderer renderer : renderLayers.values()) {
renderer.delete();
renderer.getModel().delete();
}
renderLayers.clear();
lighter.delete();
instanceWorld.delete();
}
private void buildLayers() {
for (ArrayModelRenderer renderer : renderLayers.values()) {
renderer.delete();
renderer.getModel().delete();
}
renderLayers.clear();
List<RenderType> blockLayers = RenderType.chunkBufferLayers();
Collection<StructureBlockInfo> renderedBlocks = contraption.getRenderedBlocks();
for (RenderType layer : blockLayers) {
Model layerModel = new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withModelData(contraption.modelData)
.withBlocks(renderedBlocks)
.toModel(layer + "_" + contraption.entity.getId());
renderLayers.put(layer, new ArrayModelRenderer(layerModel));
}
}
private void buildInstancedBlockEntities() {
for (BlockEntity be : contraption.maybeInstancedBlockEntities) {
if (!InstancedRenderRegistry.canInstance(be.getType())) {
continue;
}
Level world = be.getLevel();
be.setLevel(renderWorld);
instanceWorld.blockEntityInstanceManager.add(be);
be.setLevel(world);
}
}
private void buildActors() {
contraption.getActors().forEach(instanceWorld.blockEntityInstanceManager::createActor);
}
public static void setupModelViewPartial(Matrix4f matrix, Matrix4f modelMatrix, AbstractContraptionEntity entity, double camX, double camY, double camZ, float pt) {
float x = (float) (Mth.lerp(pt, entity.xOld, entity.getX()) - camX);
float y = (float) (Mth.lerp(pt, entity.yOld, entity.getY()) - camY);
float z = (float) (Mth.lerp(pt, entity.zOld, entity.getZ()) - camZ);
matrix.setTranslation(x, y, z);
matrix.mul(modelMatrix);
}
public void tick() {
instanceWorld.blockEntityInstanceManager.tick();
}
public static class ContraptionInstanceWorld {
private final Engine engine;
private final ContraptionInstanceManager blockEntityInstanceManager;
public ContraptionInstanceWorld(FlwContraption parent) {
switch (Backend.getBackendType()) {
case INSTANCING -> {
InstancingEngine<ContraptionProgram> engine = InstancingEngine.builder(CreateContexts.CWORLD)
.setGroupFactory(ContraptionGroup.forContraption(parent))
.setIgnoreOriginCoordinate(true)
.build();
blockEntityInstanceManager = new ContraptionInstanceManager(engine, parent.renderWorld, parent.contraption);
engine.addListener(blockEntityInstanceManager);
this.engine = engine;
}
case BATCHING -> {
engine = new BatchingEngine();
blockEntityInstanceManager = new ContraptionInstanceManager(engine, parent.renderWorld, parent.contraption);
}
default -> throw new IllegalArgumentException("Unknown engine type");
}
}
public void delete() {
engine.delete();
blockEntityInstanceManager.invalidate();
}
}
}

View file

@ -1,102 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.RenderLayer;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
import com.jozufozu.flywheel.config.BackendType;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.compile.ProgramContext;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.jozufozu.flywheel.util.Textures;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.render.CreateContexts;
import net.minecraft.world.level.LevelAccessor;
public class FlwContraptionManager extends ContraptionRenderingWorld<FlwContraption> {
public FlwContraptionManager(LevelAccessor world) {
super(world);
}
@Override
public void tick() {
super.tick();
for (FlwContraption contraption : visible) {
contraption.tick();
}
}
@Override
public void renderLayer(RenderLayerEvent event) {
super.renderLayer(event);
if (visible.isEmpty()) return;
GlStateTracker.State restoreState = GlStateTracker.getRestoreState();
GlTextureUnit active = GlTextureUnit.getActive();
var backendType = Backend.getBackendType();
if (backendType != BackendType.OFF) {
renderStructures(event);
}
if (backendType != BackendType.BATCHING && event.getLayer() != null) {
for (FlwContraption renderer : visible) {
renderer.renderInstanceLayer(event);
}
}
// clear the light volume state
GlTextureUnit.T4.makeActive();
glBindTexture(GL_TEXTURE_3D, 0);
event.type.clearRenderState();
active.makeActive();
restoreState.restore();
}
private void renderStructures(RenderLayerEvent event) {
event.type.setupRenderState();
Textures.bindActiveTextures();
ContraptionProgram structureShader = CreateContexts.STRUCTURE.getProgram(ProgramContext.create(Materials.Names.PASSTHRU, Formats.BLOCK, RenderLayer.getLayer(event.type)));
structureShader.bind();
structureShader.uploadViewProjection(event.viewProjection);
structureShader.uploadCameraPos(event.camX, event.camY, event.camZ);
for (FlwContraption flwContraption : visible) {
flwContraption.renderStructureLayer(event.type, structureShader);
}
}
@Override
protected FlwContraption create(Contraption c) {
VirtualRenderWorld renderWorld = ContraptionRenderDispatcher.setupRenderWorld(world, c);
return new FlwContraption(c, renderWorld);
}
@Override
public void removeDeadRenderers() {
boolean removed = renderInfos.values()
.removeIf(renderer -> {
if (renderer.isDead()) {
renderer.invalidate();
return true;
}
return false;
});
// we use visible in #tick() so we have to re-evaluate it if any were removed
if (removed) collectVisible();
}
}

View file

@ -1,40 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.light.TickingLightListener;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.infrastructure.config.AllConfigs;
public class NonStationaryLighter<C extends Contraption> extends ContraptionLighter<C> implements TickingLightListener {
public NonStationaryLighter(C contraption) {
super(contraption);
}
@Override
public boolean tickLightListener() {
if (getVolume().volume() > AllConfigs.client().maxContraptionLightVolume.get())
return false;
ImmutableBox contraptionBounds = getContraptionBounds();
if (bounds.sameAs(contraptionBounds, 2)) {
return false;
}
bounds.assign(contraptionBounds);
growBoundsForEdgeData(bounds);
lightVolume.move(bounds);
return true;
}
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bb = GridAlignedBB.from(contraption.bounds);
bb.translate(contraption.entity.blockPosition());
return bb;
}
}

View file

@ -7,20 +7,18 @@ import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> { public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> {
public OrientedContraptionEntityRenderer(EntityRendererProvider.Context context) { public OrientedContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context); super(context);
} }
@Override @Override
public boolean shouldRender(OrientedContraptionEntity entity, Frustum p_225626_2_, double p_225626_3_, public boolean shouldRender(OrientedContraptionEntity entity, Frustum frustum, double cameraX, double cameraY,
double p_225626_5_, double p_225626_7_) { double cameraZ) {
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_)) if (!super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ))
return false; return false;
if (entity.getContraption() if (entity.getContraption()
.getType() == ContraptionType.MOUNTED && entity.getVehicle() == null) .getType() == ContraptionType.MOUNTED && entity.getVehicle() == null)
return false; return false;
return true; return true;
} }
} }

Some files were not shown because too many files have changed in this diff Show more