[372] | 1 | #ifndef _Mesh_H__
|
---|
| 2 | #define _Mesh_H__
|
---|
| 3 |
|
---|
| 4 | #include <vector>
|
---|
[2176] | 5 | //
|
---|
[372] | 6 | #include "Intersectable.h"
|
---|
| 7 | #include "Plane3.h"
|
---|
| 8 | #include "Matrix4x4.h"
|
---|
| 9 | #include "AxisAlignedBox3.h"
|
---|
| 10 | #include "Material.h"
|
---|
[863] | 11 | #include "Containers.h"
|
---|
[372] | 12 |
|
---|
[863] | 13 |
|
---|
[860] | 14 | namespace GtpVisibilityPreprocessor {
|
---|
| 15 |
|
---|
[878] | 16 | extern bool MeshDebug;
|
---|
| 17 |
|
---|
[372] | 18 | struct Triangle3;
|
---|
| 19 | class MeshInstance;
|
---|
| 20 | class MeshKdTree;
|
---|
| 21 |
|
---|
| 22 |
|
---|
[1344] | 23 | /** Patch used as an element of the mesh
|
---|
| 24 | */
|
---|
[752] | 25 | struct Face {
|
---|
| 26 |
|
---|
[372] | 27 | public:
|
---|
| 28 | Face(): mVertexIndices() {}
|
---|
[752] | 29 |
|
---|
[372] | 30 | Face(const int a, const int b, const int c):mVertexIndices(3) {
|
---|
| 31 | mVertexIndices[0] = a;
|
---|
| 32 | mVertexIndices[1] = b;
|
---|
| 33 | mVertexIndices[2] = c;
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | Face(const int a, const int b, const int c, const int d):
|
---|
| 37 | mVertexIndices(4) {
|
---|
| 38 | mVertexIndices[0] = a;
|
---|
| 39 | mVertexIndices[1] = b;
|
---|
| 40 | mVertexIndices[2] = c;
|
---|
| 41 | mVertexIndices[3] = d;
|
---|
| 42 | }
|
---|
| 43 |
|
---|
[2614] | 44 | Face(const VertexIndexContainer &vertices): mVertexIndices(vertices.size()) {
|
---|
[752] | 45 | for (int i=0; i < vertices.size(); i++)
|
---|
| 46 | mVertexIndices[i] = vertices[i];
|
---|
| 47 | }
|
---|
[2614] | 48 |
|
---|
| 49 |
|
---|
[1328] | 50 | ////////////////////////////
|
---|
[1327] | 51 |
|
---|
[372] | 52 | /// list of vertex pointers
|
---|
| 53 | VertexIndexContainer mVertexIndices;
|
---|
| 54 | };
|
---|
| 55 |
|
---|
[863] | 56 |
|
---|
| 57 |
|
---|
| 58 | /// default vertex container for Mesh
|
---|
[2176] | 59 | typedef std::vector<Vector3> VertexContainer;
|
---|
[863] | 60 |
|
---|
[372] | 61 | /// default patch container for Mesh
|
---|
| 62 | typedef std::vector<Face *> FaceContainer;
|
---|
| 63 |
|
---|
| 64 | /** Mesh containing polygonal patches */
|
---|
[2609] | 65 | class Mesh
|
---|
| 66 | {
|
---|
[372] | 67 |
|
---|
| 68 | public:
|
---|
| 69 |
|
---|
| 70 | /// Default constructor
|
---|
[2609] | 71 | Mesh(): mVertices(), mFaces(), mMaterial(NULL), mKdTree(NULL), mId(0) {}
|
---|
[1001] | 72 |
|
---|
[372] | 73 | /// Constructor with container preallocation
|
---|
[2609] | 74 | Mesh(const int vertices, const int faces);
|
---|
[1001] | 75 | /** Constructor setting a unqiue mesh id.
|
---|
| 76 | */
|
---|
| 77 | Mesh(const int id);
|
---|
| 78 | /** Setting unique mesh id and using preallocation.
|
---|
| 79 | */
|
---|
| 80 | Mesh(const int id, const int vertices, const int faces);
|
---|
| 81 | /** Copy constructor making a deep copy of the faces.
|
---|
| 82 | */
|
---|
| 83 | Mesh(const Mesh &rhs);
|
---|
| 84 | /** Assignement operator.
|
---|
| 85 | @note does not copy id
|
---|
| 86 | @note preprocess may be necessary
|
---|
| 87 | */
|
---|
| 88 | Mesh& operator=(const Mesh& m);
|
---|
| 89 |
|
---|
[1005] | 90 | ~Mesh();
|
---|
| 91 | void Clear();
|
---|
[752] | 92 |
|
---|
| 93 | void IndexVertices();
|
---|
| 94 |
|
---|
| 95 | void AssignRandomMaterial();
|
---|
[372] | 96 | void AddTriangle(const Triangle3 &triangle);
|
---|
| 97 | void AddRectangle(const Rectangle3 &triangle);
|
---|
| 98 |
|
---|
[693] | 99 | void Cleanup();
|
---|
| 100 |
|
---|
| 101 | bool ValidateFace(const int face);
|
---|
[372] | 102 |
|
---|
| 103 | void AddFace(Face *face)
|
---|
| 104 | {
|
---|
[2609] | 105 | mFaces.push_back(face);
|
---|
[372] | 106 | }
|
---|
[859] | 107 |
|
---|
| 108 | void ComputeBoundingBox();
|
---|
[1001] | 109 | /** This function must be called after creating the mesh
|
---|
| 110 | because it creates the local kd tree and the bounding box.
|
---|
| 111 | */
|
---|
[1292] | 112 | void Preprocess(const bool cleanup = true);
|
---|
[372] | 113 |
|
---|
[1001] | 114 | /** Applies transformation to the mesh.
|
---|
| 115 | @note: meshkdtree will most likely be outdated after transformation, thus
|
---|
| 116 | another preprocess might be necessary.
|
---|
| 117 | */
|
---|
| 118 | void ApplyTransformation(const Matrix4x4 &m);
|
---|
| 119 |
|
---|
[2609] | 120 | /// Axis aligned bounding box of the mesh in local mesh coordinates.
|
---|
| 121 | AxisAlignedBox3 mBox;
|
---|
| 122 | /// Vertices forming the mesh.
|
---|
[372] | 123 | VertexContainer mVertices;
|
---|
[2609] | 124 | /// Patches forming the mesh.
|
---|
[372] | 125 | FaceContainer mFaces;
|
---|
[2609] | 126 | /// Global mesh material.
|
---|
[372] | 127 | Material *mMaterial;
|
---|
[2609] | 128 | /// true if the mesh is a convex mesh.
|
---|
[372] | 129 | bool mIsConvex;
|
---|
[2609] | 130 | /// true if the mesh is a convex mesh.
|
---|
[372] | 131 | bool mIsWatertight;
|
---|
| 132 |
|
---|
| 133 | MeshKdTree *mKdTree;
|
---|
[1001] | 134 |
|
---|
[372] | 135 | int
|
---|
[1001] | 136 | CastRay(Ray &ray, MeshInstance *instance);
|
---|
[372] | 137 |
|
---|
| 138 | int
|
---|
| 139 | CastRayToSelectedFaces(
|
---|
[1001] | 140 | Ray &ray,
|
---|
[2176] | 141 | const std::vector<int> &faces,
|
---|
[1001] | 142 | Intersectable *instance
|
---|
| 143 | );
|
---|
[372] | 144 |
|
---|
| 145 | int
|
---|
| 146 | CastRayToFace(
|
---|
[1001] | 147 | const int faceIndex,
|
---|
| 148 | Ray &ray,
|
---|
| 149 | float &nearestT,
|
---|
[1199] | 150 | Vector3 &nearestNormal,
|
---|
[1001] | 151 | int &nearestFace,
|
---|
| 152 | Intersectable *instance
|
---|
| 153 | );
|
---|
[372] | 154 |
|
---|
| 155 |
|
---|
| 156 | int
|
---|
| 157 | RayFaceIntersection(const int faceIndex,
|
---|
[1199] | 158 | const Ray &ray,
|
---|
| 159 | float &t,
|
---|
| 160 | Vector3 &normal,
|
---|
| 161 | const float nearestT
|
---|
| 162 | );
|
---|
[372] | 163 |
|
---|
[1418] | 164 | Plane3 GetFacePlane(const int faceIndex) const;
|
---|
[372] | 165 |
|
---|
| 166 | AxisAlignedBox3 GetFaceBox(const int faceIndex);
|
---|
| 167 |
|
---|
| 168 | int GetRandomSurfacePoint(Vector3 &point, Vector3 &normal);
|
---|
| 169 |
|
---|
[492] | 170 | int
|
---|
| 171 | GetRandomVisibleSurfacePoint(Vector3 &point,
|
---|
| 172 | Vector3 &normal,
|
---|
| 173 | const Vector3 &viewpoint,
|
---|
| 174 | const int maxTries
|
---|
| 175 | );
|
---|
[1001] | 176 |
|
---|
| 177 | /** Returns unique mesh id.
|
---|
| 178 | */
|
---|
[2609] | 179 | int GetId() const { return mId; }
|
---|
[1001] | 180 |
|
---|
[2614] | 181 | /** Returns normal of specified face.
|
---|
| 182 | */
|
---|
[1418] | 183 | Vector3 GetNormal(const int idx) const;
|
---|
| 184 |
|
---|
[1419] | 185 | // $$ matt temp
|
---|
| 186 | bool CheckMesh() const;
|
---|
| 187 |
|
---|
[2176] | 188 | void Print(std::ostream &app) const;
|
---|
[1419] | 189 |
|
---|
[2176] | 190 | virtual std::ostream &Describe(std::ostream &s) const {
|
---|
[492] | 191 | return s<<"Mesh #vertices="<<(int)mVertices.size()<<" #faces="<<(int)mFaces.size();
|
---|
| 192 | }
|
---|
[752] | 193 |
|
---|
[1001] | 194 | /** Creates a mesh from a axis aligned bounding box.
|
---|
| 195 | The mesh is handled from the resource manager.
|
---|
[991] | 196 | */
|
---|
| 197 | friend Mesh *CreateMeshFromBox(const AxisAlignedBox3 &box);
|
---|
[1001] | 198 |
|
---|
[2176] | 199 | friend std::ostream& operator<< (std::ostream &s, const Vector3 &A);
|
---|
[1419] | 200 |
|
---|
[1001] | 201 | protected:
|
---|
| 202 |
|
---|
| 203 | /// Unique id of this mesh.
|
---|
| 204 | int mId;
|
---|
[372] | 205 | };
|
---|
| 206 |
|
---|
[492] | 207 |
|
---|
[1419] | 208 | // Overload << operator for C++-style output
|
---|
[2176] | 209 | inline std::ostream&
|
---|
| 210 | operator<< (std::ostream &s, const Mesh &A)
|
---|
[1419] | 211 | {
|
---|
| 212 | A.Print(s);
|
---|
| 213 | return s;
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 |
|
---|
[2569] | 217 | class MeshInstance: public Intersectable {
|
---|
[1001] | 218 |
|
---|
[372] | 219 | public:
|
---|
[2609] | 220 | MeshInstance(Mesh *mesh): Intersectable(), mMesh(mesh), mMaterial(NULL)
|
---|
[1763] | 221 | {
|
---|
| 222 | }
|
---|
[372] | 223 |
|
---|
[1763] | 224 | int GetRandomSurfacePoint(Vector3 &point, Vector3 &normal);
|
---|
[372] | 225 |
|
---|
[1763] | 226 | int GetRandomVisibleSurfacePoint(Vector3 &point,
|
---|
| 227 | Vector3 &normal,
|
---|
| 228 | const Vector3 &viewpoint,
|
---|
| 229 | const int maxTries
|
---|
| 230 | );
|
---|
[372] | 231 |
|
---|
| 232 |
|
---|
[1763] | 233 | virtual int GetRandomEdgePoint(Vector3 &point,
|
---|
| 234 | Vector3 &normal);
|
---|
[372] | 235 |
|
---|
[1763] | 236 | Mesh *GetMesh() { return mMesh; }
|
---|
[372] | 237 |
|
---|
[1763] | 238 | virtual AxisAlignedBox3 GetBox() const {
|
---|
| 239 | return mMesh->mBox;
|
---|
| 240 | }
|
---|
[372] | 241 |
|
---|
[1763] | 242 | virtual int CastRay(Ray &ray);
|
---|
[2691] | 243 | virtual int CastSimpleRay(const SimpleRay &ray) { return 0;}
|
---|
| 244 | virtual int CastSimpleRay(const SimpleRay &ray, int IndexRay)
|
---|
| 245 | { return 0; }
|
---|
[372] | 246 |
|
---|
[1763] | 247 | virtual bool IsConvex() const { return mMesh->mIsConvex; }
|
---|
| 248 | virtual bool IsWatertight() const { return mMesh->mIsWatertight; }
|
---|
| 249 | virtual float IntersectionComplexity() { return (float)mMesh->mFaces.size(); }
|
---|
[387] | 250 |
|
---|
[1763] | 251 | virtual int NumberOfFaces() const { return (int)mMesh->mFaces.size(); }
|
---|
[372] | 252 |
|
---|
[1763] | 253 | virtual int Type() const { return MESH_INSTANCE; }
|
---|
[372] | 254 |
|
---|
[2569] | 255 | virtual int CastRay(Ray &ray, const std::vector<int> &faces);
|
---|
[372] | 256 |
|
---|
[2569] | 257 | virtual std::ostream &Describe(std::ostream &s)
|
---|
| 258 | {
|
---|
[372] | 259 | s<<"MeshInstance Id="<<GetId();
|
---|
| 260 | return mMesh->Describe(s);
|
---|
| 261 | }
|
---|
[1763] | 262 |
|
---|
[1001] | 263 | /** Sets the material. this overrides the material from
|
---|
[2569] | 264 | the mesh itself.
|
---|
[1001] | 265 | */
|
---|
| 266 | void SetMaterial(Material *mat);
|
---|
| 267 |
|
---|
| 268 | /** Returns the material of this mesh instance.
|
---|
[2569] | 269 | if not defined, returns the material of the mesh itself.
|
---|
[1001] | 270 | */
|
---|
| 271 | Material *GetMaterial() const;
|
---|
| 272 |
|
---|
[1344] | 273 | virtual Vector3 GetNormal(const int idx) const;
|
---|
| 274 |
|
---|
[1001] | 275 | protected:
|
---|
| 276 |
|
---|
| 277 | Mesh *mMesh;
|
---|
| 278 | /** This material overrides the mesh material;
|
---|
| 279 | */
|
---|
| 280 | Material *mMaterial;
|
---|
[372] | 281 | };
|
---|
| 282 |
|
---|
| 283 |
|
---|
[1001] | 284 | /** This mesh instance includes a world transform. Use this
|
---|
| 285 | class if the same mesh should be instantiated on different places.
|
---|
| 286 | */
|
---|
[1004] | 287 | class TransformedMeshInstance: public MeshInstance
|
---|
[372] | 288 | {
|
---|
| 289 | public:
|
---|
[2609] | 290 | TransformedMeshInstance(Mesh *mesh);
|
---|
[372] | 291 |
|
---|
[2609] | 292 | virtual AxisAlignedBox3 GetBox() const;
|
---|
[1004] | 293 |
|
---|
[2609] | 294 | virtual int CastRay(Ray &ray);
|
---|
[372] | 295 |
|
---|
[2609] | 296 | virtual int CastRay(Ray &ray, const std::vector<int> &faces);
|
---|
[372] | 297 |
|
---|
[2609] | 298 | virtual int Type() const { return TRANSFORMED_MESH_INSTANCE; }
|
---|
[1001] | 299 |
|
---|
[2609] | 300 | int GetRandomSurfacePoint(Vector3 &point, Vector3 &normal);
|
---|
[1001] | 301 |
|
---|
[2609] | 302 | /** Transforms this mesh instance by m.
|
---|
| 303 | */
|
---|
| 304 | void ApplyWorldTransform(const Matrix4x4 &m);
|
---|
| 305 | /** Loads the transformation matrix into this mesh instance.
|
---|
| 306 | */
|
---|
| 307 | void LoadWorldTransform(const Matrix4x4 &m);
|
---|
| 308 | /** The transformation is returned in m.
|
---|
| 309 | */
|
---|
| 310 | void GetWorldTransform(Matrix4x4 &m) const;
|
---|
| 311 | /** Transforms a mesh according to the stored world transform.
|
---|
| 312 | @param transformedMesh returns the tranformed mesh.
|
---|
| 313 | */
|
---|
| 314 | void GetTransformedMesh(Mesh &transformedMesh) const;
|
---|
[1001] | 315 |
|
---|
[2609] | 316 | Vector3 GetNormal(const int idx) const;
|
---|
[1002] | 317 |
|
---|
[1001] | 318 | protected:
|
---|
| 319 |
|
---|
| 320 | /// the transformation matrix
|
---|
| 321 | Matrix4x4 mWorldTransform;
|
---|
[372] | 322 |
|
---|
| 323 | };
|
---|
| 324 |
|
---|
[860] | 325 | }
|
---|
[372] | 326 |
|
---|
| 327 | #endif
|
---|