disable leaves culling, fix some biome bugs, fix block rotation bug, fix uv lock bugs

This commit is contained in:
Bixilon 2021-11-15 22:26:06 +01:00
parent 7344fdda6c
commit 47b620bedc
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 96 additions and 104 deletions

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.* import de.bixilon.minosoft.data.registries.blocks.types.*
import de.bixilon.minosoft.data.registries.blocks.types.button.StoneButtonBlock import de.bixilon.minosoft.data.registries.blocks.types.button.StoneButtonBlock
import de.bixilon.minosoft.data.registries.blocks.types.button.WoodenButtonBlock import de.bixilon.minosoft.data.registries.blocks.types.button.WoodenButtonBlock
import de.bixilon.minosoft.data.registries.blocks.types.leaves.LeavesBlock
import de.bixilon.minosoft.data.registries.blocks.types.portal.NetherPortalBlock import de.bixilon.minosoft.data.registries.blocks.types.portal.NetherPortalBlock
import de.bixilon.minosoft.data.registries.blocks.types.redstone.ComparatorBlock import de.bixilon.minosoft.data.registries.blocks.types.redstone.ComparatorBlock
import de.bixilon.minosoft.data.registries.blocks.types.redstone.RepeaterBlock import de.bixilon.minosoft.data.registries.blocks.types.redstone.RepeaterBlock
@ -41,4 +42,5 @@ object DefaultBlockFactories : DefaultClassFactory<BlockFactory<*>>(
KelpBlock, KelpBlock,
StoneButtonBlock, StoneButtonBlock,
WoodenButtonBlock, WoodenButtonBlock,
LeavesBlock,
) )

View File

