Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 8.93 KB | None | 0 0
  1. package ru.poopycoders.cavedefense.loader
  2.  
  3. import com.badlogic.gdx.assets.loaders.FileHandleResolver
  4. import com.badlogic.gdx.assets.loaders.ModelLoader
  5. import com.badlogic.gdx.files.FileHandle
  6. import com.badlogic.gdx.graphics.Color
  7. import com.badlogic.gdx.graphics.GL20
  8. import com.badlogic.gdx.graphics.VertexAttributes
  9. import com.badlogic.gdx.graphics.g3d.model.MeshPart
  10. import com.badlogic.gdx.graphics.g3d.model.data.*
  11. import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder
  12. import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder
  13. import com.badlogic.gdx.graphics.g3d.utils.shapebuilders.BoxShapeBuilder
  14. import com.badlogic.gdx.math.Matrix4
  15. import com.badlogic.gdx.math.Quaternion
  16. import com.badlogic.gdx.math.Vector2
  17. import com.badlogic.gdx.math.Vector3
  18. import com.badlogic.gdx.utils.ArrayMap
  19. import com.badlogic.gdx.utils.BaseJsonReader
  20. import com.badlogic.gdx.utils.JsonValue
  21.  
  22. class JsonModelLoader(val reader: BaseJsonReader, resolver: FileHandleResolver?) : ModelLoader<ModelLoader.ModelParameters>(resolver) {
  23.  
  24.     companion object {
  25.         private const val rawAttributes = VertexAttributes.Usage.Position.toLong() or VertexAttributes.Usage.Normal.toLong() or VertexAttributes.Usage.TextureCoordinates.toLong()
  26.         private const val primitiveType = GL20.GL_TRIANGLES
  27.     }
  28.  
  29.     val attributes = MeshBuilder.createAttributes(rawAttributes)
  30.  
  31.     override fun loadModelData(fileHandle: FileHandle, parameters: ModelParameters?): ModelData {
  32.         return parseModel(fileHandle)
  33.     }
  34.  
  35.     private fun parseModel(handle: FileHandle): ModelData {
  36.         val json = reader.parse(handle)
  37.         val model = ModelData()
  38.         model.id = "model"
  39.  
  40.         for (i in 0 until json.size) {
  41.             val tag = json[i]
  42.  
  43.             if (tag.name != "format_version") {
  44.                 parseGeometry(tag, model)
  45.                 break
  46.             }
  47.         }
  48.  
  49.         return model
  50.     }
  51.  
  52.     private fun parseGeometry(geometry: JsonValue, model: ModelData) {
  53.         val textureWidth = geometry.getInt("texturewidth")
  54.         val textureHeight = geometry.getInt("textureheight")
  55.  
  56.         val visibleBoundsWidth = geometry.getInt("visible_bounds_width")
  57.         val visibleBoundsHeight = geometry.getInt("visible_bounds_height")
  58.         val visibleBoundsOffset = Vector3(geometry.require("visible_bounds_offset").asFloatArray())
  59.  
  60.         val bonesJson = geometry.get("bones")
  61.  
  62.         // Parse bones
  63.         val bonesMap = HashMap<String, Bone>()
  64.         val bones = Array(bonesJson.size) {
  65.             parseBone(bonesJson[it]).apply {
  66.                 if (this.parent != null) {
  67.                     bonesMap[this.parent]!!.children.add(this)
  68.                 }
  69.  
  70.                 bonesMap[this.name] = this
  71.             }
  72.         }
  73.  
  74.         // Build nodes, root meshes and mesh parts
  75.         val nodesMap = HashMap<String, ModelNode>()
  76.  
  77.         for (bone in bones) {
  78.             if (bone.parent == null) {
  79.                 val node = bone.buildNode(nodesMap)
  80.                 model.nodes.add(node)
  81.  
  82.                 model.addMesh(bone.buildRootMesh(node))
  83.             }
  84.         }
  85.  
  86.         // Default material for all parts
  87.         model.materials.add(ModelMaterial().apply {
  88.             id = "default"
  89.  
  90.             ambient = Color(1f, 1f, 1f, 1f)
  91.             diffuse = Color(0.8f, 0.8f, 0.8f, 0.8f)
  92.             emissive = Color(0.8f, 0.8f, 0.8f, 0.8f)
  93.  
  94.             opacity = 1f
  95.             shininess = 0f
  96.  
  97.             textures = com.badlogic.gdx.utils.Array()
  98.         })
  99.  
  100.         // Test animation
  101.         model.animations.add(ModelAnimation().apply {
  102.             id = "test"
  103.  
  104.             nodeAnimations.add(ModelNodeAnimation().apply {
  105.                 nodeId = "head"
  106.                 rotation = com.badlogic.gdx.utils.Array<ModelNodeKeyframe<Quaternion>>(30)
  107.  
  108.                 for (i in 0 until 30) {
  109.                     rotation.insert(i, ModelNodeKeyframe<Quaternion>().apply {
  110.                         keytime = 1f / 30 * i
  111.                         value = Quaternion(Vector3.Y, 90 + 360f / 30 * i)
  112.                     })
  113.                 }
  114.             })
  115.         })
  116.     }
  117.  
  118.     private fun parseBone(bone: JsonValue): Bone {
  119.         val name = bone.getString("name")
  120.         val parent = bone.getString("parent", null)
  121.         val pivot = Vector3(bone.require("pivot").asFloatArray())
  122.         val rotation = if (bone.has("rotation")) Vector3(bone.require("rotation").asFloatArray()) else Vector3.Zero
  123.  
  124.         val cubesJson = if (bone.has("cubes")) bone.require("cubes") else null
  125.         val cubes = Array(cubesJson?.size ?: 0) {
  126.             val cube = cubesJson!![it]
  127.  
  128.             val origin = Vector3(cube.require("origin").asFloatArray())
  129.             val size = Vector3(cube.require("size").asFloatArray())
  130.             val uv = cube.require("uv").asFloatArray()
  131.             val inflate = if (cube.has("inflate")) cube.getFloat("inflate") else 0f
  132.  
  133.             Cube(origin, size, Vector2(uv[0], uv[1]), inflate)
  134.         }
  135.         return Bone(name, parent, pivot, rotation, cubes, ArrayList())
  136.     }
  137.  
  138.     inner class Bone(val name: String, val parent: String?, val pivot: Vector3, val rotation: Vector3, val cubes: Array<Cube>, var children: ArrayList<Bone>) {
  139.  
  140.         fun buildNode(nodesMap: HashMap<String, ModelNode>): ModelNode {
  141.             println("Build node: $name")
  142.             val node = ModelNode()
  143.             nodesMap[name] = node
  144.  
  145.             node.id = name
  146.             node.translation = Vector3.Zero
  147.             node.scale = Vector3(1.0f, 1.0f, 1.0f)
  148. //            node.rotation = Quaternion(rotation.x, rotation.y, rotation.z, 0.0f)
  149.             node.meshId = if (parent == null) name else nodesMap[parent]!!.meshId
  150.  
  151.             node.children = Array(children.size) {
  152.                 children[it].buildNode(nodesMap)
  153.             }
  154.  
  155.             return node
  156.         }
  157.  
  158.         fun buildRootMesh(rootNode: ModelNode): ModelMesh {
  159.             val mesh = ModelMesh()
  160.  
  161.             mesh.id = name
  162.             mesh.attributes = Array(attributes.size()) { attributes[it] }
  163.  
  164.             val builder = DirectMeshBuilder()
  165.             val rawParts = ArrayList<MeshPart>()
  166.  
  167.             builder.begin(rawAttributes)
  168.             buildMesh(rootNode, builder, rawParts, null) // build mesh of this part
  169.  
  170.             val (vertices, indices) = builder.endAndGetItems()
  171.             mesh.vertices = vertices
  172.  
  173.             mesh.parts = Array(rawParts.size) { // build meshes of child parts
  174.                 ModelMeshPart().apply {
  175.                     val rawPart = rawParts[it]
  176.  
  177.                     this.id = rawPart.id
  178.                     this.primitiveType = rawPart.primitiveType
  179.                     this.indices = indices.copyOfRange(rawPart.offset, rawPart.offset + rawPart.size)
  180.                 }
  181.             }
  182.  
  183.             return mesh
  184.         }
  185.  
  186.         fun buildMesh(node: ModelNode, builder: MeshBuilder, parts: ArrayList<MeshPart>, parent: ModelNode?) {
  187.             if (cubes.isNotEmpty()) {
  188.                 val part = builder.part(name, primitiveType)
  189.  
  190.                 for (cube in cubes) {
  191.                     val origin = cube.origin.mulAdd(cube.size, 0.5f)
  192.                     val size = cube.size
  193.  
  194.                     BoxShapeBuilder.build(builder, origin.x, origin.y, origin.z, size.x, size.y, size.z)
  195.                 }
  196.  
  197.                 node.parts = arrayOf(ModelNodePart().apply {
  198.                     materialId = "default"
  199.                     meshPartId = part.id
  200.                     bones = ArrayMap(1)
  201.  
  202.                     if(parent != null){
  203.                         bones.put(parent.id, Matrix4())
  204.                     }
  205.  
  206. //                    uvMapping = Array(2) {
  207. //                        IntArray(2) // later
  208. //                    }
  209.                 })
  210.  
  211.                 parts.add(part)
  212.             } else {
  213.                 node.parts = arrayOf()
  214.             }
  215.  
  216.             for ((i, child) in children.withIndex()) {
  217.                 child.buildMesh(node.children[i], builder, parts, node)
  218.             }
  219.         }
  220.     }
  221.  
  222.     data class Cube(val origin: Vector3, val size: Vector3, val uv: Vector2, val inflate: Float)
  223.  
  224.     class DirectMeshBuilder : MeshBuilder() {
  225.  
  226.         private val vertTmp1 = MeshPartBuilder.VertexInfo()
  227.         private val vertTmp2 = MeshPartBuilder.VertexInfo()
  228.         private val vertTmp3 = MeshPartBuilder.VertexInfo()
  229.         private val vertTmp4 = MeshPartBuilder.VertexInfo()
  230.  
  231.         fun endAndGetItems(): Pair<FloatArray, ShortArray> {
  232.             part("mesh_end", GL20.GL_TRIANGLES)
  233.             return Pair(vertices!!, indices!!)
  234.         }
  235.  
  236.         override fun rect(corner00: Vector3?, corner10: Vector3?, corner11: Vector3?, corner01: Vector3?, normal: Vector3?) {
  237.             rect(vertTmp1.set(corner00, normal, null, null).setUV(0f, 1f), vertTmp2.set(corner10, normal, null, null).setUV(1f, 1f),
  238.                     vertTmp3.set(corner11, normal, null, null).setUV(1f, 0f), vertTmp4.set(corner01, normal, null, null).setUV(0f, 0f))
  239.         }
  240.  
  241.     }
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement