Files
scummvm-cursorfix/engines/hpl1/engine/libraries/newton/physics/dgMeshEffect.h
2026-02-02 04:50:13 +01:00

370 lines
15 KiB
C++

/* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef __dgMeshEffect_H__
#define __dgMeshEffect_H__
#include "hpl1/engine/libraries/newton/core/dg.h"
class dgWorld;
class dgCollision;
class dgMeshEffect;
class dgMeshEffectSolidTree;
class dgMeshTreeCSGEdgePool;
#define DG_MESH_EFFECT_INITIAL_VERTEX_SIZE 8
#define DG_MESH_EFFECT_BOLLEAN_STACK 512
#define DG_MESH_EFFECT_POINT_SPLITED 512
#define DG_MESH_EFFECT_POLYGON_SPLITED 256
#define DG_MESH_EFFECT_FLAT_CUT_BORDER_EDGE 0x01
#define DG_VERTEXLIST_INDEXLIST_TOL (dgFloat64(0.0f))
#define DG_MESH_EFFECT_PRECISION_BITS 30
#define DG_MESH_EFFECT_PRECISION_SCALE dgFloat64(1 << DG_MESH_EFFECT_PRECISION_BITS)
#define DG_MESH_EFFECT_PRECISION_SCALE_INV (dgFloat64(1.0f) / DG_MESH_EFFECT_PRECISION_SCALE)
#define DG_MESG_EFFECT_BOOLEAN_INIT() \
dgMeshEffect *result = NULL; \
dgMeshEffect *sourceCoplanar = NULL; \
dgMeshEffect *leftMeshSource = NULL; \
dgMeshEffect *rightMeshSource = NULL; \
dgMeshEffect *clipperCoplanar = NULL; \
dgMeshEffect *leftMeshClipper = NULL; \
dgMeshEffect *rightMeshClipper = NULL;
#define DG_MESG_EFFECT_BOOLEAN_FINISH() \
if (sourceCoplanar) { \
sourceCoplanar->Release(); \
} \
if (clipperCoplanar) { \
clipperCoplanar->Release(); \
} \
if (leftMeshClipper) { \
leftMeshClipper->Release(); \
} \
if (rightMeshClipper) { \
rightMeshClipper->Release(); \
} \
if (leftMeshSource) { \
leftMeshSource->Release(); \
} \
if (rightMeshSource) { \
rightMeshSource->Release(); \
} \
if (result) { \
result->ConvertToPolygons(); \
dgStack<dgInt32> map(result->m_pointCount + 1); \
result->RemoveUnusedVertices(&map[0]); \
}
class dgMeshEffect : public dgPolyhedra, public dgRefCounter {
public:
class dgVertexAtribute {
public:
dgBigVector m_vertex;
dgFloat64 m_normal_x;
dgFloat64 m_normal_y;
dgFloat64 m_normal_z;
dgFloat64 m_u0;
dgFloat64 m_v0;
dgFloat64 m_u1;
dgFloat64 m_v1;
dgFloat64 m_material;
void clear() {
m_vertex = dgBigVector(0.0f, 0.0f, 0.0f, 0.0f);
m_normal_x = 0.0f;
m_normal_y = 0.0f;
m_normal_z = 0.0f;
m_u0 = 0.0f;
m_v0 = 0.0f;
m_u1 = 0.0f;
m_v1 = 0.0f;
m_material = 0.0f;
}
};
class dgIndexArray {
public:
dgInt32 m_materialCount;
dgInt32 m_indexCount;
dgInt32 m_materials[256];
dgInt32 m_materialsIndexCount[256];
dgInt32 *m_indexList;
};
dgMeshEffect(dgMemoryAllocator *const allocator, bool preAllocaBuffers);
dgMeshEffect(dgCollision *const collision);
dgMeshEffect(const dgMeshEffect &source);
dgMeshEffect(dgPolyhedra &mesh, const dgMeshEffect &source);
// Create a convex hull Mesh form point cloud
dgMeshEffect(dgMemoryAllocator *const allocator, const dgFloat64 *const vertexCloud, dgInt32 count, dgInt32 strideInByte, dgFloat64 distTol);
// create a convex approximation
dgMeshEffect(const dgMeshEffect &source, dgFloat32 maxConcavity, dgInt32 maxCount = 32);
// create a planar Mesh
dgMeshEffect(dgMemoryAllocator *const allocator, const dgMatrix &planeMatrix, dgFloat32 witdth, dgFloat32 breadth, dgInt32 material, const dgMatrix &textureMatrix0, const dgMatrix &textureMatrix1);
virtual ~dgMeshEffect(void);
void ApplyTransform(const dgMatrix &matrix);
dgMatrix CalculateOOBB(dgBigVector &size) const;
void CalculateAABB(dgBigVector &min, dgBigVector &max) const;
void CalculateNormals(dgFloat64 angleInRadians);
void SphericalMapping(dgInt32 material);
void BoxMapping(dgInt32 front, dgInt32 side, dgInt32 top);
void UniformBoxMapping(dgInt32 material, const dgMatrix &textruMatrix);
void CylindricalMapping(dgInt32 cylinderMaterial, dgInt32 capMaterial);
dgEdge *InsertEdgeVertex(dgEdge *const edge, dgFloat64 param);
dgMeshEffect *Union(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
dgMeshEffect *Difference(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
dgMeshEffect *Intersection(const dgMatrix &matrix, const dgMeshEffect *const clip) const;
void ClipMesh(const dgMatrix &matrix, const dgMeshEffect *const clip, dgMeshEffect **const top, dgMeshEffect **const bottom) const;
bool CheckIntersection(const dgMeshEffectSolidTree *const solidTree, dgFloat64 scale) const;
dgMeshEffectSolidTree *CreateSolidTree() const;
static void DestroySolidTree(dgMeshEffectSolidTree *const tree);
static bool CheckIntersection(const dgMeshEffect *const meshA, const dgMeshEffectSolidTree *const solidTreeA,
const dgMeshEffect *const meshB, const dgMeshEffectSolidTree *const solidTreeB, dgFloat64 scale);
dgMeshEffect *GetFirstLayer() const;
dgMeshEffect *GetNextLayer(const dgMeshEffect *const layer) const;
void Triangulate();
void ConvertToPolygons();
void RemoveUnusedVertices(dgInt32 *const vertexRemapTable);
void BeginPolygon();
void AddPolygon(dgInt32 count, const dgFloat32 *const vertexList, dgInt32 stride, dgInt32 material);
#ifndef __USE_DOUBLE_PRECISION__
void AddPolygon(dgInt32 count, const dgFloat64 *const vertexList, dgInt32 stride, dgInt32 material);
#endif
void EndPolygon(dgFloat64 tol);
void PackVertexArrays();
void BuildFromVertexListIndexList(dgInt32 faceCount, const dgInt32 *const faceIndexCount, const dgInt32 *const faceMaterialIndex,
const dgFloat32 *const vertex, dgInt32 vertexStrideInBytes, const dgInt32 *const vertexIndex,
const dgFloat32 *const normal, dgInt32 normalStrideInBytes, const dgInt32 *const normalIndex,
const dgFloat32 *const uv0, dgInt32 uv0StrideInBytes, const dgInt32 *const uv0Index,
const dgFloat32 *const uv1, dgInt32 uv1StrideInBytes, const dgInt32 *const uv1Index);
dgInt32 GetVertexCount() const;
dgInt32 GetVertexStrideInByte() const;
dgFloat64 *GetVertexPool() const;
dgInt32 GetPropertiesCount() const;
dgInt32 GetPropertiesStrideInByte() const;
dgFloat64 *GetAttributePool() const;
dgFloat64 *GetNormalPool() const;
dgFloat64 *GetUV0Pool() const;
dgFloat64 *GetUV1Pool() const;
dgEdge *ConectVertex(dgEdge *const e0, dgEdge *const e1);
dgInt32 GetTotalFaceCount() const;
dgInt32 GetTotalIndexCount() const;
void GetFaces(dgInt32 *const faceCount, dgInt32 *const materials, void **const faceNodeList) const;
void RepairTJoints(bool triangulate);
bool SeparateDuplicateLoops(dgEdge *const edge);
bool HasOpenEdges() const;
dgFloat64 CalculateVolume() const;
void GetVertexStreams(dgInt32 vetexStrideInByte, dgFloat32 *const vertex,
dgInt32 normalStrideInByte, dgFloat32 *const normal,
dgInt32 uvStrideInByte0, dgFloat32 *const uv0,
dgInt32 uvStrideInByte1, dgFloat32 *const uv1) const;
void GetIndirectVertexStreams(dgInt32 vetexStrideInByte, dgFloat64 *const vertex, dgInt32 *const vertexIndices, dgInt32 *const vertexCount,
dgInt32 normalStrideInByte, dgFloat64 *const normal, dgInt32 *const normalIndices, dgInt32 *const normalCount,
dgInt32 uvStrideInByte0, dgFloat64 *const uv0, dgInt32 *const uvIndices0, dgInt32 *const uvCount0,
dgInt32 uvStrideInByte1, dgFloat64 *const uv1, dgInt32 *const uvIndices1, dgInt32 *const uvCount1);
dgIndexArray *MaterialGeometryBegin() const;
void MaterialGeomteryEnd(dgIndexArray *const handle) const;
dgInt32 GetFirstMaterial(dgIndexArray *const handle) const;
dgInt32 GetNextMaterial(dgIndexArray *const handle, dgInt32 materialHandle) const;
dgInt32 GetMaterialID(dgIndexArray *const handle, dgInt32 materialHandle) const;
dgInt32 GetMaterialIndexCount(dgIndexArray *const handle, dgInt32 materialHandle) const;
void GetMaterialGetIndexStream(dgIndexArray *const handle, dgInt32 materialHandle, dgInt32 *const index) const;
void GetMaterialGetIndexStreamShort(dgIndexArray *const handle, dgInt32 materialHandle, dgInt16 *const index) const;
dgCollision *CreateCollisionTree(dgInt32 shapeID) const;
dgCollision *CreateConvexCollision(dgFloat64 tolerance, dgInt32 shapeID, const dgMatrix &matrix = dgGetIdentityMatrix()) const;
dgMeshEffect *CreateConvexApproximation(dgFloat32 maxConcavity, dgInt32 maxCount = 32) const;
dgMeshEffect *CreateDelanayTretrahedralization(dgInt32 interionMaterial, dgMatrix &matrix) const;
dgMeshEffect *CreateVoronoiPartition(dgInt32 pointsCount, dgInt32 pointStrideInBytes, const dgFloat32 *const pointCloud, dgInt32 interionMaterial, dgMatrix &matrix) const;
void PlaneClipMesh(const dgMatrix &planeMatrix, const dgMatrix &planeTextMatrix, dgInt32 planeMaterial, dgMeshEffect **const leftMeshSource, dgMeshEffect **const rightMeshSource) const;
dgVertexAtribute &GetAttribute(dgInt32 index) const;
void TransformMesh(const dgMatrix &matrix);
void *GetFirstVertex() const;
void *GetNextVertex(void *const vertex) const;
dgInt32 GetVertexIndex(void *const vertex) const;
void *GetFirstPoint() const;
void *GetNextPoint(void *const point) const;
dgInt32 GetPointIndex(const void *const point) const;
dgInt32 GetVertexIndexFromPoint(void *const point) const;
void *GetFirstEdge() const;
void *GetNextEdge(void *const edge) const;
void GetEdgeIndex(const void *const edge, dgInt32 &v0, dgInt32 &v1) const;
// void GetEdgeAttributeIndex (const void* edge, dgInt32& v0, dgInt32& v1) const;
void *GetFirstFace() const;
void *GetNextFace(void *const face) const;
dgInt32 IsFaceOpen(const void *const face) const;
dgInt32 GetFaceMaterial(const void *const face) const;
dgInt32 GetFaceIndexCount(const void *const face) const;
void GetFaceIndex(const void *const face, int *const indices) const;
void GetFaceAttributeIndex(const void *const face, int *const indices) const;
bool Sanity() const;
protected:
void Init(bool preAllocaBuffers);
dgBigVector GetOrigin() const;
dgInt32 CalculateMaxAttributes() const;
dgFloat64 QuantizeCordinade(dgFloat64 val) const;
dgInt32 EnumerateAttributeArray(dgVertexAtribute *const attib);
void ApplyAttributeArray(dgVertexAtribute *const attib, dgInt32 maxCount);
void AddVertex(const dgBigVector &vertex);
void AddAtribute(const dgVertexAtribute &attib);
void AddPoint(const dgFloat64 *vertexList, dgInt32 material);
void FixCylindricalMapping(dgVertexAtribute *const attib) const;
void MergeFaces(const dgMeshEffect *const source);
void ReverseMergeFaces(dgMeshEffect *const source);
dgVertexAtribute InterpolateEdge(dgEdge *const edge, dgFloat64 param) const;
dgVertexAtribute InterpolateVertex(const dgBigVector &point, dgEdge *const face) const;
dgMeshEffect *GetNextLayer(dgInt32 mark) const;
void FilterCoplanarFaces(const dgMeshEffect *const otherCap, dgFloat32 sign);
void ClipMesh(const dgMeshEffect *const clipMesh, dgMeshEffect **const back, dgMeshEffect **const front, dgMeshEffect **const coplanar) const;
void ClipMesh(const dgMeshEffectSolidTree *const clipper, dgMeshEffect **const back, dgMeshEffect **const front, dgMeshEffect **const coplanar) const;
dgInt32 PlaneApplyCap(const dgMeshEffect *planeMesh, const dgBigPlane &normal);
void PlaneClipMesh(const dgMeshEffect *planeMesh, dgMeshEffect **leftMeshSource, dgMeshEffect **rightMeshSource) const;
dgMeshEffect *MakeDelanayIntersection(dgMeshEffectSolidTree *const tree, dgBigVector *const points, dgInt32 count, dgInt32 materialId, const dgMatrix &textureProjectionMatrix, dgFloat32 normalAngleInRadians) const;
bool CheckSingleMesh() const;
dgInt32 m_pointCount;
dgInt32 m_maxPointCount;
dgInt32 m_atribCount;
dgInt32 m_maxAtribCount;
dgBigVector *m_points;
dgVertexAtribute *m_attib;
friend class dgConvexHull3d;
friend class dgConvexHull4d;
friend class dgMeshTreeCSGFace;
friend class dgMeshEffectSolidTree;
};
inline dgInt32 dgMeshEffect::GetVertexCount() const {
return m_pointCount;
}
inline dgInt32 dgMeshEffect::GetPropertiesCount() const {
return m_atribCount;
}
inline dgInt32 dgMeshEffect::GetMaterialID(dgIndexArray *const handle, dgInt32 materialHandle) const {
return handle->m_materials[materialHandle];
}
inline dgInt32 dgMeshEffect::GetMaterialIndexCount(dgIndexArray *const handle, dgInt32 materialHandle) const {
return handle->m_materialsIndexCount[materialHandle];
}
inline dgMeshEffect::dgVertexAtribute &dgMeshEffect::GetAttribute(dgInt32 index) const {
return m_attib[index];
}
inline dgInt32 dgMeshEffect::GetPropertiesStrideInByte() const {
return sizeof(dgVertexAtribute);
}
inline dgFloat64 *dgMeshEffect::GetAttributePool() const {
return &m_attib->m_vertex.m_x;
}
inline dgFloat64 *dgMeshEffect::GetNormalPool() const {
return &m_attib->m_normal_x;
}
inline dgFloat64 *dgMeshEffect::GetUV0Pool() const {
return &m_attib->m_u0;
}
inline dgFloat64 *dgMeshEffect::GetUV1Pool() const {
return &m_attib->m_u1;
}
inline bool dgMeshEffect::CheckIntersection(const dgMeshEffect *const meshA, const dgMeshEffectSolidTree *const solidTreeA, const dgMeshEffect *const meshB, const dgMeshEffectSolidTree *const solidTreeB, dgFloat64 scale) {
return (meshA->CheckIntersection(solidTreeB, scale) || meshB->CheckIntersection(solidTreeA, scale));
}
inline dgInt32 dgMeshEffect::GetVertexStrideInByte() const {
return sizeof(dgBigVector);
}
inline dgFloat64 *dgMeshEffect::GetVertexPool() const {
return &m_points[0].m_x;
}
inline dgMeshEffect *dgMeshEffect::GetFirstLayer() const {
return GetNextLayer(IncLRU());
}
inline dgMeshEffect *dgMeshEffect::GetNextLayer(const dgMeshEffect *const layerSegment) const {
if (!layerSegment) {
return NULL;
}
return GetNextLayer(layerSegment->IncLRU() - 1);
}
inline dgFloat64 dgMeshEffect::QuantizeCordinade(dgFloat64 x) const {
int exp;
dgFloat64 mantissa = frexp(x, &exp);
mantissa = DG_MESH_EFFECT_PRECISION_SCALE_INV * floor(mantissa * DG_MESH_EFFECT_PRECISION_SCALE);
dgFloat64 x1 = ldexp(mantissa, exp);
return x1;
}
#endif