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:
@@ -1,5 +1,6 @@
|
||||
package com.soywiz.korge.experimental.s3d
|
||||
|
||||
import com.soywiz.korge.experimental.s3d.model.internal.*
|
||||
import com.soywiz.korma.geom.*
|
||||
|
||||
abstract class Camera3D : View3D() {
|
||||
@@ -34,6 +35,8 @@ abstract class Camera3D : View3D() {
|
||||
// Do nothing except when debugging
|
||||
}
|
||||
|
||||
abstract fun clone(): Camera3D
|
||||
|
||||
class Perspective(
|
||||
fov: Angle = 60.degrees,
|
||||
near: Double = 0.3,
|
||||
@@ -52,6 +55,10 @@ abstract class Camera3D : View3D() {
|
||||
override fun updateMatrix(mat: Matrix3D, width: Double, height: Double) {
|
||||
mat.setToPerspective(fov, if (height != 0.0) width / height else 1.0, near, far)
|
||||
}
|
||||
|
||||
override fun clone(): Perspective = Perspective(fov, near, far).apply {
|
||||
this.localTransform.copyFrom(this@Perspective.localTransform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +163,19 @@ class Transform3D {
|
||||
matrixDirty = true
|
||||
scale.setTo(x, y, z, w)
|
||||
}
|
||||
|
||||
fun copyFrom(localTransform: Transform3D) {
|
||||
this.setMatrix(localTransform.matrix)
|
||||
}
|
||||
|
||||
fun setToInterpolated(a: Transform3D, b: Transform3D, t: Double) {
|
||||
_translation.setToInterpolated(a.translation, b.translation, t)
|
||||
_rotation.setToInterpolated(a.rotation, b.rotation, t)
|
||||
_scale.setToInterpolated(a.scale, b.scale, t)
|
||||
matrixDirty = true
|
||||
}
|
||||
|
||||
override fun toString(): String = "Transform3D(translation=$translation,rotation=$rotation,scale=$scale)"
|
||||
}
|
||||
|
||||
typealias PerspectiveCamera3D = Camera3D.Perspective
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.soywiz.korge.experimental.s3d.model.internal
|
||||
|
||||
import com.soywiz.korma.geom.*
|
||||
import com.soywiz.korma.geom.interpolate
|
||||
import com.soywiz.korma.interpolation.*
|
||||
import kotlin.math.*
|
||||
|
||||
fun Vector3D.Companion.lengthSq(x: Double, y: Double, z: Double, w: Double) = x * x + y * y + z * z + w * w
|
||||
fun Vector3D.Companion.length(x: Double, y: Double, z: Double, w: Double) = sqrt(lengthSq(x, y, z, w))
|
||||
|
||||
fun Quaternion.normalize(v: Quaternion = this): Quaternion {
|
||||
val length = 1.0 / Vector3D.length(v.x, v.y, v.z, v.w)
|
||||
return this.setTo(v.x / length, v.y / length, v.z / length, v.w / length)
|
||||
}
|
||||
|
||||
// @TODO: Make Quaternions interpolable
|
||||
|
||||
object Quaternion_Companion
|
||||
|
||||
fun dotProduct(l: Quaternion, r: Quaternion): Double = l.x * r.x + l.y * r.y + l.z * r.z + l.w * r.w
|
||||
|
||||
operator fun Quaternion.unaryMinus(): Quaternion = Quaternion(-x, -y, -z, -w)
|
||||
operator fun Quaternion.plus(other: Quaternion): Quaternion = Quaternion(x + other.x, y + other.y, z + other.z, w + other.w)
|
||||
operator fun Quaternion.minus(other: Quaternion): Quaternion = Quaternion(x - other.x, y - other.y, z - other.z, w - other.w)
|
||||
operator fun Quaternion.times(scale: Double): Quaternion = Quaternion(x * scale, y * scale, z * scale, w * scale)
|
||||
operator fun Double.times(scale: Quaternion): Quaternion = scale.times(this)
|
||||
|
||||
fun Quaternion.negate() = this.setTo(-x, -y, -z, -w)
|
||||
|
||||
inline fun Quaternion.setToFunc(l: Quaternion, r: Quaternion, func: (l: Double, r: Double) -> Double) = setTo(
|
||||
func(l.x, r.x),
|
||||
func(l.y, r.y),
|
||||
func(l.z, r.z),
|
||||
func(l.w, r.w)
|
||||
)
|
||||
|
||||
inline fun Vector3D.setToFunc(l: Vector3D, r: Vector3D, func: (l: Float, r: Float) -> Float) = setTo(
|
||||
func(l.x, r.x),
|
||||
func(l.y, r.y),
|
||||
func(l.z, r.z),
|
||||
func(l.w, r.w)
|
||||
)
|
||||
|
||||
// @TODO: Allocations and temps!
|
||||
private val tleft: Quaternion = Quaternion()
|
||||
private val tright: Quaternion = Quaternion()
|
||||
fun Quaternion.setToSlerp(left: Quaternion, right: Quaternion, t: Double): Quaternion {
|
||||
val tleft = tleft.copyFrom(left).normalize()
|
||||
val tright = tright.copyFrom(right).normalize()
|
||||
|
||||
var dot = dotProduct(tleft, right)
|
||||
|
||||
if (dot < 0.0f) {
|
||||
tright.negate()
|
||||
dot = -dot
|
||||
}
|
||||
|
||||
if (dot > 0.99995f) return setToFunc(tleft, tright) { l, r -> l + t * (r - l) }
|
||||
|
||||
val angle0 = acos(dot)
|
||||
val angle1 = angle0 * t
|
||||
|
||||
val s1 = sin(angle1) / sin(angle0)
|
||||
val s0 = cos(angle1) - dot * s1
|
||||
|
||||
return setToFunc(tleft, tright) { l, r -> (s0 * l) + (s1 * r) }
|
||||
}
|
||||
|
||||
fun Quaternion.setToInterpolated(left: Quaternion, right: Quaternion, t: Double): Quaternion = setToSlerp(left, right, t)
|
||||
|
||||
fun Vector3D.setToInterpolated(left: Vector3D, right: Vector3D, t: Double): Vector3D = setToFunc(left, right) { l, r -> t.interpolate(l, r) }
|
||||
@@ -147,7 +147,8 @@ object Demo3 {
|
||||
//val library = resourcesVfs["cilinder.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.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["Fallera.dae"].readColladaLibrary()
|
||||
@@ -169,10 +170,15 @@ object Demo3 {
|
||||
//cube.mesh.texture = tex
|
||||
|
||||
val mainSceneView = library.mainScene.instantiate()
|
||||
val cameras = mainSceneView.findByType<Camera3D>()
|
||||
|
||||
val camera1 = cameras.first().clone()
|
||||
val camera2 = cameras.last().clone()
|
||||
|
||||
//ambientColor = Colors.RED
|
||||
//ambientColor = Colors.WHITE
|
||||
//ambientColor = Colors.WHITE
|
||||
camera = mainSceneView.findByType<Camera3D>().first()
|
||||
camera = camera1.clone()
|
||||
this += mainSceneView
|
||||
//this += box()
|
||||
|
||||
@@ -197,6 +203,19 @@ object Demo3 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//println(camera1.localTransform)
|
||||
//println(camera2.localTransform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
sample-raw-3d/src/commonMain/resources/monkey_smooth.blend
Normal file
BIN
sample-raw-3d/src/commonMain/resources/monkey_smooth.blend
Normal file
Binary file not shown.
BIN
sample-raw-3d/src/commonMain/resources/monkey_smooth.blend1
Normal file
BIN
sample-raw-3d/src/commonMain/resources/monkey_smooth.blend1
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user