Skip to content

Commit

Permalink
Merge pull request #4 from dwursteisen/object-tree
Browse files Browse the repository at this point in the history
Object tree
  • Loading branch information
dwursteisen authored Sep 10, 2020
2 parents 4921ea5 + 6a68532 commit 0989ca9
Show file tree
Hide file tree
Showing 34 changed files with 971 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import com.dwursteisen.minigdx.scene.api.armature.Armature
import com.dwursteisen.minigdx.scene.api.camera.Camera
import com.dwursteisen.minigdx.scene.api.camera.OrthographicCamera
import com.dwursteisen.minigdx.scene.api.camera.PerspectiveCamera
import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.light.PointLight
import com.dwursteisen.minigdx.scene.api.material.Material
import com.dwursteisen.minigdx.scene.api.model.Boxe
import com.dwursteisen.minigdx.scene.api.model.Box
import com.dwursteisen.minigdx.scene.api.model.Model
import com.dwursteisen.minigdx.scene.api.relation.Node
import kotlinx.serialization.Serializable
Expand All @@ -20,21 +21,21 @@ import kotlinx.serialization.protobuf.ProtoId
@Serializable
data class Scene(
@ProtoId(0)
val perspectiveCameras: Map<String, Camera> = emptyMap(),
val perspectiveCameras: Map<Id, Camera> = emptyMap(),
@ProtoId(1)
val orthographicCameras: Map<String, Camera> = emptyMap(),
val orthographicCameras: Map<Id, Camera> = emptyMap(),
@ProtoId(2)
val models: Map<String, Model> = emptyMap(),
val models: Map<Id, Model> = emptyMap(),
@ProtoId(3)
val materials: Map<String, Material> = emptyMap(),
val materials: Map<Id, Material> = emptyMap(),
@ProtoId(4)
val pointLights: Map<String, PointLight> = emptyMap(),
val pointLights: Map<Id, PointLight> = emptyMap(),
@ProtoId(5)
val armatures: Map<Int, Armature> = emptyMap(),
val armatures: Map<Id, Armature> = emptyMap(),
@ProtoId(6)
val animations: Map<Int, List<Animation>> = emptyMap(),
val animations: Map<Id, List<Animation>> = emptyMap(),
@ProtoId(7)
val boxes: Map<String, Boxe> = emptyMap(),
val boxes: Map<Id, Box> = emptyMap(),
@ProtoId(8)
val children: List<Node> = emptyList()
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dwursteisen.minigdx.scene.api.armature

import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.common.Transformation
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
Expand All @@ -15,9 +16,9 @@ class Frame(
@Serializable
class Animation(
@ProtoId(0)
val id: Int,
val id: Id,
@ProtoId(1)
val armatureId: Int,
val armatureId: Id,
@ProtoId(2)
val name: String,
@ProtoId(3)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dwursteisen.minigdx.scene.api.armature

import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.common.Transformation
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
Expand All @@ -15,7 +16,7 @@ class Joint(
@Serializable
class Armature(
@ProtoId(0)
val id: Int,
val id: Id,
@ProtoId(1)
val name: String,
@ProtoId(2)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
package com.dwursteisen.minigdx.scene.api.camera

import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.common.Transformation
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId

interface Camera {
val id: Id
val name: String
val transformation: Transformation
}

@Serializable
data class PerspectiveCamera(
@ProtoId(0)
override val name: String,
override val id: Id,
@ProtoId(1)
val far: Float,
override val name: String,
@ProtoId(2)
val near: Float,
val far: Float,
@ProtoId(3)
val fov: Float,
val near: Float,
@ProtoId(4)
override val transformation: Transformation
val fov: Float
) : Camera

@Serializable
data class OrthographicCamera(
@ProtoId(0)
override val name: String,
override val id: Id,
@ProtoId(1)
val far: Float,
override val name: String,
@ProtoId(2)
val near: Float,
val far: Float,
@ProtoId(3)
val scale: Float,
val near: Float,
@ProtoId(4)
override val transformation: Transformation
val scale: Float
) : Camera
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
package com.dwursteisen.minigdx.scene.api.common

typealias Id = Int
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId
import kotlin.random.Random

@Serializable
data class Id(
@ProtoId(0)
val value: String = generate()
) {

companion object {
private fun generate(): String {
val randomValues = ByteArray(ID_SIZE)
Random.nextBytes(randomValues)
return randomValues.map { it.toInt() and 0x0F }
.joinToString("") { CONVERT[it] }

}

private const val ID_SIZE = 8

private val CONVERT = arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")

val None = Id("NONE")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import kotlinx.serialization.protobuf.ProtoId

@Serializable
class Transformation(
@ProtoId(1)
@ProtoId(0)
val matrix: FloatArray
)
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package com.dwursteisen.minigdx.scene.api.light

import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.model.Color
import com.dwursteisen.minigdx.scene.api.model.Position
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId


interface Light {
val id: Id
val name: String
}

@Serializable
data class PointLight(
@ProtoId(0)
val name: String,
override val id: Id,
@ProtoId(1)
val position: Position,
override val name: String,
@ProtoId(2)
val color: Color,
@ProtoId(3)
val intensity: Int
)
) : Light
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package com.dwursteisen.minigdx.scene.api.material

import com.dwursteisen.minigdx.scene.api.common.Id
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoId

@Serializable
class Material(
@ProtoId(0)
val name: String,
val id: Id,
@ProtoId(1)
val id: Int,
val name: String,
@ProtoId(2)
val width: Int,
@ProtoId(3)
val height: Int,
@ProtoId(4)
val data: ByteArray
val data: ByteArray,
@ProtoId(5)
val hasAlpha: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,21 @@ data class Vertex(
@Serializable
class Primitive(
@ProtoId(0)
val vertices: List<Vertex> = emptyList(),
val id: Id = Id(),
@ProtoId(1)
val verticesOrder: IntArray = intArrayOf(),
val vertices: List<Vertex> = emptyList(),
@ProtoId(2)
val materialId: Int = -1
val verticesOrder: IntArray = intArrayOf(),
@ProtoId(3)
val materialId: Id = Id.None
)

@Serializable
data class Boxe(
data class Box(
@ProtoId(0)
val id: Id = -1,
val id: Id,
@ProtoId(1)
val name: String,
@ProtoId(2)
val transformation: Transformation
val name: String
)

@Serializable
Expand All @@ -107,17 +107,9 @@ data class Mesh(
@Serializable
data class Model(
@ProtoId(0)
val id: Id = -1,
val id: Id,
@ProtoId(1)
val name: String,
@ProtoId(2)
@Deprecated("Prefer check the transformation from the scene graph")
val transformation: Transformation,
@ProtoId(3)
val mesh: Mesh,
@ProtoId(4)
val armatureId: Int = -1,
@Deprecated("Prefer check the box from the scene graph")
@ProtoId(5)
val boxes: List<Boxe> = emptyList()
val mesh: Mesh
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import kotlinx.serialization.protobuf.ProtoId
@Serializable
data class Node(
@ProtoId(0)
val reference: Id = -1,
val reference: Id,
@ProtoId(1)
val name: String,
@ProtoId(2)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.dwursteisen.minigdx.scene.api.relation

enum class ObjectType {
MODEL,
ARMATURE,
BOX,
CAMERA,
LIGHT
LIGHT,
MODEL
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.dwursteisen.gltf.parser.armature

import com.dwursteisen.minigdx.scene.api.common.Transformation
import com.adrienben.tools.gltf.models.*
import com.curiouscreature.kotlin.math.*
import com.dwursteisen.gltf.parser.support.Dictionary
import com.dwursteisen.gltf.parser.support.toFloatArray
import com.dwursteisen.minigdx.scene.api.armature.Animation
import com.dwursteisen.minigdx.scene.api.armature.Armature
import com.dwursteisen.minigdx.scene.api.armature.Frame
import com.dwursteisen.minigdx.scene.api.armature.Joint
import com.dwursteisen.minigdx.scene.api.common.Id
import com.dwursteisen.minigdx.scene.api.common.Transformation

typealias KeyFrame = Pair<Float, Mat4>
typealias GltfIndex = Int

class ArmatureParser(private val gltf: GltfAsset) {
class ArmatureParser(private val gltf: GltfAsset, private val ids: Dictionary) {

private fun GltfSkin.toArmature(index: Int): Armature {
private fun GltfSkin.toArmature(): Armature {
val matrices = inverseBindMatrices.toFloatArray()
.toList()
.chunked(16)
Expand All @@ -29,23 +31,22 @@ class ArmatureParser(private val gltf: GltfAsset) {
}

return Armature(
id = index,
id = ids.get(this),
name = name ?: "",
joints = joints.toTypedArray()
)
}

fun armatures(): Map<Int, Armature> {
fun armatures(): Map<Id, Armature> {
val skins = gltf.skin ?: emptyList()
return skins.mapIndexed { index, skin -> skin.toArmature(index) }
return skins.map { skin -> skin.toArmature() }
.map { it.id to it }
.toMap()
}

fun animations(): Map<Int, List<Animation>> {
return gltf.animations.mapIndexed { index, it ->
it.toAnimation(index)
}.flatten()
fun animations(): Map<Id, List<Animation>> {
return gltf.animations.map { it.toAnimation() }
.flatten()
.groupBy { it.armatureId }
}

Expand Down Expand Up @@ -115,14 +116,8 @@ class ArmatureParser(private val gltf: GltfAsset) {
}
}

private class AnimationDescription(
val name: String,
val skinId: Int,
val channels: List<GltfChannel>
)

private fun GltfAnimation.toAnimation(animationIndex: Int): List<Animation> {
return gltf.skin?.mapIndexed { index, skin ->
private fun GltfAnimation.toAnimation(): List<Animation> {
return gltf.skin?.map { skin ->
val channels = this.channels.filter { skin.joints.contains(it.target.node) }
val transformations: Map<Int, List<KeyFrame>> = channels.groupBy { it.target.node!!.index }
.mapValues { it.value.toKeyframes() }
Expand All @@ -135,8 +130,8 @@ class ArmatureParser(private val gltf: GltfAsset) {
skin.toFrames(localTransforms)
}
Animation(
id = animationIndex,
armatureId = index,
id = ids.get(this),
armatureId = ids.get(skin),
name = name ?: "",
duration = animation.keys.max() ?: 0f,
frames = animation.map { (time, globalTransformations) ->
Expand All @@ -160,6 +155,7 @@ class ArmatureParser(private val gltf: GltfAsset) {
globals[index] = global
children?.forEach { it.traverse(global) }
}

val filterIndex = joints.flatMap { it.children ?: emptyList() }
.map { it.index }

Expand Down
Loading

0 comments on commit 0989ca9

Please sign in to comment.