mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 17:07:55 -04:00
model loading
This commit is contained in:
parent
d9e1c3b97f
commit
596866c3ee
@ -164,7 +164,7 @@ class MinecraftAssetsManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAssetsIndex(hash: String): Map<ResourceLocation, String> {
|
private fun parseAssetsIndex(hash: String): Map<ResourceLocation, String> {
|
||||||
return parseAssetsIndex(Util.readJsonFromStream(readAssetAsStream(hash)))
|
return parseAssetsIndex(Util.readJsonFromStream(readAssetAsStream(hash), true))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAssetsIndex(json: JsonObject): Map<ResourceLocation, String> {
|
private fun parseAssetsIndex(json: JsonObject): Map<ResourceLocation, String> {
|
||||||
|
@ -14,12 +14,9 @@ package de.bixilon.minosoft.data.direction
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.Axes
|
import de.bixilon.minosoft.data.Axes
|
||||||
import de.bixilon.minosoft.data.registries.blocks.properties.serializer.BlockPropertiesSerializer
|
import de.bixilon.minosoft.data.registries.blocks.properties.serializer.BlockPropertiesSerializer
|
||||||
import de.bixilon.minosoft.gui.rendering.block.models.BlockModelElement
|
|
||||||
import de.bixilon.minosoft.gui.rendering.block.models.FaceSize
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.get
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.get
|
||||||
import de.bixilon.minosoft.util.KUtil
|
import de.bixilon.minosoft.util.KUtil
|
||||||
import de.bixilon.minosoft.util.enum.ValuesEnum
|
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||||
import glm_.vec2.Vec2i
|
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
@ -53,48 +50,6 @@ enum class Directions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sidesNextTo(direction: Directions): Set<Directions> {
|
|
||||||
return when (direction) {
|
|
||||||
NORTH, SOUTH -> setOf(EAST, WEST)
|
|
||||||
EAST, WEST -> setOf(NORTH, SOUTH)
|
|
||||||
else -> emptySet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the size of the face in this direction. null if the face is not touching the border (determinated by the block resolution)
|
|
||||||
*/
|
|
||||||
fun getFaceBorderSizes(start: Vec3, end: Vec3): FaceSize? {
|
|
||||||
// check if face is touching the border of a block
|
|
||||||
|
|
||||||
if (!isBlockResolutionBorder(start, end)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return getFaceSize(start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFaceSize(start: Vec3, end: Vec3): FaceSize {
|
|
||||||
return when (this) {
|
|
||||||
DOWN, UP -> FaceSize(Vec2i(start.x, start.z), Vec2i(end.x, end.z))
|
|
||||||
NORTH, SOUTH -> FaceSize(Vec2i(start.x, start.y), Vec2i(end.x, end.y))
|
|
||||||
EAST, WEST -> FaceSize(Vec2i(start.y, start.z), Vec2i(end.y, end.z))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isBlockResolutionBorder(start: Vec3, end: Vec3): Boolean {
|
|
||||||
return isCoordinateBorder(vector.x, start.x, end.x) || isCoordinateBorder(vector.y, start.y, end.y) || isCoordinateBorder(vector.z, start.z, end.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isCoordinateBorder(directionValue: Int, start: Float, end: Float): Boolean {
|
|
||||||
if (directionValue == 1) {
|
|
||||||
return start == BlockModelElement.BLOCK_RESOLUTION_FLOAT || end == BlockModelElement.BLOCK_RESOLUTION_FLOAT
|
|
||||||
}
|
|
||||||
if (directionValue == -1) {
|
|
||||||
return start == 0.0f || end == 0.0f
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun get(axis: Axes): Int {
|
operator fun get(axis: Axes): Int {
|
||||||
return vector[axis]
|
return vector[axis]
|
||||||
}
|
}
|
||||||
@ -121,6 +76,13 @@ enum class Directions(
|
|||||||
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
|
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun get(name: String): Directions {
|
||||||
|
if (name.lowercase() == "bottom") {
|
||||||
|
return DOWN
|
||||||
|
}
|
||||||
|
return super.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun byId(id: Int): Directions {
|
fun byId(id: Int): Directions {
|
||||||
return VALUES[id]
|
return VALUES[id]
|
||||||
|
@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.direction.Directions
|
|||||||
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.VecUtil.ONE
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.ONE
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.get
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.get
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||||
import de.bixilon.minosoft.util.MMath.ceil
|
import de.bixilon.minosoft.util.MMath.ceil
|
||||||
import de.bixilon.minosoft.util.MMath.floor
|
import de.bixilon.minosoft.util.MMath.floor
|
||||||
import glm_.Java.Companion.glm
|
import glm_.Java.Companion.glm
|
||||||
|
@ -94,7 +94,7 @@ open class Registry<T : RegistryItem>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
open operator fun get(resourceLocation: String): T? {
|
open operator fun get(resourceLocation: String): T? {
|
||||||
return get(ResourceLocation.getPathResourceLocation(resourceLocation))
|
return get(resourceLocation.toResourceLocation())
|
||||||
}
|
}
|
||||||
|
|
||||||
open operator fun get(resourceLocation: ResourceLocationAble): T? {
|
open operator fun get(resourceLocation: ResourceLocationAble): T? {
|
||||||
|
@ -11,16 +11,22 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.block.mesh
|
package de.bixilon.minosoft.gui.rendering.block
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkSection
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh
|
||||||
|
|
||||||
class ChunkSectionMeshCollection(
|
class SectionPreparer(
|
||||||
renderWindow: RenderWindow,
|
val renderWindow: RenderWindow,
|
||||||
val opaqueMesh: ChunkSectionArrayMesh = ChunkSectionArrayMesh(renderWindow),
|
|
||||||
var translucentMesh: ChunkSectionArrayMesh? = ChunkSectionArrayMesh(renderWindow),
|
|
||||||
var transparentMesh: ChunkSectionArrayMesh? = ChunkSectionArrayMesh(renderWindow),
|
|
||||||
) {
|
) {
|
||||||
var lowestBlockHeight = 0
|
|
||||||
var highestBlockHeight = 0
|
|
||||||
|
fun prepare(section: ChunkSection): ChunkSectionMesh {
|
||||||
|
val mesh = ChunkSectionMesh(renderWindow)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,24 +13,65 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.block
|
package de.bixilon.minosoft.gui.rendering.block
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.assets.AssetsUtil
|
||||||
|
import de.bixilon.minosoft.data.assets.Resources
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.direction.FakeDirection
|
import de.bixilon.minosoft.data.direction.FakeDirection
|
||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkSection
|
||||||
import de.bixilon.minosoft.data.world.World
|
import de.bixilon.minosoft.data.world.World
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.Renderer
|
import de.bixilon.minosoft.gui.rendering.Renderer
|
||||||
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||||
|
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.ModelLoader
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.base.phases.OpaqueDrawable
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.util.zip.GZIPInputStream
|
||||||
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
class WorldRenderer(
|
class WorldRenderer(
|
||||||
private val connection: PlayConnection,
|
private val connection: PlayConnection,
|
||||||
override val renderWindow: RenderWindow,
|
override val renderWindow: RenderWindow,
|
||||||
) : Renderer {
|
) : Renderer, OpaqueDrawable {
|
||||||
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
||||||
|
private val shader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
||||||
private val world: World = connection.world
|
private val world: World = connection.world
|
||||||
|
private val sectionPreparer = SectionPreparer(renderWindow)
|
||||||
|
private lateinit var mesh: ChunkSectionMesh
|
||||||
|
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
val asset = Resources.getAssetVersionByVersion(connection.version)
|
||||||
|
val zip = ZipInputStream(GZIPInputStream(FileInputStream(AssetsUtil.getAssetDiskPath(asset.clientJarHash!!, true))))
|
||||||
|
val modelLoader = ModelLoader(zip)
|
||||||
|
modelLoader.load()
|
||||||
|
|
||||||
|
val dirt = connection.registries.blockRegistry["dirt"]?.defaultState
|
||||||
|
val chunk = ChunkSection(Array(4096) { dirt })
|
||||||
|
mesh = sectionPreparer.prepare(chunk)
|
||||||
|
mesh.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun postInit() {
|
||||||
|
shader.load()
|
||||||
|
renderWindow.textureManager.staticTextures.use(shader)
|
||||||
|
renderWindow.textureManager.staticTextures.animator.use(shader)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupOpaque() {
|
||||||
|
super.setupOpaque()
|
||||||
|
shader.use()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drawOpaque() {
|
||||||
|
mesh.draw()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object : RendererBuilder<WorldRenderer> {
|
companion object : RendererBuilder<WorldRenderer> {
|
||||||
|
@ -23,7 +23,7 @@ import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
|||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
class ChunkSectionArrayMesh(renderWindow: RenderWindow) : Mesh(renderWindow, SectionArrayMeshStruct, initialCacheSize = 100000) {
|
class ChunkSectionMesh(renderWindow: RenderWindow) : Mesh(renderWindow, SectionArrayMeshStruct, initialCacheSize = 100000) {
|
||||||
|
|
||||||
fun addVertex(position: Vec3, uv: Vec2, texture: AbstractTexture, tintColor: RGBColor?, light: Int) {
|
fun addVertex(position: Vec3, uv: Vec2, texture: AbstractTexture, tintColor: RGBColor?, light: Int) {
|
||||||
val color = tintColor ?: ChatColors.WHITE
|
val color = tintColor ?: ChatColors.WHITE
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.block.mesh
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.AABB
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||||
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
|
class ChunkSectionMeshes(
|
||||||
|
renderWindow: RenderWindow,
|
||||||
|
val opaqueMesh: ChunkSectionMesh = ChunkSectionMesh(renderWindow),
|
||||||
|
var translucentMesh: ChunkSectionMesh? = ChunkSectionMesh(renderWindow),
|
||||||
|
var transparentMesh: ChunkSectionMesh? = ChunkSectionMesh(renderWindow),
|
||||||
|
) {
|
||||||
|
val minPosition = Vec3i.EMPTY
|
||||||
|
val maxPosition = Vec3i.EMPTY
|
||||||
|
|
||||||
|
lateinit var aabb: AABB
|
||||||
|
private set
|
||||||
|
}
|
@ -1,66 +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.gui.rendering.block.models
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.rad
|
|
||||||
import de.bixilon.minosoft.util.KUtil.listCast
|
|
||||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
|
||||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound
|
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
|
|
||||||
import glm_.vec3.Vec3
|
|
||||||
|
|
||||||
open class BlockModel(
|
|
||||||
val parent: BlockModel? = null,
|
|
||||||
data: Map<String, Any>,
|
|
||||||
) {
|
|
||||||
val textures: Map<String, String>
|
|
||||||
val elements: List<BlockModelElement>
|
|
||||||
val rotation: Vec3 = Vec3(data["x"]?.unsafeCast<Double>() ?: parent?.rotation?.x ?: 0.0f, data["y"]?.unsafeCast<Double>() ?: parent?.rotation?.y ?: 0.0f, data["z"]?.unsafeCast<Double>() ?: parent?.rotation?.z ?: 0.0f).rad
|
|
||||||
val uvLock: Boolean = data["uvlock"].nullCast<Boolean>() ?: parent?.uvLock ?: false
|
|
||||||
val rescale: Boolean = data["rescale"].nullCast<Boolean>() ?: parent?.rescale ?: false
|
|
||||||
val ambientOcclusion: Boolean = data["ambientocclusion"].nullCast<Boolean>() ?: parent?.ambientOcclusion ?: true
|
|
||||||
|
|
||||||
init {
|
|
||||||
textures = data["textures"]?.compoundCast()?.let {
|
|
||||||
val textures: MutableMap<String, String> = parent?.textures?.toMutableMap() ?: mutableMapOf()
|
|
||||||
for ((type, value) in it) {
|
|
||||||
textures[type] = value.unsafeCast()
|
|
||||||
}
|
|
||||||
for ((type, texture) in textures) {
|
|
||||||
textures[type] = getTextureByType(textures, texture)
|
|
||||||
}
|
|
||||||
textures.toMap()
|
|
||||||
} ?: parent?.textures ?: mapOf()
|
|
||||||
|
|
||||||
|
|
||||||
elements = data["elements"]?.listCast()?.let {
|
|
||||||
val elements: MutableList<BlockModelElement> = mutableListOf()
|
|
||||||
for (element in it) {
|
|
||||||
elements += BlockModelElement(element.asCompound())
|
|
||||||
}
|
|
||||||
elements.toList()
|
|
||||||
} ?: parent?.elements ?: listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTextureByType(textures: Map<String, String>, type: String): String {
|
|
||||||
var currentValue: String = type
|
|
||||||
while (currentValue.startsWith("#")) {
|
|
||||||
textures[currentValue.removePrefix("#")].let {
|
|
||||||
currentValue = it ?: return currentValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentValue
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,102 +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.gui.rendering.block.models
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.Axes
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.rotate
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
|
|
||||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
|
||||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound
|
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
|
|
||||||
import glm_.func.rad
|
|
||||||
import glm_.vec3.Vec3
|
|
||||||
|
|
||||||
open class BlockModelElement(
|
|
||||||
data: Map<String, Any>,
|
|
||||||
) {
|
|
||||||
val from: Vec3 = data["from"]?.toVec3() ?: Vec3.EMPTY
|
|
||||||
val to: Vec3 = data["to"]?.toVec3() ?: Vec3(BLOCK_RESOLUTION)
|
|
||||||
val shade: Boolean = data["shade"].nullCast<Boolean>() ?: true
|
|
||||||
val faces: MutableMap<Directions, BlockModelFace> = mutableMapOf()
|
|
||||||
val transformedPositions: Array<Vec3> = arrayOf(
|
|
||||||
Vec3(from.x, from.y, from.z),
|
|
||||||
Vec3(to.x, from.y, from.z),
|
|
||||||
Vec3(from.x, from.y, to.z),
|
|
||||||
Vec3(to.x, from.y, to.z),
|
|
||||||
Vec3(from.x, to.y, from.z),
|
|
||||||
Vec3(to.x, to.y, from.z),
|
|
||||||
Vec3(from.x, to.y, to.z),
|
|
||||||
Vec3(to.x, to.y, to.z),
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
|
||||||
|
|
||||||
data["rotation"]?.compoundCast()?.let {
|
|
||||||
val axis = Axes[it["axis"].unsafeCast<String>()]
|
|
||||||
val angle = it["angle"].unsafeCast<Double>().toFloat().rad
|
|
||||||
val rescale = it["rescale"].nullCast<Boolean>() ?: false
|
|
||||||
rotatePositions(transformedPositions, axis, angle, it["origin"]!!.toVec3(), rescale)
|
|
||||||
}
|
|
||||||
|
|
||||||
data["faces"]?.compoundCast()?.let {
|
|
||||||
for ((directionName, json) in it) {
|
|
||||||
val direction = Directions[directionName]
|
|
||||||
faces[direction] = BlockModelFace(json.asCompound(), from, to, direction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// transformed positions
|
|
||||||
for ((index, position) in transformedPositions.withIndex()) {
|
|
||||||
transformedPositions[index] = transformPosition(position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val BLOCK_RESOLUTION = 16
|
|
||||||
const val BLOCK_RESOLUTION_FLOAT = BLOCK_RESOLUTION.toFloat()
|
|
||||||
|
|
||||||
val FACE_POSITION_MAP_TEMPLATE = arrayOf(
|
|
||||||
intArrayOf(0, 2, 3, 1),
|
|
||||||
intArrayOf(6, 4, 5, 7),
|
|
||||||
intArrayOf(1, 5, 4, 0),
|
|
||||||
intArrayOf(2, 6, 7, 3),
|
|
||||||
intArrayOf(6, 2, 0, 4),
|
|
||||||
intArrayOf(5, 1, 3, 7)
|
|
||||||
)
|
|
||||||
|
|
||||||
fun rotatePositions(positions: Array<Vec3>, axis: Axes, angle: Float, origin: Vec3, rescale: Boolean) {
|
|
||||||
// TODO: optimize for 90deg, 180deg, 270deg rotations
|
|
||||||
if (angle == 0.0f) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ((i, position) in positions.withIndex()) {
|
|
||||||
var transformedPosition = position - origin
|
|
||||||
transformedPosition = transformedPosition.rotate(angle, axis, rescale)
|
|
||||||
positions[i] = transformedPosition + origin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun transformPosition(position: Vec3): Vec3 {
|
|
||||||
|
|
||||||
fun positionToFloat(uv: Float): Float {
|
|
||||||
return (uv - (BLOCK_RESOLUTION / 2)) / BLOCK_RESOLUTION
|
|
||||||
}
|
|
||||||
|
|
||||||
return Vec3(positionToFloat(position.x), positionToFloat(position.y), positionToFloat(position.z))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,156 +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.gui.rendering.block.models
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
|
||||||
import de.bixilon.minosoft.data.registries.AABB
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.readUV
|
|
||||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
|
||||||
import de.bixilon.minosoft.util.KUtil.toInt
|
|
||||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
|
||||||
import glm_.func.cos
|
|
||||||
import glm_.func.sin
|
|
||||||
import glm_.vec2.Vec2
|
|
||||||
import glm_.vec3.Vec3
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class BlockModelFace {
|
|
||||||
val textureName: String?
|
|
||||||
val cullFace: Directions?
|
|
||||||
val tint: Boolean
|
|
||||||
val positions: List<Vec2>
|
|
||||||
|
|
||||||
|
|
||||||
constructor(textureName: String?, cullFace: Directions?, tint: Boolean, positions: List<Vec2>) {
|
|
||||||
this.textureName = textureName
|
|
||||||
this.cullFace = cullFace
|
|
||||||
this.tint = tint
|
|
||||||
this.positions = positions
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(data: Map<String, Any>, from: Vec3, to: Vec3, direction: Directions) {
|
|
||||||
tint = data.containsKey("tintindex")
|
|
||||||
textureName = data["texture"].unsafeCast<String>().removePrefix("#")
|
|
||||||
cullFace = data["cullface"].nullCast<String>()?.let {
|
|
||||||
if (it == "bottom") {
|
|
||||||
Directions.DOWN
|
|
||||||
} else {
|
|
||||||
Directions[it]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val positions = calculateTexturePositions(data, from, to, direction)
|
|
||||||
val rotation = data["rotation"]?.toInt()?.div(90) ?: 0
|
|
||||||
Collections.rotate(positions, rotation)
|
|
||||||
this.positions = positions.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateTexturePositions(data: Map<String, Any>?, from: Vec3, to: Vec3, direction: Directions): MutableList<Vec2> {
|
|
||||||
val (textureTopLeft: Vec2, textureBottomRight: Vec2) = data?.get("uv")?.unsafeCast<List<Float>>()?.readUV() ?: getTexturePositionsFromRegion(AABB(from, to), direction)
|
|
||||||
return mutableListOf(
|
|
||||||
uvToFloat(Vec2(textureTopLeft.x, textureTopLeft.y)),
|
|
||||||
uvToFloat(Vec2(textureTopLeft.x, textureBottomRight.y)),
|
|
||||||
uvToFloat(Vec2(textureBottomRight.x, textureBottomRight.y)),
|
|
||||||
uvToFloat(Vec2(textureBottomRight.x, textureTopLeft.y)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTexturePositionsFromRegion(aabb: AABB, direction: Directions): Pair<Vec2, Vec2> {
|
|
||||||
// ToDo: Remove the duplicated code in Directions
|
|
||||||
return when (direction) {
|
|
||||||
Directions.UP, Directions.DOWN -> Pair(Vec2(aabb.min.x.toInt(), aabb.max.z.toInt()), Vec2(aabb.max.x.toInt(), aabb.min.z.toInt()))
|
|
||||||
Directions.NORTH, Directions.SOUTH -> Pair(Vec2(aabb.min.x.toInt(), aabb.max.y.toInt()), Vec2(aabb.max.x.toInt(), aabb.min.y.toInt()))
|
|
||||||
Directions.EAST, Directions.WEST -> Pair(Vec2(aabb.min.z.toInt(), aabb.max.y.toInt()), Vec2(aabb.max.z.toInt(), aabb.min.y.toInt()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(other: BlockModelFace) {
|
|
||||||
textureName = other.textureName
|
|
||||||
cullFace = other.cullFace
|
|
||||||
tint = other.tint
|
|
||||||
this.positions = other.positions
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(vertexPositions: List<Vec3>, direction: Directions) {
|
|
||||||
textureName = null
|
|
||||||
cullFace = null
|
|
||||||
tint = false
|
|
||||||
val template = BlockModelElement.FACE_POSITION_MAP_TEMPLATE[direction.ordinal]
|
|
||||||
val positions: MutableList<Vec2> = mutableListOf()
|
|
||||||
for (templatePosition in template) {
|
|
||||||
positions += calculateTexturePosition(vertexPositions[templatePosition], direction)
|
|
||||||
}
|
|
||||||
this.positions = positions.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateTexturePosition(position: Vec3, direction: Directions): Vec2 {
|
|
||||||
return when (direction) {
|
|
||||||
Directions.UP, Directions.DOWN -> Vec2(position.x, BlockModelElement.BLOCK_RESOLUTION - position.z)
|
|
||||||
Directions.NORTH, Directions.SOUTH -> Vec2(position.x, position.y)
|
|
||||||
Directions.EAST, Directions.WEST -> Vec2(position.z, BlockModelElement.BLOCK_RESOLUTION - position.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTexturePositionArray(direction: Directions): Array<Vec2?> {
|
|
||||||
val template = textureTemplate[direction.ordinal]
|
|
||||||
val ret: MutableList<Vec2> = mutableListOf()
|
|
||||||
for (i in template.indices) {
|
|
||||||
ret += positions[template[i]]
|
|
||||||
}
|
|
||||||
return ret.toTypedArray()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun rotate(angle: Float): BlockModelFace {
|
|
||||||
if (angle == 0.0f) {
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
val sin = angle.sin
|
|
||||||
val cos = angle.cos
|
|
||||||
val positions = this.positions.toMutableList()
|
|
||||||
for ((i, position) in positions.withIndex()) {
|
|
||||||
val offset = position - TEXTURE_MIDDLE
|
|
||||||
positions[i] = VecUtil.getRotatedValues(offset.x, offset.y, sin, cos, false) + TEXTURE_MIDDLE
|
|
||||||
}
|
|
||||||
return BlockModelFace(textureName, cullFace, tint, positions.toList())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun scale(scaleFactor: Double): BlockModelFace {
|
|
||||||
val positions = positions.toMutableList()
|
|
||||||
for ((i, position) in positions.withIndex()) {
|
|
||||||
positions[i] = position * scaleFactor
|
|
||||||
}
|
|
||||||
return BlockModelFace(textureName, cullFace, tint, positions.toList())
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private fun uvToFloat(uv: Float): Float {
|
|
||||||
return (uv) / BlockModelElement.BLOCK_RESOLUTION
|
|
||||||
}
|
|
||||||
|
|
||||||
fun uvToFloat(vec2: Vec2): Vec2 {
|
|
||||||
return Vec2(uvToFloat(vec2.x), uvToFloat(BlockModelElement.BLOCK_RESOLUTION - vec2.y))
|
|
||||||
}
|
|
||||||
|
|
||||||
val textureTemplate = arrayOf(
|
|
||||||
arrayOf(0, 1, 2, 3),
|
|
||||||
arrayOf(0, 1, 2, 3),
|
|
||||||
arrayOf(3, 2, 1, 0),
|
|
||||||
arrayOf(0, 1, 2, 3),
|
|
||||||
arrayOf(2, 3, 0, 1),
|
|
||||||
arrayOf(1, 0, 3, 2),
|
|
||||||
)
|
|
||||||
|
|
||||||
val TEXTURE_MIDDLE = Vec2(0.5, 0.5)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.models
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||||
|
|
||||||
|
enum class GUILights {
|
||||||
|
FRONT,
|
||||||
|
SIDE,
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object : ValuesEnum<GUILights> {
|
||||||
|
override val VALUES: Array<GUILights> = values()
|
||||||
|
override val NAME_MAP: Map<String, GUILights> = KUtil.getEnumValues(VALUES)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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.models
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.builtin.BuiltinModels
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedBlockModel
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedItemModel
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||||
|
import de.bixilon.minosoft.util.KUtil.fromJson
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.Util
|
||||||
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipInputStream
|
||||||
|
|
||||||
|
class ModelLoader(
|
||||||
|
val jar: ZipInputStream,
|
||||||
|
) {
|
||||||
|
private val unbakedBlockModels: MutableMap<ResourceLocation, UnbakedModel> = BuiltinModels.BUILTIN_MODELS.toMutableMap()
|
||||||
|
private val blockStateJsons: MutableMap<ResourceLocation, Map<String, Any>> = mutableMapOf()
|
||||||
|
private val modelJsons: MutableMap<ResourceLocation, Map<String, Any>> = mutableMapOf()
|
||||||
|
|
||||||
|
private fun loadJsons() {
|
||||||
|
// ToDo: Integrate in assets manager
|
||||||
|
var entry: ZipEntry? = jar.nextEntry
|
||||||
|
while (entry != null) {
|
||||||
|
if (!entry.name.startsWith("assets/minecraft/models/") && !entry.name.startsWith("assets/minecraft/blockstates/")) {
|
||||||
|
entry = jar.nextEntry
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val name = entry.name.removePrefix("assets/minecraft/").removeSuffix(".json")
|
||||||
|
val jsonString = Util.readReader(BufferedReader(InputStreamReader(jar)), false)
|
||||||
|
|
||||||
|
val json = jsonString.fromJson().asCompound()
|
||||||
|
if (name.startsWith("models/")) {
|
||||||
|
modelJsons[name.removePrefix("models/").toResourceLocation()] = json
|
||||||
|
} else {
|
||||||
|
blockStateJsons[name.removePrefix("blockstates/").toResourceLocation()] = json
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
entry = jar.nextEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load() {
|
||||||
|
loadJsons()
|
||||||
|
Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Loaded ${blockStateJsons.size} block states and ${modelJsons.size} model jsons!" }
|
||||||
|
|
||||||
|
|
||||||
|
fun loadBlockModel(name: ResourceLocation, json: Map<String, Any>? = null): UnbakedModel {
|
||||||
|
unbakedBlockModels[name]?.let { return it.unsafeCast() }
|
||||||
|
val data = json ?: modelJsons[name] ?: error("Can not find json: $name")
|
||||||
|
|
||||||
|
val parent = data["parent"]?.toResourceLocation()?.let { loadBlockModel(it) }
|
||||||
|
|
||||||
|
val model = UnbakedBlockModel(parent, data)
|
||||||
|
|
||||||
|
unbakedBlockModels[name] = model
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun loadItemModel(name: ResourceLocation, json: Map<String, Any>? = null): UnbakedModel {
|
||||||
|
unbakedBlockModels[name]?.let { return it.unsafeCast() }
|
||||||
|
val data = json ?: modelJsons[name] ?: error("Can not find json: $name")
|
||||||
|
|
||||||
|
val parent = data["parent"]?.toResourceLocation()?.let { loadItemModel(it) }
|
||||||
|
|
||||||
|
val model = UnbakedItemModel(parent, data)
|
||||||
|
|
||||||
|
unbakedBlockModels[name] = model
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((name, json) in modelJsons) {
|
||||||
|
if (name.path.startsWith("block/")) {
|
||||||
|
loadBlockModel(name, json)
|
||||||
|
} else if (name.path.startsWith("item/")) {
|
||||||
|
loadItemModel(name, json)
|
||||||
|
} else {
|
||||||
|
TODO("Unknown block model type: $name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Done loading models!" }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.builtin
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||||
|
|
||||||
|
object BuiltinModels {
|
||||||
|
val BUILTIN_MODELS: Map<ResourceLocation, UnbakedModel> = mapOf(
|
||||||
|
UnbakedBlockEntityModel.RESOURCE_LOCATION to UnbakedBlockEntityModel,
|
||||||
|
UnbakedGeneratedModel.RESOURCE_LOCATION to UnbakedGeneratedModel,
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.builtin
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
|
||||||
|
@Deprecated("TODO")
|
||||||
|
object UnbakedBlockEntityModel : UnbakedModel(null, mapOf()), CompanionResourceLocation {
|
||||||
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:builtin/entity".toResourceLocation()
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.builtin
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.CompanionResourceLocation
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
|
||||||
|
@Deprecated("TODO")
|
||||||
|
object UnbakedGeneratedModel : UnbakedModel(null, mapOf()), CompanionResourceLocation {
|
||||||
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:builtin/generated".toResourceLocation()
|
||||||
|
|
||||||
|
}
|
@ -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.gui.rendering.models.display
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.ONE
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3i
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
|
data class ModelDisplay(
|
||||||
|
val rotation: Vec3i,
|
||||||
|
val translation: Vec3i,
|
||||||
|
val scale: Vec3,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
operator fun invoke(data: Map<String, Any>): ModelDisplay {
|
||||||
|
return ModelDisplay(
|
||||||
|
rotation = data["rotation"]?.toVec3i() ?: Vec3i.EMPTY,
|
||||||
|
translation = data["translation"]?.toVec3i() ?: Vec3i.EMPTY,
|
||||||
|
scale = data["scale"]?.toVec3() ?: Vec3.ONE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.display
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.enum.AliasableEnum
|
||||||
|
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||||
|
|
||||||
|
enum class ModelDisplayPositions(vararg names: String = arrayOf()) : AliasableEnum {
|
||||||
|
THIRD_PERSON_RIGHT_HAND("thirdperson_righthand"),
|
||||||
|
THIRD_PERSON_LEFT_HAND("thirdperson_lefthand"),
|
||||||
|
FIRST_PERSON_RIGHT_HAND("firstperson_righthand"),
|
||||||
|
FIRST_PERSON_LEFT_HAND("firstperson_lefthand"),
|
||||||
|
GUI,
|
||||||
|
HEAD,
|
||||||
|
GROUND,
|
||||||
|
FIXED,
|
||||||
|
;
|
||||||
|
|
||||||
|
override val names: Array<String> = names.unsafeCast()
|
||||||
|
|
||||||
|
companion object : ValuesEnum<ModelDisplayPositions> {
|
||||||
|
override val VALUES: Array<ModelDisplayPositions> = values()
|
||||||
|
override val NAME_MAP: Map<String, ModelDisplayPositions> = KUtil.getEnumValues(VALUES)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -11,11 +11,6 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.block.models
|
package de.bixilon.minosoft.gui.rendering.models.unbaked
|
||||||
|
|
||||||
import glm_.vec2.Vec2i
|
interface Model
|
||||||
|
|
||||||
data class FaceSize(
|
|
||||||
val start: Vec2i = Vec2i(0, 0),
|
|
||||||
val end: Vec2i = Vec2i(BlockModelElement.BLOCK_RESOLUTION, BlockModelElement.BLOCK_RESOLUTION),
|
|
||||||
)
|
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toBoolean
|
||||||
|
|
||||||
|
class UnbakedBlockModel(
|
||||||
|
parent: UnbakedModel?,
|
||||||
|
json: Map<String, Any>,
|
||||||
|
) : UnbakedModel(parent, json) {
|
||||||
|
val ambientOcclusion: Boolean = json["ambientocclusion"]?.toBoolean() ?: parent?.let { return@let if (parent is UnbakedBlockModel) parent.ambientOcclusion else null } ?: true
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.GUILights
|
||||||
|
|
||||||
|
class UnbakedItemModel(
|
||||||
|
parent: UnbakedModel?,
|
||||||
|
json: Map<String, Any>,
|
||||||
|
) : UnbakedModel(parent, json) {
|
||||||
|
val guiLight: GUILights = json["gui_light"]?.toString()?.let { GUILights[it] } ?: parent?.let { return@let if (parent is UnbakedItemModel) parent.guiLight else null } ?: GUILights.SIDE
|
||||||
|
|
||||||
|
// ToDo: Overrides (predicates)
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.display.ModelDisplay
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.display.ModelDisplayPositions
|
||||||
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.element.UnbakedElement
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
||||||
|
|
||||||
|
abstract class UnbakedModel(
|
||||||
|
parent: UnbakedModel?,
|
||||||
|
json: Map<String, Any>,
|
||||||
|
) : Model {
|
||||||
|
val display: Map<ModelDisplayPositions, ModelDisplay>
|
||||||
|
val elements: Set<UnbakedElement>
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
val display = parent?.display?.toMutableMap() ?: mutableMapOf()
|
||||||
|
|
||||||
|
json["display"]?.compoundCast()?.let {
|
||||||
|
for ((name, value) in it) {
|
||||||
|
display[ModelDisplayPositions[name]] = ModelDisplay(data = value.unsafeCast())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.display = display
|
||||||
|
}
|
||||||
|
|
||||||
|
val textures: Map<String, String>
|
||||||
|
|
||||||
|
init {
|
||||||
|
val textures = parent?.textures?.toMutableMap() ?: mutableMapOf()
|
||||||
|
|
||||||
|
json["textures"]?.compoundCast()?.let {
|
||||||
|
for ((name, value) in it) {
|
||||||
|
textures[name] = value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.textures = textures
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val elements = parent?.elements?.toMutableSet() ?: mutableSetOf()
|
||||||
|
|
||||||
|
json["elements"]?.listCast<Map<String, Any>>()?.let {
|
||||||
|
for (element in it) {
|
||||||
|
elements += UnbakedElement(data = element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.elements = elements
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked.element
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toBoolean
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
|
data class UnbakedElement(
|
||||||
|
val from: Vec3,
|
||||||
|
val to: Vec3,
|
||||||
|
val rotation: UnbakedElementRotation?,
|
||||||
|
val shade: Boolean,
|
||||||
|
val faces: Set<UnbakedElementFace>,
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
operator fun invoke(data: Map<String, Any>): UnbakedElement {
|
||||||
|
val faces: MutableSet<UnbakedElementFace> = mutableSetOf()
|
||||||
|
|
||||||
|
data["faces"].asCompound().let {
|
||||||
|
for ((direction, faceData) in it) {
|
||||||
|
faces += UnbakedElementFace(direction = Directions[direction], data = faceData.unsafeCast())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UnbakedElement(
|
||||||
|
from = data["from"].toVec3(),
|
||||||
|
to = data["to"].toVec3(),
|
||||||
|
rotation = data["rotation"]?.compoundCast()?.let { return@let UnbakedElementRotation(data = it) },
|
||||||
|
shade = data["shade"]?.toBoolean() ?: true,
|
||||||
|
faces = faces,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked.element
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toInt
|
||||||
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
||||||
|
import glm_.vec2.Vec2
|
||||||
|
|
||||||
|
data class UnbakedElementFace(
|
||||||
|
val direction: Directions,
|
||||||
|
val uvStart: Vec2,
|
||||||
|
val uvEnd: Vec2,
|
||||||
|
val texture: String,
|
||||||
|
val cullFace: Directions?,
|
||||||
|
val rotation: Int,
|
||||||
|
val tintIndex: Int,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
operator fun invoke(direction: Directions, data: Map<String, Any>): UnbakedElementFace {
|
||||||
|
val uv = data["uv"]?.listCast<Number>()
|
||||||
|
val uvStart = Vec2(uv?.get(0) ?: 0.0f, uv?.get(2) ?: 0.0f)
|
||||||
|
val uvEnd = Vec2(uv?.get(1) ?: 16.0f, uv?.get(3) ?: 16.0f)
|
||||||
|
|
||||||
|
return UnbakedElementFace(
|
||||||
|
direction = direction,
|
||||||
|
uvStart = uvStart,
|
||||||
|
uvEnd = uvEnd,
|
||||||
|
texture = data["texture"].toString(),
|
||||||
|
cullFace = data["cullface"]?.toString()?.let { return@let Directions[it] },
|
||||||
|
rotation = data["rotation"]?.toInt() ?: 0,
|
||||||
|
tintIndex = data["tintindex"]?.toInt() ?: -1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.models.unbaked.element
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Axes
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toBoolean
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toFloat
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
|
data class UnbakedElementRotation(
|
||||||
|
val origin: Vec3,
|
||||||
|
val axis: Axes,
|
||||||
|
val angle: Float,
|
||||||
|
val rescale: Boolean,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
operator fun invoke(data: Map<String, Any>): UnbakedElementRotation {
|
||||||
|
return UnbakedElementRotation(
|
||||||
|
origin = data["origin"]?.toVec3() ?: Vec3.EMPTY,
|
||||||
|
axis = Axes[data["axis"].toString()],
|
||||||
|
angle = data["angle"].toFloat(),
|
||||||
|
rescale = data["rescale"]?.toBoolean() ?: false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,9 +13,6 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.util
|
package de.bixilon.minosoft.gui.rendering.util
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.JsonPrimitive
|
|
||||||
import de.bixilon.minosoft.Minosoft
|
import de.bixilon.minosoft.Minosoft
|
||||||
import de.bixilon.minosoft.data.Axes
|
import de.bixilon.minosoft.data.Axes
|
||||||
import de.bixilon.minosoft.data.direction.AbstractDirection
|
import de.bixilon.minosoft.data.direction.AbstractDirection
|
||||||
@ -23,9 +20,7 @@ import de.bixilon.minosoft.data.direction.Directions
|
|||||||
import de.bixilon.minosoft.data.registries.AABB
|
import de.bixilon.minosoft.data.registries.AABB
|
||||||
import de.bixilon.minosoft.data.registries.blocks.RandomOffsetTypes
|
import de.bixilon.minosoft.data.registries.blocks.RandomOffsetTypes
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.gui.rendering.block.models.BlockModelElement
|
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
|
||||||
import glm_.func.common.ceil
|
import glm_.func.common.ceil
|
||||||
import glm_.func.common.clamp
|
import glm_.func.common.clamp
|
||||||
import glm_.func.common.floor
|
import glm_.func.common.floor
|
||||||
@ -58,19 +53,6 @@ object VecUtil {
|
|||||||
val Vec3d.Companion.ONE: Vec3d
|
val Vec3d.Companion.ONE: Vec3d
|
||||||
get() = Vec3d(1.0, 1.0, 1.0)
|
get() = Vec3d(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
fun Any.toVec3(default: Vec3? = null): Vec3 {
|
|
||||||
return when (this) {
|
|
||||||
is List<*> -> Vec3(this[0] as Double, this[1] as Double, this[2] as Double)
|
|
||||||
is JsonArray -> Vec3(this[0].asFloat, this[1].asFloat, this[2].asFloat)
|
|
||||||
is JsonObject -> Vec3(this["x"]?.asFloat ?: 0, this["y"]?.asFloat ?: 0, this["z"]?.asFloat ?: 0)
|
|
||||||
is Map<*, *> -> Vec3(this["x"]?.unsafeCast<Double>() ?: 0, this["y"]?.unsafeCast<Double>() ?: 0, this["z"]?.unsafeCast<Double>() ?: 0)
|
|
||||||
is JsonPrimitive -> Vec3(this.asFloat)
|
|
||||||
is Float -> Vec3(this)
|
|
||||||
is Double -> Vec3(this)
|
|
||||||
else -> default ?: throw IllegalArgumentException("Not a Vec3!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Vec3.clear() {
|
fun Vec3.clear() {
|
||||||
x = 0.0f
|
x = 0.0f
|
||||||
y = 0.0f
|
y = 0.0f
|
||||||
@ -204,10 +186,6 @@ 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 List<Float>.readUV(): Pair<Vec2, Vec2> {
|
|
||||||
return Pair(Vec2(this[0], BlockModelElement.BLOCK_RESOLUTION - this[1]), Vec2(this[2], BlockModelElement.BLOCK_RESOLUTION - this[3]))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Int.chunkPosition(multiplier: Int): Int {
|
fun Int.chunkPosition(multiplier: Int): Int {
|
||||||
return if (this >= 0) {
|
return if (this >= 0) {
|
||||||
this / multiplier
|
this / multiplier
|
||||||
|
@ -74,7 +74,7 @@ object Vec2Util {
|
|||||||
is List<*> -> Vec2i(this[0].toInt(), this[1].toInt())
|
is List<*> -> Vec2i(this[0].toInt(), this[1].toInt())
|
||||||
is Map<*, *> -> Vec2i(this["x"]?.toInt() ?: 0, this["y"]?.toInt() ?: 0)
|
is Map<*, *> -> Vec2i(this["x"]?.toInt() ?: 0, this["y"]?.toInt() ?: 0)
|
||||||
is Number -> Vec2i(this.toInt())
|
is Number -> Vec2i(this.toInt())
|
||||||
else -> default ?: throw IllegalArgumentException("Not a Vec2i!")
|
else -> default ?: throw IllegalArgumentException("Not a Vec2i: $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.vec.vec3
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toFloat
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
|
object Vec3Util {
|
||||||
|
|
||||||
|
val Vec3.Companion.MIN: Vec3
|
||||||
|
get() = Vec3(Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE)
|
||||||
|
|
||||||
|
val Vec3.Companion.EMPTY: Vec3
|
||||||
|
get() = Vec3(0.0f, 0.0f, 0.0f)
|
||||||
|
|
||||||
|
val Vec3.Companion.MAX: Vec3
|
||||||
|
get() = Vec3(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE)
|
||||||
|
|
||||||
|
|
||||||
|
fun Any?.toVec3(default: Vec3? = null): Vec3 {
|
||||||
|
return when (this) {
|
||||||
|
is List<*> -> Vec3(this[0].toFloat(), this[1].toFloat(), this[2].toFloat())
|
||||||
|
is Map<*, *> -> Vec3(this["x"]?.toFloat() ?: 0.0f, this["y"]?.toFloat() ?: 0.0f, this["z"]?.toFloat() ?: 0.0f)
|
||||||
|
is Number -> Vec3(this.toFloat())
|
||||||
|
else -> default ?: throw IllegalArgumentException("Not a Vec3: $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.util.vec.vec3
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toInt
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
|
object Vec3iUtil {
|
||||||
|
|
||||||
|
val Vec3i.Companion.MIN: Vec3i
|
||||||
|
get() = Vec3i(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE)
|
||||||
|
|
||||||
|
val Vec3.Companion.EMPTY: Vec3i
|
||||||
|
get() = Vec3i(0, 0, 0)
|
||||||
|
|
||||||
|
val Vec3.Companion.MAX: Vec3i
|
||||||
|
get() = Vec3i(Int.MAX_VALUE, Int.MAX_VALUE, Int.MAX_VALUE)
|
||||||
|
|
||||||
|
|
||||||
|
fun Any?.toVec3i(default: Vec3i? = null): Vec3i {
|
||||||
|
return when (this) {
|
||||||
|
is List<*> -> Vec3i(this[0].toInt(), this[1].toInt(), this[2].toInt())
|
||||||
|
is Map<*, *> -> Vec3i(this["x"]?.toInt() ?: 0.0f, this["y"]?.toInt() ?: 0.0f, this["z"]?.toInt() ?: 0.0f)
|
||||||
|
is Number -> Vec3i(this.toInt())
|
||||||
|
else -> default ?: throw IllegalArgumentException("Not a Vec3i: $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,9 +34,9 @@ object ShutdownManager {
|
|||||||
connection.disconnect()
|
connection.disconnect()
|
||||||
}
|
}
|
||||||
if (Minosoft.configInitialized) {
|
if (Minosoft.configInitialized) {
|
||||||
Minosoft.config.saveToFile()
|
// Minosoft.config.saveToFile()
|
||||||
}
|
}
|
||||||
DefaultThreadPool.shutdown()
|
DefaultThreadPool.shutdownNow() // ToDo: Save config
|
||||||
exitProcess(reason.exitCode)
|
exitProcess(reason.exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,10 +339,13 @@ public final class Util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsonObject readJsonFromStream(@NotNull InputStream stream) throws IOException {
|
@Deprecated
|
||||||
|
public static JsonObject readJsonFromStream(@NotNull InputStream stream, boolean close) throws IOException {
|
||||||
InputStreamReader reader = new InputStreamReader(stream);
|
InputStreamReader reader = new InputStreamReader(stream);
|
||||||
JsonObject json = JsonParser.parseReader(reader).getAsJsonObject();
|
JsonObject json = JsonParser.parseReader(reader).getAsJsonObject();
|
||||||
reader.close();
|
if (close) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ interface ValuesEnum<T : Enum<*>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(name: String): T {
|
operator fun get(name: String): T {
|
||||||
return NAME_MAP[name]!!
|
return NAME_MAP[name] ?: throw IllegalArgumentException("Can not find enum value: $name")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun next(current: T): T {
|
fun next(current: T): T {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user