LookAt.hx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package hrt.prefab.fx;
  2. @:access(hrt.prefab.fx.LookAt)
  3. class LookAtObject extends h3d.scene.Object {
  4. var target: h3d.scene.Object;
  5. var definition: LookAt;
  6. public function new(parent, def) {
  7. super(parent);
  8. this.definition = def;
  9. }
  10. static var tmpMat = new h3d.Matrix();
  11. static var tmpVec = new h3d.Vector();
  12. static var tmpScale = new h3d.Vector();
  13. static var deltaVec = new h3d.Vector();
  14. static var lookAtPos = new h3d.Vector();
  15. static var lockAxis = new h3d.Vector();
  16. static var tempQ = new h3d.Quat();
  17. override function syncRec( ctx ) {
  18. posChanged = true;
  19. super.syncRec(ctx);
  20. }
  21. override function calcAbsPos() {
  22. if(target != null)
  23. target.getAbsPos().getPosition(lookAtPos);
  24. else {
  25. if(getScene() == null || getScene().camera == null) return;
  26. lookAtPos.load(getScene().camera.pos);
  27. lookAtPos.w = 1;
  28. }
  29. super.calcAbsPos();
  30. deltaVec.load(lookAtPos.sub(absPos.getPosition(tmpVec)));
  31. if(deltaVec.lengthSq() < 0.001)
  32. return;
  33. if(definition.lockAxis != null)
  34. lockAxis.set(definition.lockAxis[0], definition.lockAxis[1], definition.lockAxis[2]);
  35. else
  36. lockAxis.set();
  37. if(lockAxis.lengthSq() > 0.001) {
  38. tmpMat.load(parent.getAbsPos());
  39. tmpMat.invert();
  40. lookAtPos.transform(tmpMat);
  41. deltaVec.set(lookAtPos.x - x, lookAtPos.y - y, lookAtPos.z - z);
  42. var invParentQ = tempQ;
  43. invParentQ.initRotateMatrix(tmpMat);
  44. var targetOnPlane = h3d.col.Plane.fromNormalPoint(lockAxis.toPoint(), new h3d.col.Point()).project(deltaVec.toPoint()).toVector();
  45. targetOnPlane.normalize();
  46. var frontAxis = new h3d.Vector(1, 0, 0);
  47. var angle = hxd.Math.acos(frontAxis.dot(targetOnPlane));
  48. var cross = frontAxis.cross(deltaVec);
  49. if(lockAxis.dot(cross) < 0)
  50. angle = -angle;
  51. var q = getRotationQuat();
  52. q.initRotateAxis(lockAxis.x, lockAxis.y, lockAxis.z, angle);
  53. q.normalize();
  54. setRotationQuat(q);
  55. super.calcAbsPos();
  56. }
  57. else
  58. {
  59. tmpMat.load(absPos);
  60. var scale = tmpMat.getScale(tmpScale);
  61. qRot.initDirection(deltaVec);
  62. qRot.toMatrix(absPos);
  63. absPos._11 *= scale.x;
  64. absPos._12 *= scale.x;
  65. absPos._13 *= scale.x;
  66. absPos._21 *= scale.y;
  67. absPos._22 *= scale.y;
  68. absPos._23 *= scale.y;
  69. absPos._31 *= scale.z;
  70. absPos._32 *= scale.z;
  71. absPos._33 *= scale.z;
  72. absPos._41 = tmpMat.tx;
  73. absPos._42 = tmpMat.ty;
  74. absPos._43 = tmpMat.tz;
  75. }
  76. }
  77. }
  78. @:allow(hrt.prefab.fx.LookAt.LookAtInstance)
  79. class LookAt extends Object3D {
  80. @:s var target(default,null) : String;
  81. @:s var lockAxis: Array<Float> = [0,0,0];
  82. public function new(?parent) {
  83. super(parent);
  84. type = "lookAt";
  85. }
  86. override function updateInstance(ctx:hrt.prefab.Context, ?propName:String) {
  87. super.updateInstance(ctx, propName);
  88. var targetObj = null;
  89. if(target != "camera")
  90. targetObj = ctx.locateObject(target);
  91. }
  92. override function makeInstance( ctx : Context ) {
  93. ctx = ctx.clone(this);
  94. ctx.local3d = new LookAtObject(ctx.local3d, this);
  95. ctx.local3d.name = name;
  96. updateInstance(ctx);
  97. return ctx;
  98. }
  99. #if editor
  100. override function getHideProps() : HideProps {
  101. return {
  102. icon : "cog",
  103. name : "LookAt"
  104. };
  105. }
  106. override function edit(ctx:EditContext) {
  107. super.edit(ctx);
  108. var group = new hide.Element('
  109. <div class="group" name="LookAt">
  110. <dl>
  111. <dt>Target</dt><dd><select field="target"><option value="">-- Choose --</option></select></dd>
  112. </dl>
  113. </div>');
  114. group.append(hide.comp.PropsEditor.makePropsList([
  115. { name: "lockAxis", t: PVec(3), def: [1,0,0] }
  116. ]));
  117. var props = ctx.properties.add(group ,this, function(_) { trace(this.lockAxis); });
  118. var select = props.find("select");
  119. var opt = new hide.Element("<option>").attr("value", "camera").html("Camera");
  120. select.append(opt);
  121. for( path in ctx.getNamedObjects() ) {
  122. var parts = path.split(".");
  123. var opt = new hide.Element("<option>").attr("value", path).html([for( p in 1...parts.length ) "&nbsp; "].join("") + parts.pop());
  124. select.append(opt);
  125. }
  126. select.val(Reflect.field(this, select.attr("field")));
  127. }
  128. #end
  129. static var _ = Library.register("lookAt", LookAt);
  130. }