Open Dynamics Engine
|
00001 // dHeightfield Collider 00002 // Martijn Buijs 2006 http://home.planet.nl/~buijs512/ 00003 // Based on Terrain & Cone contrib by: 00004 // Benoit CHAPEROT 2003-2004 http://www.jstarlab.com 00005 00006 #ifndef _DHEIGHTFIELD_H_ 00007 #define _DHEIGHTFIELD_H_ 00008 //------------------------------------------------------------------------------ 00009 00010 #include <ode/common.h> 00011 #include "collision_kernel.h" 00012 00013 00014 #define HEIGHTFIELDMAXCONTACTPERCELL 10 00015 00016 00017 class HeightFieldVertex; 00018 class HeightFieldEdge; 00019 class HeightFieldTriangle; 00020 00021 // 00022 // dxHeightfieldData 00023 // 00024 // Heightfield Data structure 00025 // 00026 struct dxHeightfieldData 00027 { 00028 dReal m_fWidth; // World space heightfield dimension on X axis 00029 dReal m_fDepth; // World space heightfield dimension on Z axis 00030 dReal m_fSampleWidth; // Vertex spacing on X axis edge (== m_vWidth / (m_nWidthSamples-1)) 00031 dReal m_fSampleDepth; // Vertex spacing on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) 00032 dReal m_fSampleZXAspect; // Relation of Z axis spacing to X axis spacing (== m_fSampleDepth / m_fSampleWidth) 00033 dReal m_fInvSampleWidth; // Cache of inverse Vertex count on X axis edge (== m_vWidth / (m_nWidthSamples-1)) 00034 dReal m_fInvSampleDepth; // Cache of inverse Vertex count on Z axis edge (== m_vDepth / (m_nDepthSamples-1)) 00035 00036 dReal m_fHalfWidth; // Cache of half of m_fWidth 00037 dReal m_fHalfDepth; // Cache of half of m_fDepth 00038 00039 dReal m_fMinHeight; // Min sample height value (scaled and offset) 00040 dReal m_fMaxHeight; // Max sample height value (scaled and offset) 00041 dReal m_fThickness; // Surface thickness (added to bottom AABB) 00042 dReal m_fScale; // Sample value multiplier 00043 dReal m_fOffset; // Vertical sample offset 00044 00045 int m_nWidthSamples; // Vertex count on X axis edge (number of samples) 00046 int m_nDepthSamples; // Vertex count on Z axis edge (number of samples) 00047 int m_bCopyHeightData; // Do we own the sample data? 00048 int m_bWrapMode; // Heightfield wrapping mode (0=finite, 1=infinite) 00049 int m_nGetHeightMode; // GetHeight mode ( 0=callback, 1=byte, 2=short, 3=float ) 00050 00051 const void* m_pHeightData; // Sample data array 00052 void* m_pUserData; // Callback user data 00053 00054 dContactGeom m_contacts[HEIGHTFIELDMAXCONTACTPERCELL]; 00055 00056 dHeightfieldGetHeight* m_pGetHeightCallback; // Callback pointer. 00057 00058 dxHeightfieldData(); 00059 ~dxHeightfieldData(); 00060 00061 void SetData( int nWidthSamples, int nDepthSamples, 00062 dReal fWidth, dReal fDepth, 00063 dReal fScale, dReal fOffset, 00064 dReal fThickness, int bWrapMode ); 00065 00066 void ComputeHeightBounds(); 00067 00068 bool IsOnHeightfield2 ( const HeightFieldVertex * const CellCorner, 00069 const dReal * const pos, const bool isABC) const; 00070 00071 dReal GetHeight(int x, int z); 00072 dReal GetHeight(dReal x, dReal z); 00073 00074 }; 00075 00076 typedef int HeightFieldVertexCoords[2]; 00077 00078 class HeightFieldVertex 00079 { 00080 public: 00081 HeightFieldVertex(){}; 00082 00083 dVector3 vertex; 00084 HeightFieldVertexCoords coords; 00085 bool state; 00086 }; 00087 00088 class HeightFieldEdge 00089 { 00090 public: 00091 HeightFieldEdge(){}; 00092 00093 HeightFieldVertex *vertices[2]; 00094 }; 00095 00096 class HeightFieldTriangle 00097 { 00098 public: 00099 HeightFieldTriangle(){}; 00100 00101 inline void setMinMax() 00102 { 00103 maxAAAB = vertices[0]->vertex[1] > vertices[1]->vertex[1] ? vertices[0]->vertex[1] : vertices[1]->vertex[1]; 00104 maxAAAB = vertices[2]->vertex[1] > maxAAAB ? vertices[2]->vertex[1] : maxAAAB; 00105 }; 00106 00107 HeightFieldVertex *vertices[3]; 00108 dReal planeDef[4]; 00109 dReal maxAAAB; 00110 00111 bool isUp; 00112 bool state; 00113 }; 00114 00115 class HeightFieldPlane 00116 { 00117 public: 00118 HeightFieldPlane(): 00119 trianglelist(0), 00120 trianglelistReservedSize(0), 00121 trianglelistCurrentSize(0) 00122 { 00123 00124 }; 00125 ~HeightFieldPlane() 00126 { 00127 delete [] trianglelist; 00128 }; 00129 00130 inline void setMinMax() 00131 { 00132 const size_t asize = trianglelistCurrentSize; 00133 if (asize > 0) 00134 { 00135 maxAAAB = trianglelist[0]->maxAAAB; 00136 for (size_t k = 1; asize > k; k++) 00137 { 00138 if (trianglelist[k]->maxAAAB > maxAAAB) 00139 maxAAAB = trianglelist[k]->maxAAAB; 00140 } 00141 } 00142 }; 00143 00144 void resetTriangleListSize(const size_t newSize) 00145 { 00146 if (trianglelistReservedSize < newSize) 00147 { 00148 delete [] trianglelist; 00149 trianglelistReservedSize = newSize; 00150 trianglelist = new HeightFieldTriangle *[newSize]; 00151 } 00152 trianglelistCurrentSize = 0; 00153 } 00154 00155 void addTriangle(HeightFieldTriangle *tri) 00156 { 00157 dIASSERT(trianglelistCurrentSize < trianglelistReservedSize); 00158 00159 trianglelist[trianglelistCurrentSize++] = tri; 00160 } 00161 00162 HeightFieldTriangle **trianglelist; 00163 size_t trianglelistReservedSize; 00164 size_t trianglelistCurrentSize; 00165 00166 dReal maxAAAB; 00167 dReal planeDef[4]; 00168 }; 00169 00170 // 00171 // dxHeightfield 00172 // 00173 // Heightfield geom structure 00174 // 00175 struct dxHeightfield : public dxGeom 00176 { 00177 dxHeightfieldData* m_p_data; 00178 00179 dxHeightfield( dSpaceID space, dHeightfieldDataID data, int bPlaceable ); 00180 ~dxHeightfield(); 00181 00182 void computeAABB(); 00183 00184 int dCollideHeightfieldZone( const int minX, const int maxX, const int minZ, const int maxZ, 00185 dxGeom *o2, const int numMaxContacts, 00186 int flags, dContactGeom *contact, int skip ); 00187 00188 enum 00189 { 00190 TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 4, 00191 TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X = 4, 00192 TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z = 4, 00193 TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT = 1, // Triangles are easy to reallocate and hard to predict 00194 }; 00195 00196 static inline size_t AlignBufferSize(size_t value, size_t alignment) { dIASSERT((alignment & (alignment - 1)) == 0); return (value + (alignment - 1)) & ~(alignment - 1); } 00197 00198 void allocateTriangleBuffer(size_t numTri); 00199 void resetTriangleBuffer(); 00200 void allocatePlaneBuffer(size_t numTri); 00201 void resetPlaneBuffer(); 00202 void allocateHeightBuffer(size_t numX, size_t numZ); 00203 void resetHeightBuffer(); 00204 00205 void sortPlanes(const size_t numPlanes); 00206 00207 HeightFieldPlane **tempPlaneBuffer; 00208 HeightFieldPlane *tempPlaneInstances; 00209 size_t tempPlaneBufferSize; 00210 00211 HeightFieldTriangle *tempTriangleBuffer; 00212 size_t tempTriangleBufferSize; 00213 00214 HeightFieldVertex **tempHeightBuffer; 00215 HeightFieldVertex *tempHeightInstances; 00216 size_t tempHeightBufferSizeX; 00217 size_t tempHeightBufferSizeZ; 00218 00219 }; 00220 00221 00222 //------------------------------------------------------------------------------ 00223 #endif //_DHEIGHTFIELD_H_