PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmath/xform.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 315 lines | 247 code | 36 blank | 32 comment | 26 complexity | 113f537a2b87c0845a39ece666bb0094 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file xform.h
  3. *
  4. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #ifndef LL_XFORM_H
  26. #define LL_XFORM_H
  27. #include "v3math.h"
  28. #include "m4math.h"
  29. #include "llquaternion.h"
  30. const F32 MAX_OBJECT_Z = 4096.f; // should match REGION_HEIGHT_METERS, Pre-havok4: 768.f
  31. const F32 MIN_OBJECT_Z = -256.f;
  32. const F32 DEFAULT_MAX_PRIM_SCALE = 64.f;
  33. const F32 DEFAULT_MAX_PRIM_SCALE_NO_MESH = 10.f;
  34. const F32 MIN_PRIM_SCALE = 0.01f;
  35. const F32 MAX_PRIM_SCALE = 65536.f; // something very high but not near FLT_MAX
  36. class LLXform
  37. {
  38. protected:
  39. LLVector3 mPosition;
  40. LLQuaternion mRotation;
  41. LLVector3 mScale;
  42. //RN: TODO: move these world transform members to LLXformMatrix
  43. // as they are *never* updated or accessed in the base class
  44. LLVector3 mWorldPosition;
  45. LLQuaternion mWorldRotation;
  46. LLXform* mParent;
  47. U32 mChanged;
  48. BOOL mScaleChildOffset;
  49. public:
  50. typedef enum e_changed_flags
  51. {
  52. UNCHANGED = 0x00,
  53. TRANSLATED = 0x01,
  54. ROTATED = 0x02,
  55. SCALED = 0x04,
  56. SHIFTED = 0x08,
  57. GEOMETRY = 0x10,
  58. TEXTURE = 0x20,
  59. MOVED = TRANSLATED|ROTATED|SCALED,
  60. SILHOUETTE = 0x40,
  61. ALL_CHANGED = 0x7f
  62. }EChangedFlags;
  63. void init()
  64. {
  65. mParent = NULL;
  66. mChanged = UNCHANGED;
  67. mPosition.setVec(0,0,0);
  68. mRotation.loadIdentity();
  69. mScale. setVec(1,1,1);
  70. mWorldPosition.clearVec();
  71. mWorldRotation.loadIdentity();
  72. mScaleChildOffset = FALSE;
  73. }
  74. LLXform();
  75. virtual ~LLXform();
  76. void getLocalMat4(LLMatrix4 &mat) const { mat.initAll(mScale, mRotation, mPosition); }
  77. inline BOOL setParent(LLXform *parent);
  78. inline void setPosition(const LLVector3& pos);
  79. inline void setPosition(const F32 x, const F32 y, const F32 z);
  80. inline void setPositionX(const F32 x);
  81. inline void setPositionY(const F32 y);
  82. inline void setPositionZ(const F32 z);
  83. inline void addPosition(const LLVector3& pos);
  84. inline void setScale(const LLVector3& scale);
  85. inline void setScale(const F32 x, const F32 y, const F32 z);
  86. inline void setRotation(const LLQuaternion& rot);
  87. inline void setRotation(const F32 x, const F32 y, const F32 z);
  88. inline void setRotation(const F32 x, const F32 y, const F32 z, const F32 s);
  89. // Above functions must be inline for speed, but also
  90. // need to emit warnings. llwarns causes inline LLError::CallSite
  91. // static objects that make more work for the linker.
  92. // Avoid inline llwarns by calling this function.
  93. void warn(const char* const msg);
  94. void setChanged(const U32 bits) { mChanged |= bits; }
  95. BOOL isChanged() const { return mChanged; }
  96. BOOL isChanged(const U32 bits) const { return mChanged & bits; }
  97. void clearChanged() { mChanged = 0; }
  98. void clearChanged(U32 bits) { mChanged &= ~bits; }
  99. void setScaleChildOffset(BOOL scale) { mScaleChildOffset = scale; }
  100. BOOL getScaleChildOffset() { return mScaleChildOffset; }
  101. LLXform* getParent() const { return mParent; }
  102. LLXform* getRoot() const;
  103. virtual BOOL isRoot() const;
  104. virtual BOOL isRootEdit() const;
  105. const LLVector3& getPosition() const { return mPosition; }
  106. const LLVector3& getScale() const { return mScale; }
  107. const LLQuaternion& getRotation() const { return mRotation; }
  108. const LLVector3& getPositionW() const { return mWorldPosition; }
  109. const LLQuaternion& getWorldRotation() const { return mWorldRotation; }
  110. const LLVector3& getWorldPosition() const { return mWorldPosition; }
  111. };
  112. class LLXformMatrix : public LLXform
  113. {
  114. public:
  115. LLXformMatrix() : LLXform() {};
  116. virtual ~LLXformMatrix();
  117. const LLMatrix4& getWorldMatrix() const { return mWorldMatrix; }
  118. void setWorldMatrix (const LLMatrix4& mat) { mWorldMatrix = mat; }
  119. void init()
  120. {
  121. mWorldMatrix.setIdentity();
  122. mMin.clearVec();
  123. mMax.clearVec();
  124. LLXform::init();
  125. }
  126. void update();
  127. void updateMatrix(BOOL update_bounds = TRUE);
  128. void getMinMax(LLVector3& min,LLVector3& max) const;
  129. protected:
  130. LLMatrix4 mWorldMatrix;
  131. LLVector3 mMin;
  132. LLVector3 mMax;
  133. };
  134. BOOL LLXform::setParent(LLXform* parent)
  135. {
  136. // Validate and make sure we're not creating a loop
  137. if (parent == mParent)
  138. {
  139. return TRUE;
  140. }
  141. if (parent)
  142. {
  143. LLXform *cur_par = parent->mParent;
  144. while (cur_par)
  145. {
  146. if (cur_par == this)
  147. {
  148. //warn("LLXform::setParent Creating loop when setting parent!");
  149. return FALSE;
  150. }
  151. cur_par = cur_par->mParent;
  152. }
  153. }
  154. mParent = parent;
  155. return TRUE;
  156. }
  157. void LLXform::setPosition(const LLVector3& pos)
  158. {
  159. setChanged(TRANSLATED);
  160. if (pos.isFinite())
  161. mPosition = pos;
  162. else
  163. {
  164. mPosition.clearVec();
  165. warn("Non Finite in LLXform::setPosition(LLVector3)");
  166. }
  167. }
  168. void LLXform::setPosition(const F32 x, const F32 y, const F32 z)
  169. {
  170. setChanged(TRANSLATED);
  171. if (llfinite(x) && llfinite(y) && llfinite(z))
  172. mPosition.setVec(x,y,z);
  173. else
  174. {
  175. mPosition.clearVec();
  176. warn("Non Finite in LLXform::setPosition(F32,F32,F32)");
  177. }
  178. }
  179. void LLXform::setPositionX(const F32 x)
  180. {
  181. setChanged(TRANSLATED);
  182. if (llfinite(x))
  183. mPosition.mV[VX] = x;
  184. else
  185. {
  186. mPosition.mV[VX] = 0.f;
  187. warn("Non Finite in LLXform::setPositionX");
  188. }
  189. }
  190. void LLXform::setPositionY(const F32 y)
  191. {
  192. setChanged(TRANSLATED);
  193. if (llfinite(y))
  194. mPosition.mV[VY] = y;
  195. else
  196. {
  197. mPosition.mV[VY] = 0.f;
  198. warn("Non Finite in LLXform::setPositionY");
  199. }
  200. }
  201. void LLXform::setPositionZ(const F32 z)
  202. {
  203. setChanged(TRANSLATED);
  204. if (llfinite(z))
  205. mPosition.mV[VZ] = z;
  206. else
  207. {
  208. mPosition.mV[VZ] = 0.f;
  209. warn("Non Finite in LLXform::setPositionZ");
  210. }
  211. }
  212. void LLXform::addPosition(const LLVector3& pos)
  213. {
  214. setChanged(TRANSLATED);
  215. if (pos.isFinite())
  216. mPosition += pos;
  217. else
  218. warn("Non Finite in LLXform::addPosition");
  219. }
  220. void LLXform::setScale(const LLVector3& scale)
  221. {
  222. setChanged(SCALED);
  223. if (scale.isFinite())
  224. mScale = scale;
  225. else
  226. {
  227. mScale.setVec(1.f, 1.f, 1.f);
  228. warn("Non Finite in LLXform::setScale");
  229. }
  230. }
  231. void LLXform::setScale(const F32 x, const F32 y, const F32 z)
  232. {
  233. setChanged(SCALED);
  234. if (llfinite(x) && llfinite(y) && llfinite(z))
  235. mScale.setVec(x,y,z);
  236. else
  237. {
  238. mScale.setVec(1.f, 1.f, 1.f);
  239. warn("Non Finite in LLXform::setScale");
  240. }
  241. }
  242. void LLXform::setRotation(const LLQuaternion& rot)
  243. {
  244. setChanged(ROTATED);
  245. if (rot.isFinite())
  246. mRotation = rot;
  247. else
  248. {
  249. mRotation.loadIdentity();
  250. warn("Non Finite in LLXform::setRotation");
  251. }
  252. }
  253. void LLXform::setRotation(const F32 x, const F32 y, const F32 z)
  254. {
  255. setChanged(ROTATED);
  256. if (llfinite(x) && llfinite(y) && llfinite(z))
  257. {
  258. mRotation.setQuat(x,y,z);
  259. }
  260. else
  261. {
  262. mRotation.loadIdentity();
  263. warn("Non Finite in LLXform::setRotation");
  264. }
  265. }
  266. void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
  267. {
  268. setChanged(ROTATED);
  269. if (llfinite(x) && llfinite(y) && llfinite(z) && llfinite(s))
  270. {
  271. mRotation.mQ[VX] = x; mRotation.mQ[VY] = y; mRotation.mQ[VZ] = z; mRotation.mQ[VS] = s;
  272. }
  273. else
  274. {
  275. mRotation.loadIdentity();
  276. warn("Non Finite in LLXform::setRotation");
  277. }
  278. }
  279. #endif