@ -117,6 +117,8 @@ open class Block(
return blockState.outlineShape return blockState.outlineShape
} }
open fun canCull(blockState: BlockState, other: BlockState): Boolean = true
companion object : ResourceLocationDeserializer<Block>, BlockFactory<Block> { companion object : ResourceLocationDeserializer<Block>, BlockFactory<Block> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: Map<String, Any>): Block { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: Map<String, Any>): Block {
check(registries != null) { "Registries is null!" } check(registries != null) { "Registries is null!" }

View File

@ -0,0 +1,37 @@
/*
* Minosoft
* Copyright (C) 2021 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.blocks.types.leaves
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.BlockFactory
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.registries.Registries
open class LeavesBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : Block(resourceLocation, registries, data) {
override fun canCull(blockState: BlockState, other: BlockState): Boolean {
if (other.block is LeavesBlock) {
return false
}
return true
}
companion object : BlockFactory<LeavesBlock> {
override fun build(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>): LeavesBlock {
return LeavesBlock(resourceLocation, registries, data)
}
}
}

View File

@ -18,13 +18,12 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.world.ChunkSection.Companion.index import de.bixilon.minosoft.data.world.ChunkSection.Companion.index
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
import de.bixilon.minosoft.data.world.biome.source.BiomeSource import de.bixilon.minosoft.data.world.biome.source.BiomeSource
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inSectionHeight
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
import de.bixilon.minosoft.modding.event.EventInitiators import de.bixilon.minosoft.modding.event.EventInitiators
import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.unsafeCast import de.bixilon.minosoft.util.KUtil.unsafeCast
import glm_.vec2.Vec2i import glm_.vec2.Vec2i
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
@ -59,15 +58,15 @@ class Chunk(
operator fun get(sectionHeight: Int): ChunkSection? = sections?.getOrNull(sectionHeight - lowestSection) operator fun get(sectionHeight: Int): ChunkSection? = sections?.getOrNull(sectionHeight - lowestSection)
fun get(x: Int, y: Int, z: Int): BlockState? { fun get(x: Int, y: Int, z: Int): BlockState? {
return this[y.sectionHeight]?.blocks?.get(x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z) return this[y.sectionHeight]?.blocks?.get(x, y.inSectionHeight, z)
} }
operator fun get(position: Vec3i): BlockState? = get(position.x, position.y, position.z) operator fun get(position: Vec3i): BlockState? = get(position.x, position.y, position.z)
fun set(x: Int, y: Int, z: Int, blockState: BlockState?, blockEntity: BlockEntity? = null) { fun set(x: Int, y: Int, z: Int, blockState: BlockState?, blockEntity: BlockEntity? = null) {
val section = getOrPut(y.sectionHeight) val section = getOrPut(y.sectionHeight)
section.blocks[x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z] = blockState section.blocks[x, y.inSectionHeight, z] = blockState
section.blockEntities[x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z] = blockEntity // ToDo section.blockEntities[x, y.inSectionHeight, z] = blockEntity // ToDo
} }
operator fun set(position: Vec3i, blockState: BlockState?) = set(position.x, position.y, position.z, blockState) operator fun set(position: Vec3i, blockState: BlockState?) = set(position.x, position.y, position.z, blockState)
@ -79,13 +78,13 @@ class Chunk(
} }
fun getBlockEntity(x: Int, y: Int, z: Int): BlockEntity? { fun getBlockEntity(x: Int, y: Int, z: Int): BlockEntity? {
return this[y.sectionHeight]?.blockEntities?.get(x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z) return this[y.sectionHeight]?.blockEntities?.get(x, y.inSectionHeight, z)
} }
fun getBlockEntity(position: Vec3i): BlockEntity? = getBlockEntity(position.x, position.y, position.z) fun getBlockEntity(position: Vec3i): BlockEntity? = getBlockEntity(position.x, position.y, position.z)
fun setBlockEntity(x: Int, y: Int, z: Int, blockEntity: BlockEntity?) { fun setBlockEntity(x: Int, y: Int, z: Int, blockEntity: BlockEntity?) {
getOrPut(y.sectionHeight).blockEntities[x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z] = blockEntity getOrPut(y.sectionHeight).blockEntities[x, y.inSectionHeight, z] = blockEntity
} }
fun setBlockEntity(position: Vec3i, blockEntity: BlockEntity?) = setBlockEntity(position.x, position.y, position.z, blockEntity) fun setBlockEntity(position: Vec3i, blockEntity: BlockEntity?) = setBlockEntity(position.x, position.y, position.z, blockEntity)
@ -206,14 +205,8 @@ class Chunk(
override fun getBiome(x: Int, y: Int, z: Int): Biome? { override fun getBiome(x: Int, y: Int, z: Int): Biome? {
if (cacheBiomes) { if (cacheBiomes) {
val sectionHeight = y.sectionHeight val section = this[y.sectionHeight] ?: return connection.world.cacheBiomeAccessor?.getBiome((chunkPosition.x shl 4) or x, y, (chunkPosition.y shl 4) or z, chunkPosition.x, chunkPosition.y, this, null)
val section = this[sectionHeight] return section.biomes[x, y.inSectionHeight, z]
if (section == null) {
// ToDo: Faster
val chunkPosition = Vec3i(x, y, z).chunkPosition
return connection.world.cacheBiomeAccessor?.getBiome(x, y, z, chunkPosition.x, chunkPosition.y, this, null)
}
return section.biomes[x, y % ProtocolDefinition.SECTION_HEIGHT_Y, z]
} }
return biomeSource?.getBiome(x and 0x0F, y, z and 0x0F) return biomeSource?.getBiome(x and 0x0F, y, z and 0x0F)
} }

View File

@ -23,7 +23,6 @@ import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
import de.bixilon.minosoft.data.registries.sounds.SoundEvent import de.bixilon.minosoft.data.registries.sounds.SoundEvent
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.biome.accessor.WorldBiomeAccessor
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
import de.bixilon.minosoft.gui.rendering.particle.types.Particle import de.bixilon.minosoft.gui.rendering.particle.types.Particle
import de.bixilon.minosoft.gui.rendering.sound.AudioPlayer import de.bixilon.minosoft.gui.rendering.sound.AudioPlayer
@ -67,7 +66,6 @@ class World(
var difficulty: Difficulties? = null var difficulty: Difficulties? = null
var difficultyLocked = false var difficultyLocked = false
var hashedSeed = 0L var hashedSeed = 0L
val biomeAccessor: BiomeAccessor = WorldBiomeAccessor(this)
var time = 0L var time = 0L
var age = 0L var age = 0L
var raining = false var raining = false
@ -151,11 +149,11 @@ class World(
} }
override fun getBiome(blockPosition: Vec3i): Biome? { override fun getBiome(blockPosition: Vec3i): Biome? {
return biomeAccessor.getBiome(blockPosition) return this[blockPosition.chunkPosition]?.getBiome(blockPosition.inChunkPosition)
} }
override fun getBiome(x: Int, y: Int, z: Int): Biome? { override fun getBiome(x: Int, y: Int, z: Int): Biome? {
return biomeAccessor.getBiome(x, y, z) return this[Vec2i(x shr 4, z shr 4)]?.getBiome(x and 0x0F, y, z and 0x0F)
} }
fun tick() { fun tick() {

View File

@ -1,31 +0,0 @@
/*
* Minosoft
* Copyright (C) 2021 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.world.biome.accessor
import de.bixilon.minosoft.data.registries.biomes.Biome
import de.bixilon.minosoft.data.world.World
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
import glm_.vec3.Vec3i
class WorldBiomeAccessor(val world: World) : BiomeAccessor {
override fun getBiome(x: Int, y: Int, z: Int): Biome? {
return getBiome(Vec3i(x, y, z)) // ToDo
}
override fun getBiome(blockPosition: Vec3i): Biome? {
return world[blockPosition.chunkPosition]?.getBiome(blockPosition.inChunkPosition)
}
}

View File

@ -62,9 +62,6 @@ class Camera(
var fogStart = Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo var fogStart = Minosoft.config.config.game.camera.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo
private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity private var mouseSensitivity = Minosoft.config.config.game.controls.moseSensitivity
@Deprecated("", ReplaceWith("connection.player"))
val entity: LocalPlayerEntity
get() = connection.player
private var lastMousePosition: Vec2d = Vec2d(0.0, 0.0) private var lastMousePosition: Vec2d = Vec2d(0.0, 0.0)
private var zoom = 0.0f private var zoom = 0.0f
@ -288,7 +285,7 @@ class Camera(
} }
private fun setSkyColor() { private fun setSkyColor() {
renderWindow[SkyRenderer.Companion]?.let { skyRenderer -> renderWindow[SkyRenderer]?.let { skyRenderer ->
skyRenderer.baseColor = connection.world.getBiome(connection.player.positionInfo.blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR skyRenderer.baseColor = connection.world.getBiome(connection.player.positionInfo.blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR

View File

@ -4,7 +4,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparenci
object CullUtil { object CullUtil {
fun Array<FaceProperties>.canCull(properties: FaceProperties, sameBlock: Boolean): Boolean { fun Array<FaceProperties>.canCull(properties: FaceProperties, blockCull: Boolean): Boolean {
val sizeStartX = properties.sizeStart.x val sizeStartX = properties.sizeStart.x
val sizeStartY = properties.sizeStart.y val sizeStartY = properties.sizeStart.y
val sizeEndX = properties.sizeEnd.x val sizeEndX = properties.sizeEnd.x
@ -16,7 +16,7 @@ object CullUtil {
&& property.sizeEnd.x >= sizeEndX && property.sizeEnd.x >= sizeEndX
&& property.sizeEnd.y >= sizeEndY && property.sizeEnd.y >= sizeEndY
&& !((properties.transparency == TextureTransparencies.OPAQUE && property.transparency != TextureTransparencies.OPAQUE) && !((properties.transparency == TextureTransparencies.OPAQUE && property.transparency != TextureTransparencies.OPAQUE)
|| (properties.transparency != TextureTransparencies.OPAQUE && property.transparency == properties.transparency && !sameBlock) || (properties.transparency != TextureTransparencies.OPAQUE && property.transparency == properties.transparency && !blockCull)
|| (properties.transparency == TextureTransparencies.TRANSPARENT && property.transparency == TextureTransparencies.TRANSLUCENT)) || (properties.transparency == TextureTransparencies.TRANSPARENT && property.transparency == TextureTransparencies.TRANSLUCENT))
) { ) {
return true return true

View File

@ -53,7 +53,7 @@ class BakedBlockStateModel(
neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted) neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted)
} }
for (face in faces) { for (face in faces) {
if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, blockState == neighbour)) { if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, neighbour != null && blockState.block.canCull(blockState, neighbour))) {
continue continue
} }
face.singleRender(positionArray, mesh, light, ambientLight) face.singleRender(positionArray, mesh, light, ambientLight)

View File

@ -22,22 +22,22 @@ import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
class MultipartRootModel( class MultipartRootModel(
private val conditions: MutableMap<MutableSet<Set<Map<BlockProperties, Any>>>, Set<UnbakedBlockStateModel>>, private val conditions: MutableMap<MutableSet<Map<BlockProperties, Set<Any>>>, MutableSet<UnbakedBlockStateModel>>,
) : RootModel { ) : RootModel {
private fun Set<Map<BlockProperties, Any>>.matches(blockState: BlockState): Boolean { private fun Map<BlockProperties, Set<Any>>.matches(blockState: BlockState): Boolean {
var matches = false var matches = true
for (propertyMap in this) { for ((property, values) in this) {
var singleMatches = false var singleMatches = false
for ((property, value) in propertyMap) { for (value in values) {
if (blockState.properties[property] == value) { if (blockState.properties[property] == value) {
singleMatches = true singleMatches = true
break break
} }
} }
if (singleMatches) { if (!singleMatches) {
matches = true matches = false
break break
} }
} }
@ -45,13 +45,15 @@ class MultipartRootModel(
return matches return matches
} }
private fun MutableSet<Set<Map<BlockProperties, Any>>>.matchesAny(blockState: BlockState): Boolean { private fun Set<Map<BlockProperties, Set<Any>>>.matchesAny(blockState: BlockState): Boolean {
var matches = true var matches = true
for (or in this) { for (or in this) {
if (!or.matches(blockState)) { if (!or.matches(blockState)) {
matches = false matches = false
break continue
} }
matches = true
break
} }
return matches return matches
} }
@ -70,26 +72,31 @@ class MultipartRootModel(
companion object { companion object {
private fun getCondition(data: MutableMap<String, Any>): MutableSet<Map<BlockProperties, Any>> { private fun getCondition(data: MutableMap<String, Any>): MutableMap<BlockProperties, Set<Any>> {
val singleCondition: MutableSet<Map<BlockProperties, Any>> = mutableSetOf() val condition: MutableMap<BlockProperties, Set<Any>> = mutableMapOf()
for ((propertyName, value) in data) { for ((propertyName, value) in data) {
val properties: MutableMap<BlockProperties, Any> = mutableMapOf() var property: BlockProperties? = null
val values: MutableSet<Any> = mutableSetOf()
for (propertyValue in value.toString().split("|")) { for (propertyValue in value.toString().split("|")) {
properties += BlockProperties.parseProperty(propertyName, propertyValue) val (parsedProperty, parsedValue) = BlockProperties.parseProperty(propertyName, propertyValue)
if (property == null) {
property = parsedProperty
}
values += parsedValue
} }
singleCondition += properties condition[property!!] = values
} }
return singleCondition return condition
} }
operator fun invoke(models: Map<ResourceLocation, GenericUnbakedModel>, data: List<Any>): MultipartRootModel { operator fun invoke(models: Map<ResourceLocation, GenericUnbakedModel>, data: List<Any>): MultipartRootModel {
val conditions: MutableMap<MutableSet<Set<Map<BlockProperties, Any>>>, Set<UnbakedBlockStateModel>> = mutableMapOf() val conditions: MutableMap<MutableSet<Map<BlockProperties, Set<Any>>>, MutableSet<UnbakedBlockStateModel>> = mutableMapOf()
for (modelData in data) { for (modelData in data) {
check(modelData is Map<*, *>) check(modelData is Map<*, *>)
val condition: MutableSet<Set<Map<BlockProperties, Any>>> = mutableSetOf() val condition: MutableSet<Map<BlockProperties, Set<Any>>> = mutableSetOf()
val applyData = modelData["apply"]!! val applyData = modelData["apply"]!!
val apply: MutableSet<UnbakedBlockStateModel> = mutableSetOf() val apply: MutableSet<UnbakedBlockStateModel> = mutableSetOf()
if (applyData is Map<*, *>) { if (applyData is Map<*, *>) {
@ -113,7 +120,7 @@ class MultipartRootModel(
conditions[condition] = apply conditions.getOrPut(condition) { mutableSetOf() } += apply
} }
return MultipartRootModel(conditions) return MultipartRootModel(conditions)

View File

@ -87,7 +87,6 @@ data class UnbakedBlockStateModel(
val touchingFaceProperties: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() } val touchingFaceProperties: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
for (element in model.elements) { for (element in model.elements) {
val rescale = element.rotation?.rescale ?: false
for (face in element.faces) { for (face in element.faces) {
val texture = resolvedTextures[face.texture.removePrefix("#")]!! // ToDo: Allow direct texture names? val texture = resolvedTextures[face.texture.removePrefix("#")]!! // ToDo: Allow direct texture names?
val positions = face.direction.getPositions(element.from, element.to) val positions = face.direction.getPositions(element.from, element.to)
@ -119,13 +118,14 @@ data class UnbakedBlockStateModel(
texturePositions = texturePositions.rotateLeft((face.rotation % 360) / 90).toTypedArray() texturePositions = texturePositions.rotateLeft((face.rotation % 360) / 90).toTypedArray()
} }
if (this.uvLock && this.rotation != null && face.direction.axis != Axes.Z) { if (this.uvLock && this.rotation != null) {
var rad = this.rotation[face.direction.axis].rad val axis = when (face.direction) {
if (direction.negative) { Directions.UP, Directions.DOWN -> Axes.Y
rad = -rad else -> Axes.X
} }
val rad = this.rotation[axis].rad
for ((index, position) in texturePositions.withIndex()) { for ((index, position) in texturePositions.withIndex()) {
texturePositions[index] = (Vec3(position.x - 0.5f, 0.0f, position.y - 0.5f).apply { rotateAssign(rad, direction.axis) }).xz + 0.5f texturePositions[index] = (Vec3(position.x - 0.5f, 0.0f, position.y - 0.5f).apply { rotateAssign(rad, axis) }).xz + 0.5f
} }
} }

View File

@ -141,37 +141,24 @@ object VecUtil {
return this * cos + (axis cross this) * sin + axis * (axis dot this) * (1 - cos) return this * cos + (axis cross this) * sin + axis * (axis dot this) * (1 - cos)
} }
fun Int.chunkPosition(multiplier: Int): Int {
return if (this >= 0) {
this / multiplier
} else {
((this + 1) / multiplier) - 1
}
}
val Vec3i.chunkPosition: Vec2i val Vec3i.chunkPosition: Vec2i
get() = Vec2i(this.x.chunkPosition(ProtocolDefinition.SECTION_WIDTH_X), this.z.chunkPosition(ProtocolDefinition.SECTION_WIDTH_Z)) get() = Vec2i(x shr 4, z shr 4)
val Vec3i.inChunkPosition: Vec3i val Vec3i.inChunkPosition: Vec3i
get() = Vec3i(x and 0x0F, y, this.z and 0x0F) get() = Vec3i(x and 0x0F, y, this.z and 0x0F)
val Vec3i.inChunkSectionPosition: Vec3i val Vec3i.inChunkSectionPosition: Vec3i
get() { get() = Vec3i(x and 0x0F, y.inSectionHeight, z and 0x0F)
val inVec2i = inChunkPosition
val y = if (y < 0) { val Int.inSectionHeight: Int
((ProtocolDefinition.SECTION_HEIGHT_Y + (y % ProtocolDefinition.SECTION_HEIGHT_Y))) % ProtocolDefinition.SECTION_HEIGHT_Y get() = if (this < 0) {
} else { ((ProtocolDefinition.SECTION_HEIGHT_Y + (this % ProtocolDefinition.SECTION_HEIGHT_Y))) % ProtocolDefinition.SECTION_HEIGHT_Y
y % ProtocolDefinition.SECTION_HEIGHT_Y } else {
} this % ProtocolDefinition.SECTION_HEIGHT_Y
return Vec3i(inVec2i.x, y, inVec2i.z)
} }
val Int.sectionHeight: Int val Int.sectionHeight: Int
get() = if (this < 0) { get() = this shr 4
(this + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1
} else {
this / ProtocolDefinition.SECTION_HEIGHT_Y
}
val Vec3i.sectionHeight: Int val Vec3i.sectionHeight: Int
get() = y.sectionHeight get() = y.sectionHeight

View File

@ -67,8 +67,8 @@ object Vec3Util {
this -= 0.5f this -= 0.5f
} }
rotateAssign(-rotation.x, Axes.X)
rotateAssign(rotation.y, Axes.Y) rotateAssign(rotation.y, Axes.Y)
rotateAssign(rotation.x, Axes.X)
if (centerBlock) { if (centerBlock) {
this += 0.5f this += 0.5f