123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- package hrt.prefab.fx;
- @:access(hrt.prefab.fx.LookAt)
- class LookAtObject extends h3d.scene.Object {
- var target: h3d.scene.Object;
- var definition: LookAt;
- public function new(parent, def) {
- super(parent);
- this.definition = def;
- }
- static var tmpMat = new h3d.Matrix();
- static var tmpVec = new h3d.Vector();
- static var tmpScale = new h3d.Vector();
- static var deltaVec = new h3d.Vector();
- static var lookAtPos = new h3d.Vector();
- static var lockAxis = new h3d.Vector();
- static var tempQ = new h3d.Quat();
- override function syncRec( ctx ) {
- posChanged = true;
- super.syncRec(ctx);
- }
- override function calcAbsPos() {
- if(target != null)
- target.getAbsPos().getPosition(lookAtPos);
- else {
- if(getScene() == null || getScene().camera == null) return;
- lookAtPos.load(getScene().camera.pos);
- lookAtPos.w = 1;
- }
- super.calcAbsPos();
- deltaVec.load(lookAtPos.sub(absPos.getPosition(tmpVec)));
- if(deltaVec.lengthSq() < 0.001)
- return;
- if(definition.lockAxis != null)
- lockAxis.set(definition.lockAxis[0], definition.lockAxis[1], definition.lockAxis[2]);
- else
- lockAxis.set();
- if(lockAxis.lengthSq() > 0.001) {
- tmpMat.load(parent.getAbsPos());
- tmpMat.invert();
- lookAtPos.transform(tmpMat);
- deltaVec.set(lookAtPos.x - x, lookAtPos.y - y, lookAtPos.z - z);
- var invParentQ = tempQ;
- invParentQ.initRotateMatrix(tmpMat);
- 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.dot(targetOnPlane));
- var cross = frontAxis.cross(deltaVec);
- if(lockAxis.dot(cross) < 0)
- angle = -angle;
- var q = getRotationQuat();
- q.initRotateAxis(lockAxis.x, lockAxis.y, lockAxis.z, angle);
- q.normalize();
- setRotationQuat(q);
- super.calcAbsPos();
- }
- else
- {
- tmpMat.load(absPos);
- var scale = tmpMat.getScale(tmpScale);
- qRot.initDirection(deltaVec);
- qRot.toMatrix(absPos);
- absPos._11 *= scale.x;
- absPos._12 *= scale.x;
- absPos._13 *= scale.x;
- absPos._21 *= scale.y;
- absPos._22 *= scale.y;
- absPos._23 *= scale.y;
- absPos._31 *= scale.z;
- absPos._32 *= scale.z;
- absPos._33 *= scale.z;
- absPos._41 = tmpMat.tx;
- absPos._42 = tmpMat.ty;
- absPos._43 = tmpMat.tz;
- }
- }
- }
- @:allow(hrt.prefab.fx.LookAt.LookAtInstance)
- class LookAt extends Object3D {
- @:s var target(default,null) : String;
- @:s var lockAxis: Array<Float> = [0,0,0];
- public function new(?parent) {
- super(parent);
- type = "lookAt";
- }
- override function updateInstance(ctx:hrt.prefab.Context, ?propName:String) {
- super.updateInstance(ctx, propName);
- var targetObj = null;
- if(target != "camera")
- targetObj = ctx.locateObject(target);
- }
- override function makeInstance( ctx : Context ) {
- ctx = ctx.clone(this);
- ctx.local3d = new LookAtObject(ctx.local3d, this);
- ctx.local3d.name = name;
- updateInstance(ctx);
- return ctx;
- }
- #if editor
- override function getHideProps() : HideProps {
- return {
- icon : "cog",
- name : "LookAt"
- };
- }
- override function edit(ctx:EditContext) {
- super.edit(ctx);
- var group = new hide.Element('
- <div class="group" name="LookAt">
- <dl>
- <dt>Target</dt><dd><select field="target"><option value="">-- Choose --</option></select></dd>
- </dl>
- </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");
- select.append(opt);
- for( path in ctx.getNamedObjects() ) {
- var parts = path.split(".");
- var opt = new hide.Element("<option>").attr("value", path).html([for( p in 1...parts.length ) " "].join("") + parts.pop());
- select.append(opt);
- }
- select.val(Reflect.field(this, select.attr("field")));
- }
- #end
- static var _ = Library.register("lookAt", LookAt);
- }
|