1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2012
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / Scene Compositor sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 
27 #ifndef _GF_MESH_H_
28 #define _GF_MESH_H_
29 
30 #include <gpac/scenegraph_vrml.h>
31 #include <gpac/path2d.h>
32 #include <gpac/mediaobject.h>
33 
34 /*by default we store each color on 32 bit rather than 4 floats (128 bits)*/
35 
36 //#define MESH_USE_SFCOLOR
37 
38 #ifdef MESH_USE_SFCOLOR
39 #define MESH_MAKE_COL(_argb) _argb
40 #define MESH_GET_COLOR(_argb, _vertex) _argb = (_vertex).color;
41 #else
42 #define MESH_MAKE_COL(_argb) GF_COL_ARGB(FIX2INT(255*(_argb.alpha)), FIX2INT(255*(_argb.blue)), FIX2INT(255*(_argb.green)), FIX2INT(255*(_argb.red)))
43 #define MESH_GET_COLOR(_argb, _vertex) { _argb.alpha = INT2FIX(GF_COL_A((_vertex).color))/255; _argb.red = INT2FIX(GF_COL_R((_vertex).color))/255; _argb.green = INT2FIX(GF_COL_G((_vertex).color))/255; _argb.blue = INT2FIX(GF_COL_B((_vertex).color))/255; }
44 #endif
45 
46 /*by default we store normals as signed bytes rather than floats*/
47 
48 //#define MESH_USE_FIXED_NORMAL
49 
50 #ifdef MESH_USE_FIXED_NORMAL
51 #define MESH_SET_NORMAL(_vertex, _nor) _vertex.normal = _nor;
52 #define MESH_GET_NORMAL(_nor, _vertex) _nor = _vertex.normal;
53 #define MESH_NORMAL_UNIT	FIX_ONE
54 #else
55 
56 typedef struct
57 {
58 	s8 x, y, z;
59 	s8 __dummy;
60 } SFVec3f_bytes;
61 
62 #define MESH_NORMAL_UNIT	1
63 
64 #ifdef GPAC_FIXED_POINT
65 #define MESH_SET_NORMAL(_vertex, _nor) { SFVec3f_bytes __nor; __nor.x = (s8) FIX2INT(_nor.x*100); __nor.y = (s8) FIX2INT(_nor.y*100); __nor.z = (s8) FIX2INT(_nor.z*100); __nor.__dummy=0; _vertex.normal = __nor; }
66 #define MESH_GET_NORMAL(_nor, _vertex) { (_nor).x = INT2FIX(_vertex.normal.x); (_nor).y = INT2FIX(_vertex.normal.y); (_nor).z = INT2FIX(_vertex.normal.z); gf_vec_norm(&(_nor)); }
67 #else
68 #define MESH_SET_NORMAL(_vertex, _nor) { SFVec3f_bytes __nor; __nor.x = (s8) (_nor.x*100); __nor.y = (s8) (_nor.y*100); __nor.z = (s8) (_nor.z*100); __nor.__dummy=0; _vertex.normal = __nor; }
69 #define MESH_GET_NORMAL(_nor, _vertex) { (_nor).x = _vertex.normal.x; (_nor).y = _vertex.normal.y; (_nor).z = _vertex.normal.z; gf_vec_norm(&(_nor)); }
70 #endif
71 
72 #endif
73 
74 typedef struct
75 {
76 	/*position*/
77 	SFVec3f pos;
78 	/*texture coordinates*/
79 	SFVec2f texcoords;
80 	/*normal*/
81 #ifdef MESH_USE_FIXED_NORMAL
82 	SFVec3f normal;
83 #else
84 	SFVec3f_bytes normal;
85 #endif
86 	/*color if used by mesh object*/
87 #ifdef MESH_USE_SFCOLOR
88 	SFColorRGBA color;
89 #else
90 	u32 color;
91 #endif
92 } GF_Vertex;
93 
94 /*memory offset in bytes from start of vertex to texcoords = 3 * 4bytes*/
95 #define MESH_TEX_OFFSET	12
96 /*memory offset in bytes from start of vertex to normal = 5 * 4bytes*/
97 #define MESH_NORMAL_OFFSET	20
98 /*memory offset in bytes from start of vertex to color - platform dependent*/
99 #ifdef MESH_USE_FIXED_NORMAL
100 /*3+2+3 * 4*/
101 #define MESH_COLOR_OFFSET	32
102 #else
103 /*3+2 * 4 + 4 (3 + 1 byte alignment)*/
104 #define MESH_COLOR_OFFSET	24
105 #endif
106 
107 /*mesh type used*/
108 enum
109 {
110 	/*default: triangles described by indices (nb triangles = nb indices / 3) */
111 	MESH_TRIANGLES = 0,
112 	/*point set: indices is meaningless*/
113 	MESH_POINTSET,
114 	/*line set: lines described by indices (nb lines = nb indices / 2) */
115 	MESH_LINESET,
116 };
117 
118 /*mesh flags*/
119 enum
120 {
121 	/*vertex.color is used*/
122 	MESH_HAS_COLOR = 1,
123 	/*mesh is 2D: normal should be ignored and a global normal set to 0 0 1*/
124 	MESH_IS_2D = 1<<1,
125 	/*mesh has no texture coords - disable texturing*/
126 	MESH_NO_TEXTURE = 1<<2,
127 	/*mesh faces are clockwise*/
128 	MESH_IS_CW = 1<<3,
129 	/*mesh is solid (back face culling + 2 side lighting)*/
130 	MESH_IS_SOLID = 1<<4,
131 	/*mesh has smoothed normals*/
132 	MESH_IS_SMOOTHED = 1<<5,
133 	/*vertex.color is used with alpha channel*/
134 	MESH_HAS_ALPHA = 1<<6,
135 	/*flag only used by VRgeometry proto*/
136 	MESH_WAS_VISIBLE = 1<<7,
137 };
138 
139 /*indexes as used in glDrawElements - note that integer type is not allowed with oglES*/
140 #if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2)
141 #define IDX_TYPE	u16
142 #else
143 #define IDX_TYPE	u32
144 #endif
145 
146 /*mesh object used by all 2D/3D primitives. */
147 typedef struct __gf_mesh
148 {
149 	/*vertex list*/
150 	u32 v_count, v_alloc;
151 	GF_Vertex *vertices;
152 	/*triangle indexes*/
153 	u32 i_count, i_alloc;
154 	IDX_TYPE *indices;
155 
156 	/*one of the above type*/
157 	u32 mesh_type;
158 
159 	/*one of the above flags*/
160 	u32 flags;
161 
162 	/*bounds info: bounding box and bounding sphere radius*/
163 	GF_BBox bounds;
164 
165 	/*aabb tree of the mesh if any*/
166 	struct __AABBNode *aabb_root;
167 	/*triangle indexes used in AABB tree - order may be different than the one in mesh->indices*/
168 	IDX_TYPE *aabb_indices;
169 //	u32 aabb_nb_index;
170 
171 	u32 vbo;
172 	u32 vbo_idx;
173 	Bool vbo_dirty, vbo_dynamic;
174 } GF_Mesh;
175 
176 GF_Mesh *new_mesh();
177 void mesh_free(GF_Mesh *mesh);
178 /*reset mesh*/
179 void mesh_reset(GF_Mesh *mesh);
180 /*recompute mesh bounds*/
181 void mesh_update_bounds(GF_Mesh *mesh);
182 /*adds new vertex*/
183 void mesh_set_vertex_vx(GF_Mesh *mesh, GF_Vertex *vx);
184 /*adds new vertex (exported for tesselator only)*/
185 void mesh_set_vertex(GF_Mesh *mesh, Fixed x, Fixed y, Fixed z, Fixed nx, Fixed ny, Fixed nz, Fixed u, Fixed v);
186 /*adds an index (exported for tesselator only)*/
187 void mesh_set_index(GF_Mesh *mesh, u32 idx);
188 /*adds an point & associated color, normal set to NULL*/
189 void mesh_set_point(GF_Mesh *mesh, Fixed x, Fixed y, Fixed z, SFColorRGBA col);
190 /*adds an index (exported for tesselator only)*/
191 void mesh_set_triangle(GF_Mesh *mesh, u32 id1, u32 id2, u32 id3);
192 /*make dest mesh the clone of orig*/
193 void mesh_clone(GF_Mesh *dest, GF_Mesh *orig);
194 /*recompute all normals*/
195 void mesh_recompute_normals(GF_Mesh *mesh);
196 /*generate texture coordinate - ONLY LOCAL MODES SUPPORTED FOR NOW*/
197 void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords);
198 
199 /*inserts a box (lines only) of size 1.0 1.0 1.0*/
200 void mesh_new_unit_bbox(GF_Mesh *mesh);
201 
202 /*insert base primitives - low res indicates less subdivision steps for circles (cone, cylinder, ellipse, sphere)*/
203 void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size, SFVec2f *orig, Bool flip);
204 void mesh_new_ellipse(GF_Mesh *mesh, Fixed a_dia, Fixed b_dia, Bool low_res);
205 void mesh_new_box(GF_Mesh *mesh, SFVec3f size);
206 void mesh_new_cylinder(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool top, Bool low_res);
207 void mesh_new_cone(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool low_res);
208 
209 
210 typedef struct
211 {
212 	Fixed min_phi;
213 	Fixed max_phi;
214 	Fixed min_theta;
215 	Fixed max_theta;
216 } GF_MeshSphereAngles;
217 /*create a new sphere of the given radius. If angles is set, mesh is a partial sphere but tx coords still range from 0,0 to 1,1*/
218 void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res, GF_MeshSphereAngles *angles);
219 /*inserts ILS/ILS2D and IFS2D outline when not filled*/
220 void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node *__color, MFInt32 *colorIndex, Bool colorPerVertex, Bool do_close);
221 /*inserts IFS2D*/
222 void mesh_new_ifs2d(GF_Mesh *mesh, GF_Node *ifs2d);
223 /*inserts IFS*/
224 void mesh_new_ifs(GF_Mesh *mesh, GF_Node *ifs);
225 /*inserts PS/PS2D*/
226 void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color);
227 /*inserts ElevationGrid*/
228 void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *eg);
229 /*inserts Extrusion*/
230 void mesh_new_extrusion(GF_Mesh *mesh, GF_Node *ext);
231 /*builds mesh from path, performing tesselation if desired*/
232 void mesh_from_path(GF_Mesh *mesh, GF_Path *path);
233 /*builds mesh for outline of the given path*/
234 void mesh_get_outline(GF_Mesh *mesh, GF_Path *path);
235 /*constructs an extrusion from given path - mesh is reseted, txcoords computed from path bounds
236 @thespine: spine line
237 @creaseAngle: creaseAngle for normal smoothing, 0 for no smoothing
238 begin_cap, end_cap: indicates whether start/end faces shall be added
239 @spine_ori: orientation at spine points
240 @spine_scale: scale at spine points
241 @tx_along_spine: if set, texture coords are generated so that the texture is mapped on the side,
242 otherwise the same txcoords are used all along the extrusion spine
243 */
244 void mesh_extrude_path(GF_Mesh *mesh, GF_Path *path, MFVec3f *thespine, Fixed creaseAngle, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool tx_along_spine);
245 /*special extension of the above: APPENDS an extrusion from given path - mesh is NOT reseted, txcoords are computed based on min_cx, min_cy, width_cx, width_cy*/
246 void mesh_extrude_path_ext(GF_Mesh *mesh, GF_Path *path, MFVec3f *thespine, Fixed creaseAngle, Fixed min_cx, Fixed min_cy, Fixed width_cx, Fixed width_cy, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool tx_along_spine);
247 
248 /*returns 1 if intersection and set outPoint to closest intersection, 0 otherwise*/
249 Bool gf_mesh_intersect_ray(GF_Mesh *mesh, GF_Ray *r, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords);
250 /*returns 1 if any face is less than min_dist from pos, with collision point on closest face (towards pos)*/
251 Bool gf_mesh_closest_face(GF_Mesh *mesh, SFVec3f pos, Fixed min_dist, SFVec3f *outPoint);
252 
253 
254 
255 
256 /*AABB tree node (exported for bounds drawing)*/
257 typedef struct __AABBNode
258 {
259 	/*bbox*/
260 	SFVec3f min, max;
261 	/*sorted indices in mesh indices list*/
262 	IDX_TYPE *indices;
263 	/*nb triangles*/
264 	u32 nb_idx;
265 	/*children nodes, NULL if leaf*/
266 	struct __AABBNode *pos, *neg;
267 } AABBNode;
268 
269 /*tree construction modes*/
270 enum
271 {
272 	/*AABB tree is not used*/
273 	AABB_NONE,
274 	/*longest box axis is used to divide an AABB node*/
275 	AABB_LONGEST,
276 	/*keep tree well-balanced*/
277 	AABB_BALANCED,
278 	/*best axis is use: test largest, then middle, then smallest axis*/
279 	AABB_BEST_AXIS,
280 	/*use variance to pick axis*/
281 	AABB_SPLATTER,
282 	/*fifty/fifty point split*/
283 	AABB_FIFTY,
284 };
285 
286 void gf_mesh_build_aabbtree(GF_Mesh *mesh);
287 
288 
289 /*
290  *		tesselation functions
291  */
292 
293 /*appends given face (and tesselate if needed) to the mesh. Only vertices are used in the face
294 indices are ignored.
295 partially implemented on ogl-ES*/
296 void TesselateFaceMesh(GF_Mesh *mesh, GF_Mesh *face);
297 
298 #ifdef GPAC_HAS_GLU
299 /*converts 2D path into a polygon - these are only partially implemented when using oglES
300 for_outline:
301 	 0, regular odd/even windining rule with texCoords
302 	 1, zero-non-zero windining rule without texCoords
303 	 2, zero-non-zero windining rule with texCoords
304 */
305 void gf_mesh_tesselate_path(GF_Mesh *mesh, GF_Path *path, u32 outline_style);
306 
307 /*appends given face (and tesselate if needed) to the mesh. Only vertices are used in the face
308 indices are ignored.
309 Same as TesselateFaceMesh + faces info to determine where are the polygons in the face - used by extruder only
310 */
311 void TesselateFaceMeshComplex(GF_Mesh *dest, GF_Mesh *orig, u32 nbFaces, u32 *ptsPerFaces);
312 
313 #endif
314 
315 #endif		/*_GF_MESH_H_*/
316 
317