2e437817591191833e8684f85afa0cd3aa2cd6f9
[laserbrain_demo] / src / mesh.h
1 #ifndef MESH_H_
2 #define MESH_H_
3
4 #include <stdio.h>
5 #include <string>
6 #include <vector>
7 #include "gmath/gmath.h"
8 #include "geom.h"
9
10 enum {
11         MESH_ATTR_VERTEX,
12         MESH_ATTR_NORMAL,
13         MESH_ATTR_TANGENT,
14         MESH_ATTR_TEXCOORD,
15         MESH_ATTR_COLOR,
16         MESH_ATTR_BONEWEIGHTS,
17         MESH_ATTR_BONEIDX,
18         MESH_ATTR_TEXCOORD2,
19
20         NUM_MESH_ATTR
21 };
22
23 // intersection mode flags
24 enum {
25         ISECT_DEFAULT   = 0,    // default (whole mesh, all intersections)
26         ISECT_FRONT             = 1,    // front-faces only
27         ISECT_FACE              = 2,    // return intersected face pointer instead of mesh
28         ISECT_VERTICES  = 4             // return (?) TODO
29 };
30
31 //class XFormNode;
32
33
34 class Triangle {
35 public:
36         Vec3 v[3];
37         Vec3 normal;
38         bool normal_valid;
39         int id;
40
41         Triangle();
42         Triangle(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2);
43         Triangle(int n, const Vec3 *varr, const unsigned int *idxarr = 0);
44
45         /// calculate normal (quite expensive)
46         void calc_normal();
47         const Vec3 &get_normal() const;
48
49         void transform(const Mat4 &xform);
50
51         void draw() const;
52         void draw_wire() const;
53
54         /// calculate barycentric coordinates of a point
55         Vec3 calc_barycentric(const Vec3 &pos) const;
56
57         bool intersect(const Ray &ray, HitPoint *hit = 0) const;
58 };
59
60
61 class Mesh {
62 private:
63         std::string name;
64         unsigned int nverts, nfaces;
65
66         // current value for each attribute for the immedate mode
67         // interface.
68         Vec4 cur_val[NUM_MESH_ATTR];
69
70         unsigned int buffer_objects[NUM_MESH_ATTR + 1];
71
72         // vertex attribute data and buffer objects
73         struct VertexAttrib {
74                 int nelem;                                      // number of elements per attribute range: [1, 4]
75                 std::vector<float> data;
76                 unsigned int vbo;
77                 mutable bool vbo_valid;         // if this is false, the vbo needs updating from the data
78                 mutable bool data_valid;        // if this is false, the data needs to be pulled from the vbo
79                 //int sdr_loc;
80         } vattr[NUM_MESH_ATTR];
81
82         static int global_sdr_loc[NUM_MESH_ATTR];
83
84         //std::vector<XFormNode*> bones;        // bones affecting this mesh
85
86         // index data and buffer object
87         std::vector<unsigned int> idata;
88         unsigned int ibo;
89         mutable bool ibo_valid;
90         mutable bool idata_valid;
91
92         // index buffer object for wireframe rendering (constructed on demand)
93         unsigned int wire_ibo;
94         mutable bool wire_ibo_valid;
95
96         // axis-aligned bounding box
97         mutable AABox aabb;
98         mutable bool aabb_valid;
99
100         // bounding sphere
101         mutable Sphere bsph;
102         mutable bool bsph_valid;
103
104         // keeps the last intersected face
105         mutable Triangle hitface;
106         // keeps the last intersected vertex position
107         mutable Vec3 hitvert;
108
109         void calc_aabb();
110         void calc_bsph();
111
112         static unsigned int intersect_mode;
113         static float vertex_sel_dist;
114
115         static float vis_vecsize;
116
117         /// update the VBOs after data has changed (invalid vbo/ibo)
118         void update_buffers();
119         /// construct/update the wireframe index buffer (called from draw_wire).
120         void update_wire_ibo();
121
122         mutable int cur_sdr;
123         bool pre_draw() const;
124         void post_draw() const;
125
126
127 public:
128         static bool use_custom_sdr_attr;
129
130         Mesh();
131         ~Mesh();
132
133         Mesh(const Mesh &rhs);
134         Mesh &operator =(const Mesh &rhs);
135         bool clone(const Mesh &m);
136
137         void set_name(const char *name);
138         const char *get_name() const;
139
140         bool has_attrib(int attr) const;
141         bool is_indexed() const;
142
143         // clears everything about this mesh, and returns to the newly constructed state
144         void clear();
145
146         // access the vertex attribute data
147         // if vdata == 0, space is just allocated
148         float *set_attrib_data(int attrib, int nelem, unsigned int num, const float *vdata = 0); // invalidates vbo
149         float *get_attrib_data(int attrib);     // invalidates vbo
150         const float *get_attrib_data(int attrib) const;
151
152         // simple access to any particular attribute
153         void set_attrib(int attrib, int idx, const Vec4 &v); // invalidates vbo
154         Vec4 get_attrib(int attrib, int idx) const;
155
156         int get_attrib_count(int attrib) const;
157
158         // ... same for index data
159         unsigned int *set_index_data(int num, const unsigned int *indices = 0); // invalidates ibo
160         unsigned int *get_index_data(); // invalidates ibo
161         const unsigned int *get_index_data() const;
162
163         int get_index_count() const;
164
165         void append(const Mesh &mesh);
166
167         // immediate-mode style mesh construction interface
168         void vertex(float x, float y, float z);
169         void normal(float nx, float ny, float nz);
170         void tangent(float tx, float ty, float tz);
171         void texcoord(float u, float v, float w);
172         void boneweights(float w1, float w2, float w3, float w4);
173         void boneidx(int idx1, int idx2, int idx3, int idx4);
174
175         int get_poly_count() const;
176
177         /* apply a transformation to the vertices and its inverse-transpose
178          * to the normals and tangents.
179          */
180         void apply_xform(const Mat4 &xform);
181         void apply_xform(const Mat4 &xform, const Mat4 &dir_xform);
182
183         void flip();    // both faces and normals
184         void flip_faces();
185         void flip_normals();
186
187         void explode(); // undo all vertex sharing
188
189         void calc_face_normals(); // this is only guaranteed to work on an exploded mesh
190
191         // adds a bone and returns its index
192         /*int add_bone(XFormNode *bone);
193         const XFormNode *get_bone(int idx) const;
194         int get_bones_count() const;*/
195
196         // access the shader attribute locations
197         static void set_attrib_location(int attr, int loc);
198         static int get_attrib_location(int attr);
199         static void clear_attrib_locations();
200
201         static void set_vis_vecsize(float sz);
202         static float get_vis_vecsize();
203
204         void draw() const;
205         void draw_wire() const;
206         void draw_vertices() const;
207         void draw_normals() const;
208         void draw_tangents() const;
209
210         /** get the bounding box in local space. The result will be cached, and subsequent
211          * calls will return the same box. The cache gets invalidated by any functions that can affect
212          * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included).
213          * @{ */
214         void get_aabbox(Vec3 *vmin, Vec3 *vmax) const;
215         const AABox &get_aabbox() const;
216         /// @}
217
218         /** get the bounding sphere in local space. The result will be cached, and subsequent
219          * calls will return the same box. The cache gets invalidated by any functions that can affect
220          * the vertex data (non-const variant of get_attrib_data(MESH_ATTR_VERTEX, ...) included).
221          * @{ */
222         float get_bsphere(Vec3 *center, float *rad) const;
223         const Sphere &get_bsphere() const;
224         /// @}
225
226         static void set_intersect_mode(unsigned int mode);
227         static unsigned int get_intersect_mode();
228         static void set_vertex_select_distance(float dist);
229         static float get_vertex_select_distance();
230
231         /** Find the intersection between the mesh and a ray.
232          * XXX Brute force at the moment, not intended to be used for anything other than picking in tools.
233          *     If you intend to use it in a speed-critical part of the code, you'll *have* to optimize it!
234          */
235         bool intersect(const Ray &ray, HitPoint *hit = 0) const;
236
237         // texture coordinate manipulation
238         void texcoord_apply_xform(const Mat4 &xform);
239         void texcoord_gen_plane(const Vec3 &norm, const Vec3 &tang);
240         void texcoord_gen_box();
241         void texcoord_gen_cylinder();
242
243         bool dump(const char *fname) const;
244         bool dump(FILE *fp) const;
245         bool dump_obj(const char *fname) const;
246         bool dump_obj(FILE *fp) const;
247 };
248
249 #endif  // MESH_H_