optimize fluid physics

water and lava is now cached
This commit is contained in:
Bixilon 2023-05-31 19:17:57 +02:00
parent b9c23b8a34
commit 17633547e8
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 49 additions and 12 deletions

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.fluid
import de.bixilon.minosoft.data.registries.fluid.fluids.LavaFluid
import de.bixilon.minosoft.data.registries.fluid.fluids.PixLyzerFluid
import de.bixilon.minosoft.data.registries.fluid.fluids.WaterFluid
import de.bixilon.minosoft.data.registries.registries.Registries
import de.bixilon.minosoft.data.registries.registries.registry.Registry
class FluidRegistry : Registry<Fluid>(codec = PixLyzerFluid, integrated = FluidFactories) {
// yep, bad design, but physics heavy rely on them atm, boosting performance a lot
var water: Fluid? = null
var lava: Fluid? = null
fun updateWaterLava() {
water = this[WaterFluid]
lava = this[LavaFluid]
}
override fun postInit(registries: Registries) {
updateWaterLava()
}
}

View File

@ -43,9 +43,7 @@ import de.bixilon.minosoft.data.registries.entities.damage.DamageType
import de.bixilon.minosoft.data.registries.entities.variants.CatVariant import de.bixilon.minosoft.data.registries.entities.variants.CatVariant
import de.bixilon.minosoft.data.registries.entities.variants.FrogVariant import de.bixilon.minosoft.data.registries.entities.variants.FrogVariant
import de.bixilon.minosoft.data.registries.entities.villagers.VillagerProfession import de.bixilon.minosoft.data.registries.entities.villagers.VillagerProfession
import de.bixilon.minosoft.data.registries.fluid.Fluid import de.bixilon.minosoft.data.registries.fluid.FluidRegistry
import de.bixilon.minosoft.data.registries.fluid.FluidFactories
import de.bixilon.minosoft.data.registries.fluid.fluids.PixLyzerFluid
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.item.ItemRegistry import de.bixilon.minosoft.data.registries.item.ItemRegistry
import de.bixilon.minosoft.data.registries.materials.Material import de.bixilon.minosoft.data.registries.materials.Material
@ -89,7 +87,7 @@ class Registries(
val biome: Registry<Biome> = register("biome", Registry(codec = Biome)) val biome: Registry<Biome> = register("biome", Registry(codec = Biome))
val dimension: Registry<Dimension> = register("dimension_type", Registry(codec = Dimension)) val dimension: Registry<Dimension> = register("dimension_type", Registry(codec = Dimension))
val material: Registry<Material> = register("material", Registry(codec = Material)) val material: Registry<Material> = register("material", Registry(codec = Material))
val fluid: Registry<Fluid> = register("fluid", Registry(codec = PixLyzerFluid, integrated = FluidFactories)) val fluid: FluidRegistry = register("fluid", FluidRegistry())
val soundEvent: ResourceLocationRegistry = register("sound_event", ResourceLocationRegistry()) val soundEvent: ResourceLocationRegistry = register("sound_event", ResourceLocationRegistry())
val recipes = RecipeRegistry() val recipes = RecipeRegistry()

View File

@ -35,7 +35,6 @@ import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.inChunkPositio
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition
import de.bixilon.minosoft.physics.VanillaMath.vanillaNormalizeAssign import de.bixilon.minosoft.physics.VanillaMath.vanillaNormalizeAssign
import de.bixilon.minosoft.physics.entities.EntityPhysics import de.bixilon.minosoft.physics.entities.EntityPhysics
import de.bixilon.minosoft.physics.properties.SwimmingVehicle import de.bixilon.minosoft.physics.properties.SwimmingVehicle
@ -107,7 +106,8 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
physics.velocity = physics.velocity + update.velocity physics.velocity = physics.velocity + update.velocity
} }
private fun update(fluid: Fluid, aabb: AABB, pushable: Boolean, previousHeight: Double) { private fun update(fluid: Fluid?, aabb: AABB, pushable: Boolean, previousHeight: Double) {
if (fluid == null) return
val update = getFluidUpdate(fluid, aabb, pushable) val update = getFluidUpdate(fluid, aabb, pushable)
if (update == null) { if (update == null) {
@ -130,11 +130,13 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
} }
} }
@Deprecated("performance")
private fun update(type: ResourceLocation, aabb: AABB, pushable: Boolean, previousHeight: Double) { private fun update(type: ResourceLocation, aabb: AABB, pushable: Boolean, previousHeight: Double) {
val fluid = physics.entity.connection.registries.fluid[type] ?: return // TODO: remove this and stream fluids: waterlogged makes problems val fluid = physics.entity.connection.registries.fluid[type] // TODO: remove this and stream fluids: waterlogged makes problems
update(fluid, aabb, pushable, previousHeight) update(fluid, aabb, pushable, previousHeight)
} }
@Deprecated("performance")
private fun update(type: Identified, aabb: AABB, pushable: Boolean, previous: Double) = update(type.identifier, aabb, pushable, previous) private fun update(type: Identified, aabb: AABB, pushable: Boolean, previous: Double) = update(type.identifier, aabb, pushable, previous)
private fun updateWaterSubmersion() { private fun updateWaterSubmersion() {
@ -146,11 +148,12 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
if (vehicle is Boat) { if (vehicle is Boat) {
// TODO // TODO
} }
val eyePosition = Vec3d(physics.position.x, eyeHeight, physics.position.z).blockPosition val position = physics.position
val block = world[eyePosition] ?: return val block = physics.positionInfo.chunk?.get(position.x.toInt() and 0x0F, position.y.toInt(), position.z.toInt() and 0x0F) ?: return
if (block.block !is FluidHolder) { if (block.block !is FluidHolder) {
return return
} }
val eyePosition = Vec3i(physics.position.x.toInt(), eyeHeight.toInt(), physics.position.z.toInt())
val fluidHeight = eyePosition.y + getFluidHeight(eyePosition, block, block.block.fluid) val fluidHeight = eyePosition.y + getFluidHeight(eyePosition, block, block.block.fluid)
if (fluidHeight > eyeHeight) { if (fluidHeight > eyeHeight) {
@ -164,11 +167,11 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
if (vehicle is SwimmingVehicle && !vehicle.canUpdatePassengerFluidMovement(WaterFluid)) { if (vehicle is SwimmingVehicle && !vehicle.canUpdatePassengerFluidMovement(WaterFluid)) {
return return
} }
update(WaterFluid, aabb, pushable, previous) update(physics.entity.connection.registries.fluid.water, aabb, pushable, previous)
} }
private fun clear() { private fun clear() {
this.heights = Object2DoubleOpenHashMap() this.heights = Object2DoubleOpenHashMap(0)
primaryFluid = null primaryFluid = null
} }
@ -180,7 +183,7 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
val pushable = physics.fluidPushable val pushable = physics.fluidPushable
updateWater(aabb, pushable, previous.getDouble(WaterFluid)) updateWater(aabb, pushable, previous.getDouble(WaterFluid))
update(LavaFluid, aabb, pushable, previous.getDouble(LavaFluid)) update(physics.entity.connection.registries.fluid.lava, aabb, pushable, previous.getDouble(LavaFluid))
} }
override fun tick() { override fun tick() {

View File

@ -189,6 +189,7 @@ class PlayConnection(
taskWorker += { taskWorker += {
events.fire(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.PRE)) events.fire(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.PRE))
registries.parent = version.load(profiles.resources, latch.child(0)) registries.parent = version.load(profiles.resources, latch.child(0))
registries.fluid.updateWaterLava()
events.fire(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.POST)) events.fire(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.POST))
this::legacyTags.forceSet(FallbackTags.map(registries)) this::legacyTags.forceSet(FallbackTags.map(registries))
} }