boxConvex.cpp
Engine/source/collision/boxConvex.cpp
Classes:
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