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