added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / src / gfx / 3dgeom.hpp
1 /*
2 This file is part of the 3dengfx, realtime visualization system.
3 Copyright (c) 2004, 2005 John Tsiombikas <nuclear@siggraph.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 /* fundamendal data structures for 3D graphics
21  *
22  * Author: John Tsiombikas 2004
23  * Modified: 
24  *              Mihalis Georgoulopoulos 2004
25  *              John Tsiombikas 2005
26  */
27
28 // JT: seperated animation classes and placed them in animation.hpp/cpp - 2/2005
29
30 #ifndef _3DGEOM_HPP_
31 #define _3DGEOM_HPP_
32
33 #include "3dengfx_config.h"
34
35 #include "n3dmath2/n3dmath2.hpp"
36 #include "color.hpp"
37
38 #include <iostream>
39 #include <vector>
40
41 typedef uint32_t Index;
42
43 struct TexCoord {
44         scalar_t u, v, w;       // or s,t,v if you prefer... I like u,v,w more though.
45
46         TexCoord(scalar_t u = 0.0f, scalar_t v = 0.0f, scalar_t w = 0.0f);
47 };
48
49 class Triangle; // fwd declaration
50
51 class Vertex {
52 public:
53         Vector3 pos;
54         Vector3 normal;
55         Vector3 tangent;
56         Color color;
57         TexCoord tex[2];
58
59         Vertex();
60         Vertex(const Vector3 &position, scalar_t tu = 0.0f, scalar_t tv = 0.0f, const Color &color = Color(1.0f, 1.0f, 1.0f));
61 };
62
63 #define NO_ADJFACE 0xFFFFFFFF
64
65 class Edge {
66 public:
67         Index vertices[2];
68         Index adjfaces[2];
69
70         Edge();
71         Edge(Index v1, Index v2, Index af1 = NO_ADJFACE, Index af2 = NO_ADJFACE);
72 };
73
74 std::ostream &operator <<(std::ostream &o, const Edge &e);
75
76
77 class Triangle {
78 public:
79         Index vertices[3];
80         Vector3 normal;
81         Vector3 tangent;
82         unsigned int smoothing_group;
83
84         Triangle(Index v1 = 0, Index v2 = 0, Index v3 = 0);
85
86         void calculate_normal(const Vertex *vbuffer, bool normalize=false);
87         void calculate_tangent(const Vertex *vbuffer, bool normalize=false);
88 };
89
90 std::ostream &operator <<(std::ostream &o, const Triangle &t);
91
92
93
94 class Quad {
95 public:
96         Index vertices[4];
97         Vector3 normal;
98         unsigned int smoothing_group;
99
100         Quad(Index v1 = 0, Index v2 = 0, Index v3 = 0, Index v4 = 0);
101
102         void calculate_normal(const Vertex *vbuffer, bool normalize=0);
103 };
104
105
106 //////////////// Geometry Arrays //////////////
107 template <class DataType>
108 class GeometryArray {
109 private:
110         DataType *data;
111         unsigned long count;
112         bool dynamic;
113         unsigned int buffer_object;             // for OGL VBOs
114         bool vbo_in_sync;
115
116         void sync_buffer_object();
117
118 public:
119         GeometryArray(bool dynamic = true);
120         GeometryArray(const DataType *data, unsigned long count, bool dynamic = true);
121         GeometryArray(const GeometryArray &ga);
122         ~GeometryArray();
123
124         GeometryArray &operator =(const GeometryArray &ga);
125
126         inline void set_data(const DataType *data, unsigned long count);
127         inline const DataType *get_data() const;
128         inline DataType *get_mod_data();
129
130         inline unsigned long get_count() const;
131
132         inline void set_dynamic(bool enable);
133         inline bool get_dynamic() const;
134         
135         inline unsigned int get_buffer_object() const;
136 };
137
138
139 // specialization of template class GeometryArray for type Index
140 template <>
141 class GeometryArray<Index> {
142 private:
143         Index *data;
144         unsigned long count;
145         bool dynamic;
146         unsigned int buffer_object;
147         bool vbo_in_sync;
148
149         void sync_buffer_object();
150
151 public:
152         GeometryArray(bool dynamic = true);
153         GeometryArray(const Index *data, unsigned long count, bool dynamic = true);
154         GeometryArray(const GeometryArray<Triangle> &tarray);   // conversion from triangle data
155         GeometryArray(const GeometryArray &ga);
156         ~GeometryArray();
157
158         GeometryArray &operator =(const GeometryArray &ga);
159
160         void set_data(const Index *data, unsigned long count);
161         inline const Index *get_data() const;
162         inline Index *get_mod_data();
163
164         inline unsigned long get_count() const;
165
166         inline void set_dynamic(bool enable);
167         inline bool get_dynamic() const;
168
169         inline unsigned int get_buffer_object() const;
170         
171         friend void tri_to_index_array(GeometryArray<Index> *ia, const GeometryArray<Triangle> &ta);
172 };
173
174 typedef GeometryArray<Vertex> VertexArray;
175 typedef GeometryArray<Triangle> TriangleArray;
176 typedef GeometryArray<Index> IndexArray;
177
178 ////////////// triangle mesh class ////////////
179 struct VertexStatistics {
180         Vector3 centroid;
181         scalar_t min_dist;
182         scalar_t max_dist;
183         scalar_t avg_dist;
184         scalar_t xmin, xmax, ymin, ymax, zmin, zmax;
185 };
186
187 class TriMesh {
188 private:
189         VertexArray varray;
190         TriangleArray tarray;
191         IndexArray iarray;
192         IndexArray index_graph;
193         
194         GeometryArray<Edge> earray;
195
196         mutable VertexStatistics vstats;
197         
198         mutable bool vertex_stats_valid;
199         bool indices_valid;
200         bool edges_valid;
201         bool index_graph_valid;
202         bool triangle_normals_valid;
203         bool triangle_normals_normalized;
204         
205         void calculate_edges();
206         void calculate_index_graph();
207         void calculate_triangle_normals(bool normalize);
208         
209 public:
210         TriMesh();
211         TriMesh(const Vertex *vdata, unsigned long vcount, const Triangle *tdata, unsigned long tcount);
212         
213         inline const VertexArray *get_vertex_array() const;
214         inline VertexArray *get_mod_vertex_array();
215         
216         inline const TriangleArray *get_triangle_array() const;
217         inline TriangleArray *get_mod_triangle_array();
218         
219         const IndexArray *get_index_array();
220         const GeometryArray<Edge> *get_edge_array() const;
221         
222         void set_data(const Vertex *vdata, unsigned long vcount, const Triangle *tdata, unsigned long tcount);  
223
224         void calculate_normals_by_index();
225         void calculate_normals();
226         void normalize_normals();
227         void invert_winding();
228
229         void calculate_tangents();
230
231         void apply_xform(const Matrix4x4 &xform);
232
233         void operator +=(const TriMesh *m2);
234
235         void sort_triangles(Vector3 point, bool hilo=true);
236         
237         VertexStatistics get_vertex_stats() const;
238
239         // shadow volumes
240         std::vector<Edge> *get_contour_edges(const Vector3 &pov_or_dir, bool dir = false);
241         //TriMesh *get_uncapped_shadow_volume(const Vector3 &pov_or_dir, bool dir = false);
242         TriMesh *get_shadow_volume(const Vector3 &pov_or_dir, bool dir = false);
243 };
244
245
246 /* utility functions
247  */
248 void join_tri_mesh(TriMesh *ret, const TriMesh *m1, const TriMesh *m2);
249 TriMesh *join_tri_mesh(const TriMesh *m1, const TriMesh *m2);
250 Vector3 extrude(const Vector3 &vec, scalar_t distance, const Vector3 &pov_or_dir, bool dir);
251
252 #include "3dgeom.inl"
253
254 #endif  // _3DGEOM_HPP_