boxConvex.cpp

Engine/source/collision/boxConvex.cpp

More...

Classes:

class
class

Public Variables

struct Corner
struct Face
sFace []

Public Functions

bool
isOnPlane(const Point3F & p, PlaneF & plane)

Detailed Description

Public Variables

struct Corner sCorner []
struct Face sFace []

Public Functions

isOnPlane(const Point3F & p, PlaneF & plane)

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