babylon.boneLookController.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. module BABYLON {
  2. export class BoneLookController {
  3. public static _tmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
  4. private static _tmpQuat = Quaternion.Identity();
  5. private static _tmpMat1 = Matrix.Identity();
  6. private static _tmpMat2 = Matrix.Identity();
  7. public target: Vector3;
  8. public mesh: AbstractMesh;
  9. public bone: Bone;
  10. public upAxis: Vector3 = Vector3.Up();
  11. public adjustYaw = 0;
  12. public adjustPitch = 0;
  13. public adjustRoll = 0;
  14. public slerpAmount = 1;
  15. private _minYaw:number;
  16. private _maxYaw:number;
  17. private _minPitch:number;
  18. private _maxPitch:number;
  19. private _minYawSin:number;
  20. private _minYawCos:number;
  21. private _maxYawSin:number;
  22. private _maxYawCos:number;
  23. private _minPitchTan:number;
  24. private _maxPitchTan:number;
  25. private _boneQuat:Quaternion = Quaternion.Identity();
  26. private _slerping = false;
  27. get minYaw():number{
  28. return this._minYaw;
  29. }
  30. set minYaw(value:number){
  31. this._minYaw = value;
  32. this._minYawSin = Math.sin(value);
  33. this._minYawCos = Math.cos(value);
  34. }
  35. get maxYaw():number{
  36. return this._maxYaw;
  37. }
  38. set maxYaw(value:number){
  39. this._maxYaw = value;
  40. this._maxYawSin = Math.sin(value);
  41. this._maxYawCos = Math.cos(value);
  42. }
  43. get minPitch():number{
  44. return this._minPitch;
  45. }
  46. set minPitch(value:number){
  47. this._minPitch = value;
  48. this._minPitchTan = Math.tan(value);
  49. }
  50. get maxPitch():number{
  51. return this._maxPitch;
  52. }
  53. set maxPitch(value:number){
  54. this._maxPitch = value;
  55. this._maxPitchTan = Math.tan(value);
  56. }
  57. constructor(mesh: AbstractMesh, bone: Bone, target: Vector3, options?: {adjustYaw?: number, adjustPitch?: number, adjustRoll?: number, slerpAmount?: number, maxYaw?:number, minYaw?:number, maxPitch?:number, minPitch?:number} ){
  58. this.mesh = mesh;
  59. this.bone = bone;
  60. this.target = target;
  61. if(options){
  62. if(options.adjustYaw){
  63. this.adjustYaw = options.adjustYaw;
  64. }
  65. if(options.adjustPitch){
  66. this.adjustPitch = options.adjustPitch;
  67. }
  68. if(options.adjustRoll){
  69. this.adjustRoll = options.adjustRoll;
  70. }
  71. if(options.maxYaw != undefined){
  72. this.maxYaw = options.maxYaw;
  73. }
  74. if(options.minYaw != undefined){
  75. this.minYaw = options.minYaw;
  76. }
  77. if(options.maxPitch != undefined){
  78. this.maxPitch = options.maxPitch;
  79. }
  80. if(options.minPitch != undefined){
  81. this.minPitch = options.minPitch;
  82. }
  83. if(options.slerpAmount != undefined){
  84. this.slerpAmount = options.slerpAmount;
  85. }
  86. }
  87. }
  88. public update (): void {
  89. var bone = this.bone;
  90. var target = this.target;
  91. var mat1 = BoneLookController._tmpMat1;
  92. var mat2 = BoneLookController._tmpMat2;
  93. var parentBone = bone.getParent();
  94. if(parentBone){
  95. if(this._maxPitch != undefined || this._minPitch != undefined){
  96. var localTarget = BoneLookController._tmpVecs[4];
  97. var _tmpVec5 = BoneLookController._tmpVecs[5];
  98. parentBone.getLocalPositionFromAbsoluteToRef(target, this.mesh, localTarget);
  99. bone.getPositionToRef(Space.LOCAL, null, _tmpVec5);
  100. localTarget.x -= _tmpVec5.x;
  101. localTarget.y -= _tmpVec5.y;
  102. localTarget.z -= _tmpVec5.z;
  103. var xzlen = Math.sqrt(localTarget.x*localTarget.x + localTarget.z*localTarget.z);
  104. var pitch = Math.atan2(localTarget.y, xzlen);
  105. if(pitch > this._maxPitch){
  106. localTarget.y = this._maxPitchTan*xzlen + _tmpVec5.y;
  107. parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
  108. target = localTarget;
  109. }else if(pitch < this._minPitch){
  110. localTarget.y = this._minPitchTan*xzlen + _tmpVec5.y;
  111. parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
  112. target = localTarget;
  113. }
  114. }
  115. if(this._maxYaw != undefined || this._minYaw != undefined){
  116. var localTarget = BoneLookController._tmpVecs[6];
  117. var _tmpVec7 = BoneLookController._tmpVecs[7];
  118. parentBone.getLocalPositionFromAbsoluteToRef(target, this.mesh, localTarget);
  119. bone.getPositionToRef(Space.LOCAL, null, _tmpVec7);
  120. localTarget.x -= _tmpVec7.x;
  121. localTarget.z -= _tmpVec7.z;
  122. var yaw = Math.atan2(localTarget.x, localTarget.z);
  123. var xzlen = Math.sqrt(localTarget.x*localTarget.x + localTarget.z*localTarget.z);
  124. if(yaw > this._maxYaw){
  125. localTarget.z = this._maxYawCos*xzlen;
  126. localTarget.x = this._maxYawSin*xzlen;
  127. parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
  128. target = localTarget;
  129. }else if(yaw < this._minYaw){
  130. localTarget.z = this._minYawCos*xzlen;
  131. localTarget.x = this._minYawSin*xzlen;
  132. parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
  133. target = localTarget;
  134. }
  135. }
  136. }
  137. var bonePos = BoneLookController._tmpVecs[0];
  138. var zaxis = BoneLookController._tmpVecs[1];
  139. var xaxis = BoneLookController._tmpVecs[2];
  140. var yaxis = BoneLookController._tmpVecs[3];
  141. var _tmpQuat = BoneLookController._tmpQuat;
  142. bone.getAbsolutePositionToRef(this.mesh, bonePos);
  143. target.subtractToRef(bonePos, zaxis);
  144. zaxis.normalize();
  145. Vector3.CrossToRef(this.upAxis, zaxis, xaxis);
  146. xaxis.normalize();
  147. Vector3.CrossToRef(zaxis, xaxis, yaxis);
  148. yaxis.normalize();
  149. Matrix.FromXYZAxesToRef(xaxis, yaxis, zaxis, mat1);
  150. if (this.adjustYaw || this.adjustPitch || this.adjustRoll) {
  151. Matrix.RotationYawPitchRollToRef(this.adjustYaw, this.adjustPitch, this.adjustRoll, mat2);
  152. mat2.multiplyToRef(mat1, mat1);
  153. }
  154. if (this.slerpAmount < 1) {
  155. if (!this._slerping) {
  156. this.bone.getRotationQuaternionToRef(Space.WORLD, this.mesh, this._boneQuat);
  157. }
  158. Quaternion.FromRotationMatrixToRef(mat1, _tmpQuat);
  159. Quaternion.SlerpToRef(this._boneQuat, _tmpQuat, this.slerpAmount, this._boneQuat);
  160. this.bone.setRotationQuaternion(this._boneQuat, Space.WORLD, this.mesh);
  161. this._slerping = true;
  162. } else {
  163. this.bone.setRotationMatrix(mat1, Space.WORLD, this.mesh);
  164. this._slerping = false;
  165. }
  166. }
  167. }
  168. }