Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2014
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.59 KB | None | 0 0
  1. package com.pigeoncoop.extensions;
  2.  
  3. import com.badlogic.gdx.Gdx;
  4. import com.badlogic.gdx.math.*;
  5. import com.badlogic.gdx.utils.Array;
  6.  
  7. /**
  8. * 3D transform system similar to Unity3D for libGDX
  9. * @author Tim Aksu - timur.s.aksu@gmail.com
  10. */
  11. public class Transform {
  12.  
  13. private static final String TAG = "Transform";
  14.  
  15. private Vector3 _localPosition;
  16. private Quaternion _localRotation;
  17. private Vector3 _localScale;
  18.  
  19. private Transform _parent;
  20. private Array<Transform> _children;
  21. private Matrix4 _localToWorldMatrix;
  22.  
  23. public Transform()
  24. {
  25. _localPosition = new Vector3(0,0,0);
  26. _localRotation = new Quaternion();
  27. _localScale = new Vector3(1,1,1);
  28.  
  29. _parent = null;
  30. _children = new Array<Transform>();
  31. _localToWorldMatrix = new Matrix4(_localPosition, _localRotation, _localScale);
  32. }
  33.  
  34. /**
  35. * Matrix that transforms a point from local space into world space
  36. * @return A copy of this transforms local to world matrix
  37. */
  38. public Matrix4 GetLocalToWorldMatrix()
  39. {
  40. return _localToWorldMatrix.cpy();
  41. }
  42.  
  43. /**
  44. * @return The current position in local space
  45. */
  46. public Vector3 GetLocalPosition()
  47. {
  48. return _localPosition.cpy();
  49. }
  50. /**
  51. * @return The current rotation in local space
  52. */
  53. public Quaternion GetLocalRotation()
  54. {
  55. return _localRotation.cpy();
  56. }
  57.  
  58. /**
  59. * @return The current scale in local space
  60. */
  61. public Vector3 GetLocalScale()
  62. {
  63. return _localScale.cpy();
  64. }
  65.  
  66. /**
  67. * @return The current position in world space
  68. */
  69. public Vector3 GetPosition()
  70. {
  71. Vector3 result = new Vector3();
  72. _localToWorldMatrix.getTranslation(result);
  73. return result;
  74. }
  75. /**
  76. * @return The current rotation in world space
  77. */
  78. public Quaternion GetRotation()
  79. {
  80. Quaternion result = new Quaternion();
  81. _localToWorldMatrix.getRotation(result,true);
  82. return result;
  83. }
  84.  
  85. /**
  86. * @return The current scale in world space
  87. */
  88. public Vector3 GetScale()
  89. {
  90. Vector3 result = new Vector3();
  91. _localToWorldMatrix.getScale(result);
  92. return result;
  93. }
  94.  
  95. /**
  96. * @param position The new local position
  97. */
  98. public void SetLocalPosition(Vector3 position)
  99. {
  100. _localPosition.set(position);
  101. UpdateMatricies();
  102. }
  103.  
  104. /**
  105. * @param rotation The new local rotation
  106. */
  107. public void SetLocalRotation(Quaternion rotation)
  108. {
  109. _localRotation.set(rotation);
  110. UpdateMatricies();
  111. }
  112.  
  113. /**
  114. * @param scale The new local scale
  115. */
  116. public void SetLocalScale(Vector3 scale)
  117. {
  118. _localScale.set(scale);
  119. UpdateMatricies();
  120. }
  121.  
  122. /**
  123. * @param position The world position to match in local space
  124. */
  125. public void SetPosition(Vector3 position)
  126. {
  127. if(_parent == null)
  128. _localPosition.set(position);
  129. else
  130. _localPosition.set(position.mul(_parent.GetLocalToWorldMatrix().inv()));
  131.  
  132. UpdateMatricies();
  133. }
  134.  
  135. /**
  136. * @param rotation The world rotation to match in local space
  137. */
  138. public void SetRotation(Quaternion rotation)
  139. {
  140. if(_parent == null)
  141. {
  142. _localRotation.set(rotation);
  143. }
  144. else
  145. {
  146. Quaternion temp = new Quaternion();
  147. _localRotation.set(rotation.mul(_parent.GetLocalToWorldMatrix().inv().getRotation(temp,true)));
  148. }
  149.  
  150. UpdateMatricies();
  151. }
  152.  
  153. /**
  154. * @param scale The world scale to match in local space
  155. */
  156. public void SetScale(Vector3 scale)
  157. {
  158. if(_parent == null)
  159. _localScale.set(scale);
  160. else
  161. _localScale.set(scale.mul(_parent.GetLocalToWorldMatrix().inv()));
  162.  
  163. UpdateMatricies();
  164. }
  165.  
  166. /**
  167. * @return Current Root of the Transform hierarchy
  168. * that this Transform exists in
  169. */
  170. public Transform GetRoot()
  171. {
  172. if(_parent == null)
  173. return this;
  174. else
  175. return _parent.GetRoot();
  176. }
  177.  
  178. /**
  179. * @param target The transform to check
  180. * @return True if this transform is a child of target (directly or indirectly)
  181. */
  182. public boolean IsChildOf(Transform target)
  183. {
  184. boolean isChild = false;
  185.  
  186. for (Transform child: target._children)
  187. {
  188. if(child == this)
  189. isChild = true;
  190. else
  191. isChild = IsChildOf(child);
  192.  
  193. if(isChild)
  194. break;
  195. }
  196.  
  197. return isChild;
  198. }
  199.  
  200. /**
  201. * @return The current parent (null if no parent)
  202. */
  203. public Transform GetParent()
  204. {
  205. return _parent;
  206. }
  207.  
  208. /**
  209. * Sets the parent. Also modifies the transform
  210. * to match its world space transform in its new local space.
  211. *
  212. * Calls RemoveParent if current parent is not null.
  213. *
  214. * Circular parenting will log an error and not do anything.
  215. * This will result in an error: A->B->C->A
  216. * @param to The transform to parent to
  217. */
  218. public void SetParent(Transform to)
  219. {
  220. if(to.IsChildOf(this))
  221. {
  222. Gdx.app.error(TAG, "Prevented circular parenting");
  223. return;
  224. }
  225.  
  226. if(_parent != null)
  227. RemoveParent();
  228.  
  229. Matrix4 parentWorldToLocalMatrix = to.GetLocalToWorldMatrix().inv().mul(GetLocalToWorldMatrix());;
  230.  
  231. parentWorldToLocalMatrix.getTranslation(_localPosition);
  232. parentWorldToLocalMatrix.getRotation(_localRotation,true);
  233. parentWorldToLocalMatrix.getScale(_localScale);
  234.  
  235. to._children.add(this);
  236. _parent = to;
  237. to.UpdateMatricies();
  238.  
  239. }
  240.  
  241. /**
  242. * Removed the current parent. Also modifies the transform
  243. * to match its old local space transform in world space
  244. */
  245. public void RemoveParent()
  246. {
  247.  
  248. if(_parent == null)
  249. {
  250. return;
  251. }
  252. else
  253. {
  254. _localPosition = GetPosition();
  255. _localRotation = GetRotation();
  256. _localScale = GetScale();
  257.  
  258. _parent._children.removeValue(this, true);
  259. _parent = null;
  260.  
  261. UpdateMatricies();
  262. }
  263. }
  264.  
  265. private void UpdateMatricies()
  266. {
  267. _localToWorldMatrix = new Matrix4(_localPosition, _localRotation, _localScale);
  268.  
  269. if(_parent != null)
  270. {
  271. _localToWorldMatrix = new Matrix4(_parent._localToWorldMatrix).mul(_localToWorldMatrix);
  272. }
  273.  
  274. for(Transform child: _children)
  275. {
  276. child.UpdateMatricies();
  277. }
  278. }
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement