forked from LeenkxTeam/Leenkx_Templates
168 lines
3.7 KiB
Haxe
168 lines
3.7 KiB
Haxe
package lnx;
|
|
|
|
import iron.math.Vec4;
|
|
import iron.math.Quat;
|
|
import iron.math.Mat4;
|
|
import iron.system.Input;
|
|
import iron.object.Object;
|
|
import iron.object.BoneAnimation;
|
|
import leenkx.trait.physics.PhysicsWorld;
|
|
import leenkx.trait.internal.CameraController;
|
|
|
|
class FirstPersonController extends CameraController {
|
|
|
|
#if (!lnx_physics)
|
|
public function new() { super(); }
|
|
#else
|
|
|
|
static inline var rotationSpeed = 0.5;
|
|
|
|
public function new() {
|
|
super();
|
|
notifyOnInit(function() {
|
|
PhysicsWorld.active.notifyOnPreUpdate(preUpdate);
|
|
notifyOnUpdate(update);
|
|
|
|
notifyOnRemove(function() {
|
|
PhysicsWorld.active.removePreUpdate(preUpdate);
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function findAnimation(o:Object):BoneAnimation {
|
|
if (o.animation != null) return cast o.animation;
|
|
for (c in o.children) {
|
|
var co = findAnimation(c);
|
|
if (co != null) return co;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
var xVec = Vec4.xAxis();
|
|
var zVec = Vec4.zAxis();
|
|
var angle = 0.0;
|
|
var nextFrameRot = 0.0;
|
|
var anim:BoneAnimation = null;
|
|
var q = new Quat();
|
|
var mat = Mat4.identity();
|
|
|
|
function preUpdate() {
|
|
if (Input.occupied || !body.ready) return;
|
|
|
|
var mouse = Input.getMouse();
|
|
var kb = Input.getKeyboard();
|
|
|
|
if (mouse.started() && !mouse.locked) mouse.lock();
|
|
else if (kb.started("escape") && mouse.locked) mouse.unlock();
|
|
|
|
if (nextFrameRot != 0.0) {
|
|
var origin = object.getChild("CameraOrigin");
|
|
origin.transform.rotate(xVec, nextFrameRot);
|
|
origin.transform.buildMatrix();
|
|
}
|
|
nextFrameRot = 0;
|
|
|
|
if (mouse.moved) {
|
|
var d = mouse.movementY / 250;
|
|
if (angle + d < 0.25 && angle + d > -0.25) {
|
|
angle += d;
|
|
nextFrameRot = mouse.movementY / 250 * rotationSpeed;
|
|
}
|
|
}
|
|
|
|
if (anim == null) {
|
|
anim = findAnimation(object.getChild("Armature"));
|
|
anim.notifyOnUpdate(updateBones);
|
|
}
|
|
|
|
if (mouse.moved) transform.rotate(zVec, -mouse.movementX / 250 * rotationSpeed);
|
|
body.syncTransform();
|
|
}
|
|
|
|
function updateBones() {
|
|
// Fetch bone
|
|
var bone1 = anim.getBone("mixamorig:LeftForeLnx");
|
|
var bone2 = anim.getBone("mixamorig:RightForeLnx");
|
|
// Fetch bone matrix - this is in local bone space for now
|
|
var m1 = anim.getBoneMat(bone1);
|
|
var m2 = anim.getBoneMat(bone2);
|
|
var m1b = anim.getBoneMatBlend(bone1);
|
|
var m2b = anim.getBoneMatBlend(bone2);
|
|
var a1 = anim.getAbsMat(bone1.parent);
|
|
var a2 = anim.getAbsMat(bone2.parent);
|
|
|
|
// Rotate hand bones to aim with gun
|
|
// Some raw math follows..
|
|
var tx = m1._30;
|
|
var ty = m1._31;
|
|
var tz = m1._32;
|
|
m1._30 = 0;
|
|
m1._31 = 0;
|
|
m1._32 = 0;
|
|
mat.getInverse(a1);
|
|
q.fromAxisAngle(mat.right(), angle);
|
|
m1.applyQuat(q);
|
|
m1._30 = tx;
|
|
m1._31 = ty;
|
|
m1._32 = tz;
|
|
|
|
var tx = m2._30;
|
|
var ty = m2._31;
|
|
var tz = m2._32;
|
|
m2._30 = 0;
|
|
m2._31 = 0;
|
|
m2._32 = 0;
|
|
mat.getInverse(a2);
|
|
var v = mat.right();
|
|
v.mult(-1);
|
|
// Todo: We do not do inverse kinematics just yet, right hand moves unnaturally
|
|
// Point the hand down to the ground for now
|
|
q.fromAxisAngle(v, -angle / 3.0);
|
|
m2.applyQuat(q);
|
|
m2._30 = tx;
|
|
m2._31 = ty;
|
|
m2._32 = tz;
|
|
|
|
// Animation blending is in progress, we need to rotate those bones too
|
|
if (m1b != null && m2b != null) {
|
|
var tx = m1b._30;
|
|
var ty = m1b._31;
|
|
var tz = m1b._32;
|
|
m1b._30 = 0;
|
|
m1b._31 = 0;
|
|
m1b._32 = 0;
|
|
mat.getInverse(a1);
|
|
q.fromAxisAngle(mat.right(), angle);
|
|
m1b.applyQuat(q);
|
|
m1b._30 = tx;
|
|
m1b._31 = ty;
|
|
m1b._32 = tz;
|
|
|
|
var tx = m2b._30;
|
|
var ty = m2b._31;
|
|
var tz = m2b._32;
|
|
m2b._30 = 0;
|
|
m2b._31 = 0;
|
|
m2b._32 = 0;
|
|
mat.getInverse(a2);
|
|
var v = mat.right();
|
|
v.mult(-1);
|
|
q.fromAxisAngle(v, -angle / 3.0);
|
|
m2b.applyQuat(q);
|
|
m2b._30 = tx;
|
|
m2b._31 = ty;
|
|
m2b._32 = tz;
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
if (!body.ready) return;
|
|
|
|
// Keep vertical
|
|
body.setAngularFactor(0, 0, 0);
|
|
camera.buildMatrix();
|
|
}
|
|
#end
|
|
}
|