mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 18:05:51 -04:00
chunk border renderer
This commit is contained in:
parent
c1918a1ffd
commit
74f1e1f5d7
@ -17,6 +17,7 @@ import de.bixilon.minosoft.config.config.game.controls.ControlsGameConfig
|
|||||||
import de.bixilon.minosoft.config.config.game.entities.EntitiesConfig
|
import de.bixilon.minosoft.config.config.game.entities.EntitiesConfig
|
||||||
import de.bixilon.minosoft.config.config.game.graphics.GraphicsGameConfig
|
import de.bixilon.minosoft.config.config.game.graphics.GraphicsGameConfig
|
||||||
import de.bixilon.minosoft.config.config.game.sound.SoundConfig
|
import de.bixilon.minosoft.config.config.game.sound.SoundConfig
|
||||||
|
import de.bixilon.minosoft.config.config.game.world.WorldConfig
|
||||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElement
|
import de.bixilon.minosoft.gui.rendering.hud.elements.primitive.HUDElement
|
||||||
|
|
||||||
@ -29,4 +30,5 @@ data class GameConfig(
|
|||||||
var camera: CameraGameConfig = CameraGameConfig(),
|
var camera: CameraGameConfig = CameraGameConfig(),
|
||||||
var sound: SoundConfig = SoundConfig(),
|
var sound: SoundConfig = SoundConfig(),
|
||||||
var entities: EntitiesConfig = EntitiesConfig(),
|
var entities: EntitiesConfig = EntitiesConfig(),
|
||||||
|
var world: WorldConfig = WorldConfig(),
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.config.game.world
|
||||||
|
|
||||||
|
data class ChunkBorderConfig(
|
||||||
|
var enabled: Boolean = false,
|
||||||
|
)
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.config.game.world
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
|
||||||
|
data class WorldConfig(
|
||||||
|
@Json(name = "chunk_borders") var chunkBorders: ChunkBorderConfig = ChunkBorderConfig(),
|
||||||
|
)
|
@ -80,4 +80,6 @@ object RenderConstants {
|
|||||||
const val MAX_BLOCK_OUTLINE_RAYCAST_DISTANCE = 5.0f
|
const val MAX_BLOCK_OUTLINE_RAYCAST_DISTANCE = 5.0f
|
||||||
|
|
||||||
const val MAXIMUM_PARTICLE_AMOUNT = 200000
|
const val MAXIMUM_PARTICLE_AMOUNT = 200000
|
||||||
|
|
||||||
|
const val DEFAULT_LINE_WIDTH = 1.0f / 128.0f
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import de.bixilon.minosoft.Minosoft
|
|||||||
import de.bixilon.minosoft.config.StaticConfiguration
|
import de.bixilon.minosoft.config.StaticConfiguration
|
||||||
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkBorderRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.block.outline.BlockOutlineRenderer
|
import de.bixilon.minosoft.gui.rendering.chunk.block.outline.BlockOutlineRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.entities.EntityHitBoxRenderer
|
import de.bixilon.minosoft.gui.rendering.entities.EntityHitBoxRenderer
|
||||||
@ -119,6 +120,9 @@ class RenderWindow(
|
|||||||
if (Minosoft.config.config.game.entities.hitBox.enabled) {
|
if (Minosoft.config.config.game.entities.hitBox.enabled) {
|
||||||
registerRenderer(EntityHitBoxRenderer)
|
registerRenderer(EntityHitBoxRenderer)
|
||||||
}
|
}
|
||||||
|
if (Minosoft.config.config.game.world.chunkBorders.enabled) {
|
||||||
|
registerRenderer(ChunkBorderRenderer)
|
||||||
|
}
|
||||||
registerRenderer(HUDRenderer)
|
registerRenderer(HUDRenderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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.gui.rendering.chunk
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.text.ChatColors
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.Renderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
import glm_.vec2.Vec2i
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import org.lwjgl.opengl.GL11.*
|
||||||
|
|
||||||
|
class ChunkBorderRenderer(
|
||||||
|
val connection: PlayConnection,
|
||||||
|
val renderWindow: RenderWindow,
|
||||||
|
) : Renderer {
|
||||||
|
private var lastChunkPosition: Vec2i? = null
|
||||||
|
private var lastMesh: LineMesh? = null
|
||||||
|
|
||||||
|
|
||||||
|
private fun prepare() {
|
||||||
|
val chunkPosition = renderWindow.connection.player.positionInfo.chunkPosition
|
||||||
|
if (chunkPosition == lastChunkPosition && lastMesh != null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastMesh?.unload(false)
|
||||||
|
val mesh = LineMesh()
|
||||||
|
|
||||||
|
val dimension = renderWindow.connection.world.dimension ?: return
|
||||||
|
val basePosition = chunkPosition * Vec2i(ProtocolDefinition.SECTION_WIDTH_X, ProtocolDefinition.SECTION_WIDTH_Z)
|
||||||
|
|
||||||
|
|
||||||
|
// vertical lines
|
||||||
|
for (x in 0..ProtocolDefinition.SECTION_WIDTH_X) {
|
||||||
|
val color = when {
|
||||||
|
x % ProtocolDefinition.SECTION_WIDTH_X == 0 -> ChatColors.BLUE
|
||||||
|
x % 2 == 0 -> ChatColors.GREEN
|
||||||
|
else -> ChatColors.YELLOW
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y), Vec3(basePosition.x + x, dimension.height, basePosition.y), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + x, dimension.minY, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + x, dimension.height, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (z in 0..ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||||
|
val color = when {
|
||||||
|
z % ProtocolDefinition.SECTION_WIDTH_Z == 0 -> ChatColors.BLUE
|
||||||
|
z % 2 == 0 -> ChatColors.GREEN
|
||||||
|
else -> ChatColors.YELLOW
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.drawLine(Vec3(basePosition.x, dimension.minY, basePosition.y + z), Vec3(basePosition.x, dimension.height, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.minY, basePosition.y + z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, dimension.height, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
// horizontal lines
|
||||||
|
for (y in dimension.minY..dimension.height) {
|
||||||
|
val borderColor = when {
|
||||||
|
y % ProtocolDefinition.SECTION_HEIGHT_Y == 0 -> ChatColors.BLUE
|
||||||
|
y % 2 == 0 -> ChatColors.GREEN
|
||||||
|
else -> ChatColors.YELLOW
|
||||||
|
}
|
||||||
|
|
||||||
|
// x/z border
|
||||||
|
mesh.drawLine(Vec3(basePosition.x, y, basePosition.y), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y), RenderConstants.DEFAULT_LINE_WIDTH * 5, borderColor)
|
||||||
|
mesh.drawLine(Vec3(basePosition.x, y, basePosition.y), Vec3(basePosition.x, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, borderColor)
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y), RenderConstants.DEFAULT_LINE_WIDTH * 5, borderColor)
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), Vec3(basePosition.x, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, borderColor)
|
||||||
|
|
||||||
|
|
||||||
|
if (y % ProtocolDefinition.SECTION_HEIGHT_Y != 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (x in 1..ProtocolDefinition.SECTION_MAX_X) {
|
||||||
|
val color = when {
|
||||||
|
x % 2 == 0 -> ChatColors.GREEN
|
||||||
|
else -> ChatColors.YELLOW
|
||||||
|
}
|
||||||
|
mesh.drawLine(Vec3(basePosition.x + x, y, basePosition.y), Vec3(basePosition.x + x, y, basePosition.y + ProtocolDefinition.SECTION_WIDTH_Z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
}
|
||||||
|
for (z in 1..ProtocolDefinition.SECTION_MAX_Z) {
|
||||||
|
val color = when {
|
||||||
|
z % 2 == 0 -> ChatColors.GREEN
|
||||||
|
else -> ChatColors.YELLOW
|
||||||
|
}
|
||||||
|
mesh.drawLine(Vec3(basePosition.x, y, basePosition.y + z), Vec3(basePosition.x + ProtocolDefinition.SECTION_WIDTH_X, y, basePosition.y + z), RenderConstants.DEFAULT_LINE_WIDTH * 5, color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.load()
|
||||||
|
this.lastMesh = mesh
|
||||||
|
this.lastChunkPosition = chunkPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun draw() {
|
||||||
|
prepare()
|
||||||
|
val mesh = lastMesh ?: return
|
||||||
|
renderWindow.shaderManager.genericColorShader.use()
|
||||||
|
glDisable(GL_CULL_FACE)
|
||||||
|
mesh.draw()
|
||||||
|
glEnable(GL_CULL_FACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object : RendererBuilder<ChunkBorderRenderer> {
|
||||||
|
override val RESOURCE_LOCATION = ResourceLocation("minosoft:chunk_borders")
|
||||||
|
|
||||||
|
override fun build(connection: PlayConnection, renderWindow: RenderWindow): ChunkBorderRenderer {
|
||||||
|
return ChunkBorderRenderer(connection, renderWindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -91,11 +91,11 @@ class BlockOutlineRenderer(
|
|||||||
|
|
||||||
val blockOffset = raycastHit.blockPosition.toVec3d + raycastHit.blockPosition.getWorldOffset(raycastHit.blockState.block)
|
val blockOffset = raycastHit.blockPosition.toVec3d + raycastHit.blockPosition.getWorldOffset(raycastHit.blockState.block)
|
||||||
|
|
||||||
currentMesh.drawVoxelShape(raycastHit.blockState.outlineShape, blockOffset, LINE_WIDTH, Minosoft.config.config.game.other.blockOutline.outlineColor)
|
currentMesh.drawVoxelShape(raycastHit.blockState.outlineShape, blockOffset, RenderConstants.DEFAULT_LINE_WIDTH, Minosoft.config.config.game.other.blockOutline.outlineColor)
|
||||||
|
|
||||||
|
|
||||||
if (Minosoft.config.config.game.other.blockOutline.collisionBoxes) {
|
if (Minosoft.config.config.game.other.blockOutline.collisionBoxes) {
|
||||||
currentMesh.drawVoxelShape(raycastHit.blockState.collisionShape, blockOffset, LINE_WIDTH, Minosoft.config.config.game.other.blockOutline.collisionColor, 0.005f)
|
currentMesh.drawVoxelShape(raycastHit.blockState.collisionShape, blockOffset, RenderConstants.DEFAULT_LINE_WIDTH, Minosoft.config.config.game.other.blockOutline.collisionColor, 0.005f)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMesh.load()
|
currentMesh.load()
|
||||||
@ -110,7 +110,6 @@ class BlockOutlineRenderer(
|
|||||||
|
|
||||||
companion object : RendererBuilder<BlockOutlineRenderer> {
|
companion object : RendererBuilder<BlockOutlineRenderer> {
|
||||||
override val RESOURCE_LOCATION = ResourceLocation("minosoft:block_outline")
|
override val RESOURCE_LOCATION = ResourceLocation("minosoft:block_outline")
|
||||||
private const val LINE_WIDTH = 1.0f / 128.0f
|
|
||||||
|
|
||||||
override fun build(connection: PlayConnection, renderWindow: RenderWindow): BlockOutlineRenderer {
|
override fun build(connection: PlayConnection, renderWindow: RenderWindow): BlockOutlineRenderer {
|
||||||
return BlockOutlineRenderer(connection, renderWindow)
|
return BlockOutlineRenderer(connection, renderWindow)
|
||||||
|
@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.entities
|
|||||||
|
|
||||||
import de.bixilon.minosoft.Minosoft
|
import de.bixilon.minosoft.Minosoft
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
|
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
||||||
@ -33,15 +34,11 @@ class EntityHitBoxMesh(
|
|||||||
entity.isInvisible -> Minosoft.config.config.game.entities.hitBox.invisibleEntitiesColor
|
entity.isInvisible -> Minosoft.config.config.game.entities.hitBox.invisibleEntitiesColor
|
||||||
else -> Minosoft.config.config.game.entities.hitBox.hitBoxColor
|
else -> Minosoft.config.config.game.entities.hitBox.hitBoxColor
|
||||||
}
|
}
|
||||||
drawAABB(entity.aabb, Vec3d.EMPTY, LINE_WIDTH, hitBoxColor)
|
drawAABB(entity.aabb, Vec3d.EMPTY, RenderConstants.DEFAULT_LINE_WIDTH, hitBoxColor)
|
||||||
|
|
||||||
val halfWidth = entity.dimensions.x / 2
|
val halfWidth = entity.dimensions.x / 2
|
||||||
val eyeAABB = AABB(Vec3(-halfWidth, entity.eyeHeight - LINE_WIDTH, -halfWidth), Vec3(halfWidth, entity.eyeHeight - LINE_WIDTH, halfWidth)).hShrink(LINE_WIDTH)
|
val eyeAABB = AABB(Vec3(-halfWidth, entity.eyeHeight - RenderConstants.DEFAULT_LINE_WIDTH, -halfWidth), Vec3(halfWidth, entity.eyeHeight - RenderConstants.DEFAULT_LINE_WIDTH, halfWidth)).hShrink(RenderConstants.DEFAULT_LINE_WIDTH)
|
||||||
drawAABB(eyeAABB, entity.position, LINE_WIDTH, Minosoft.config.config.game.entities.hitBox.eyeHeightColor)
|
drawAABB(eyeAABB, entity.position, RenderConstants.DEFAULT_LINE_WIDTH, Minosoft.config.config.game.entities.hitBox.eyeHeightColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val LINE_WIDTH = 1.0f / 128.0f
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ class Camera(
|
|||||||
}
|
}
|
||||||
yaw %= 180
|
yaw %= 180
|
||||||
val pitch = glm.clamp(yOffset + entity.rotation.pitch, -89.9, 89.9)
|
val pitch = glm.clamp(yOffset + entity.rotation.pitch, -89.9, 89.9)
|
||||||
|
entity.rotation = EntityRotation(yaw, pitch)
|
||||||
setRotation(yaw, pitch)
|
setRotation(yaw, pitch)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,9 +161,7 @@ class Camera(
|
|||||||
return glm.lookAt(cameraPosition, cameraPosition + cameraFront, CAMERA_UP_VEC3)
|
return glm.lookAt(cameraPosition, cameraPosition + cameraFront, CAMERA_UP_VEC3)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setRotation(yaw: Double, pitch: Double) {
|
private fun setRotation(yaw: Double, pitch: Double) {
|
||||||
entity.rotation = EntityRotation(yaw, pitch)
|
|
||||||
|
|
||||||
cameraFront = Vec3d(
|
cameraFront = Vec3d(
|
||||||
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
||||||
(-pitch).rad.sin,
|
(-pitch).rad.sin,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user