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 {
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}"
}
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()
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')
@ -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'))
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 {
if (Boolean.parseBoolean(project.use_parchment)) {
if (Boolean.parseBoolean(use_parchment)) {
mappings channel: 'parchment', version: "${parchment_version}-${minecraft_version}"
} else {
mappings channel: 'official', version: "${minecraft_version}"
@ -48,64 +51,39 @@ minecraft {
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs {
client {
workingDirectory project.file('run')
arg '-mixin.config=create.mixins.json'
//jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling
//jvmArgs '-XX:+IgnoreUnrecognizedVMOptions', '-XX:+AllowEnhancedClassRedefinition' // uncomment with jbr
configureEach {
property 'forge.logging.markers', ''
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 {
create {
source sourceSets.main
}
}
}
if (inWorkspace) {
flywheel {
source project(":Flywheel").sourceSets.main
}
}
}
client {
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 {
workingDirectory project.file('run')
arg '-mixin.config=create.mixins.json'
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
property 'forge.logging.console.level', 'debug'
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 {
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
}
}
@ -156,6 +134,7 @@ repositories {
}
}
mavenCentral()
mavenLocal()
flatDir {
dirs 'libs'
@ -168,17 +147,14 @@ dependencies {
jarJar("com.tterrag.registrate:Registrate:${registrate_version}") {
jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
}
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
jarJar.ranged(it, '[0.6.11,)')
jarJar("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
jarJar.ranged(it, '[1.0,2.0)')
}
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
if (inWorkspace) {
implementation project(':Flywheel')
} else {
implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}")
}
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${flywheel_minecraft_version}:${flywheel_version}")
runtimeOnly fg.deobf("dev.engine_room.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}-forge-api:${jei_version}")
@ -252,10 +228,6 @@ sourceSets.main.resources {
exclude '.cache/'
}
mixin {
add sourceSets.main, 'create.refmap.json'
}
// Workaround for SpongePowered/MixinGradle#38
afterEvaluate {
tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava)

View file

@ -8,22 +8,22 @@ mod_version = 0.5.1.h
artifact_minecraft_version = 1.20.1
minecraft_version = 1.20.1
forge_version = 47.1.43
forge_version = 47.2.6
# build dependency versions
forgegradle_version = 6.0.6
mixingradle_version = 0.7-SNAPSHOT
forgegradle_version = [6.0.16,6.2)
mixingradle_version = 0.7.+
mixin_version = 0.8.5
librarian_version = 1.+
cursegradle_version = 1.4.0
parchment_version = 2023.06.26
parchment_version = 2023.09.03
use_parchment = true
# dependency versions
registrate_version = MC1.20-1.3.3
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_version = 15.10.0.39
curios_minecraft_version = 1.20.1

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
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
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

7
gradlew vendored
View file

@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/}
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.
MAX_FD=maximum
@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
done
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;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# 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'

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

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.SuperGlueRenderer;
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.equipment.blueprint.BlueprintEntity;
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.trains.entity.CarriageContraptionEntity;
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.utility.Lang;
import com.tterrag.registrate.util.entry.EntityEntry;
@ -33,15 +34,22 @@ import net.minecraft.world.entity.MobCategory;
public class AllEntityTypes {
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 =
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",
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 =
contraption("carriage_contraption", CarriageContraptionEntity::new,
() -> CarriageContraptionEntityRenderer::new, 15, 3, true).instance(() -> CarriageContraptionInstance::new)
() -> CarriageContraptionEntityRenderer::new, 15, 3, true)
.visual(() -> CarriageContraptionVisual::new)
.register();
public static final EntityEntry<SuperGlueEntity> SUPER_GLUE =

View file

@ -6,12 +6,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.content.fluids.FluidTransportBehaviour;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.DyeColor;
@ -219,11 +219,11 @@ public class AllPartialModels {
}
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) {
return new PartialModel(Create.asResource("entity/" + path));
return PartialModel.of(Create.asResource("entity/" + path));
}
public static void init() {

View file

@ -1,8 +1,8 @@
package com.simibubi.create;
import com.simibubi.create.content.contraptions.glue.SuperGlueSelectionHandler;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.contraptions.render.SBBContraptionManager;
import com.simibubi.create.content.contraptions.render.ContraptionRenderInfo;
import com.simibubi.create.content.contraptions.render.ContraptionRenderInfoManager;
import com.simibubi.create.content.decoration.encasing.CasingConnectivity;
import com.simibubi.create.content.equipment.bell.SoulPulseEffectHandler;
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.outliner.Outliner;
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.CreateContexts;
import com.simibubi.create.foundation.render.StitchedSprite;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.ModelSwapper;
@ -62,8 +63,10 @@ public class CreateClient {
public static void onCtorClient(IEventBus modEventBus, IEventBus forgeEventBus) {
modEventBus.addListener(CreateClient::clientInit);
modEventBus.addListener(AllParticleTypes::registerFactories);
modEventBus.addListener(CreateContexts::flwInit);
modEventBus.addListener(ContraptionRenderDispatcher::gatherContext);
modEventBus.addListener(StitchedSprite::onTextureStitchPost);
AllInstanceTypes.init();
MODEL_SWAPPER.registerListeners(modEventBus);
@ -77,7 +80,7 @@ public class CreateClient {
BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL);
BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK);
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);
AllPartialModels.init();
@ -92,7 +95,7 @@ public class CreateClient {
BUFFER_CACHE.invalidate();
SCHEMATIC_HANDLER.updateRenderers();
ContraptionRenderDispatcher.reset();
ContraptionRenderInfoManager.resetAll();
}
public static void checkGraphicsFanciness() {

View file

@ -1,8 +1,6 @@
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.VertexConsumer;
import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks;
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.utility.AnimationTickHolder;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.Blocks;
@ -84,14 +82,10 @@ public class AnimatedBlazeBurner extends AnimatedKinetics {
uScroll = uScroll - Math.floor(uScroll);
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())
.shiftUVScrolling(spriteShift, (float) uScroll, (float) vScroll)
.light(LightTexture.FULL_BRIGHT)
.renderInto(matrixStack, vb);
.renderInto(matrixStack, graphics.bufferSource().getBuffer(RenderType.cutoutMipped()));
matrixStack.popPose();
}

View file

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

View file

@ -1,6 +1,5 @@
package com.simibubi.create.compat.jei.category.animations;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.gui.CustomLightingSettings;
@ -8,6 +7,7 @@ import com.simibubi.create.foundation.gui.ILightingSettings;
import com.simibubi.create.foundation.gui.element.GuiGameElement;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import mezz.jei.api.gui.drawable.IDrawable;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.level.block.state.BlockState;

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.glue.SuperGlueEntity;
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.decoration.slidingDoor.SlidingDoorBlock;
import com.simibubi.create.content.trains.entity.CarriageContraption;
@ -383,7 +383,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
if (!contraption.deferInvalidate)
return;
contraption.deferInvalidate = false;
ContraptionRenderDispatcher.invalidate(contraption);
ContraptionRenderInfo.invalidate(contraption);
});
if (!(level() instanceof ServerLevelAccessor sl))

View file

@ -18,6 +18,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Function;
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.RopeBlock;
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.kinetics.base.BlockBreakingMovementBehaviour;
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.Shapes;
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.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
@ -162,8 +159,7 @@ public abstract class Contraption {
// Client
public Map<BlockPos, ModelData> modelData;
public Map<BlockPos, BlockEntity> presentBlockEntities;
public List<BlockEntity> maybeInstancedBlockEntities;
public List<BlockEntity> specialRenderedBlockEntities;
public List<BlockEntity> renderedBlockEntities;
protected ContraptionWorld world;
public boolean deferInvalidate;
@ -180,8 +176,7 @@ public abstract class Contraption {
glueToRemove = new HashSet<>();
initialPassengers = new HashMap<>();
presentBlockEntities = new HashMap<>();
maybeInstancedBlockEntities = new ArrayList<>();
specialRenderedBlockEntities = new ArrayList<>();
renderedBlockEntities = new ArrayList<>();
pendingSubContraptions = new ArrayList<>();
stabilizedSubContraptions = new HashMap<>();
simplifiedEntityColliders = Optional.empty();
@ -709,7 +704,7 @@ public abstract class Contraption {
public void readNBT(Level world, CompoundTag nbt, boolean spawnData) {
blocks.clear();
presentBlockEntities.clear();
specialRenderedBlockEntities.clear();
renderedBlockEntities.clear();
Tag blocks = nbt.get("Blocks");
// used to differentiate between the 'old' and the paletted serialization
@ -942,20 +937,17 @@ public abstract class Contraption {
if (be == null)
return;
be.setLevel(world);
modelData.put(info.pos(), be.getModelData());
if (be instanceof KineticBlockEntity kbe)
kbe.setSpeed(0);
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);
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;
}
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
// TODO: move lighters to registry
return new EmptyLighter(this);
}
public void invalidateColliders() {
simplifiedEntityColliders = Optional.empty();
gatherBBsOffThread();
@ -1458,12 +1444,18 @@ public abstract class Contraption {
return storage.getFluids();
}
public Collection<StructureBlockInfo> getRenderedBlocks() {
return blocks.values();
public RenderedBlocks getRenderedBlocks() {
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() {
return specialRenderedBlockEntities;
public Collection<BlockEntity> getRenderedBEs() {
return renderedBlockEntities;
}
public boolean isHiddenInPortal(BlockPos localPos) {
@ -1511,4 +1503,7 @@ public abstract class Contraption {
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 com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllEntityTypes;
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.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
@ -246,10 +246,12 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity {
float angle = getAngle(partialTicks);
Axis axis = getRotationAxis();
TransformStack.cast(matrixStack)
if (axis != null) {
TransformStack.of(matrixStack)
.nudge(getId())
.centre()
.rotate(angle, axis)
.unCentre();
.center()
.rotateDegrees(angle, axis)
.uncenter();
}
}
}

View file

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

View file

@ -8,7 +8,6 @@ import java.util.UUID;
import javax.annotation.Nullable;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllEntityTypes;
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.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -539,13 +539,13 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity {
repositionOnContraption(matrixStack, partialTicks, ridingEntity);
}
TransformStack.cast(matrixStack)
TransformStack.of(matrixStack)
.nudge(getId())
.centre()
.rotateY(angleYaw)
.rotateZ(anglePitch)
.rotateY(angleInitialYaw)
.unCentre();
.center()
.rotateYDegrees(angleYaw)
.rotateZDegrees(anglePitch)
.rotateYDegrees(angleInitialYaw)
.uncenter();
}
@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 com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllTags.AllItemTags;
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.Chaser;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
@ -135,9 +135,9 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity {
public void rotate(BlockState state, PoseStack ms) {
Direction facing = state.getValue(ControlsBlock.FACING);
float yRot = AngleHelper.horizontalAngle(facing);
TransformStack.cast(ms)
.rotateY(yRot + 180)
.rotateX(67.5f);
TransformStack.of(ms)
.rotateYDegrees(yRot + 180)
.rotateXDegrees(67.5f);
}
@Override

View file

@ -1,6 +1,5 @@
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.behaviour.MovementBehaviour;
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.animation.LerpedFloat;
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.nbt.CompoundTag;
@ -138,11 +138,6 @@ public class ContraptionControlsMovement implements MovementBehaviour {
.string();
}
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override
@OnlyIn(Dist.CLIENT)
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 com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
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.DyeHelper;
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.gui.Font;
import net.minecraft.client.renderer.MultiBufferSource;
@ -93,14 +93,14 @@ public class ContraptionControlsRenderer extends SmartBlockEntityRenderer<Contra
String text = efs.currentShortName;
String description = efs.currentLongName;
PoseStack ms = matrices.getViewProjection();
TransformStack msr = TransformStack.cast(ms);
var msr = TransformStack.of(ms);
ms.pushPose();
msr.translate(ctx.localPos);
msr.rotateCentered(Direction.UP,
AngleHelper.rad(AngleHelper.horizontalAngle(ctx.state.getValue(ContraptionControlsBlock.FACING))));
msr.rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(ctx.state.getValue(ContraptionControlsBlock.FACING))),
Direction.UP);
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;
if (ctx.contraption.presentBlockEntities.get(ctx.localPos) instanceof ContraptionControlsBlockEntity cbe)

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;
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.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.AnimationTickHolder;
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.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.Vec3;
public class HarvesterActorInstance extends ActorInstance {
public class HarvesterActorVisual extends ActorVisual {
static float originOffset = 1 / 16f;
static Vec3 rotOffset = new Vec3(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
protected ModelData harvester;
protected TransformedInstance harvester;
private Direction facing;
protected float horizontalAngle;
@ -30,21 +30,20 @@ public class HarvesterActorInstance extends ActorInstance {
private double rotation;
private double previousRotation;
public HarvesterActorInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, MovementContext context) {
super(materialManager, simulationWorld, context);
public HarvesterActorVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, MovementContext movementContext) {
super(visualizationContext, simulationWorld, movementContext);
Material<ModelData> material = materialManager.defaultCutout()
.material(Materials.TRANSFORMED);
BlockState state = context.state;
BlockState state = movementContext.state;
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);
harvester.setBlockLight(localBlockLight());
harvester.light(localBlockLight(), 0);
harvester.setChanged();
}
protected PartialModel getRollingPartial() {
@ -84,14 +83,20 @@ public class HarvesterActorInstance extends ActorInstance {
@Override
public void beginFrame() {
harvester.loadIdentity()
harvester.setIdentityTransform()
.translate(context.localPos)
.centre()
.rotateY(horizontalAngle)
.unCentre()
.center()
.rotateYDegrees(horizontalAngle)
.uncenter()
.translate(getRotationOffset())
.rotateX(getRotation())
.translateBack(getRotationOffset());
.rotateXDegrees((float) getRotation())
.translateBack(getRotationOffset())
.setChanged();
}
@Override
protected void _delete() {
harvester.delete();
}
protected double getRotation() {

View file

@ -4,18 +4,18 @@ import javax.annotation.Nullable;
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.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.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
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.core.BlockPos;
import net.minecraft.tags.BlockTags;
@ -45,25 +45,6 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.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
public Vec3 getActiveAreaOffset(MovementContext context) {
return Vec3.atLowerCornerOf(context.state.getValue(HarvesterBlock.FACING)
@ -218,4 +199,23 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.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 com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
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.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
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.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -53,8 +53,8 @@ public class HarvesterRenderer extends SafeBlockEntityRenderer<HarvesterBlockEnt
superBuffer.transform(matrices.getModel());
transform(context.world, facing, superBuffer, speed, PIVOT);
superBuffer
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
superBuffer.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffers.getBuffer(RenderType.cutoutMipped()));
}
@ -64,9 +64,9 @@ public class HarvesterRenderer extends SafeBlockEntityRenderer<HarvesterBlockEnt
float time = AnimationTickHolder.getRenderTime(world) / 20;
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)
.rotate(Direction.WEST, AngleHelper.rad(angle))
.rotate(AngleHelper.rad(angle), Direction.WEST)
.translate(-rotOffset.x, -rotOffset.y, -rotOffset.z);
}
}

View file

@ -1,27 +1,31 @@
package com.simibubi.create.content.contraptions.actors.psi;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import java.util.function.Consumer;
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.Direction;
import net.minecraft.world.level.block.state.BlockState;
public class PIInstance {
private final MaterialManager materialManager;
private final InstancerProvider instancerProvider;
private final BlockState blockState;
private final BlockPos instancePos;
private final float angleX;
private final float angleY;
private boolean lit;
ModelData middle;
ModelData top;
TransformedInstance middle;
TransformedInstance top;
public PIInstance(MaterialManager materialManager, BlockState blockState, BlockPos instancePos) {
this.materialManager = materialManager;
public PIInstance(InstancerProvider instancerProvider, BlockState blockState, BlockPos instancePos) {
this.instancerProvider = instancerProvider;
this.blockState = blockState;
this.instancePos = instancePos;
Direction facing = blockState.getValue(PortableStorageInterfaceBlock.FACING);
@ -31,42 +35,38 @@ public class PIInstance {
public void init(boolean lit) {
this.lit = lit;
middle = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
middle = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit)))
.createInstance();
top = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getTopForState(blockState), blockState)
top = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getTopForState(blockState)))
.createInstance();
}
public void beginFrame(float progress) {
middle.loadIdentity()
middle.setIdentityTransform()
.translate(instancePos)
.centre()
.rotateY(angleY)
.rotateX(angleX)
.unCentre();
.center()
.rotateYDegrees(angleY)
.rotateXDegrees(angleX)
.uncenter();
top.loadIdentity()
top.setIdentityTransform()
.translate(instancePos)
.centre()
.rotateY(angleY)
.rotateX(angleX)
.unCentre();
.center()
.rotateYDegrees(angleY)
.rotateXDegrees(angleX)
.uncenter();
middle.translate(0, progress * 0.5f + 0.375f, 0);
top.translate(0, progress, 0);
middle.setChanged();
top.setChanged();
}
public void tick(boolean lit) {
if (this.lit != lit) {
this.lit = lit;
materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit)))
.stealInstance(middle);
}
}
@ -75,4 +75,9 @@ public class PIInstance {
middle.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 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.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.ContraptionRenderDispatcher;
import com.simibubi.create.content.trains.entity.CarriageContraption;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
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.core.BlockPos;
import net.minecraft.core.Direction;
@ -40,22 +40,22 @@ public class PortableStorageInterfaceMovement implements MovementBehaviour {
}
@Override
public boolean hasSpecialInstancedRendering() {
public boolean disableBlockEntityRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
return new PSIActorInstance(materialManager, simulationWorld, context);
public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new PSIActorVisual(visualizationContext, simulationWorld, movementContext);
}
@Override
@OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) {
if (!ContraptionRenderDispatcher.canInstance())
if (!VisualizationManager.supportsVisualization(context.world))
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 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.VertexConsumer;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
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.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
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.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.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -35,7 +35,7 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
@Override
protected void renderSafe(PortableStorageInterfaceBlockEntity be, float partialTicks, PoseStack ms,
MultiBufferSource buffer, int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel()))
if (VisualizationManager.supportsVisualization(be.getLevel()))
return;
BlockState blockState = be.getBlockState();
@ -55,8 +55,8 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
float progress = animation.getValue(renderPartialTicks);
boolean lit = animation.settled();
render(blockState, lit, progress, matrices.getModel(),
sbb -> sbb
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
sbb -> sbb.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), vb));
}
@ -80,10 +80,10 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
}
private static void rotateToFacing(SuperByteBuffer buffer, Direction facing) {
buffer.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.unCentre();
buffer.center()
.rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.uncenter();
}
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 com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
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.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
@ -182,9 +182,9 @@ public class RollerBlockEntity extends SmartBlockEntity {
public void rotate(BlockState state, PoseStack ms) {
Direction facing = state.getValue(RollerBlock.FACING);
float yRot = AngleHelper.horizontalAngle(facing) + 180;
TransformStack.cast(ms)
.rotateY(yRot)
.rotateX(90);
TransformStack.of(ms)
.rotateYDegrees(yRot)
.rotateXDegrees(90);
}
@Override

View file

@ -9,15 +9,13 @@ import java.util.function.BiConsumer;
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.AllBlocks;
import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
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.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.content.logistics.filter.FilterItemStack;
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.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
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.core.BlockPos;
import net.minecraft.core.Direction;
@ -70,21 +71,21 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
}
@Override
public boolean hasSpecialInstancedRendering() {
public boolean disableBlockEntityRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
return new RollerActorInstance(materialManager, simulationWorld, context);
public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new RollerActorVisual(visualizationContext, simulationWorld, movementContext);
}
@Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!ContraptionRenderDispatcher.canInstance())
if (!VisualizationManager.supportsVisualization(context.world))
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 com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
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.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
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.RenderType;
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);
BlockState blockState = be.getBlockState();
VertexConsumer vc = buffer.getBuffer(RenderType.cutoutMipped());
ms.pushPose();
ms.translate(0, -0.25, 0);
@ -43,21 +45,22 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
.scale(17 / 16f));
HarvesterRenderer.transform(be.getLevel(), facing, superBuffer, be.getAnimatedSpeed(), Vec3.ZERO);
superBuffer.translate(0, -.5, .5)
.rotateY(90)
.rotateYDegrees(90)
.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
.renderInto(ms, vc);
ms.popPose();
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)
.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
.renderInto(ms, vc);
}
public static void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
BlockState blockState = context.state;
Direction facing = blockState.getValue(HORIZONTAL_FACING);
VertexConsumer vc = buffers.getBuffer(RenderType.cutoutMipped());
SuperByteBuffer superBuffer = CachedBufferer.partial(AllPartialModels.ROLLER_WHEEL, blockState);
float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())
? context.getAnimationSpeed()
@ -73,18 +76,20 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
PoseStack viewProjection = matrices.getViewProjection();
viewProjection.pushPose();
viewProjection.translate(0, -.25, 0);
int contraptionWorldLight = ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld);
int contraptionWorldLight = LevelRenderer.getLightColor(renderWorld, context.localPos);
superBuffer.translate(0, -.5, .5)
.rotateY(90)
.light(matrices.getWorld(), contraptionWorldLight)
.renderInto(viewProjection, buffers.getBuffer(RenderType.cutoutMipped()));
.rotateYDegrees(90)
.light(contraptionWorldLight)
.useLevelLight(context.world, matrices.getWorld())
.renderInto(viewProjection, vc);
viewProjection.popPose();
CachedBufferer.partial(AllPartialModels.ROLLER_FRAME, blockState)
.transform(matrices.getModel())
.rotateCentered(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180))
.light(matrices.getWorld(), contraptionWorldLight)
.renderInto(viewProjection, buffers.getBuffer(RenderType.cutoutMipped()));
.rotateCentered(AngleHelper.rad(AngleHelper.horizontalAngle(facing) + 180), Direction.UP)
.light(contraptionWorldLight)
.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> tLevels = new HashMap<>();
BlockPos tePosition = bc.tePositions.getFirst();
BlockPos bePosition = bc.bePositions.getFirst();
double radius = -task.getHorizontalInterval()
.getFirst();
double r1 = radius - .575;
@ -109,10 +109,10 @@ public class TrackPaverV2 {
double handleLength = bc.getHandleLength();
Vec3 start = bc.starts.getFirst()
.subtract(Vec3.atLowerCornerOf(tePosition))
.subtract(Vec3.atLowerCornerOf(bePosition))
.add(0, 3 / 16f, 0);
Vec3 end = bc.starts.getSecond()
.subtract(Vec3.atLowerCornerOf(tePosition))
.subtract(Vec3.atLowerCornerOf(bePosition))
.add(0, 3 / 16f, 0);
Vec3 startHandle = bc.axes.getFirst()
.scale(handleLength)
@ -190,7 +190,7 @@ public class TrackPaverV2 {
BlockPos targetPos = new BlockPos(entry.getKey()
.getFirst(), floor,
entry.getKey()
.getSecond()).offset(tePosition);
.getSecond()).offset(bePosition);
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 com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
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.animation.LerpedFloat;
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.core.Direction;

View file

@ -1,17 +1,17 @@
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.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
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.RenderType;
import net.minecraft.core.Direction;
@ -29,30 +29,32 @@ public class ControlsRenderer {
float hAngle = 180 + AngleHelper.horizontalAngle(facing);
PoseStack ms = matrices.getModel();
cover.transform(ms)
.centre()
.rotateY(hAngle)
.unCentre()
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
.center()
.rotateYDegrees(hAngle)
.uncenter()
.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped()));
double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f);
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);
ms.pushPose();
TransformStack.cast(ms)
.centre()
.rotateY(hAngle)
TransformStack.of(ms)
.center()
.rotateYDegrees(hAngle)
.translate(0, 0, 4 / 16f)
.rotateX(vAngle - 45)
.rotateXDegrees(vAngle - 45)
.translate(0, yOffset, 0)
.rotateX(45)
.unCentre()
.rotateXDegrees(45)
.uncenter()
.translate(0, -2 / 16f, -3 / 16f)
.translate(first ? 0 : 6 / 16f, 0, 0);
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()));
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.Contraption;
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.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.state.BlockState;
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 {
@ -104,9 +101,4 @@ public class BearingContraption extends Contraption {
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;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
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.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.RenderType;
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,
int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) return;
if (VisualizationManager.supportsVisualization(be.getLevel())) return;
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
@ -42,9 +42,9 @@ public class BearingRenderer<T extends KineticBlockEntity & IBearingBlockEntity>
if (facing.getAxis()
.isHorizontal())
superBuffer.rotateCentered(Direction.UP,
AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite())));
superBuffer.rotateCentered(Direction.EAST, AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing)));
superBuffer.rotateCentered(
AngleHelper.rad(AngleHelper.horizontalAngle(facing.getOpposite())), Direction.UP);
superBuffer.rotateCentered(AngleHelper.rad(-90 - AngleHelper.verticalAngle(facing)), Direction.EAST);
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.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class ClockworkContraption extends Contraption {
@ -132,9 +129,4 @@ public class ClockworkContraption extends Contraption {
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 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.simibubi.create.AllPartialModels;
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.behaviour.MovementBehaviour;
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.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
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.RenderType;
import net.minecraft.core.Direction;
@ -36,11 +37,16 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
return null;
}
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override
@OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) {
if (ContraptionRenderDispatcher.canInstance())
if (!VisualizationManager.supportsVisualization(context.world))
return;
Direction facing = context.state.getValue(BlockStateProperties.FACING);
@ -49,7 +55,7 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
float renderPartialTicks = AnimationTickHolder.getPartialTicks();
// rotate to match blockstate
Quaternionf orientation = BearingInstance.getBlockStateOrientation(facing);
Quaternionf orientation = BearingVisual.getBlockStateOrientation(facing);
// rotate against parent
float angle = getCounterRotationAngle(context, facing, renderPartialTicks) * facing.getAxisDirection()
@ -66,21 +72,16 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
superBuffer.rotateCentered(orientation);
// render
superBuffer
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld))
superBuffer.light(LevelRenderer.getLightColor(renderWorld, context.localPos))
.useLevelLight(context.world, matrices.getWorld())
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
}
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
return new StabilizedBearingInstance(materialManager, simulationWorld, context);
public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new StabilizedBearingVisual(visualizationContext, simulationWorld, movementContext);
}
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.Contraption;
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.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class StabilizedContraption extends Contraption {
@ -66,9 +62,4 @@ public class StabilizedContraption extends Contraption {
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;
public class BellMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override
public boolean isActive(MovementContext context) {
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;
public class CampfireMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override
public void tick(MovementContext context) {
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 com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
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.foundation.virtualWorld.VirtualRenderWorld;
import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.item.ItemEntity;
@ -80,11 +80,7 @@ public interface MovementBehaviour {
default void writeExtraData(MovementContext context) {}
default boolean renderAsNormalBlockEntity() {
return false;
}
default boolean hasSpecialInstancedRendering() {
default boolean disableBlockEntityRendering() {
return false;
}
@ -94,8 +90,8 @@ public interface MovementBehaviour {
@OnlyIn(Dist.CLIENT)
@Nullable
default ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld,
MovementContext context) {
default ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return null;
}
}

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.chassis;
import java.util.List;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents;
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.Chaser;
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -70,7 +70,7 @@ public class StickerBlockEntity extends SmartBlockEntity {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false));
piston.chase(target, .4f, Chaser.LINEAR);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> VisualizationHelper.queueUpdate(this));
}
public boolean isAttachedToBlock() {

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;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
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.AnimationTickHolder;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
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,
int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) return;
if (VisualizationManager.supportsVisualization(be.getLevel())) return;
BlockState state = be.getBlockState();
SuperByteBuffer head = CachedBufferer.partial(AllPartialModels.STICKER_HEAD, state);
@ -36,10 +36,10 @@ public class StickerRenderer extends SafeBlockEntityRenderer<StickerBlockEntity>
Direction facing = state.getValue(StickerBlock.FACING);
head.nudge(be.hashCode())
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing) + 90)
.unCentre()
.center()
.rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateXDegrees(AngleHelper.verticalAngle(facing) + 90)
.uncenter()
.translate(0, (offset * offset) * 4 / 16f, 0);
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,13 +30,12 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
protected void renderSafe(ElevatorPulleyBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
// if (Backend.canUseInstancing(be.getLevel()))
// if (VisualizationManager.supportsVisualization(be.getLevel()))
// 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);
RenderType type = getRenderType(be, state);
if (type != null)
renderRotatingBuffer(be, getRotatedModel(be, state), ms, buffer.getBuffer(type), light);
//
@ -55,9 +54,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
SuperByteBuffer magnet = CachedBufferer.partial(AllPartialModels.ELEVATOR_MAGNET, blockState);
if (running || offset == 0)
AbstractPulleyRenderer.renderAt(world, magnet.centre()
.rotateY(blockStateAngle)
.unCentre(), offset, pos, ms, vb);
AbstractPulleyRenderer.renderAt(world, magnet.center()
.rotateYDegrees(blockStateAngle)
.uncenter(), offset, pos, ms, vb);
SuperByteBuffer rotatedCoil = getRotatedCoil(be);
if (offset == 0) {
@ -83,9 +82,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
float f = offset % 1;
if (f < .25f || f > .75f) {
halfRope.centre()
.rotateY(blockStateAngle)
.unCentre();
halfRope.center()
.rotateYDegrees(blockStateAngle)
.uncenter();
AbstractPulleyRenderer.renderAt(world,
halfRope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize), f > .75f ? f - 1 : f, pos, ms,
vb);
@ -95,9 +94,9 @@ public class ElevatorPulleyRenderer extends KineticBlockEntityRenderer<ElevatorP
return;
for (int i = 0; i < offset - .25f; i++) {
rope.centre()
.rotateY(blockStateAngle)
.unCentre();
rope.center()
.rotateYDegrees(blockStateAngle)
.uncenter();
AbstractPulleyRenderer.renderAt(world, rope.shiftUVScrolling(beltShift, (float) beltScroll * spriteSize),
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;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
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.Iterate;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -31,7 +31,7 @@ public class GantryCarriageRenderer extends KineticBlockEntityRenderer<GantryCar
int light, int 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();
Direction facing = state.getValue(GantryCarriageBlock.FACING);
@ -55,14 +55,14 @@ public class GantryCarriageRenderer extends KineticBlockEntityRenderer<GantryCar
angleForBE *= -1;
SuperByteBuffer cogs = CachedBufferer.partial(AllPartialModels.GANTRY_COGS, state);
cogs.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateY(alongFirst ^ facing.getAxis() == Axis.X ? 0 : 90)
cogs.center()
.rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateYDegrees(alongFirst ^ facing.getAxis() == Axis.X ? 0 : 90)
.translate(0, -9 / 16f, 0)
.rotateX(-angleForBE)
.rotateXDegrees(-angleForBE)
.translate(0, 9 / 16f, 0)
.unCentre();
.uncenter();
cogs.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));

View file

@ -1,21 +1,27 @@
package com.simibubi.create.content.contraptions.gantry;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import java.util.function.Consumer;
import com.simibubi.create.AllPartialModels;
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.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.Direction;
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 Boolean alongFirst;
@ -25,11 +31,10 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
private float lastAngle = Float.NaN;
public GantryCarriageInstance(MaterialManager materialManager, GantryCarriageBlockEntity blockEntity) {
super(materialManager, blockEntity);
public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
gantryCogs = getTransformMaterial()
.getModel(AllPartialModels.GANTRY_COGS, blockState)
gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS))
.createInstance();
facing = blockState.getValue(GantryCarriageBlock.FACING);
@ -46,7 +51,7 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
}
@Override
public void beginFrame() {
public void beginFrame(DynamicVisual.Context ctx) {
float cogAngle = getCogAngle();
if (Mth.equal(cogAngle, lastAngle)) return;
@ -59,16 +64,17 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
}
private void animateCogs(float cogAngle) {
gantryCogs.loadIdentity()
.translate(getInstancePosition())
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateY(alongFirst ^ facing.getAxis() == Direction.Axis.X ? 0 : 90)
gantryCogs.setIdentityTransform()
.translate(getVisualPosition())
.center()
.rotateYDegrees(AngleHelper.horizontalAngle(facing))
.rotateXDegrees(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90)
.rotateYDegrees(alongFirst ^ facing.getAxis() == Direction.Axis.X ? 0 : 90)
.translate(0, -9 / 16f, 0)
.rotateX(-cogAngle)
.rotateXDegrees(-cogAngle)
.translate(0, 9 / 16f, 0)
.unCentre();
.uncenter()
.setChanged();
}
static float getRotationMultiplier(Direction.Axis gantryAxis, Direction facing) {
@ -92,13 +98,19 @@ public class GantryCarriageInstance extends ShaftInstance<GantryCarriageBlockEnt
}
@Override
public void updateLight() {
relight(pos, gantryCogs, rotatingModel);
public void updateLight(float partialTick) {
relight(gantryCogs, rotatingModel);
}
@Override
public void remove() {
super.remove();
protected void _delete() {
super._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.ContraptionType;
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.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
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 {
@ -65,9 +61,4 @@ public class GantryContraption extends TranslatingContraption {
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 com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
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.VecHelper;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
@ -79,7 +79,7 @@ public class CouplingRenderer {
double connectorPitch = Math.atan2(endPointDiff.y, endPointDiff.multiply(1, 0, 1)
.length()) * 180 / Math.PI;
TransformStack msr = TransformStack.cast(ms);
var msr = TransformStack.of(ms);
carts.forEachWithContext((cart, isFirst) -> {
CartEndpoint cartTransform = transforms.get(isFirst);
@ -87,7 +87,7 @@ public class CouplingRenderer {
cartTransform.apply(ms, camera);
attachment.light(lightValues.get(isFirst))
.renderInto(ms, builder);
msr.rotateY(connectorYaw - cartTransform.yaw);
msr.rotateYDegrees((float) connectorYaw - cartTransform.yaw);
ring.light(lightValues.get(isFirst))
.renderInto(ms, builder);
ms.popPose();
@ -100,8 +100,8 @@ public class CouplingRenderer {
ms.pushPose();
msr.translate(firstEndpoint.subtract(camera))
.rotateY(connectorYaw)
.rotateZ(connectorPitch);
.rotateYDegrees((float) connectorYaw)
.rotateZDegrees((float) connectorPitch);
ms.scale((float) endPointDiff.length(), 1, 1);
connector.light(meanSkyLight << 20 | meanBlockLight << 4)
@ -201,14 +201,14 @@ public class CouplingRenderer {
}
public void apply(PoseStack ms, Vec3 camera) {
TransformStack.cast(ms)
TransformStack.of(ms)
.translate(camera.scale(-1)
.add(x, y, z))
.rotateY(yaw)
.rotateZ(pitch)
.rotateX(roll)
.rotateYDegrees(yaw)
.rotateZDegrees(pitch)
.rotateXDegrees(roll)
.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.ContraptionType;
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.NBTHelper;
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.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.wrapper.InvWrapper;
public class MountedContraption extends Contraption {
@ -160,9 +156,4 @@ public class MountedContraption extends Contraption {
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.TranslatingContraption;
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.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.material.PushReaction;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class PistonContraption extends TranslatingContraption {
@ -244,9 +241,4 @@ public class PistonContraption extends TranslatingContraption {
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;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
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.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.MultiBufferSource;
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,
int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel()))
if (VisualizationManager.supportsVisualization(be.getLevel()))
return;
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()
.getBlock()).getRotationAxis(be.getBlockState());
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
kineticRotationTransform(getRotatedCoil(be), be, rotationAxis, AngleHelper.rad(offset * 180), light)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));
.renderInto(ms, vb);
Level world = be.getLevel();
BlockState blockState = be.getBlockState();
@ -65,7 +66,6 @@ public abstract class AbstractPulleyRenderer<T extends KineticBlockEntity> exten
SuperByteBuffer magnet = renderMagnet(be);
SuperByteBuffer rope = renderRope(be);
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
if (running || offset == 0)
renderAt(world, offset > .25f ? magnet : halfMagnet, offset, pos, ms, vb);

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,13 +3,10 @@ package com.simibubi.create.content.contraptions.pulley;
import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.TranslatingContraption;
import com.simibubi.create.content.contraptions.render.ContraptionLighter;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class PulleyContraption extends TranslatingContraption {
@ -57,12 +54,6 @@ public class PulleyContraption extends TranslatingContraption {
super.readNBT(world, nbt, spawnData);
}
@Override
@OnlyIn(Dist.CLIENT)
public ContraptionLighter<?> makeLighter() {
return new PulleyLighter(this);
}
public int getInitialOffset() {
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;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.foundation.render.CachedBufferer;
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.core.Direction.Axis;
import net.minecraft.util.Mth;

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;
import org.apache.commons.lang3.tuple.Pair;
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.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.RenderType;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
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 ContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context);
}
@ -22,7 +35,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
}
@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) {
if (entity.getContraption() == null)
return false;
@ -31,18 +44,71 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
if (!entity.isReadyForRender())
return false;
return super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ);
return super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ);
}
@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) {
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
super.render(entity, yaw, partialTicks, poseStack, buffers, overlay);
Contraption contraption = entity.getContraption();
if (contraption != null) {
ContraptionRenderDispatcher.renderFromEntity(entity, contraption, buffers);
if (contraption == null) {
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 light = new Matrix4f();
private boolean ready;
public void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
float partialTicks = AnimationTickHolder.getPartialTicks();
this.viewProjection.pushPose();
@ -41,17 +39,14 @@ public class ContraptionMatrices {
light.set(world);
light.mul(model.last()
.pose());
ready = true;
}
public void clear() {
void clear() {
clearStack(modelViewProjection);
clearStack(viewProjection);
clearStack(model);
world.identity();
light.identity();
ready = false;
}
public PoseStack getModelViewProjection() {
@ -74,10 +69,6 @@ public class ContraptionMatrices {
return light;
}
public boolean isReady() {
return ready;
}
public static void transform(PoseStack ms, PoseStack transform) {
ms.last()
.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;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
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 org.apache.commons.lang3.tuple.Pair;
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 final Contraption contraption;
public final VirtualRenderWorld renderWorld;
public static final SuperByteBufferCache.Compartment<Pair<Contraption, RenderType>> CONTRAPTION = new SuperByteBufferCache.Compartment<>();
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 boolean visible;
public ContraptionRenderInfo(Contraption contraption, VirtualRenderWorld renderWorld) {
ContraptionRenderInfo(Level level, Contraption contraption) {
this.contraption = contraption;
this.renderWorld = renderWorld;
this.renderWorld = setupRenderWorld(level, contraption);
}
public int getEntityId() {
return contraption.entity.getId();
public static ContraptionRenderInfo get(Contraption contraption) {
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() {
return !contraption.entity.isAliveOrStale();
}
public void beginFrame(BeginFrameEvent event) {
matrices.clear();
AbstractContraptionEntity entity = contraption.entity;
visible = event.getFrustum()
.isVisible(entity.getBoundingBoxForCulling()
.inflate(2));
public Contraption getContraption() {
return contraption;
}
public boolean isVisible() {
return visible && contraption.entity.isAliveOrStale() && contraption.entity.isReadyForRender();
public VirtualRenderWorld getRenderWorld() {
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() {
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;
public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> {
public OrientedContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context);
}
@Override
public boolean shouldRender(OrientedContraptionEntity entity, Frustum p_225626_2_, double p_225626_3_,
double p_225626_5_, double p_225626_7_) {
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_))
public boolean shouldRender(OrientedContraptionEntity entity, Frustum frustum, double cameraX, double cameraY,
double cameraZ) {
if (!super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ))
return false;
if (entity.getContraption()
.getType() == ContraptionType.MOUNTED && entity.getVehicle() == null)
return false;
return true;
}
}

View file

@ -1,62 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.LevelAccessor;
public class SBBContraptionManager extends ContraptionRenderingWorld<ContraptionRenderInfo> {
public static final SuperByteBufferCache.Compartment<Pair<Contraption, RenderType>> CONTRAPTION = new SuperByteBufferCache.Compartment<>();
public SBBContraptionManager(LevelAccessor world) {
super(world);
}
@Override
public void renderLayer(RenderLayerEvent event) {
super.renderLayer(event);
RenderType type = event.getType();
VertexConsumer consumer = event.buffers.bufferSource()
.getBuffer(type);
visible.forEach(info -> renderContraptionLayerSBB(info, type, consumer));
event.buffers.bufferSource().endBatch(type);
}
@Override
public boolean invalidate(Contraption contraption) {
for (RenderType chunkBufferLayer : RenderType.chunkBufferLayers()) {
CreateClient.BUFFER_CACHE.invalidate(CONTRAPTION, Pair.of(contraption, chunkBufferLayer));
}
return super.invalidate(contraption);
}
@Override
protected ContraptionRenderInfo create(Contraption c) {
VirtualRenderWorld renderWorld = ContraptionRenderDispatcher.setupRenderWorld(world, c);
return new ContraptionRenderInfo(c, renderWorld);
}
private void renderContraptionLayerSBB(ContraptionRenderInfo renderInfo, RenderType layer, VertexConsumer consumer) {
if (!renderInfo.isVisible()) return;
SuperByteBuffer contraptionBuffer = CreateClient.BUFFER_CACHE.get(CONTRAPTION, Pair.of(renderInfo.contraption, layer), () -> ContraptionRenderDispatcher.buildStructureBuffer(renderInfo.renderWorld, renderInfo.contraption, layer));
if (!contraptionBuffer.isEmpty()) {
ContraptionMatrices matrices = renderInfo.getMatrices();
contraptionBuffer.transform(matrices.getModel())
.light(matrices.getWorld())
.hybridLight()
.renderInto(matrices.getViewProjection(), consumer);
}
}
}

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