vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
grass_mesh.h
Go to the documentation of this file.
1 #ifndef GRASS_MESH_H
2 #define GRASS_MESH_H
3 
4 #include <osg/Geode>
5 #include <osg/Vec3>
6 
7 using namespace osg;
8 
9 namespace grass
10 {
11 
12 
13 
14 
15  // vertex with its normal
16  struct Vertex
17  {
18  Vec3 position, normal;
19  Vertex() {}
20  Vertex(Vec3 nPosition) : position(nPosition), normal(0,0,0) {}
21  Vertex(Vec3 nPosition, Vec3 nNormal) : position(nPosition), normal(nNormal) {}
22 
23  // moves this vertex between two specified vertices
24  // and sets its normal to average of normals of two specified vertices
25  void IsAverageOf(const Vertex & a, const Vertex & b)
26  {
27  this->position = (a.position + b.position) * 0.5f;
28  this->normal = (a.normal + b.normal) * 0.5f;
29  }
30  };
31 
32 
33 
34  // three triangle's vertices and its area and center
35  struct Triangle
36  {
37  public:
38  Vertex *A, *B, *C;
39  float area;
40  Vec3 center;
41 
42  private:
43  Vertex GetPointAt(const float a, const float b, const float c) const
44  {
45  return Vertex( A->position*a + B->position*b + C->position*c,
46  A->normal*a + B->normal*b + C->normal*c );
47  }
48  public:
49  // default constructor
50  Triangle() {}
51 
52  // constructor that gets pointers to its three vertices
53  // and computer the area and center itself
54  Triangle(Vertex * nA, Vertex * nB, Vertex * nC) : A(nA), B(nB), C(nC)
55  {
56  center = (A->position+B->position+C->position) * 0.33333f;
57  area = ( (A->position-B->position) ^ (A->position-C->position) ).length() * 0.5f;
58  }
59 
60  // returns random point (with its normal) lying on this triangle.
61  Vertex GetRandomPoint() const
62  {
63  // select an order of vertices while getting their coefficients
64  const int point = rand() % 6;
65  const float a = rand() / float(RAND_MAX*1.2f);
66  const float b = (1.0f - a) * rand() / float(RAND_MAX);
67  const float c = 1.0f - a - b;
68  switch(point)
69  {
70  case 0: return GetPointAt(a,b,c);
71  case 1: return GetPointAt(a,c,b);
72  case 2: return GetPointAt(b,c,a);
73  case 3: return GetPointAt(b,a,c);
74  case 4: return GetPointAt(c,a,b);
75  default: return GetPointAt(c,b,a);
76  }
77  }
78  };
79 
80 
81 
82 
83  // mesh containing info about vertices, normals and triangles
84  class Mesh : public osg::Referenced
85  {
86  private:
87  // maximal height of the grass
88  float maxGrassHeight;
89 
90  // triangles of this subtree (used in all meshes of this subtree)
91  Triangle * triangleBuffer;
92  unsigned int numOfTriangles;
93 
94  // vertices of triangles stored in vector 'triangleBuffer'
95  Vertex * vertices;
96  unsigned int numOfVertices;
97 
98  // boundingbox of this mesh
99  BoundingBox boundingBox;
100 
101  // computes boundingbox
102  void ComputeBoundingBox();
103 
104  public:
105  // pointers to triangles used in this single mesh
106  std::vector<Triangle*> triangles;
107 
108  // creates empty mesh
109  Mesh(const float nMaxGrassHeight)
110  : maxGrassHeight(nMaxGrassHeight), Referenced()
111  {
112  triangleBuffer = 0;
113  numOfTriangles = 0;
114  vertices = 0;
115  numOfVertices = 0;
116  }
117 
118  virtual ~Mesh()
119  {
120  if(vertices)
121  delete [] vertices;
122  if(triangleBuffer)
123  delete [] triangleBuffer;
124  }
125 
126  // returns the bounding box of this mesh
127  BoundingBox GetBound() const {return boundingBox;}
128 
129  // Divides this mesh into at least two and at most eight smaller meshes.
130  // Returns a vector with pointers to those new meshes. The original mesh is preserved.
131  std::vector<Mesh *> Divide() const;
132 
133  friend class TriangleCollector;
134  };
135 
136 
137 
138 
139 
140 }; // end of namespace grass
141 
142 #endif // GRASS_MESH_H