summaryrefslogtreecommitdiff
path: root/include/gpac/internal/mesh.h
blob: 76a4582c5f318b277fe15b92676f8731a580e3ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / Scene Compositor sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#ifndef _GF_MESH_H_
#define _GF_MESH_H_

#include <gpac/scenegraph_vrml.h>
#include <gpac/path2d.h>
#include <gpac/mediaobject.h>

/*by default we store each color on 32 bit rather than 4 floats (128 bits)*/

//#define MESH_USE_SFCOLOR

#ifdef MESH_USE_SFCOLOR
#define MESH_MAKE_COL(_argb) _argb
#define MESH_GET_COLOR(_argb, _vertex) _argb = (_vertex).color;
#else
#define MESH_MAKE_COL(_argb) GF_COL_ARGB(FIX2INT(255*(_argb.alpha)), FIX2INT(255*(_argb.blue)), FIX2INT(255*(_argb.green)), FIX2INT(255*(_argb.red)))
#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; }
#endif

/*by default we store normals as signed bytes rather than floats*/

//#define MESH_USE_FIXED_NORMAL

#ifdef MESH_USE_FIXED_NORMAL
#define MESH_SET_NORMAL(_vertex, _nor) _vertex.normal = _nor;
#define MESH_GET_NORMAL(_nor, _vertex) _nor = _vertex.normal;
#define MESH_NORMAL_UNIT	FIX_ONE
#else

typedef struct
{
	s8 x, y, z;
	s8 __dummy;
} SFVec3f_bytes;

#define MESH_NORMAL_UNIT	1

#ifdef GPAC_FIXED_POINT
#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; }
#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)); }
#else
#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; }
#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)); }
#endif

#endif

typedef struct
{
	/*position*/
	SFVec3f pos;
	/*texture coordinates*/
	SFVec2f texcoords;
	/*normal*/
#ifdef MESH_USE_FIXED_NORMAL
	SFVec3f normal;
#else
	SFVec3f_bytes normal;
#endif
	/*color if used by mesh object*/
#ifdef MESH_USE_SFCOLOR
	SFColorRGBA color;
#else
	u32 color;
#endif
} GF_Vertex;

/*memory offset in bytes from start of vertex to texcoords = 3 * 4bytes*/
#define MESH_TEX_OFFSET	12
/*memory offset in bytes from start of vertex to normal = 5 * 4bytes*/
#define MESH_NORMAL_OFFSET	20
/*memory offset in bytes from start of vertex to color - platform dependent*/
#ifdef MESH_USE_FIXED_NORMAL
/*3+2+3 * 4*/
#define MESH_COLOR_OFFSET	32
#else
/*3+2 * 4 + 4 (3 + 1 byte alignment)*/
#define MESH_COLOR_OFFSET	24
#endif

/*mesh type used*/
enum
{
	/*default: triangles described by indices (nb triangles = nb indices / 3) */
	MESH_TRIANGLES = 0,
	/*point set: indices is meaningless*/
	MESH_POINTSET,
	/*line set: lines described by indices (nb lines = nb indices / 2) */
	MESH_LINESET,
};

/*mesh flags*/
enum
{
	/*vertex.color is used*/
	MESH_HAS_COLOR = 1,
	/*mesh is 2D: normal should be ignored and a global normal set to 0 0 1*/
	MESH_IS_2D = 1<<1,
	/*mesh has no texture coords - disable texturing*/
	MESH_NO_TEXTURE = 1<<2,
	/*mesh faces are clockwise*/
	MESH_IS_CW = 1<<3,
	/*mesh is solid (back face culling + 2 side lighting)*/
	MESH_IS_SOLID = 1<<4,
	/*mesh has smoothed normals*/
	MESH_IS_SMOOTHED = 1<<5,
	/*vertex.color is used with alpha channel*/
	MESH_HAS_ALPHA = 1<<6,
};

/*indexes as used in glDrawElements - note that integer type is not allowed with oglES*/
#if defined(GPAC_USE_GLES1X) || defined(GPAC_USE_GLES2)
#define IDX_TYPE	u16
#else
#define IDX_TYPE	u32
#endif

/*mesh object used by all 2D/3D primitives. */
typedef struct __gf_mesh
{
	/*vertex list*/
	u32 v_count, v_alloc;
	GF_Vertex *vertices;
	/*triangle indexes*/
	u32 i_count, i_alloc;
	IDX_TYPE *indices;

	/*one of the above type*/
	u32 mesh_type;

	/*one of the above flags*/
	u32 flags;

	/*bounds info: bounding box and bounding sphere radius*/
	GF_BBox bounds;

	/*aabb tree of the mesh if any*/
	struct __AABBNode *aabb_root;
	/*triangle indexes used in AABB tree - order may be different than the one in mesh->indices*/
	IDX_TYPE *aabb_indices;
//	u32 aabb_nb_index;

	u32 vbo;
	u32 vbo_idx;
	Bool vbo_dirty, vbo_dynamic;
} GF_Mesh;

