|
@@ -1,16 +1,22 @@
|
|
|
package hide.prefab.fx;
|
|
|
|
|
|
|
|
|
+@:access(hide.prefab.fx.LookAt)
|
|
|
class LookAtInstance {
|
|
|
var object: h3d.scene.Object;
|
|
|
var target: h3d.scene.Object;
|
|
|
- public function new(obj, target) {
|
|
|
+ var definition: LookAt;
|
|
|
+
|
|
|
+ public function new(def, obj, target) {
|
|
|
+ this.definition = def;
|
|
|
this.object = obj;
|
|
|
this.target = target;
|
|
|
}
|
|
|
|
|
|
static var tmpMat = new h3d.Matrix();
|
|
|
- static var tmpVec = new h3d.Vector();
|
|
|
+ static var deltaVec = new h3d.Vector();
|
|
|
+ static var lockAxis = new h3d.Vector();
|
|
|
+ static var invParentQ = new h3d.Quat();
|
|
|
public function apply() {
|
|
|
if(object == null || object.getScene() == null)
|
|
|
return;
|
|
@@ -21,27 +27,58 @@ class LookAtInstance {
|
|
|
else
|
|
|
object.getScene().camera.pos;
|
|
|
|
|
|
- tmpVec.load(lookAtPos.sub(object.getAbsPos().getPosition()));
|
|
|
- if(tmpVec.lengthSq() < 0.001)
|
|
|
+ deltaVec.load(lookAtPos.sub(object.getAbsPos().getPosition()));
|
|
|
+ if(deltaVec.lengthSq() < 0.001)
|
|
|
return;
|
|
|
- h3d.Matrix.lookAtX(tmpVec, tmpMat);
|
|
|
+
|
|
|
+ tmpMat.load(object.parent.getAbsPos());
|
|
|
+ tmpMat.invert();
|
|
|
+ invParentQ.initRotateMatrix(tmpMat);
|
|
|
+
|
|
|
+ if(definition.lockAxis != null) {
|
|
|
+ lockAxis.set(definition.lockAxis[0], definition.lockAxis[1], definition.lockAxis[2]);
|
|
|
+ if(lockAxis.lengthSq() > 0.001) {
|
|
|
+ var targetOnPlane = h3d.col.Plane.fromNormalPoint(lockAxis.toPoint(), new h3d.col.Point()).project(deltaVec.toPoint()).toVector();
|
|
|
+ targetOnPlane.normalize();
|
|
|
+ var frontAxis = new h3d.Vector(1, 0, 0);
|
|
|
+ var angle = hxd.Math.acos(frontAxis.dot3(targetOnPlane));
|
|
|
+
|
|
|
+ var cross = frontAxis.cross(deltaVec);
|
|
|
+ if(lockAxis.dot3(cross) < 0)
|
|
|
+ angle = -angle;
|
|
|
+
|
|
|
+ var q = object.getRotationQuat();
|
|
|
+ q.initRotateAxis(lockAxis.x, lockAxis.y, lockAxis.z, angle);
|
|
|
+ q.multiply(invParentQ, q);
|
|
|
+ object.setRotationQuat(q);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Default look at
|
|
|
+ h3d.Matrix.lookAtX(deltaVec, tmpMat);
|
|
|
var q = object.getRotationQuat();
|
|
|
q.initRotateMatrix(tmpMat);
|
|
|
object.setRotationQuat(q);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+@:allow(hide.prefab.fx.LookAt.LookAtInstance)
|
|
|
class LookAt extends Prefab {
|
|
|
|
|
|
- public var target(default,null) : String;
|
|
|
+ var target(default,null) : String;
|
|
|
+ var lockAxis: Array<Float> = [0,0,0];
|
|
|
|
|
|
override public function load(v:Dynamic) {
|
|
|
target = v.target;
|
|
|
+ if(v.lockAxis != null)
|
|
|
+ lockAxis = v.lockAxis;
|
|
|
}
|
|
|
|
|
|
override function save() {
|
|
|
return {
|
|
|
- target : target
|
|
|
+ target : target,
|
|
|
+ lockAxis: lockAxis
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -49,7 +86,7 @@ class LookAt extends Prefab {
|
|
|
var targetObj = null;
|
|
|
if(target != "camera")
|
|
|
targetObj = ctx.locateObject(target);
|
|
|
- ctx.custom = new LookAtInstance(ctx.local3d, targetObj);
|
|
|
+ ctx.custom = new LookAtInstance(this, ctx.local3d, targetObj);
|
|
|
}
|
|
|
|
|
|
override function makeInstance( ctx : Context ) {
|
|
@@ -69,13 +106,18 @@ class LookAt extends Prefab {
|
|
|
}
|
|
|
|
|
|
override function edit(ctx:EditContext) {
|
|
|
- var props = ctx.properties.add(new hide.Element('
|
|
|
+ var group = new hide.Element('
|
|
|
+ <div class="group" name="LookAt">
|
|
|
<dl>
|
|
|
- <dt>Target</dt><dd><select field="target"><option value="">-- Choose --</option></select>
|
|
|
+ <dt>Target</dt><dd><select field="target"><option value="">-- Choose --</option></select></dd>
|
|
|
</dl>
|
|
|
- '),this, function(_) {
|
|
|
+ </div>');
|
|
|
+
|
|
|
+ group.append(hide.comp.PropsEditor.makePropsList([
|
|
|
+ { name: "lockAxis", t: PVec(3), def: [1,0,0] }
|
|
|
+ ]));
|
|
|
|
|
|
- });
|
|
|
+ var props = ctx.properties.add(group ,this, function(_) { trace(this.lockAxis); });
|
|
|
|
|
|
var select = props.find("select");
|
|
|
var opt = new hide.Element("<option>").attr("value", "camera").html("Camera");
|