boxConvex.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "math/mMath.h"
  24. #include "T3D/gameBase/gameBase.h"
  25. #include "collision/boxConvex.h"
  26. #include "abstractPolyList.h"
  27. //----------------------------------------------------------------------------
  28. static struct Corner {
  29. S32 a,b,c;
  30. S32 ab,ac,bc;
  31. } sCorner[] =
  32. {
  33. { 1,2,4, 4,0,1 },
  34. { 0,3,5, 4,0,3 },
  35. { 0,3,6, 4,1,2 },
  36. { 1,2,7, 4,3,2 },
  37. { 0,5,6, 0,1,5 },
  38. { 1,4,7, 0,3,5 },
  39. { 2,4,7, 1,2,5 },
  40. { 3,5,6, 3,2,5 },
  41. };
  42. static struct Face {
  43. S32 vertex[4];
  44. S32 axis;
  45. bool flip;
  46. } sFace[] =
  47. {
  48. { {0,4,5,1}, 1,true },
  49. { {0,2,6,4}, 0,true },
  50. { {3,7,6,2}, 1,false },
  51. { {3,1,5,7}, 0,false },
  52. { {0,1,3,2}, 2,true },
  53. { {4,6,7,5}, 2,false },
  54. };
  55. Point3F BoxConvex::support(const VectorF& v) const
  56. {
  57. Point3F p = mCenter;
  58. p.x += (v.x >= 0)? mSize.x: -mSize.x;
  59. p.y += (v.y >= 0)? mSize.y: -mSize.y;
  60. p.z += (v.z >= 0)? mSize.z: -mSize.z;
  61. return p;
  62. }
  63. Point3F BoxConvex::getVertex(S32 v)
  64. {
  65. Point3F p = mCenter;
  66. p.x += (v & 1)? mSize.x: -mSize.x;
  67. p.y += (v & 2)? mSize.y: -mSize.y;
  68. p.z += (v & 4)? mSize.z: -mSize.z;
  69. return p;
  70. }
  71. inline bool isOnPlane(const Point3F& p,PlaneF& plane)
  72. {
  73. F32 dist = mDot(plane,p) + plane.d;
  74. return dist < 0.1 && dist > -0.1;
  75. }
  76. void BoxConvex::getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf)
  77. {
  78. cf->material = 0;
  79. cf->mObject = mObject;
  80. S32 v = 0;
  81. v += (n.x >= 0)? 1: 0;
  82. v += (n.y >= 0)? 2: 0;
  83. v += (n.z >= 0)? 4: 0;
  84. PlaneF plane;
  85. plane.set(getVertex(v),n);
  86. // Emit vertex and edge
  87. S32 mask = 0;
  88. Corner& corner = sCorner[v];
  89. mask |= isOnPlane(getVertex(corner.a),plane)? 1: 0;
  90. mask |= isOnPlane(getVertex(corner.b),plane)? 2: 0;
  91. mask |= isOnPlane(getVertex(corner.c),plane)? 4: 0;
  92. switch(mask) {
  93. case 0: {
  94. cf->mVertexList.increment();
  95. mat.mulP(getVertex(v),&cf->mVertexList.last());
  96. break;
  97. }
  98. case 1:
  99. emitEdge(v,corner.a,mat,cf);
  100. break;
  101. case 2:
  102. emitEdge(v,corner.b,mat,cf);
  103. break;
  104. case 4:
  105. emitEdge(v,corner.c,mat,cf);
  106. break;
  107. case 1 | 2:
  108. emitFace(corner.ab,mat,cf);
  109. break;
  110. case 2 | 4:
  111. emitFace(corner.bc,mat,cf);
  112. break;
  113. case 1 | 4:
  114. emitFace(corner.ac,mat,cf);
  115. break;
  116. }
  117. }
  118. void BoxConvex::getPolyList(AbstractPolyList* list)
  119. {
  120. list->setTransform(&getTransform(), getScale());
  121. list->setObject(getObject());
  122. U32 base = list->addPoint(mCenter + Point3F(-mSize.x, -mSize.y, -mSize.z));
  123. list->addPoint(mCenter + Point3F( mSize.x, -mSize.y, -mSize.z));
  124. list->addPoint(mCenter + Point3F(-mSize.x, mSize.y, -mSize.z));
  125. list->addPoint(mCenter + Point3F( mSize.x, mSize.y, -mSize.z));
  126. list->addPoint(mCenter + Point3F(-mSize.x, -mSize.y, mSize.z));
  127. list->addPoint(mCenter + Point3F( mSize.x, -mSize.y, mSize.z));
  128. list->addPoint(mCenter + Point3F(-mSize.x, mSize.y, mSize.z));
  129. list->addPoint(mCenter + Point3F( mSize.x, mSize.y, mSize.z));
  130. for (U32 i = 0; i < 6; i++) {
  131. list->begin(0, i);
  132. list->vertex(base + sFace[i].vertex[0]);
  133. list->vertex(base + sFace[i].vertex[1]);
  134. list->vertex(base + sFace[i].vertex[2]);
  135. list->vertex(base + sFace[i].vertex[3]);
  136. list->plane(base + sFace[i].vertex[0],
  137. base + sFace[i].vertex[1],
  138. base + sFace[i].vertex[2]);
  139. list->end();
  140. }
  141. }
  142. void BoxConvex::emitEdge(S32 v1,S32 v2,const MatrixF& mat,ConvexFeature* cf)
  143. {
  144. S32 vc = cf->mVertexList.size();
  145. cf->mVertexList.increment(2);
  146. Point3F *vp = cf->mVertexList.begin();
  147. mat.mulP(getVertex(v1),&vp[vc]);
  148. mat.mulP(getVertex(v2),&vp[vc + 1]);
  149. cf->mEdgeList.increment();
  150. ConvexFeature::Edge& edge = cf->mEdgeList.last();
  151. edge.vertex[0] = vc;
  152. edge.vertex[1] = vc + 1;
  153. }
  154. void BoxConvex::emitFace(S32 fi,const MatrixF& mat,ConvexFeature* cf)
  155. {
  156. Face& face = sFace[fi];
  157. // Emit vertices
  158. S32 vc = cf->mVertexList.size();
  159. cf->mVertexList.increment(4);
  160. Point3F *vp = cf->mVertexList.begin();
  161. for (S32 v = 0; v < 4; v++)
  162. mat.mulP(getVertex(face.vertex[v]),&vp[vc + v]);
  163. // Emit edges
  164. cf->mEdgeList.increment(4);
  165. ConvexFeature::Edge* edge = cf->mEdgeList.end() - 4;
  166. for (S32 e = 0; e < 4; e++) {
  167. edge[e].vertex[0] = vc + e;
  168. edge[e].vertex[1] = vc + ((e + 1) & 3);
  169. }
  170. // Emit 2 triangle faces
  171. cf->mFaceList.increment(2);
  172. ConvexFeature::Face* ef = cf->mFaceList.end() - 2;
  173. mat.getColumn(face.axis,&ef->normal);
  174. if (face.flip)
  175. ef[0].normal.neg();
  176. ef[1].normal = ef[0].normal;
  177. ef[1].vertex[0] = ef[0].vertex[0] = vc;
  178. ef[1].vertex[1] = ef[0].vertex[2] = vc + 2;
  179. ef[0].vertex[1] = vc + 1;
  180. ef[1].vertex[2] = vc + 3;
  181. }
  182. const MatrixF& OrthoBoxConvex::getTransform() const
  183. {
  184. Point3F translation;
  185. Parent::getTransform().getColumn(3, &translation);
  186. mOrthoMatrixCache.setColumn(3, translation);
  187. return mOrthoMatrixCache;
  188. }