summaryrefslogtreecommitdiffstats
path: root/dev/MinGfx/src/mesh.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dev/MinGfx/src/mesh.h674
1 files changed, 337 insertions, 337 deletions
diff --git a/dev/MinGfx/src/mesh.h b/dev/MinGfx/src/mesh.h
index 74f2a2f..f3f877e 100644
--- a/dev/MinGfx/src/mesh.h
+++ b/dev/MinGfx/src/mesh.h
@@ -1,337 +1,337 @@
-/*
- This file is part of the MinGfx Project.
-
- Copyright (c) 2017,2018 Regents of the University of Minnesota.
- All Rights Reserved.
-
- Original Author(s) of this File:
- Dan Keefe, 2018, University of Minnesota
-
- Author(s) of Significant Updates/Modifications to the File:
- ...
- */
-
-#ifndef SRC_MESH_H_
-#define SRC_MESH_H_
-
-
-
-#include "bvh.h"
-#include "color.h"
-#include "opengl_headers.h"
-#include "point2.h"
-#include "point3.h"
-#include "vector3.h"
-
-#include <vector>
-
-
-namespace mingfx {
-
-class Matrix4;
-
-/** A triangle mesh data structure that can be rendered with a ShaderProgram
- like DefaultShader. The mesh can be created algorithmically by adding triangles
- one at a time or it can be loaded from an .obj file.
-
- Vertices are required -- you cannot have a mesh without vertices, but other
- attributes (normals, colors, texture coordinates) are optional. When Draw()
- is called the mesh will automatically set these other attributes if available.
-
- Example of loading from a file:
- ~~~
- // during initialization
- Mesh m;
- m.LoadFromOBJ(Platform::FindMinGfxDataFile("teapot.obj"));
- // also create a shader to draw it.
- DefaultShader s;
-
-
- // later to draw
- Matrix4 M;
- Matrix4 V = Matrix4::LookAt(Point3(0,0,3), Point3(0,0,0), Vector3(0,1,0));
- Matrix4 P = Matrix4::Perspective(60.0, aspect_ratio(), 0.1, 10.0);
- s.Draw(M, V, P, m, DefaultShader::MaterialProperties());
- ~~~
-
- Example of creating a mesh algorithmically:
- ~~~
- Mesh mesh1;
- int tri_id;
- // add a first triangle
- tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,0,0), Point3(1,1,0));
- // set attributes for the vertices
- mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
- mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,1), Point2(1,0));
-
- // add a second triangle and attributes
- tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,1,0), Point3(0,1,0));
- mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
- mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,0), Point2(0,0));
-
- // call this when done to save to the GPU
- mesh1.UpdateGPUMemory();
-
- // then you can draw the same way as in the previous example.
- ~~~
- In the mode used above where you add one triangle at a time there is no way to
- reuse vertices in multiple triangles. If you need to do this for efficiency
- or other reasons, then you can use an indexed faces mode where you set the
- mesh data structures directly.
-
- Example of creating a mesh that renders in an indexed faces mode:
- ~~~
- std::vector<unsigned int> indices;
- std::vector<Point3> vertices;
- std::vector<Vector3> normals;
- std::vector<Point2> texcoords;
-
- // four vertices, each requires 3 floats: (x,y,z)
- vertices.push_back(Point3(0,0,0));
- vertices.push_back(Point3(1,0,0));
- vertices.push_back(Point3(1,1,0));
- vertices.push_back(Point3(0,1,0));
-
- // four normals, each requires 3 floats: (x,y,z)
- normals.push_back(Vector3(0,0,1));
- normals.push_back(Vector3(0,0,1));
- normals.push_back(Vector3(0,0,1));
- normals.push_back(Vector3(0,0,1));
-
- // four texture coords, each requires 2 floats: (u,v)
- texcoords.push_back(Point2(0,1));
- texcoords.push_back(Point2(1,1));
- texcoords.push_back(Point2(1,0));
- texcoords.push_back(Point2(0,0));
-
- // indices into the arrays above for the first triangle
- indices.push_back(0);
- indices.push_back(1);
- indices.push_back(2);
-
- // indices for the second triangle, note some are reused
- indices.push_back(0);
- indices.push_back(2);
- indices.push_back(3);
-
- Mesh mesh1;
- mesh1.SetVertices(vertices);
- mesh1.SetNormals(normals);
- mesh1.SetTexCoords(0, texcoords);
- mesh1.SetIndices(indices);
- mesh1.UpdateGPUMemory();
-
- // then you can draw the same way as in the previous example.
- ~~~
- */
-class Mesh {
-public:
- /// Creates an empty mesh.
- Mesh();
-
- /// Copies all data and sets GPU dirty bit for the new mesh.
- Mesh(const Mesh &other);
-
- virtual ~Mesh();
-
-
- /** This reads a mesh stored in the common Wavefront Obj file format. The
- loader here is simplistic and not guaranteed to work on all valid .obj
- files, but it should work on many simple ones. UpdateGPUMemory() is
- called automatically after the model is loaded. */
- void LoadFromOBJ(const std::string &filename);
-
-
-
- // ---- TRIANGLE LIST MODE ----
- // No indices are stored, each set of 3 vertices forms a triangle, and if the
- // triangles share vertices, those vertices need to be repeated.
-
- /** Adds a triangle to the mesh datastructure and returns a triangle ID.
- The ID should then be used as the first argument for follow-on calls to
- SetNormals(), SetColors(), and SetTexCoords(). The vertices must be
- specified in counter-clockwise order so that the normal of the triangle
- can be determined following the right-hand rule. */
- int AddTriangle(Point3 v1, Point3 v2, Point3 v3);
-
- /** Updates the vertex positions for a triangle that has already been added
- to the mesh. */
- void UpdateTriangle(int triangle_id, Point3 v1, Point3 v2, Point3 v3);
-
- /** Sets the normals for the three vertices of a triangle that has already
- been added to the mesh */
- void SetNormals(int triangle_id, Vector3 n1, Vector3 n2, Vector3 n3);
-
- /** Sets per-vertex colors for the three vertices of a triangle that has already
- been added to the mesh */
- void SetColors(int triangle_id, Color c1, Color c2, Color c3);
-
- /** Sets the texture coordinates for the three vertices of a triangle that
- has already been added to the mesh. The first textureUnit is 0, and you
- should always use 0 for this parameter unless you are doing multi-texturing. */
- void SetTexCoords(int triangle_id, int texture_unit, Point2 uv1, Point2 uv2, Point2 uv3);
-
-
-
- // ---- INDEXED TRIANGLES MODE ----
- // Vertices are stored in an array and indices are stored in a separate array
- // each set of 3 indices into the vertex array defines one triangle. Here,
- // you cannot add one triangle at a time to the mesh. Instead you must set
- // the arrays of indices, vertices, and other attributes for the mesh at
- // once.
-
- /// Sets the vertex array for the mesh directly.
- void SetVertices(const std::vector<Point3> &verts);
-
- /// Sets the normal array for the mesh directly.
- void SetNormals(const std::vector<Vector3> &norms);
-
- /// Sets the per-vertex colors array for the mesh directly.
- void SetColors(const std::vector<Color> &colors);
-
- /// Sets a texture coordinates array for the mesh directly.
- void SetTexCoords(int texture_unit, const std::vector<Point2> &tex_coords);
-
- /// Sets the indices into the vertex array to use to create the triangles.
- /// Each consecutive set of 3 indices forms one triangle:
- /// (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ...
- void SetIndices(const std::vector<unsigned int> index_array);
-
-
- void SetInstanceTransforms(const std::vector<Matrix4> &xforms);
-
-
- // ---- These functions can be used instead of the above if you are working with
- // regular C-style arrays and floats rather than the higher level types like
- // Point3 and Vector3. ----
-
- /// Sets the vertex array for the mesh directly. Vertices are stored as
- /// (x,y,z), (x,y,z), (x,y,z), ...
- /// This version of the function accepts a C-style array rather than std::vector<>
- void SetVertices(float *verts_array, int num_verts);
-
- /// Sets the normal array for the mesh directly. Normals are stored as
- /// (x,y,z), (x,y,z), (x,y,z), ... following the same ordering as was used
- /// for SetVertices().
- /// This version of the function accepts a C-style array rather than std::vector<>
- void SetNormals(float *norms_array, int num_norms);
-
- /// Sets the per-vertex colors array for the mesh directly. Colors are stored as
- /// (r,g,b,a), (r,g,b,a), (r,g,b,a), ... following the same ordering as was used
- /// for SetVertices().
- /// This version of the function accepts a C-style array rather than std::vector<>
- void SetColors(float *colors_array, int num_colors);
-
- /// Sets a texture coordinates array for the mesh directly. Tex coords are stored as
- /// (u,v), (u,v), (u,v), ... following the same ordering as was used
- /// for SetVertices().
- /// This version of the function accepts a C-style array rather than std::vector<>
- void SetTexCoords(int texture_unit, float *tex_coords_array, int num_tex_coords);
-
- /// Sets the indices into the vertex array to use to create the triangles.
- /// Each consecutive set of 3 indices forms one triangle:
- /// (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ...
- /// This version of the function accepts a C-style array rather than std::vector<>
- void SetIndices(unsigned int *index_array, int num_indices);
-
-
-
- /** This copies the entire mesh data structure to a vertex array in GPU memory,
- which must happen before you can draw the mesh. For large meshes, this can
- take some time, so you may want to call this during initialization immediately
- after generating the mesh. If you do not, it will be called automatically
- for you the first time Draw() is called. If the mesh contains normals, per-
- vertex colors and/or texture coordinates these are added as attributes within
- the vertex array. */
- void UpdateGPUMemory();
-
- /** This sends the mesh vertices and attributes down the graphics pipe using
- glDrawArrays() for the non-indexed mode and glDrawElements() for the indexed
- mode. This is just the geometry -- for anything to show up on the screen,
- you must already have a ShaderProgram enabled before calling this function. */
- void Draw();
-
-
-
- /** This (re)calculates the normals for the mesh and stores them with the mesh
- data structure. It assumes a faceted mesh, like a cube, where each triangle
- has separate vertices. The normal is calculated for each triangle face and
- then the result is associated with each vertex that makes up the triangle.
- If you have a smooth mesh where vertices are shared between multiple faces
- then use CalcPerVertexNormals() instead. */
- void CalcPerFaceNormals();
-
- /** This (re)calculates the normals for the mesh and stores them with the mesh
- data structure. It assumes a smooth mesh, like a sphere, where each vertex
- belongs to one or more triangles. Each vertex normal is calculated as a
- weighted sum of the face normals for adjacent faces. The weighting is based
- upon the relative areas of the neighboring faces (i.e., a large neighboring
- triangle contributes more to the vertex normal than a small one). */
- void CalcPerVertexNormals();
-
-
- /** This (re)calculates a Bounding Volume Hierarchy for the mesh, which can
- be used together with Ray::FastIntersectMesh() to do faster ray-mesh
- intersection testing. */
- void BuildBVH();
-
- /** Returns a pointer to the underlying BVH data structure. If the data
- struture has not yet been build or needs to be updated due to a change in
- the geometry of the mesh, then the BVH is recalculated before returning
- the pointer. */
- BVH* bvh_ptr();
-
- // Access to properties indexed by vertex number
-
- /// The total number of vertices in the mesh.
- int num_vertices() const;
-
- /// Read only access to the vertex position data. Data are returned as a Point3. Indexed by vertex number. Also see num_vertices().
- /// Use the SetVertices() function to set (or edit) vertex data.
- Point3 read_vertex_data(int vertex_id) const;
-
- /// Read only access to per-vertex normal data. Data are returned as a Vector3. Indexed by vertex number. Also see num_vertices().
- /// Use the SetNormals() function to set (or edit) per-vertex normal data.
- Vector3 read_normal_data(int vertex_id) const;
-
- /// Read only access to per-vertex color data. Data are returned as a Color. Indexed by vertex number. Also see num_vertices().
- /// Use the SetColors() function to set (or edit) per-vertex color data.
- Color read_color_data(int vertex_id) const;
-
- /// Read only access to per-vertex texture coordinates data. Data are returned as a Point2. Indexed by vertex number. Also see num_vertices().
- /// Use the SetTexCoords() function to set (or edit) per-vertex tex coords.
- Point2 read_tex_coords_data(int texture_unit, int vertex_id) const;
-
-
- // Access to triangles
-
- /// The total number of triangles in the mesh.
- int num_triangles() const;
-
- /// Read only access to the indices that make up a particular triangle. Data are returned as a 3-element array
- // of unsigned ints. Use the SetIndices() function to set (or edit) the indices for the mesh.
- std::vector<unsigned int> read_triangle_indices_data(int triangle_id) const;
-
-
-private:
- std::vector<float> verts_;
- std::vector<float> norms_;
- std::vector<float> colors_;
- std::vector< std::vector<float> > tex_coords_;
- std::vector<unsigned int> indices_;
- std::vector<float> instance_xforms_;
-
- bool gpu_dirty_;
- GLuint vertex_buffer_;
- GLuint vertex_array_;
- GLuint element_buffer_;
-
- bool bvh_dirty_;
- BVH bvh_;
-};
-
-
-} // end namespace
-
-
-#endif
+/*
+ This file is part of the MinGfx Project.
+
+ Copyright (c) 2017,2018 Regents of the University of Minnesota.
+ All Rights Reserved.
+
+ Original Author(s) of this File:
+ Dan Keefe, 2018, University of Minnesota
+
+ Author(s) of Significant Updates/Modifications to the File:
+ ...
+ */
+
+#ifndef SRC_MESH_H_
+#define SRC_MESH_H_
+
+
+
+#include "bvh.h"
+#include "color.h"
+#include "opengl_headers.h"
+#include "point2.h"
+#include "point3.h"
+#include "vector3.h"
+
+#include <vector>
+
+
+namespace mingfx {
+
+class Matrix4;
+
+/** A triangle mesh data structure that can be rendered with a ShaderProgram
+ like DefaultShader. The mesh can be created algorithmically by adding triangles
+ one at a time or it can be loaded from an .obj file.
+
+ Vertices are required -- you cannot have a mesh without vertices, but other
+ attributes (normals, colors, texture coordinates) are optional. When Draw()
+ is called the mesh will automatically set these other attributes if available.
+
+ Example of loading from a file:
+ ~~~
+ // during initialization
+ Mesh m;
+ m.LoadFromOBJ(Platform::FindMinGfxDataFile("teapot.obj"));
+ // also create a shader to draw it.
+ DefaultShader s;
+
+
+ // later to draw
+ Matrix4 M;
+ Matrix4 V = Matrix4::LookAt(Point3(0,0,3), Point3(0,0,0), Vector3(0,1,0));
+ Matrix4 P = Matrix4::Perspective(60.0, aspect_ratio(), 0.1, 10.0);
+ s.Draw(M, V, P, m, DefaultShader::MaterialProperties());
+ ~~~
+
+ Example of creating a mesh algorithmically:
+ ~~~
+ Mesh mesh1;
+ int tri_id;
+ // add a first triangle
+ tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,0,0), Point3(1,1,0));
+ // set attributes for the vertices
+ mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
+ mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,1), Point2(1,0));
+
+ // add a second triangle and attributes
+ tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,1,0), Point3(0,1,0));
+ mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
+ mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,0), Point2(0,0));
+
+ // call this when done to save to the GPU
+ mesh1.UpdateGPUMemory();
+
+ // then you can draw the same way as in the previous example.
+ ~~~
+ In the mode used above where you add one triangle at a time there is no way to
+ reuse vertices in multiple triangles. If you need to do this for efficiency
+ or other reasons, then you can use an indexed faces mode where you set the
+ mesh data structures directly.
+
+ Example of creating a mesh that renders in an indexed faces mode:
+ ~~~
+ std::vector<unsigned int> indices;
+ std::vector<Point3> vertices;
+ std::vector<Vector3> normals;
+ std::vector<Point2> texcoords;
+
+ // four vertices, each requires 3 floats: (x,y,z)
+ vertices.push_back(Point3(0,0,0));
+ vertices.push_back(Point3(1,0,0));
+ vertices.push_back(Point3(1,1,0));
+ vertices.push_back(Point3(0,1,0));
+
+ // four normals, each requires 3 floats: (x,y,z)
+ normals.push_back(Vector3(0,0,1));
+ normals.push_back(Vector3(0,0,1));
+ normals.push_back(Vector3(0,0,1));
+ normals.push_back(Vector3(0,0,1));
+
+ // four texture coords, each requires 2 floats: (u,v)
+ texcoords.push_back(Point2(0,1));
+ texcoords.push_back(Point2(1,1));
+ texcoords.push_back(Point2(1,0));
+ texcoords.push_back(Point2(0,0));
+
+ // indices into the arrays above for the first triangle
+ indices.push_back(0);
+ indices.push_back(1);
+ indices.push_back(2);
+
+ // indices for the second triangle, note some are reused
+ indices.push_back(0);
+ indices.push_back(2);
+ indices.push_back(3);
+
+ Mesh mesh1;
+ mesh1.SetVertices(vertices);
+ mesh1.SetNormals(normals);
+ mesh1.SetTexCoords(0, texcoords);
+ mesh1.SetIndices(indices);
+ mesh1.UpdateGPUMemory();
+
+ // then you can draw the same way as in the previous example.
+ ~~~
+ */
+class Mesh {
+public:
+ /// Creates an empty mesh.
+ Mesh();
+
+ /// Copies all data and sets GPU dirty bit for the new mesh.
+ Mesh(const Mesh &other);
+
+ virtual ~Mesh();
+
+
+ /** This reads a mesh stored in the common Wavefront Obj file format. The
+ loader here is simplistic and not guaranteed to work on all valid .obj
+ files, but it should work on many simple ones. UpdateGPUMemory() is
+ called automatically after the model is loaded. */
+ void LoadFromOBJ(const std::string &filename);
+
+
+
+ // ---- TRIANGLE LIST MODE ----
+ // No indices are stored, each set of 3 vertices forms a triangle, and if the
+ // triangles share vertices, those vertices need to be repeated.
+
+ /** Adds a triangle to the mesh datastructure and returns a triangle ID.
+ The ID should then be used as the first argument for follow-on calls to
+ SetNormals(), SetColors(), and SetTexCoords(). The vertices must be
+ specified in counter-clockwise order so that the normal of the triangle
+ can be determined following the right-hand rule. */
+ int AddTriangle(Point3 v1, Point3 v2, Point3 v3);
+
+ /** Updates the vertex positions for a triangle that has already been added
+ to the mesh. */
+ void UpdateTriangle(int triangle_id, Point3 v1, Point3 v2, Point3 v3);
+
+ /** Sets the normals for the three vertices of a triangle that has already
+ been added to the mesh */
+ void SetNormals(int triangle_id, Vector3 n1, Vector3 n2, Vector3 n3);
+
+ /** Sets per-vertex colors for the three vertices of a triangle that has already
+ been added to the mesh */
+ void SetColors(int triangle_id, Color c1, Color c2, Color c3);
+
+ /** Sets the texture coordinates for the three vertices of a triangle that
+ has already been added to the mesh. The first textureUnit is 0, and you
+ should always use 0 for this parameter unless you are doing multi-texturing. */
+ void SetTexCoords(int triangle_id, int texture_unit, Point2 uv1, Point2 uv2, Point2 uv3);
+
+
+
+ // ---- INDEXED TRIANGLES MODE ----
+ // Vertices are stored in an array and indices are stored in a separate array
+ // each set of 3 indices into the vertex array defines one triangle. Here,
+ // you cannot add one triangle at a time to the mesh. Instead you must set
+ // the arrays of indices, vertices, and other attributes for the mesh at
+ // once.
+
+ /// Sets the vertex array for the mesh directly.
+ void SetVertices(const std::vector<Point3> &verts);
+
+ /// Sets the normal array for the mesh directly.
+ void SetNormals(const std::vector<Vector3> &norms);
+
+ /// Sets the per-vertex colors array for the mesh directly.
+ void SetColors(const std::vector<Color> &colors);
+
+ /// Sets a texture coordinates array for the mesh directly.
+ void SetTexCoords(int texture_unit, const std::vector<Point2> &tex_coords);
+
+ /// Sets the indices into the vertex array to use to create the triangles.
+ /// Each consecutive set of 3 indices forms one triangle:
+ /// (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ...
+ void SetIndices(const std::vector<unsigned int> index_array);
+
+
+ void SetInstanceTransforms(const std::vector<Matrix4> &xforms);
+
+
+ // ---- These functions can be used instead of the above if you are working with
+ // regular C-style arrays and floats rather than the higher level types like
+ // Point3 and Vector3. ----
+
+ /// Sets the vertex array for the mesh directly. Vertices are stored as
+ /// (x,y,z), (x,y,z), (x,y,z), ...
+ /// This version of the function accepts a C-style array rather than std::vector<>
+ void SetVertices(float *verts_array, int num_verts);
+
+ /// Sets the normal array for the mesh directly. Normals are stored as
+ /// (x,y,z), (x,y,z), (x,y,z), ... following the same ordering as was used
+ /// for SetVertices().
+ /// This version of the function accepts a C-style array rather than std::vector<>
+ void SetNormals(float *norms_array, int num_norms);
+
+ /// Sets the per-vertex colors array for the mesh directly. Colors are stored as
+ /// (r,g,b,a), (r,g,b,a), (r,g,b,a), ... following the same ordering as was used
+ /// for SetVertices().
+ /// This version of the function accepts a C-style array rather than std::vector<>
+ void SetColors(float *colors_array, int num_colors);
+
+ /// Sets a texture coordinates array for the mesh directly. Tex coords are stored as
+ /// (u,v), (u,v), (u,v), ... following the same ordering as was used
+ /// for SetVertices().
+ /// This version of the function accepts a C-style array rather than std::vector<>
+ void SetTexCoords(int texture_unit, float *tex_coords_array, int num_tex_coords);
+
+ /// Sets the indices into the vertex array to use to create the triangles.
+ /// Each consecutive set of 3 indices forms one triangle:
+ /// (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ...
+ /// This version of the function accepts a C-style array rather than std::vector<>
+ void SetIndices(unsigned int *index_array, int num_indices);
+
+
+
+ /** This copies the entire mesh data structure to a vertex array in GPU memory,
+ which must happen before you can draw the mesh. For large meshes, this can
+ take some time, so you may want to call this during initialization immediately
+ after generating the mesh. If you do not, it will be called automatically
+ for you the first time Draw() is called. If the mesh contains normals, per-
+ vertex colors and/or texture coordinates these are added as attributes within
+ the vertex array. */
+ void UpdateGPUMemory();
+
+ /** This sends the mesh vertices and attributes down the graphics pipe using
+ glDrawArrays() for the non-indexed mode and glDrawElements() for the indexed
+ mode. This is just the geometry -- for anything to show up on the screen,
+ you must already have a ShaderProgram enabled before calling this function. */
+ void Draw();
+
+
+
+ /** This (re)calculates the normals for the mesh and stores them with the mesh
+ data structure. It assumes a faceted mesh, like a cube, where each triangle
+ has separate vertices. The normal is calculated for each triangle face and
+ then the result is associated with each vertex that makes up the triangle.
+ If you have a smooth mesh where vertices are shared between multiple faces
+ then use CalcPerVertexNormals() instead. */
+ void CalcPerFaceNormals();
+
+ /** This (re)calculates the normals for the mesh and stores them with the mesh
+ data structure. It assumes a smooth mesh, like a sphere, where each vertex
+ belongs to one or more triangles. Each vertex normal is calculated as a
+ weighted sum of the face normals for adjacent faces. The weighting is based
+ upon the relative areas of the neighboring faces (i.e., a large neighboring
+ triangle contributes more to the vertex normal than a small one). */
+ void CalcPerVertexNormals();
+
+
+ /** This (re)calculates a Bounding Volume Hierarchy for the mesh, which can
+ be used together with Ray::FastIntersectMesh() to do faster ray-mesh
+ intersection testing. */
+ void BuildBVH();
+
+ /** Returns a pointer to the underlying BVH data structure. If the data
+ struture has not yet been build or needs to be updated due to a change in
+ the geometry of the mesh, then the BVH is recalculated before returning
+ the pointer. */
+ BVH* bvh_ptr();
+
+ // Access to properties indexed by vertex number
+
+ /// The total number of vertices in the mesh.
+ int num_vertices() const;
+
+ /// Read only access to the vertex position data. Data are returned as a Point3. Indexed by vertex number. Also see num_vertices().
+ /// Use the SetVertices() function to set (or edit) vertex data.
+ Point3 read_vertex_data(int vertex_id) const;
+
+ /// Read only access to per-vertex normal data. Data are returned as a Vector3. Indexed by vertex number. Also see num_vertices().
+ /// Use the SetNormals() function to set (or edit) per-vertex normal data.
+ Vector3 read_normal_data(int vertex_id) const;
+
+ /// Read only access to per-vertex color data. Data are returned as a Color. Indexed by vertex number. Also see num_vertices().
+ /// Use the SetColors() function to set (or edit) per-vertex color data.
+ Color read_color_data(int vertex_id) const;
+
+ /// Read only access to per-vertex texture coordinates data. Data are returned as a Point2. Indexed by vertex number. Also see num_vertices().
+ /// Use the SetTexCoords() function to set (or edit) per-vertex tex coords.
+ Point2 read_tex_coords_data(int texture_unit, int vertex_id) const;
+
+
+ // Access to triangles
+
+ /// The total number of triangles in the mesh.
+ int num_triangles() const;
+
+ /// Read only access to the indices that make up a particular triangle. Data are returned as a 3-element array
+ // of unsigned ints. Use the SetIndices() function to set (or edit) the indices for the mesh.
+ std::vector<unsigned int> read_triangle_indices_data(int triangle_id) const;
+
+
+private:
+ std::vector<float> verts_;
+ std::vector<float> norms_;
+ std::vector<float> colors_;
+ std::vector< std::vector<float> > tex_coords_;
+ std::vector<unsigned int> indices_;
+ std::vector<float> instance_xforms_;
+
+ bool gpu_dirty_;
+ GLuint vertex_buffer_;
+ GLuint vertex_array_;
+ GLuint element_buffer_;
+
+ bool bvh_dirty_;
+ BVH bvh_;
+};
+
+
+} // end namespace
+
+
+#endif