22 #ifndef __ND_MESH_EFFECT_H__
23 #define __ND_MESH_EFFECT_H__
25 #include "ndCollisionStdafx.h"
27 #define DG_MESH_EFFECT_PRECISION_BITS 48
28 #define DG_MESH_EFFECT_PRECISION_SCALE ndFloat64(ndInt64(1)<<DG_MESH_EFFECT_PRECISION_BITS)
29 #define DG_MESH_EFFECT_PRECISION_SCALE_INV (ndFloat64 (1.0f) / DG_MESH_EFFECT_PRECISION_SCALE)
31 #define DG_VERTEXLIST_INDEXLIST_TOL (ndFloat64 (0.0f))
32 #define DG_MESH_EFFECT_POINT_SPLITED 512
33 #define DG_MESH_EFFECT_BVH_STACK_DEPTH 256
40 ndInt32 m_materialCount;
42 ndInt32 m_materials[256];
43 ndInt32 m_materialsIndexCount[256];
57 dgMeshBVHNode (
const ndMeshEffect*
const mesh, dEdge*
const face,
void*
const userData);
58 dgMeshBVHNode (dgMeshBVHNode*
const left, dgMeshBVHNode*
const right);
60 void SetBox (
const dVector& p0,
const dVector& p1);
62 DG_CLASS_ALLOCATOR(allocator)
69 dgMeshBVHNode* m_left;
70 dgMeshBVHNode* m_right;
71 dgMeshBVHNode* m_parent;
74 class dgFitnessList:
public dTree <dgMeshBVHNode*, dgMeshBVHNode*>
77 dgFitnessList (dMemoryAllocator___*
const allocator);
78 dFloat64 TotalCost ()
const;
85 virtual void Build ();
86 virtual void Cleanup ();
88 void FaceRayCast (
const dBigVector& l0,
const dBigVector& l1,
void*
const userData)
const;
89 void GetOverlapNodes (dList<dgMeshBVHNode*>& overlapNodes,
const dBigVector& p0,
const dBigVector& p1)
const;
92 virtual dgMeshBVHNode* CreateLeafNode (dEdge*
const face,
void*
const userData) = 0;
94 dgMeshBVHNode* AddFaceNode (dEdge*
const face,
void*
const userData);
95 void RemoveNode (dgMeshBVHNode*
const treeNode);
96 void ImproveNodeFitness ();
97 void ImproveNodeFitness (dgMeshBVHNode*
const node);
98 dFloat32 CalculateSurfaceArea (dgMeshBVHNode*
const node0, dgMeshBVHNode*
const node1, dVector& minBox, dVector& maxBox)
const;
99 virtual bool SanityCheck()
const;
101 virtual dFloat64 RayFaceIntersect (
const dgMeshBVHNode*
const face,
const dBigVector& p0,
const dBigVector& p1,
void*
const userData)
const;
106 dgMeshBVHNode* m_rootNode;
107 dgFitnessList m_fitness;
115 ndMeshEffect (dMemoryAllocator___*
const allocator, dgDeserialize deserialization,
void*
const userData);
118 ndMeshEffect(dMemoryAllocator___*
const allocator,
const char*
const fileName);
121 ndMeshEffect (dMemoryAllocator___*
const allocator,
const dFloat64*
const vertexCloud, dInt32 count, dInt32 strideInByte, dFloat64 distTol);
124 ndMeshEffect(dMemoryAllocator___*
const allocator,
const dMatrix& planeMatrix, dFloat32 witdth, dFloat32 breadth, dInt32 material,
const dMatrix& textureMatrix0,
const dMatrix& textureMatrix1);
127 void CylindricalMapping (dInt32 cylinderMaterial, dInt32 capMaterial,
const dMatrix& uvAligment);
128 void AngleBaseFlatteningMapping (dInt32 cylinderMaterial, dgReportProgress progressReportCallback,
void*
const userData);
139 dInt32 GetVertexBaseCount()
const;
140 void SetVertexBaseCount(dInt32 count);
142 dEdge* SpliteFace (dInt32 v0, dInt32 v1);
144 dInt32 GetTotalFaceCount()
const;
145 dInt32 GetTotalIndexCount()
const;
146 void GetFaces (dInt32*
const faceCount, dInt32*
const materials,
void**
const faceNodeList)
const;
148 void OptimizePoints();
149 void OptimizeAttibutes();
150 const dInt32* GetIndexToVertexMap()
const;
152 bool HasLayersChannel()
const;
153 bool HasNormalChannel()
const;
154 bool HasBinormalChannel()
const;
155 bool HasUV0Channel()
const;
156 bool HasUV1Channel()
const;
157 bool HasVertexColorChannel()
const;
159 dgCollisionInstance* CreateCollisionTree(dgWorld*
const world, dInt32 shapeID)
const;
160 ndMeshEffect* CreateSimplification (dInt32 maxVertexCount, dgReportProgress reportProgressCallback,
void*
const userData)
const;
161 ndMeshEffect* CreateConvexApproximation (dFloat32 maxConcavity, dFloat32 backFaceDistanceFactor, dInt32 maxHullOuputCount, dInt32 maxVertexPerHull, dgReportProgress reportProgressCallback,
void*
const userData)
const;
164 void CreateTetrahedraLinearBlendSkinWeightsChannel (
const ndMeshEffect*
const tetrahedraMesh);
167 static ndMeshEffect* CreateFromSerialization (dMemoryAllocator___*
const allocator, dgDeserialize deserialization,
void*
const userData);
169 void LoadOffMesh (
const char*
const filename);
170 void LoadTetraMesh (
const char*
const filename);
171 void Serialize (dgSerialize callback,
void*
const userData)
const;
173 dBigVector GetVertex (dInt32 index)
const;
174 dInt32 GetVertexLayer (dInt32 index)
const;
176 void TransformMesh (
const dMatrix& matrix);
178 void* GetFirstVertex ()
const;
179 void* GetNextVertex (
const void*
const vertex)
const;
180 dInt32 GetVertexIndex (
const void*
const vertex)
const;
182 void* GetFirstPoint ()
const;
183 void* GetNextPoint (
const void*
const point)
const;
184 dInt32 GetPointIndex (
const void*
const point)
const;
185 dInt32 GetVertexIndexFromPoint (
const void*
const point)
const;
187 void* GetFirstEdge ()
const;
188 void* GetNextEdge (
const void*
const edge)
const;
190 void GetEdgeIndex (
const void*
const edge, dInt32& v0, dInt32& v1)
const;
193 const dEdge* GetPolyhedraEdgeFromNode(
const void*
const edge)
const;
195 void* GetFirstFace ()
const;
196 void* GetNextFace (
const void*
const face)
const;
197 dInt32 IsFaceOpen (
const void*
const face)
const;
198 dInt32 GetFaceIndexCount (
const void*
const face)
const;
199 void GetFaceIndex (
const void*
const face, dInt32*
const indices)
const;
200 void GetFaceAttributeIndex (
const void*
const face, dInt32*
const indices)
const;
201 dBigVector CalculateFaceNormal (
const void*
const face)
const;
203 void SetFaceMaterial (
const void*
const face, dInt32 materialID);
204 dInt32 InterpolateVertex (
const dBigVector& point,
const dEdge*
const face)
const;
207 dBigVector GetOrigin ()
const;
208 dInt32 CalculateMaxAttributes ()
const;
226 template<
class T, ndChannelType type>
227 class ndChannel:
public ndArray<T>
231 ndChannel(
const ndChannel& source);
235 void PushBack(
const T& element);
237 ndChannelType m_type;
251 ndInt32 m_vertexIndex;
252 ndInt32 m_attibuteIndex;
258 const ndChannel<ndBigVector, m_point>* m_points;
259 ndInt32 m_vertexSortIndex;
262 static ndInt32 CompareVertex(
const ndSortKey*
const ptr0,
const ndSortKey*
const ptr1,
void*
const context);
265 class ndPointFormat:
public ndFormat
269 ndPointFormat(
const ndPointFormat& source);
273 void SetCount(ndInt32 count);
274 void CompactVertexData(ndInt32*
const indexList, ndFloat32 tol);
277 void CompressData(ndPointFormat& output, ndInt32*
const indexList,
ndSortKey*
const remapIndex,
const ndSortCluster& batch, ndFloat32 tol);
280 ndChannel<ndInt32, m_layer> m_layers;
281 ndChannel<ndBigVector, m_point> m_vertex;
284 class ndAttibutFormat:
public ndFormat
295 ndAttibutFormat(
const ndAttibutFormat& source);
299 void SetCount(ndInt32 count);
300 void CopyFrom(
const ndAttibutFormat& source);
301 void CopyEntryFrom(ndInt32 index,
const ndAttibutFormat& source, ndInt32 sourceIndex);
302 void CompactVertexData(
const ndPointFormat& points, ndInt32*
const indexList, ndFloat32 tol);
305 void CompressData(ndAttibutFormat& output,
const ndPointFormat& points, ndInt32*
const indexList,
ndSortKey*
const remapIndex,
const ndSortCluster& batch, ndFloat32 tol);
308 ndChannel<ndInt32, m_vertex> m_pointChannel;
309 ndChannel<ndInt32, m_material> m_materialChannel;
310 ndChannel<ndTriplex, m_normal> m_normalChannel;
311 ndChannel<ndTriplex, m_binormal> m_binormalChannel;
312 ndChannel<ndVector, m_color> m_colorChannel;
313 ndChannel<dgUV, m_uv0> m_uv0Channel;
314 ndChannel<dgUV, m_uv1> m_uv1Channel;
322 :m_ambient(ndFloat32(0.8f), ndFloat32(0.8f), ndFloat32(0.8f), ndFloat32(1.0f))
323 ,m_diffuse(ndFloat32(0.8f), ndFloat32(0.8f), ndFloat32(0.8f), ndFloat32(1.0f))
324 ,m_specular(ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f), ndFloat32(1.0f))
325 ,m_opacity(ndFloat32(1.0f))
326 ,m_shiness(ndFloat32 (60.0f))
329 strcpy(m_textureName,
"default.tga");
337 char m_textureName[32];
346 const ndFloat64* m_data;
347 const ndInt32* m_indexList;
348 ndInt32 m_strideInBytes;
354 const ndFloat32* m_data;
355 const ndInt32* m_indexList;
356 ndInt32 m_strideInBytes;
370 const ndInt32* m_faceIndexCount;
371 const ndInt32* m_faceMaterial;
372 dDoubleData m_vertex;
374 dFloatData m_binormal;
377 dFloatData m_vertexColor;
400 D_COLLISION_API
ndMeshEffect(
const ndFloat64*
const vertexCloud, ndInt32 count, ndInt32 strideInByte, ndFloat64 distTol);
404 void SetName (
const ndString& name);
408 ndInt32 GetPropertiesCount()
const;
410 ndInt32 GetVertexCount()
const;
411 ndInt32 GetVertexStrideInByte()
const;
412 const ndFloat64* GetVertexPool()
const;
414 ndInt32 GetFaceMaterial(
ndEdge*
const faceEdge)
const;
417 D_COLLISION_API
dVertexCluster* CreateCluster(
const char*
const name);
418 D_COLLISION_API
dVertexCluster* FindCluster(
const char*
const name)
const;
420 D_COLLISION_API ndFloat64 CalculateVolume()
const;
424 D_COLLISION_API
void ApplyTransform(
const ndMatrix& matrix);
425 D_COLLISION_API
void CalculateNormals(ndFloat64 angleInRadians);
428 D_COLLISION_API
void GetVertexIndexChannel(ndInt32*
const bufferOut)
const;
429 D_COLLISION_API
void GetVertexChannel64(ndInt32 strideInByte, ndFloat64*
const bufferOut)
const;
430 D_COLLISION_API
void GetVertexChannel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
431 D_COLLISION_API
void GetNormalChannel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
432 D_COLLISION_API
void GetBinormalChannel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
433 D_COLLISION_API
void GetUV0Channel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
434 D_COLLISION_API
void GetUV1Channel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
435 D_COLLISION_API
void GetVertexColorChannel(ndInt32 strideInByte, ndFloat32*
const bufferOut)
const;
438 D_COLLISION_API ndInt32 GetFirstMaterial(
ndIndexArray*
const handle)
const;
439 D_COLLISION_API ndInt32 GetNextMaterial(
ndIndexArray*
const handle, ndInt32 materialHandle)
const;
440 D_COLLISION_API ndInt32 GetMaterialID(
ndIndexArray*
const handle, ndInt32 materialHandle)
const;
441 D_COLLISION_API ndInt32 GetMaterialIndexCount(
ndIndexArray*
const handle, ndInt32 materialHandle)
const;
442 D_COLLISION_API
void GetMaterialGetIndexStream(
ndIndexArray*
const handle, ndInt32 materialHandle, ndInt32*
const index)
const;
443 D_COLLISION_API
void GetMaterialGetIndexStream(
ndIndexArray*
const handle, ndInt32 materialHandle, ndInt16*
const index)
const;
444 D_COLLISION_API
void MaterialGeometryEnd(
ndIndexArray*
const handle);
446 D_COLLISION_API
void BeginBuild();
447 D_COLLISION_API
void BeginBuildFace();
448 D_COLLISION_API
void AddPoint(ndFloat64 x, ndFloat64 y, ndFloat64 z);
449 D_COLLISION_API
void AddLayer(ndInt32 layer);
450 D_COLLISION_API
void AddMaterial(ndInt32 materialIndex);
451 D_COLLISION_API
void AddNormal(ndFloat32 x, ndFloat32 y, ndFloat32 z);
452 D_COLLISION_API
void AddBinormal(ndFloat32 x, ndFloat32 y, ndFloat32 z);
453 D_COLLISION_API
void AddVertexColor(ndFloat32 x, ndFloat32 y, ndFloat32 z, ndFloat32 w);
454 D_COLLISION_API
void AddUV0(ndFloat32 u, ndFloat32 v);
455 D_COLLISION_API
void AddUV1(ndFloat32 u, ndFloat32 v);
456 D_COLLISION_API
void EndBuildFace();
457 D_COLLISION_API
void EndBuild(
bool fixTjoint =
true);
460 D_COLLISION_API
void SphericalMapping(ndInt32 materialIndex,
const ndMatrix& textureMatrix);
461 D_COLLISION_API
void UniformBoxMapping(ndInt32 materialIndex,
const ndMatrix& textureMatrix);
462 D_COLLISION_API
void BoxMapping(ndInt32 front, ndInt32 side, ndInt32 top,
const ndMatrix& textureMatrix);
463 D_COLLISION_API
void RepairTJoints();
468 D_COLLISION_API
void FlipWinding();
469 D_COLLISION_API
bool HasOpenEdges()
const;
470 D_COLLISION_API
void Triangulate();
471 D_COLLISION_API
void ConvertToPolygons();
472 D_COLLISION_API
ndEdge* InsertEdgeVertex(
ndEdge*
const edge, ndFloat64 param);
473 D_COLLISION_API
void AddInterpolatedEdgeAttribute(
ndEdge*
const edge, ndFloat64 param);
474 D_COLLISION_API
void RemoveUnusedVertices(ndInt32*
const vertexRemapTable);
475 D_COLLISION_API ndInt32 PlaneClip(
const ndMeshEffect& convexMesh,
const ndEdge*
const face);
476 D_COLLISION_API
ndShapeInstance* CreateConvexCollision(ndFloat64 tolerance)
const;
482 D_COLLISION_API
void Init();
483 D_COLLISION_API
virtual void BeginFace();
484 D_COLLISION_API
virtual bool EndFace();
485 ndFloat64 QuantizeCordinade(ndFloat64 val)
const;
490 void PackAttibuteData();
491 void UnpackAttibuteData();
492 bool SeparateDuplicateLoops(
ndEdge*
const face);
493 ndInt32 AddInterpolatedHalfAttribute(
ndEdge*
const edge, ndInt32 midPoint);
496 D_COLLISION_API
ndMeshEffect* GetNextLayer(ndInt32 mark);
499 ndPointFormat m_points;
500 ndAttibutFormat m_attrib;
503 ndInt32 m_vertexBaseCount;
504 ndInt32 m_constructionIndex;
509 inline dInt32 ndMeshEffect::GetVertexBaseCount()
const
511 return m_vertexBaseCount;
514 inline void ndMeshEffect::SetVertexBaseCount(dInt32 count)
516 m_vertexBaseCount = count;
520 inline const dInt32* ndMeshEffect::GetIndexToVertexMap()
const
522 return &m_attrib.m_pointChannel[0];
525 inline dBigVector ndMeshEffect::GetVertex (dInt32 index)
const
528 dAssert(index < m_points.m_vertex.m_count);
529 return m_points.m_vertex[index];
532 inline bool ndMeshEffect::HasLayersChannel()
const
534 return m_points.m_layers.m_count != 0;
537 inline dInt32 ndMeshEffect::GetVertexLayer(dInt32 index)
const
540 dAssert(index < m_points.m_vertex.m_count);
541 return (m_points.m_layers.m_count) ? m_points.m_layers[index] : 0;
545 inline ndFloat64 ndMeshEffect::QuantizeCordinade(ndFloat64 x)
const
548 ndFloat64 mantissa = frexp(x, &exp);
549 mantissa = DG_MESH_EFFECT_PRECISION_SCALE_INV * floor (mantissa * DG_MESH_EFFECT_PRECISION_SCALE);
551 ndFloat64 x1 = ldexp(mantissa, exp);
555 template<
class T, ndMeshEffect::ndChannelType type>
556 ndMeshEffect::ndChannel<T, type>::ndChannel()
563 template<
class T, ndMeshEffect::ndChannelType type>
564 ndMeshEffect::ndChannel<T, type>::ndChannel(
const ndChannel& source)
566 ,m_type(source.m_type)
567 ,m_isValid(source.m_isValid)
571 template<
class T, ndMeshEffect::ndChannelType type>
572 ndMeshEffect::ndChannel<T, type>::~ndChannel()
576 template<
class T, ndMeshEffect::ndChannelType type>
577 void ndMeshEffect::ndChannel<T, type>::Clear()
583 template<
class T, ndMeshEffect::ndChannelType type>
584 void ndMeshEffect::ndChannel<T, type>::PushBack(
const T& element)
591 inline ndMeshEffect::ndPointFormat::ndPointFormat()
597 inline ndMeshEffect::ndPointFormat::ndPointFormat(
const ndPointFormat& source)
598 :m_layers(source.m_layers)
599 ,m_vertex(source.m_vertex)
603 inline ndMeshEffect::ndPointFormat::~ndPointFormat()
607 inline void ndMeshEffect::ndPointFormat::Clear()
613 inline void ndMeshEffect::ndPointFormat::SetCount(ndInt32 count)
615 m_vertex.Resize(count);
616 m_vertex.SetCount(count);
618 m_layers.Resize(count);
619 m_layers.SetCount(count);
622 inline ndMeshEffect::ndAttibutFormat::ndAttibutFormat()
633 inline ndMeshEffect::ndAttibutFormat::ndAttibutFormat(
const ndAttibutFormat& source)
634 :m_pointChannel(source.m_pointChannel)
635 ,m_materialChannel(source.m_materialChannel)
636 ,m_normalChannel(source.m_normalChannel)
637 ,m_binormalChannel(source.m_binormalChannel)
638 ,m_colorChannel(source.m_colorChannel)
639 ,m_uv0Channel(source.m_uv0Channel)
640 ,m_uv1Channel(source.m_uv1Channel)
644 inline ndMeshEffect::ndAttibutFormat::~ndAttibutFormat()
648 inline void ndMeshEffect::ndAttibutFormat::Clear()
650 m_pointChannel.Clear();
651 m_materialChannel.Clear();
652 m_normalChannel.Clear();
653 m_binormalChannel.Clear();
654 m_colorChannel.Clear();
655 m_uv0Channel.Clear();
656 m_uv1Channel.Clear();
659 inline void ndMeshEffect::ndAttibutFormat::SetCount(ndInt32 count)
661 m_pointChannel.Resize(count);
662 m_pointChannel.SetCount(count);
664 m_materialChannel.Resize(count);
665 m_materialChannel.SetCount(count);
667 m_normalChannel.Resize(count);
668 m_normalChannel.SetCount(count);
670 m_binormalChannel.Resize(count);
671 m_binormalChannel.SetCount(count);
673 m_colorChannel.Resize(count);
674 m_colorChannel.SetCount(count);
676 m_uv0Channel.Resize(count);
677 m_uv0Channel.SetCount(count);
679 m_uv1Channel.Resize(count);
680 m_uv1Channel.SetCount(count);
683 inline ndInt32 ndMeshEffect::GetPropertiesCount()
const
685 return m_attrib.m_pointChannel.GetCount();
688 inline void ndMeshEffect::SetName(
const ndString& name)
693 inline const ndString& ndMeshEffect::GetName()
const
703 inline ndInt32 ndMeshEffect::GetVertexCount()
const
705 return m_points.m_vertex.GetCount();
708 inline ndInt32 ndMeshEffect::GetVertexStrideInByte()
const
713 inline const ndFloat64* ndMeshEffect::GetVertexPool()
const
715 return &m_points.m_vertex[0].m_x;
718 inline ndInt32 ndMeshEffect::GetFaceMaterial(
ndEdge*
const faceEdge)
const
720 return ndInt32(m_attrib.m_materialChannel.GetCount() ? m_attrib.m_materialChannel[ndInt32(faceEdge->m_userData)] : 0);
725 return GetNextLayer(IncLRU());
734 return GetNextLayer(layerSegment->IncLRU() - 1);