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.FrogVariant
import de.bixilon.minosoft.data.registries.entities.villagers.VillagerProfession
import de.bixilon.minosoft.data.registries.fluid.Fluid
import de.bixilon.minosoft.data.registries.fluid.FluidFactories
import de.bixilon.minosoft.data.registries.fluid.fluids.PixLyzerFluid
import de.bixilon.minosoft.data.registries.fluid.FluidRegistry
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.item.ItemRegistry
import de.bixilon.minosoft.data.registries.materials.Material
@ -89,7 +87,7 @@ class Registries(
val biome: Registry<Biome> = register("biome", Registry(codec = Biome))
val dimension: Registry<Dimension> = register("dimension_type", Registry(codec = Dimension))
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 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.vec.vec3.Vec3dUtil
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.entities.EntityPhysics
import de.bixilon.minosoft.physics.properties.SwimmingVehicle
@ -107,7 +106,8 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
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)
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) {
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)
}
@Deprecated("performance")
private fun update(type: Identified, aabb: AABB, pushable: Boolean, previous: Double) = update(type.identifier, aabb, pushable, previous)
private fun updateWaterSubmersion() {
@ -146,11 +148,12 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
if (vehicle is Boat) {
// TODO
}
val eyePosition = Vec3d(physics.position.x, eyeHeight, physics.position.z).blockPosition
val block = world[eyePosition] ?: return
val position = physics.position
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) {
return
}
val eyePosition = Vec3i(physics.position.x.toInt(), eyeHeight.toInt(), physics.position.z.toInt())
val fluidHeight = eyePosition.y + getFluidHeight(eyePosition, block, block.block.fluid)
if (fluidHeight > eyeHeight) {
@ -164,11 +167,11 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
if (vehicle is SwimmingVehicle && !vehicle.canUpdatePassengerFluidMovement(WaterFluid)) {
return
}
update(WaterFluid, aabb, pushable, previous)
update(physics.entity.connection.registries.fluid.water, aabb, pushable, previous)
}
private fun clear() {
this.heights = Object2DoubleOpenHashMap()
this.heights = Object2DoubleOpenHashMap(0)
primaryFluid = null
}
@ -180,7 +183,7 @@ class SubmersionState(private val physics: EntityPhysics<*>) : Tickable {
val pushable = physics.fluidPushable
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() {

View File

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