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