mirror of
https://github.com/jlengrand/korge-samples.git
synced 2026-03-10 08:31:18 +00:00
More work on 3d
This commit is contained in:
@@ -15,7 +15,7 @@ object Shaders3D {
|
||||
val u_AmbientColor = Uniform("u_ambientColor", VarType.Float4)
|
||||
val u_ProjMat = Uniform("u_ProjMat", VarType.Mat4)
|
||||
val u_ViewMat = Uniform("u_ViewMat", VarType.Mat4)
|
||||
val u_BindMat = Uniform("u_BindMat", VarType.Mat4)
|
||||
val u_BindShapeMatrix = Uniform("u_BindMat", VarType.Mat4)
|
||||
val u_ModMat = Uniform("u_ModMat", VarType.Mat4)
|
||||
val u_NormMat = Uniform("u_NormMat", VarType.Mat4)
|
||||
//val MAX_BONE_MATS = 16
|
||||
@@ -156,14 +156,16 @@ object Shaders3D {
|
||||
SET(skinMatrix, getBone(wIndex))
|
||||
SET(localPos, localPos + skinMatrix * vec4(a_pos, 1f.lit) * getWeight(wIndex))
|
||||
SET(localNorm, localNorm + skinMatrix * vec4(a_norm, 0f.lit) * getWeight(wIndex))
|
||||
//SET(localPos, localPos + vec4(a_pos, 1f.lit) * getWeight(wIndex))
|
||||
//SET(localNorm, localNorm + vec4(a_norm, 0f.lit) * getWeight(wIndex))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SET(modelViewMat, u_ModMat * u_ViewMat)
|
||||
SET(normalMat, u_NormMat)
|
||||
SET(v_Pos, vec3(modelViewMat * u_BindMat * localPos))
|
||||
SET(v_Norm, vec3(normalMat * u_BindMat * localNorm))
|
||||
SET(v_Pos, vec3(modelViewMat * u_BindShapeMatrix * localPos))
|
||||
SET(v_Norm, vec3(normalMat * u_BindShapeMatrix * localNorm))
|
||||
if (hasTexture) {
|
||||
SET(v_TexCoords, a_tex["xy"])
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ open class Light3D(
|
||||
var linearAttenuation: Double = 0.0,
|
||||
var quadraticAttenuation: Double = 0.00111109
|
||||
) : View3D() {
|
||||
internal val tempVec1 = Vector3D()
|
||||
internal val tempVec2 = Vector3D()
|
||||
internal val colorVec = Vector3D()
|
||||
internal val attenuationVec = Vector3D()
|
||||
|
||||
fun setTo(
|
||||
color: RGBA = Colors.WHITE,
|
||||
@@ -227,12 +227,15 @@ fun <T : View3D> T.addTo(container: Container3D) = this.apply {
|
||||
container.addChild(this)
|
||||
}
|
||||
|
||||
data class Bone3D(
|
||||
data class Bone3D constructor(
|
||||
val name: String,
|
||||
val matrix: Matrix3D
|
||||
)
|
||||
val invBindMatrix: Matrix3D
|
||||
) {
|
||||
//val finalMatrix: Matrix3D = invBindMatrix.clone()
|
||||
val finalMatrix: Matrix3D = Matrix3D()
|
||||
}
|
||||
|
||||
data class Skeleton3D(val bindShapeMatrix: Matrix3D, val bones: List<Bone3D>) {
|
||||
data class Skin3D(val bindShapeMatrix: Matrix3D, val bones: List<Bone3D>) {
|
||||
//val matrices = Array(bones.size) { Matrix3D() }
|
||||
val matrices = Array(Shaders3D.MAX_BONE_MATS) { Matrix3D() }
|
||||
}
|
||||
@@ -264,6 +267,8 @@ class Mesh3D constructor(
|
||||
val hasTexture: Boolean = false,
|
||||
val maxWeights: Int = 0
|
||||
) {
|
||||
var skin: Skin3D? = null
|
||||
|
||||
val fbuffer by lazy {
|
||||
FBuffer.alloc(data.size * 4).apply {
|
||||
setAlignedArrayFloat32(0, this@Mesh3D.data, 0, this@Mesh3D.data.size)
|
||||
@@ -273,7 +278,6 @@ class Mesh3D constructor(
|
||||
//}
|
||||
}
|
||||
|
||||
var skeleton: Skeleton3D? = null
|
||||
var material: Material3D? = null
|
||||
|
||||
//val modelMat = Matrix3D()
|
||||
@@ -350,7 +354,11 @@ inline fun Container3D.mesh(mesh: Mesh3D, callback: ViewWithMesh3D.() -> Unit =
|
||||
return ViewWithMesh3D(mesh).apply(callback).addTo(this)
|
||||
}
|
||||
|
||||
open class ViewWithMesh3D(var mesh: Mesh3D) : View3D() {
|
||||
open class ViewWithMesh3D(
|
||||
var mesh: Mesh3D,
|
||||
var skeleton: View3D? = null
|
||||
) : View3D() {
|
||||
|
||||
private val uniformValues = AG.UniformValues()
|
||||
private val rs = AG.RenderState(depthFunc = AG.CompareMode.LESS_EQUAL)
|
||||
//private val rs = AG.RenderState(depthFunc = AG.CompareMode.ALWAYS)
|
||||
@@ -396,12 +404,14 @@ open class ViewWithMesh3D(var mesh: Mesh3D) : View3D() {
|
||||
program = mesh.program ?: getProgram3D(ctx.lights.size.clamp(0, 4), mesh.maxWeights, meshMaterial, mesh.hasTexture),
|
||||
vertexLayout = mesh.layout,
|
||||
vertexCount = mesh.vertexCount,
|
||||
blending = AG.Blending.NONE,
|
||||
//vertexCount = 6 * 6,
|
||||
uniforms = uniformValues.apply {
|
||||
this[u_ProjMat] = ctx.projCameraMat
|
||||
this[u_ViewMat] = localTransform.matrix
|
||||
this[u_ModMat] = tempMat2.multiply(tempMat1.apply { prepareExtraModelMatrix(this) }, modelMat)
|
||||
this[u_NormMat] = tempMat3.multiply(tempMat2, localTransform.matrix).invert().transpose()
|
||||
//this[u_NormMat] = tempMat3.multiply(tempMat2, localTransform.matrix).invert().transpose()
|
||||
this[u_NormMat] = tempMat3.multiply(tempMat2, localTransform.matrix).invert()
|
||||
|
||||
this[u_Shiness] = meshMaterial?.shiness ?: 0.5f
|
||||
this[u_IndexOfRefraction] = meshMaterial?.indexOfRefraction ?: 1f
|
||||
@@ -413,11 +423,11 @@ open class ViewWithMesh3D(var mesh: Mesh3D) : View3D() {
|
||||
setMaterialLight(ctx, specular, meshMaterial.specular)
|
||||
}
|
||||
|
||||
val skeleton = mesh.skeleton
|
||||
val skeleton = mesh.skin
|
||||
if (skeleton != null) {
|
||||
this[u_BindMat] = ctx.bindMat4.copyFrom(skeleton.bindShapeMatrix)
|
||||
this[u_BindShapeMatrix] = ctx.bindMat4.copyFrom(skeleton.bindShapeMatrix)
|
||||
skeleton.bones.fastForEachWithIndex { index, bone ->
|
||||
skeleton.matrices[index].copyFrom(bone.matrix)
|
||||
skeleton.matrices[index].copyFrom(bone.finalMatrix)
|
||||
//skeleton.matrices[index].copyFrom(bone.matrix)
|
||||
//skeleton.matrices[index].identity()
|
||||
}
|
||||
@@ -428,7 +438,7 @@ open class ViewWithMesh3D(var mesh: Mesh3D) : View3D() {
|
||||
//skeleton.matrices[0][0, 0] = 0.1f
|
||||
this[u_BoneMats] = skeleton.matrices
|
||||
} else {
|
||||
this[u_BindMat] = ctx.bindMat4.identity()
|
||||
this[u_BindShapeMatrix] = ctx.bindMat4.identity()
|
||||
}
|
||||
|
||||
this[u_AmbientColor] = ctx.ambientColor
|
||||
@@ -436,10 +446,8 @@ open class ViewWithMesh3D(var mesh: Mesh3D) : View3D() {
|
||||
ctx.lights.fastForEachWithIndex { index, light: Light3D ->
|
||||
val lightColor = light.color
|
||||
this[lights[index].u_sourcePos] = light.localTransform.translation
|
||||
//println("light.localTransform.translation:${light.localTransform.translation}")
|
||||
this[lights[index].u_color] = light.tempVec1.setTo(lightColor.rf, lightColor.gf, lightColor.bf, 1f)
|
||||
//println(light.tempVec1.setTo(lightColor.rf, lightColor.gf, lightColor.bf, 1f))
|
||||
this[lights[index].u_attenuation] = light.tempVec2.setTo(light.constantAttenuation, light.linearAttenuation, light.quadraticAttenuation)
|
||||
this[lights[index].u_color] = light.colorVec.setTo(lightColor.rf, lightColor.gf, lightColor.bf, 1f)
|
||||
this[lights[index].u_attenuation] = light.attenuationVec.setTo(light.constantAttenuation, light.linearAttenuation, light.quadraticAttenuation)
|
||||
}
|
||||
},
|
||||
renderState = rs
|
||||
|
||||
@@ -26,8 +26,7 @@ class ColladaParser {
|
||||
data class NamesSourceParam(override val name: String, val names: ArrayList<String>) : SourceParam
|
||||
data class Source(val id: String, val params: FastStringMap<SourceParam>)
|
||||
data class Input(val semantic: String, val offset: Int, val source: Source, val indices: IntArrayList)
|
||||
data class Geometry(val id: String, val name: String, val inputs: FastStringMap<Input> = FastStringMap(), var materialId: String? = null) {
|
||||
}
|
||||
data class Geometry(val id: String, val name: String, val inputs: FastStringMap<Input> = FastStringMap(), var materialId: String? = null)
|
||||
data class Skin(
|
||||
val controllerId: String,
|
||||
val controllerName: String,
|
||||
@@ -54,7 +53,7 @@ class ColladaParser {
|
||||
parseAnimations(xml)
|
||||
val skins = parseControllers(xml)
|
||||
for (skin in skins) {
|
||||
library.skins[skin.controllerId] = skin
|
||||
library.skinDefs[skin.controllerId] = skin
|
||||
}
|
||||
generateGeometries(geometries, skins)
|
||||
parseVisualScenes(xml)
|
||||
@@ -239,7 +238,7 @@ class ColladaParser {
|
||||
maxWeights = maxWeights
|
||||
).apply {
|
||||
if (skinDef != null) {
|
||||
this.skeleton = Skeleton3D(skinDef.bindShapeMatrix, skinDef.bones.map { it.toBone() })
|
||||
this.skin = Skin3D(skinDef.bindShapeMatrix, skinDef.bones.map { it.toBone() })
|
||||
}
|
||||
},
|
||||
skin = skinDef,
|
||||
@@ -535,19 +534,20 @@ class ColladaParser {
|
||||
}
|
||||
|
||||
fun Library3D.parseVisualScenes(xml: Xml) {
|
||||
val instancesById = FastStringMap<Library3D.Instance3D>()
|
||||
for (vscene in xml["library_visual_scenes"]["visual_scene"]) {
|
||||
val scene = Library3D.Scene3D()
|
||||
scene.id = vscene.str("id")
|
||||
scene.name = vscene.str("name")
|
||||
for (node in vscene["node"]) {
|
||||
val instance = parseVisualSceneNode(node)
|
||||
val instance = parseVisualSceneNode(node, instancesById)
|
||||
scene.children += instance
|
||||
}
|
||||
scenes[scene.id] = scene
|
||||
}
|
||||
}
|
||||
|
||||
fun Library3D.parseVisualSceneNode(node: Xml): Library3D.Instance3D {
|
||||
fun Library3D.parseVisualSceneNode(node: Xml, instancesById: FastStringMap<Library3D.Instance3D>): Library3D.Instance3D {
|
||||
val instance = Library3D.Instance3D()
|
||||
var location: Vector3D? = null
|
||||
var scale: Vector3D? = null
|
||||
@@ -559,6 +559,8 @@ class ColladaParser {
|
||||
instance.name = node.str("name")
|
||||
instance.type = node.str("type")
|
||||
|
||||
instancesById[instance.id] = instance
|
||||
|
||||
for (child in node.allNodeChildren) {
|
||||
when (child.nameLC) {
|
||||
"matrix" -> {
|
||||
@@ -605,9 +607,18 @@ class ColladaParser {
|
||||
instance.def = geometryDefs[geometryId]
|
||||
}
|
||||
"node" -> {
|
||||
val childInstance = parseVisualSceneNode(child)
|
||||
val childInstance = parseVisualSceneNode(child, instancesById)
|
||||
instance.children.add(childInstance)
|
||||
}
|
||||
"instance_controller" -> {
|
||||
val skinId = child.str("url").trim('#')
|
||||
val skeletonId = child["skeleton"].firstText?.trim('#') ?: ""
|
||||
val skin = skinDefs[skinId]
|
||||
val skeleton = instancesById[skeletonId]
|
||||
instance.def = geometryDefs[skin?.skinSource ?: ""]
|
||||
instance.skin = skin
|
||||
instance.skeleton = skeleton
|
||||
}
|
||||
"extra" -> {
|
||||
}
|
||||
else -> {
|
||||
|
||||
@@ -15,7 +15,7 @@ data class Library3D(
|
||||
val effectDefs: FastStringMap<EffectDef> = FastStringMap(),
|
||||
val imageDefs: FastStringMap<ImageDef> = FastStringMap(),
|
||||
val geometryDefs: FastStringMap<GeometryDef> = FastStringMap(),
|
||||
val skins: FastStringMap<ColladaParser.Skin> = FastStringMap()
|
||||
val skinDefs: FastStringMap<ColladaParser.Skin> = FastStringMap()
|
||||
) {
|
||||
|
||||
suspend fun loadTextures() {
|
||||
@@ -45,6 +45,8 @@ data class Library3D(
|
||||
var id: String = ""
|
||||
var name: String = ""
|
||||
var type: String = ""
|
||||
var skin: ColladaParser.Skin? = null
|
||||
var skeleton: Instance3D? = null
|
||||
}
|
||||
|
||||
open class Scene3D : Instance3D() {
|
||||
@@ -96,8 +98,8 @@ data class Library3D(
|
||||
val material: MaterialDef? = null
|
||||
) : ObjectDef()
|
||||
|
||||
data class BoneDef(val name: String, val pose: Matrix3D) : Def() {
|
||||
fun toBone() = Bone3D(name, pose.clone())
|
||||
data class BoneDef(val name: String, val invBindMatrix: Matrix3D) : Def() {
|
||||
fun toBone() = Bone3D(name, invBindMatrix.clone())
|
||||
}
|
||||
|
||||
data class SkinDef(
|
||||
@@ -125,7 +127,7 @@ fun Library3D.Instance3D.instantiate(): View3D {
|
||||
}
|
||||
}
|
||||
is Library3D.GeometryDef -> {
|
||||
ViewWithMesh3D(def.mesh)
|
||||
ViewWithMesh3D(def.mesh, this.skeleton?.instantiate())
|
||||
}
|
||||
is Library3D.PerspectiveCameraDef -> {
|
||||
Camera3D.Perspective(def.xfov, def.zmin, def.zmax)
|
||||
|
||||
@@ -15,8 +15,8 @@ import com.soywiz.korma.interpolation.*
|
||||
import kotlin.jvm.*
|
||||
|
||||
//suspend fun main(args: Array<String>) = Demo3.main(args)
|
||||
suspend fun main(args: Array<String>) = Demo3.main()
|
||||
//suspend fun main(args: Array<String>) = Demo1.main()
|
||||
//suspend fun main(args: Array<String>) = Demo3.main()
|
||||
suspend fun main(args: Array<String>) = Demo1.main()
|
||||
|
||||
object Demo1 {
|
||||
@JvmStatic
|
||||
@@ -145,12 +145,12 @@ object Demo3 {
|
||||
|
||||
//val library = resourcesVfs["scene.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["cilinder.dae"].readColladaLibrary()
|
||||
val library = resourcesVfs["box_textured.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["box_textured.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["monkey.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["monkey-smooth.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["monkey_smooth_two_camera.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["shape2.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["skinning.dae"].readColladaLibrary()
|
||||
val library = resourcesVfs["skinning.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["Fallera.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["model.dae"].readColladaLibrary()
|
||||
//val library = resourcesVfs["skinning_sample.dae"].readColladaLibrary()
|
||||
@@ -172,8 +172,8 @@ object Demo3 {
|
||||
val mainSceneView = library.mainScene.instantiate()
|
||||
val cameras = mainSceneView.findByType<Camera3D>()
|
||||
|
||||
val camera1 = cameras.first()
|
||||
val camera2 = cameras.last()
|
||||
val camera1 = cameras.firstOrNull() ?: camera
|
||||
val camera2 = cameras.lastOrNull() ?: camera
|
||||
|
||||
//ambientColor = Colors.RED
|
||||
//ambientColor = Colors.WHITE
|
||||
@@ -191,25 +191,27 @@ object Demo3 {
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
var tick = 0
|
||||
addUpdatable {
|
||||
val angle = (tick / 1.0).degrees
|
||||
camera.positionLookingAt(
|
||||
cos(angle * 1) * 6, 2.0, -sin(angle * 1) * 6, // Orbiting camera
|
||||
//1, 0, 4,
|
||||
0, 0, 0
|
||||
)
|
||||
tick++
|
||||
}
|
||||
*/
|
||||
launchImmediately {
|
||||
while (true) {
|
||||
tween(time = 2.seconds, easing = Easing.SMOOTH) {
|
||||
camera.localTransform.setToInterpolated(camera1.localTransform, camera2.localTransform, it)
|
||||
}
|
||||
tween(time = 2.seconds, easing = Easing.SMOOTH) {
|
||||
camera.localTransform.setToInterpolated(camera2.localTransform, camera1.localTransform, it)
|
||||
if (camera1 == camera2) {
|
||||
var tick = 0
|
||||
val camera1Len = camera.localTransform.translation.length3
|
||||
addUpdatable {
|
||||
val angle = (tick / 1.0).degrees
|
||||
camera.positionLookingAt(
|
||||
cos(angle * 1) * camera1Len, 2.0, -sin(angle * 1) * camera1Len, // Orbiting camera
|
||||
//1, 0, 4,
|
||||
0, 0, 0
|
||||
)
|
||||
tick++
|
||||
}
|
||||
} else {
|
||||
launchImmediately {
|
||||
while (true) {
|
||||
tween(time = 2.seconds, easing = Easing.SMOOTH) {
|
||||
camera.localTransform.setToInterpolated(camera1.localTransform, camera2.localTransform, it)
|
||||
}
|
||||
tween(time = 2.seconds, easing = Easing.SMOOTH) {
|
||||
camera.localTransform.setToInterpolated(camera2.localTransform, camera1.localTransform, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user