GeomTransformGroup.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* ************************************************************************ */
  2. /*
  3. grouped and transformed geometry functions
  4. author: Tim Schmidt [email protected]
  5. */
  6. #include <ode/common.h>
  7. #include <ode/geom.h>
  8. #include <ode/rotation.h>
  9. #include <ode/odemath.h>
  10. #include <ode/memory.h>
  11. #include <ode/misc.h>
  12. #include <ode/objects.h>
  13. #include <ode/matrix.h>
  14. #include <ode/GeomTransformGroup.h>
  15. #include "objects.h"
  16. #include "array.h"
  17. #include "geom_internal.h"
  18. // given a pointer `p' to a dContactGeom, return the dContactGeom at
  19. // p + skip bytes.
  20. #define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip)))
  21. // ############################################################################
  22. int dGeomTransformGroupClass = -1;
  23. // ############################################################################
  24. struct dxGeomTransformGroup {
  25. dArray<dxGeom*> parts; // all the geoms that make up the group
  26. dVector3 relativePosition;
  27. dMatrix3 relativeRotation;
  28. };
  29. // ############################################################################
  30. void dGeomTransformGroupSetRelativePosition (dxGeom *g, dReal x, dReal y, dReal z)
  31. {
  32. dAASSERT (g);
  33. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  34. transformGroup->relativePosition[0] = x;
  35. transformGroup->relativePosition[1] = y;
  36. transformGroup->relativePosition[2] = z;
  37. }
  38. // ############################################################################
  39. void dGeomTransformGroupSetRelativeRotation (dxGeom *g, const dMatrix3 R)
  40. {
  41. dAASSERT (g);
  42. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  43. memcpy (transformGroup->relativeRotation,R,sizeof(dMatrix3));
  44. }
  45. // ############################################################################
  46. const dReal * dGeomTransformGroupGetRelativePosition (dxGeom *g)
  47. {
  48. dAASSERT (g);
  49. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  50. return transformGroup->relativePosition;
  51. }
  52. // ############################################################################
  53. const dReal * dGeomTransformGroupGetRelativeRotation (dxGeom *g)
  54. {
  55. dAASSERT (g);
  56. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  57. return transformGroup->relativeRotation;
  58. }
  59. // ############################################################################
  60. static void computeFinalTransformation (const dxGeom *tg, const dxGeom *part)
  61. {
  62. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(tg);
  63. dMULTIPLY0_331 (part->pos,tg->R,transformGroup->relativePosition);
  64. part->pos[0] += tg->pos[0];
  65. part->pos[1] += tg->pos[1];
  66. part->pos[2] += tg->pos[2];
  67. dMULTIPLY0_333 (part->R,tg->R,transformGroup->relativeRotation);
  68. }
  69. // ############################################################################
  70. int dCollideTransformGroup (const dxGeom *o1, const dxGeom *o2, int flags,
  71. dContactGeom *contact, int skip)
  72. {
  73. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(o1);
  74. if (transformGroup->parts.size() == 0)
  75. {
  76. return 0;
  77. }
  78. int numleft = flags & NUMC_MASK;
  79. if (numleft == 0) numleft = 1;
  80. flags &= ~NUMC_MASK;
  81. int num=0, i=0;
  82. while (i < transformGroup->parts.size() && numleft > 0)
  83. {
  84. dUASSERT (transformGroup->parts[i]->spaceid==0,
  85. "GeomTransformGroup encapsulated object must not be in a space");
  86. dUASSERT (transformGroup->parts[i]->body==0,
  87. "GeomTransformGroup encapsulated object must not be attached to a body");
  88. if (!o1->space_aabb)
  89. {
  90. computeFinalTransformation (o1, transformGroup->parts[i]);
  91. }
  92. dxBody *bodyBackup = transformGroup->parts[i]->body;
  93. transformGroup->parts[i]->body = o1->body;
  94. int n = dCollide (transformGroup->parts[i],const_cast<dxGeom*>(o2),
  95. flags | numleft,contact,skip);
  96. transformGroup->parts[i]->body = bodyBackup;
  97. contact = CONTACT (contact,skip*n);
  98. numleft -= n;
  99. num += n;
  100. i++;
  101. }
  102. return num;
  103. }
  104. // ############################################################################
  105. static dColliderFn * dGeomTransformGroupColliderFn (int num)
  106. {
  107. return (dColliderFn *) &dCollideTransformGroup;
  108. }
  109. // ############################################################################
  110. static void dGeomTransformGroupAABB (dxGeom *geom, dReal aabb[6])
  111. {
  112. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom);
  113. aabb[0] = dInfinity;
  114. aabb[1] = -dInfinity;
  115. aabb[2] = dInfinity;
  116. aabb[3] = -dInfinity;
  117. aabb[4] = dInfinity;
  118. aabb[5] = -dInfinity;
  119. int i,j;
  120. for (i=0; i < transformGroup->parts.size(); i++)
  121. {
  122. computeFinalTransformation (geom, transformGroup->parts[i]);
  123. dReal aabb2[6];
  124. transformGroup->parts[i]->_class->aabb (transformGroup->parts[i],aabb2);
  125. for (j=0; j<6; j += 2) if (aabb2[j] < aabb[j]) aabb[j] = aabb2[j];
  126. for (j=1; j<6; j += 2) if (aabb2[j] > aabb[j]) aabb[j] = aabb2[j];
  127. }
  128. }
  129. // ############################################################################
  130. static void dGeomTransformGroupDtor (dxGeom *geom)
  131. {
  132. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom);
  133. transformGroup->parts.~dArray();
  134. }
  135. // ############################################################################
  136. dxGeom *dCreateGeomTransformGroup (dSpaceID space)
  137. {
  138. if (dGeomTransformGroupClass == -1) {
  139. dGeomClass c;
  140. c.bytes = sizeof (dxGeomTransformGroup);
  141. c.collider = &dGeomTransformGroupColliderFn;
  142. c.aabb = &dGeomTransformGroupAABB;
  143. c.aabb_test = 0;
  144. c.dtor = dGeomTransformGroupDtor;
  145. dGeomTransformGroupClass = dCreateGeomClass (&c);
  146. }
  147. dxGeom *g = dCreateGeom (dGeomTransformGroupClass);
  148. if (space)
  149. {
  150. dSpaceAdd (space,g);
  151. }
  152. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  153. transformGroup->parts.constructor();
  154. dSetZero (transformGroup->relativePosition,4);
  155. dRSetIdentity (transformGroup->relativeRotation);
  156. return g;
  157. }
  158. // ############################################################################
  159. void dGeomTransformGroupAddGeom (dxGeom *g, dxGeom *obj)
  160. {
  161. dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
  162. "argument not a geom TransformGroup");
  163. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  164. transformGroup->parts.push (obj);
  165. }
  166. // ############################################################################
  167. void dGeomTransformGroupRemoveGeom (dxGeom *g, dxGeom *obj)
  168. {
  169. dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
  170. "argument not a geom TransformGroup");
  171. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  172. for (int i=0; i < transformGroup->parts.size(); i++) {
  173. if (transformGroup->parts[i] == obj) {
  174. transformGroup->parts.remove (i);
  175. return;
  176. }
  177. }
  178. }
  179. // ############################################################################
  180. dxGeom * dGeomTransformGroupGetGeom (dxGeom *g, int i)
  181. {
  182. dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
  183. "argument not a geom TransformGroup");
  184. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  185. dAASSERT (i >= 0 && i < transformGroup->parts.size());
  186. return transformGroup->parts[i];
  187. }
  188. // ############################################################################
  189. int dGeomTransformGroupGetNumGeoms (dxGeom *g)
  190. {
  191. dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
  192. "argument not a geom TransformGroup");
  193. dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
  194. return transformGroup->parts.size();
  195. }