GF_Mesh *new_mesh();
void mesh_free(GF_Mesh *mesh);
/*reset mesh*/
void mesh_reset(GF_Mesh *mesh);
/*recompute mesh bounds*/
void mesh_update_bounds(GF_Mesh *mesh);
/*adds new vertex*/
void mesh_set_vertex_vx(GF_Mesh *mesh, GF_Vertex *vx);
/*adds new vertex (exported for tesselator only)*/
void mesh_set_vertex(GF_Mesh *mesh, Fixed x, Fixed y, Fixed z, Fixed nx, Fixed ny, Fixed nz, Fixed u, Fixed v);
/*adds an index (exported for tesselator only)*/
void mesh_set_index(GF_Mesh *mesh, u32 idx);
/*adds an point & associated color, normal set to NULL*/
void mesh_set_point(GF_Mesh *mesh, Fixed x, Fixed y, Fixed z, SFColorRGBA col);
/*adds an index (exported for tesselator only)*/
void mesh_set_triangle(GF_Mesh *mesh, u32 id1, u32 id2, u32 id3);
/*make dest mesh the clone of orig*/
void mesh_clone(GF_Mesh *dest, GF_Mesh *orig);
/*recompute all normals*/
void mesh_recompute_normals(GF_Mesh *mesh);
/*generate texture coordinate - ONLY LOCAL MODES SUPPORTED FOR NOW*/
void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords);

/*inserts a box (lines only) of size 1.0 1.0 1.0*/
void mesh_new_unit_bbox(GF_Mesh *mesh);

/*insert base primitives - low res indicates less subdivision steps for circles (cone, cylinder, ellipse, sphere)*/
void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size, SFVec2f *orig, Bool flip);
void mesh_new_ellipse(GF_Mesh *mesh, Fixed a_dia, Fixed b_dia, Bool low_res);
void mesh_new_box(GF_Mesh *mesh, SFVec3f size);
void mesh_new_cylinder(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool top, Bool low_res);
void mesh_new_cone(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool low_res);


typedef struct
{
	Fixed min_phi;
	Fixed max_phi;
	Fixed min_theta;	
	Fixed max_theta;
} GF_MeshSphereAngles;
/*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*/
void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res, GF_MeshSphereAngles *angles);
/*inserts ILS/ILS2D and IFS2D outline when not filled*/
void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node *__color, MFInt32 *colorIndex, Bool colorPerVertex, Bool do_close);
/*inserts IFS2D*/
void mesh_new_ifs2d(GF_Mesh *mesh, GF_Node *ifs2d);
/*inserts IFS*/
void mesh_new_ifs(GF_Mesh *mesh, GF_Node *ifs);
/*inserts PS/PS2D*/
void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color);
/*inserts ElevationGrid*/
void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *eg);
/*inserts Extrusion*/
void mesh_new_extrusion(GF_Mesh *mesh, GF_Node *ext);
/*builds mesh from path, performing tesselation if desired*/
void mesh_from_path(GF_Mesh *mesh, GF_Path *path);
/*builds mesh for outline of the given path*/
void mesh_get_outline(GF_Mesh *mesh, GF_Path *path);
/*constructs an extrusion from given path - mesh is reseted, txcoords computed from path bounds
@thespine: spine line
@creaseAngle: creaseAngle for normal smoothing, 0 for no smoothing
begin_cap, end_cap: indicates whether start/end faces shall be added
@spine_ori: orientation at spine points
@spine_scale: scale at spine points
@tx_along_spine: if set, texture coords are generated so that the texture is mapped on the side,
otherwise the same txcoords are used all along the extrusion spine
*/
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);
/*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*/
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);

/*returns 1 if intersection and set outPoint to closest intersection, 0 otherwise*/
Bool gf_mesh_intersect_ray(GF_Mesh *mesh, GF_Ray *r, SFVec3f *outPoint, SFVec3f *outNormal, SFVec2f *outTexCoords);
/*returns 1 if any face is less than min_dist from pos, with collision point on closest face (towards pos)*/
Bool gf_mesh_closest_face(GF_Mesh *mesh, SFVec3f pos, Fixed min_dist, SFVec3f *outPoint);




/*AABB tree node (exported for bounds drawing)*/
typedef struct __AABBNode
{
	/*bbox*/
	SFVec3f min, max;
	/*sorted indices in mesh indices list*/
	IDX_TYPE *indices;
	/*nb triangles*/
	u32 nb_idx;
	/*children nodes, NULL if leaf*/
	struct __AABBNode *pos, *neg;
} AABBNode;

/*tree construction modes*/
enum
{
	/*AABB tree is not used*/
	AABB_NONE,
	/*longest box axis is used to divide an AABB node*/
	AABB_LONGEST,
	/*keep tree well-balanced*/
	AABB_BALANCED,
	/*best axis is use: test largest, then middle, then smallest axis*/
	AABB_BEST_AXIS,
	/*use variance to pick axis*/
	AABB_SPLATTER,
	/*fifty/fifty point split*/
	AABB_FIFTY,
};

void gf_mesh_build_aabbtree(GF_Mesh *mesh);


/*
 *		tesselation functions
 */

/*appends given face (and tesselate if needed) to the mesh. Only vertices are used in the face
indices are ignored.
partially implemented on ogl-ES*/
void TesselateFaceMesh(GF_Mesh *mesh, GF_Mesh *face);

#ifdef GPAC_HAS_GLU
/*converts 2D path into a polygon - these are only partially implemented when using oglES
for_outline:
	 0, regular odd/even windining rule with texCoords
	 1, zero-non-zero windining rule without texCoords
	 2, zero-non-zero windining rule with texCoords
*/
void gf_mesh_tesselate_path(GF_Mesh *mesh, GF_Path *path, u32 outline_style);

/*appends given face (and tesselate if needed) to the mesh. Only vertices are used in the face
indices are ignored.
Same as TesselateFaceMesh + faces info to determine where are the polygons in the face - used by extruder only
*/
void TesselateFaceMeshComplex(GF_Mesh *dest, GF_Mesh *orig, u32 nbFaces, u32 *ptsPerFaces);

#endif

#endif		/*_GF_MESH_H_*/