goat3d
changeset 17:1d85d7dd0038
goatprim done
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 27 Sep 2013 02:29:52 +0300 |
parents | cb6c1a945a11 |
children | bdfc8dd14965 |
files | generators/goatprim/main.c src/goat3d.cc src/goat3d_scene.cc src/goat3d_writexml.cc src/log.cc src/scene.cc |
diffstat | 6 files changed, 569 insertions(+), 321 deletions(-) [+] |
line diff
1.1 --- a/generators/goatprim/main.c Thu Sep 26 14:16:09 2013 +0300 1.2 +++ b/generators/goatprim/main.c Fri Sep 27 02:29:52 2013 +0300 1.3 @@ -1,78 +1,306 @@ 1.4 #include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <math.h> 1.8 #include "goat3d.h" 1.9 1.10 -static struct goat3d_mesh *create_box(void); 1.11 +#define DEF_USUB 16 1.12 +#define DEF_VSUB 8 1.13 +#define DEF_SIZE 1.0 1.14 +#define DEF_OUTER 0.25 1.15 1.16 -int main(void) 1.17 +enum { BOX, SPHERE, TORUS }; 1.18 + 1.19 +void gen_box(struct goat3d_mesh *mesh, float size); 1.20 +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub); 1.21 +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax); 1.22 +void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub); 1.23 +void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer, 1.24 + int usub, int vsub, float umax, float vmin, float vmax); 1.25 + 1.26 + 1.27 +int main(int argc, char **argv) 1.28 { 1.29 + int i, prim = BOX; 1.30 + int usub = DEF_USUB; 1.31 + int vsub = DEF_VSUB; 1.32 + float size = DEF_SIZE; 1.33 + float outer = DEF_OUTER; 1.34 struct goat3d *goat; 1.35 struct goat3d_material *mtl; 1.36 struct goat3d_mesh *mesh; 1.37 + const char *fname = 0; 1.38 + 1.39 + for(i=1; i<argc; i++) { 1.40 + if(strcmp(argv[i], "-box") == 0) { 1.41 + prim = BOX; 1.42 + 1.43 + } else if(strcmp(argv[i], "-sphere") == 0) { 1.44 + prim = SPHERE; 1.45 + 1.46 + } else if(strcmp(argv[i], "-torus") == 0) { 1.47 + prim = TORUS; 1.48 + 1.49 + } else if(strcmp(argv[i], "-rad") == 0 || strcmp(argv[i], "-size") == 0 1.50 + || strcmp(argv[i], "-inner") == 0) { 1.51 + if((size = atof(argv[++i])) == 0.0) { 1.52 + fprintf(stderr, "invalid size\n"); 1.53 + return 1; 1.54 + } 1.55 + 1.56 + } else if(strcmp(argv[i], "-outer") == 0) { 1.57 + if((outer = atof(argv[++i])) == 0.0) { 1.58 + fprintf(stderr, "invalid outer radius\n"); 1.59 + return 1; 1.60 + } 1.61 + 1.62 + } else if(strcmp(argv[i], "-usub") == 0) { 1.63 + if(!(usub = atoi(argv[++i]))) { 1.64 + fprintf(stderr, "invalid usub\n"); 1.65 + return 1; 1.66 + } 1.67 + 1.68 + } else if(strcmp(argv[i], "-vsub") == 0) { 1.69 + if(!(vsub = atoi(argv[++i]))) { 1.70 + fprintf(stderr, "invalid vsub\n"); 1.71 + return 1; 1.72 + } 1.73 + 1.74 + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) { 1.75 + printf("Usage: %s [filename] [options]\n", argv[0]); 1.76 + printf("Options:\n"); 1.77 + printf(" -box create box (default)\n"); 1.78 + printf(" -sphere create sphere\n"); 1.79 + printf(" -torus create torus\n"); 1.80 + printf(" -size <n>, -rad <n>, -inner <n> (default: %g)\n", DEF_SIZE); 1.81 + printf(" -outer <n> torus outer radius (default: %g)\n", DEF_OUTER); 1.82 + printf(" -usub <n> subdivisions along the horizontal direction (default: %d)\n", DEF_USUB); 1.83 + printf(" -vsub <n> subdivisions along the vertical direction (default: %d)\n", DEF_VSUB); 1.84 + printf(" -h, -help print usage information and exit\n"); 1.85 + return 0; 1.86 + 1.87 + } else { 1.88 + if(fname) { 1.89 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.90 + return 1; 1.91 + } 1.92 + fname = argv[i]; 1.93 + } 1.94 + } 1.95 + 1.96 + if(!fname) { 1.97 + fname = "out.xml"; 1.98 + } 1.99 1.100 goat = goat3d_create(); 1.101 + goat3d_set_name(goat, fname); 1.102 1.103 mtl = goat3d_create_mtl(); 1.104 goat3d_set_mtl_name(mtl, "mat"); 1.105 goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, 1, 0, 0, 1); 1.106 goat3d_add_mtl(goat, mtl); 1.107 1.108 - mesh = create_box(); 1.109 + mesh = goat3d_create_mesh(); 1.110 + 1.111 + switch(prim) { 1.112 + case BOX: 1.113 + gen_box(mesh, size); 1.114 + break; 1.115 + 1.116 + case SPHERE: 1.117 + gen_sphere(mesh, size, usub, vsub); 1.118 + break; 1.119 + 1.120 + case TORUS: 1.121 + gen_torus(mesh, size, outer, usub, vsub); 1.122 + break; 1.123 + 1.124 + default: 1.125 + return 1; 1.126 + } 1.127 + goat3d_set_mesh_mtl(mesh, mtl); 1.128 goat3d_add_mesh(goat, mesh); 1.129 1.130 goat3d_setopt(goat, GOAT3D_OPT_SAVEXML, 1); 1.131 - goat3d_save(goat, "foo.xml"); 1.132 + goat3d_save(goat, fname); 1.133 1.134 goat3d_free(goat); 1.135 return 0; 1.136 } 1.137 1.138 -static struct goat3d_mesh *create_box(void) 1.139 +void gen_box(struct goat3d_mesh *mesh, float size) 1.140 { 1.141 - struct goat3d_mesh *mesh = goat3d_create_mesh(); 1.142 + float hsz = size / 2.0; 1.143 1.144 goat3d_begin(mesh, GOAT3D_QUADS); 1.145 // +X 1.146 goat3d_normal3f(1, 0, 0); 1.147 - goat3d_vertex3f(-1, -1, 1); 1.148 - goat3d_vertex3f(-1, -1, -1); 1.149 - goat3d_vertex3f(-1, 1, -1); 1.150 - goat3d_vertex3f(-1, 1, 1); 1.151 + goat3d_texcoord2f(0, 0); 1.152 + goat3d_vertex3f(hsz, -hsz, hsz); 1.153 + goat3d_texcoord2f(1, 0); 1.154 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.155 + goat3d_texcoord2f(1, 1); 1.156 + goat3d_vertex3f(hsz, hsz, -hsz); 1.157 + goat3d_texcoord2f(0, 1); 1.158 + goat3d_vertex3f(hsz, hsz, hsz); 1.159 1.160 // -X 1.161 goat3d_normal3f(-1, 0, 0); 1.162 - goat3d_vertex3f(-1, -1, -1); 1.163 - goat3d_vertex3f(-1, -1, 1); 1.164 - goat3d_vertex3f(-1, 1, 1); 1.165 - goat3d_vertex3f(-1, 1, -1); 1.166 + goat3d_texcoord2f(0, 0); 1.167 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.168 + goat3d_texcoord2f(1, 0); 1.169 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.170 + goat3d_texcoord2f(1, 1); 1.171 + goat3d_vertex3f(-hsz, hsz, hsz); 1.172 + goat3d_texcoord2f(0, 1); 1.173 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.174 1.175 // +Y 1.176 goat3d_normal3f(0, 1, 0); 1.177 - goat3d_vertex3f(-1, 1, 1); 1.178 - goat3d_vertex3f(1, 1, 1); 1.179 - goat3d_vertex3f(1, 1, -1); 1.180 - goat3d_vertex3f(-1, 1, -1); 1.181 + goat3d_texcoord2f(0, 0); 1.182 + goat3d_vertex3f(-hsz, hsz, hsz); 1.183 + goat3d_texcoord2f(1, 0); 1.184 + goat3d_vertex3f(hsz, hsz, hsz); 1.185 + goat3d_texcoord2f(1, 1); 1.186 + goat3d_vertex3f(hsz, hsz, -hsz); 1.187 + goat3d_texcoord2f(0, 1); 1.188 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.189 1.190 // -Y 1.191 goat3d_normal3f(0, -1, 0); 1.192 - goat3d_vertex3f(-1, -1, -1); 1.193 - goat3d_vertex3f(1, -1, -1); 1.194 - goat3d_vertex3f(1, -1, 1); 1.195 - goat3d_vertex3f(-1, -1, 1); 1.196 + goat3d_texcoord2f(0, 0); 1.197 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.198 + goat3d_texcoord2f(1, 0); 1.199 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.200 + goat3d_texcoord2f(1, 1); 1.201 + goat3d_vertex3f(hsz, -hsz, hsz); 1.202 + goat3d_texcoord2f(0, 1); 1.203 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.204 1.205 // +Z 1.206 goat3d_normal3f(0, 0, 1); 1.207 - goat3d_vertex3f(-1, -1, 1); 1.208 - goat3d_vertex3f(1, -1, 1); 1.209 - goat3d_vertex3f(1, -1, 1); 1.210 - goat3d_vertex3f(-1, -1, 1); 1.211 + goat3d_texcoord2f(0, 0); 1.212 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.213 + goat3d_texcoord2f(1, 0); 1.214 + goat3d_vertex3f(hsz, -hsz, hsz); 1.215 + goat3d_texcoord2f(1, 1); 1.216 + goat3d_vertex3f(hsz, hsz, hsz); 1.217 + goat3d_texcoord2f(0, 1); 1.218 + goat3d_vertex3f(-hsz, hsz, hsz); 1.219 1.220 // -Z 1.221 goat3d_normal3f(0, 0, -1); 1.222 - goat3d_vertex3f(-1, -1, 1); 1.223 - goat3d_vertex3f(1, -1, 1); 1.224 - goat3d_vertex3f(1, -1, -1); 1.225 - goat3d_vertex3f(-1, -1, -1); 1.226 + goat3d_texcoord2f(0, 0); 1.227 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.228 + goat3d_texcoord2f(1, 0); 1.229 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.230 + goat3d_texcoord2f(1, 1); 1.231 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.232 + goat3d_texcoord2f(0, 1); 1.233 + goat3d_vertex3f(hsz, hsz, -hsz); 1.234 goat3d_end(); 1.235 +} 1.236 1.237 - return mesh; 1.238 +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub) 1.239 +{ 1.240 + gen_sphere_part(mesh, rad, usub, vsub, 1.0, 1.0); 1.241 } 1.242 + 1.243 +#define sphere_vertex(u, v) \ 1.244 + do { \ 1.245 + float x, y, z, theta, phi; \ 1.246 + float costheta, sinphi; \ 1.247 + theta = (u) * 2.0 * M_PI; \ 1.248 + phi = (v) * M_PI; \ 1.249 + costheta = cos(theta); \ 1.250 + sinphi = sin(phi); \ 1.251 + x = costheta * sinphi; \ 1.252 + y = cos(phi); \ 1.253 + z = sin(theta) * sinphi; \ 1.254 + goat3d_normal3f(x, y, z); \ 1.255 + goat3d_texcoord2f(u, v); \ 1.256 + goat3d_vertex3f(rad * x, rad * y, rad * z); \ 1.257 + } while(0) 1.258 + 1.259 +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax) 1.260 +{ 1.261 + int i, j; 1.262 + float u, v, du, dv; 1.263 + 1.264 + if(usub < 3) usub = 3; 1.265 + if(vsub < 3) vsub = 3; 1.266 + 1.267 + du = umax / (float)usub; 1.268 + dv = vmax / (float)vsub; 1.269 + 1.270 + goat3d_begin(mesh, GOAT3D_QUADS); 1.271 + 1.272 + u = 0.0; 1.273 + for(i=0; i<usub; i++) { 1.274 + v = 0.0; 1.275 + for(j=0; j<vsub; j++) { 1.276 + sphere_vertex(u, v); 1.277 + sphere_vertex(u + du, v); 1.278 + sphere_vertex(u + du, v + dv); 1.279 + sphere_vertex(u, v + dv); 1.280 + v += dv; 1.281 + } 1.282 + u += du; 1.283 + } 1.284 + goat3d_end(); 1.285 +} 1.286 + 1.287 + 1.288 +void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub) 1.289 +{ 1.290 + gen_torus_part(mesh, inner, outer, usub, vsub, 1.0, 0.0, 1.0); 1.291 +} 1.292 + 1.293 +#define torus_vertex(u, v) \ 1.294 + do { \ 1.295 + float rx, ry, rz, cx, cy, cz, theta, phi; \ 1.296 + float costheta, sintheta, sinphi; \ 1.297 + theta = (u) * 2.0 * M_PI; \ 1.298 + phi = (v) * 2.0 * M_PI; \ 1.299 + costheta = cos(theta); \ 1.300 + sintheta = sin(theta); \ 1.301 + sinphi = sin(phi); \ 1.302 + cx = costheta * inner; \ 1.303 + cy = 0.0f; \ 1.304 + cz = sintheta * inner; \ 1.305 + rx = costheta * sinphi; \ 1.306 + ry = cos(phi); \ 1.307 + rz = sintheta * sinphi; \ 1.308 + goat3d_normal3f(rx, ry, rz); \ 1.309 + goat3d_texcoord2f(u, v); \ 1.310 + goat3d_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \ 1.311 + } while(0) 1.312 + 1.313 +void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer, 1.314 + int usub, int vsub, float umax, float vmin, float vmax) 1.315 +{ 1.316 + int i, j; 1.317 + float u, v, du, dv; 1.318 + 1.319 + if(usub < 3) usub = 3; 1.320 + if(vsub < 3) vsub = 3; 1.321 + 1.322 + du = umax / (float)usub; 1.323 + dv = (vmax - vmin) / (float)vsub; 1.324 + 1.325 + goat3d_begin(mesh, GOAT3D_QUADS); 1.326 + 1.327 + u = 0.0; 1.328 + for(i=0; i<usub; i++) { 1.329 + v = vmin; 1.330 + for(j=0; j<vsub; j++) { 1.331 + torus_vertex(u, v); 1.332 + torus_vertex(u + du, v); 1.333 + torus_vertex(u + du, v + dv); 1.334 + torus_vertex(u, v + dv); 1.335 + v += dv; 1.336 + } 1.337 + u += du; 1.338 + } 1.339 + goat3d_end(); 1.340 +}
2.1 --- a/src/goat3d.cc Thu Sep 26 14:16:09 2013 +0300 2.2 +++ b/src/goat3d.cc Fri Sep 27 02:29:52 2013 +0300 2.3 @@ -360,42 +360,44 @@ 2.4 2.5 void goat3d_end(void) 2.6 { 2.7 - static int tri_offs[] = {0, 1, 2}; 2.8 - static int quad_offs[] = {0, 1, 2, 0, 2, 3}; 2.9 - int *index_offs; 2.10 - 2.11 - int num_faces, in_face_verts, out_face_verts; 2.12 switch(im_prim) { 2.13 case GOAT3D_TRIANGLES: 2.14 - in_face_verts = 3; 2.15 - out_face_verts = 3; 2.16 - index_offs = tri_offs; 2.17 + { 2.18 + int num_faces = (int)im_mesh->vertices.size() / 3; 2.19 + im_mesh->faces.resize(num_faces); 2.20 + 2.21 + int vidx = 0; 2.22 + for(int i=0; i<num_faces; i++) { 2.23 + im_mesh->faces[i].v[0] = vidx++; 2.24 + im_mesh->faces[i].v[1] = vidx++; 2.25 + im_mesh->faces[i].v[2] = vidx++; 2.26 + } 2.27 + } 2.28 break; 2.29 2.30 case GOAT3D_QUADS: 2.31 - in_face_verts = 4; 2.32 - out_face_verts = 6; 2.33 - index_offs = quad_offs; 2.34 + { 2.35 + int num_quads = (int)im_mesh->vertices.size() / 4; 2.36 + im_mesh->faces.resize(num_quads * 2); 2.37 + 2.38 + int vidx = 0; 2.39 + for(int i=0; i<num_quads; i++) { 2.40 + im_mesh->faces[i * 2].v[0] = vidx; 2.41 + im_mesh->faces[i * 2].v[1] = vidx + 1; 2.42 + im_mesh->faces[i * 2].v[2] = vidx + 2; 2.43 + 2.44 + im_mesh->faces[i * 2 + 1].v[0] = vidx; 2.45 + im_mesh->faces[i * 2 + 1].v[1] = vidx + 2; 2.46 + im_mesh->faces[i * 2 + 1].v[2] = vidx + 3; 2.47 + 2.48 + vidx += 4; 2.49 + } 2.50 + } 2.51 break; 2.52 2.53 default: 2.54 return; 2.55 }; 2.56 - 2.57 - num_faces = (int)im_mesh->vertices.size() / in_face_verts; 2.58 - if(!num_faces) { 2.59 - return; 2.60 - } 2.61 - 2.62 - im_mesh->faces.resize(num_faces); 2.63 - 2.64 - int vidx = 0; 2.65 - for(int i=0; i<num_faces; i++) { 2.66 - for(int j=0; j<out_face_verts; j++) { 2.67 - im_mesh->faces[i].v[j] = vidx + index_offs[j]; 2.68 - } 2.69 - vidx += 4; 2.70 - } 2.71 } 2.72 2.73 void goat3d_vertex3f(float x, float y, float z) 2.74 @@ -424,21 +426,25 @@ 2.75 void goat3d_normal3f(float x, float y, float z) 2.76 { 2.77 im_norm = Vector3(x, y, z); 2.78 + im_use[GOAT3D_MESH_ATTR_NORMAL] = true; 2.79 } 2.80 2.81 void goat3d_tangent3f(float x, float y, float z) 2.82 { 2.83 im_tang = Vector3(x, y, z); 2.84 + im_use[GOAT3D_MESH_ATTR_TANGENT] = true; 2.85 } 2.86 2.87 void goat3d_texcoord2f(float x, float y) 2.88 { 2.89 im_texcoord = Vector2(x, y); 2.90 + im_use[GOAT3D_MESH_ATTR_TEXCOORD] = true; 2.91 } 2.92 2.93 void goat3d_skin_weight4f(float x, float y, float z, float w) 2.94 { 2.95 im_skinw = Vector4(x, y, z, w); 2.96 + im_use[GOAT3D_MESH_ATTR_SKIN_WEIGHT] = true; 2.97 } 2.98 2.99 void goat3d_skin_matrix4i(int x, int y, int z, int w) 2.100 @@ -447,16 +453,18 @@ 2.101 im_skinmat.y = y; 2.102 im_skinmat.z = z; 2.103 im_skinmat.w = w; 2.104 + im_use[GOAT3D_MESH_ATTR_SKIN_MATRIX] = true; 2.105 } 2.106 2.107 void goat3d_color3f(float x, float y, float z) 2.108 { 2.109 - im_color = Vector4(x, y, z, 1.0f); 2.110 + goat3d_color4f(x, y, z, 1.0f); 2.111 } 2.112 2.113 void goat3d_color4f(float x, float y, float z, float w) 2.114 { 2.115 im_color = Vector4(x, y, z, w); 2.116 + im_use[GOAT3D_MESH_ATTR_COLOR] = true; 2.117 } 2.118 2.119 void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh)
3.1 --- a/src/goat3d_scene.cc Thu Sep 26 14:16:09 2013 +0300 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,258 +0,0 @@ 3.4 -#include <stdarg.h> 3.5 -#include "goat3d.h" 3.6 -#include "goat3d_impl.h" 3.7 -#include "chunk.h" 3.8 - 3.9 -Scene::Scene() 3.10 - : name("unnamed"), ambient(0.05, 0.05, 0.05) 3.11 -{ 3.12 -} 3.13 - 3.14 -Scene::~Scene() 3.15 -{ 3.16 - clear(); 3.17 -} 3.18 - 3.19 -void Scene::clear() 3.20 -{ 3.21 - for(size_t i=0; i<materials.size(); i++) { 3.22 - delete materials[i]; 3.23 - } 3.24 - materials.clear(); 3.25 - 3.26 - for(size_t i=0; i<meshes.size(); i++) { 3.27 - delete meshes[i]; 3.28 - } 3.29 - meshes.clear(); 3.30 - 3.31 - for(size_t i=0; i<lights.size(); i++) { 3.32 - delete lights[i]; 3.33 - } 3.34 - lights.clear(); 3.35 - 3.36 - for(size_t i=0; i<cameras.size(); i++) { 3.37 - delete cameras[i]; 3.38 - } 3.39 - cameras.clear(); 3.40 - 3.41 - for(size_t i=0; i<nodes.size(); i++) { 3.42 - delete_node_tree(nodes[i]); 3.43 - } 3.44 - nodes.clear(); 3.45 - 3.46 - name = "unnamed"; 3.47 -} 3.48 - 3.49 -void Scene::set_name(const char *name) 3.50 -{ 3.51 - this->name = name; 3.52 -} 3.53 - 3.54 -const char *Scene::get_name() const 3.55 -{ 3.56 - return name.c_str(); 3.57 -} 3.58 - 3.59 -void Scene::set_ambient(const Vector3 &amb) 3.60 -{ 3.61 - ambient = amb; 3.62 -} 3.63 - 3.64 -const Vector3 &Scene::get_ambient() const 3.65 -{ 3.66 - return ambient; 3.67 -} 3.68 - 3.69 -void Scene::add_material(Material *mat) 3.70 -{ 3.71 - materials.push_back(mat); 3.72 -} 3.73 - 3.74 -Material *Scene::get_material(int idx) const 3.75 -{ 3.76 - return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; 3.77 -} 3.78 - 3.79 -Material *Scene::get_material(const char *name) const 3.80 -{ 3.81 - for(size_t i=0; i<materials.size(); i++) { 3.82 - if(materials[i]->name == std::string(name)) { 3.83 - return materials[i]; 3.84 - } 3.85 - } 3.86 - return 0; 3.87 -} 3.88 - 3.89 -int Scene::get_material_count() const 3.90 -{ 3.91 - return (int)materials.size(); 3.92 -} 3.93 - 3.94 - 3.95 -void Scene::add_mesh(Mesh *mesh) 3.96 -{ 3.97 - meshes.push_back(mesh); 3.98 -} 3.99 - 3.100 -Mesh *Scene::get_mesh(int idx) const 3.101 -{ 3.102 - return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; 3.103 -} 3.104 - 3.105 -Mesh *Scene::get_mesh(const char *name) const 3.106 -{ 3.107 - for(size_t i=0; i<meshes.size(); i++) { 3.108 - if(meshes[i]->name == std::string(name)) { 3.109 - return meshes[i]; 3.110 - } 3.111 - } 3.112 - return 0; 3.113 -} 3.114 - 3.115 -int Scene::get_mesh_count() const 3.116 -{ 3.117 - return (int)meshes.size(); 3.118 -} 3.119 - 3.120 - 3.121 -void Scene::add_light(Light *light) 3.122 -{ 3.123 - lights.push_back(light); 3.124 -} 3.125 - 3.126 -Light *Scene::get_light(int idx) const 3.127 -{ 3.128 - return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; 3.129 -} 3.130 - 3.131 -Light *Scene::get_light(const char *name) const 3.132 -{ 3.133 - for(size_t i=0; i<lights.size(); i++) { 3.134 - if(lights[i]->name == std::string(name)) { 3.135 - return lights[i]; 3.136 - } 3.137 - } 3.138 - return 0; 3.139 -} 3.140 - 3.141 -int Scene::get_light_count() const 3.142 -{ 3.143 - return (int)lights.size(); 3.144 -} 3.145 - 3.146 - 3.147 -void Scene::add_camera(Camera *cam) 3.148 -{ 3.149 - cameras.push_back(cam); 3.150 -} 3.151 - 3.152 -Camera *Scene::get_camera(int idx) const 3.153 -{ 3.154 - return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; 3.155 -} 3.156 - 3.157 -Camera *Scene::get_camera(const char *name) const 3.158 -{ 3.159 - for(size_t i=0; i<cameras.size(); i++) { 3.160 - if(cameras[i]->name == std::string(name)) { 3.161 - return cameras[i]; 3.162 - } 3.163 - } 3.164 - return 0; 3.165 -} 3.166 - 3.167 -int Scene::get_camera_count() const 3.168 -{ 3.169 - return (int)cameras.size(); 3.170 -} 3.171 - 3.172 - 3.173 -void Scene::add_node(Node *node) 3.174 -{ 3.175 - nodes.push_back(node); 3.176 -} 3.177 - 3.178 -Node *Scene::get_node(int idx) const 3.179 -{ 3.180 - return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; 3.181 -} 3.182 - 3.183 -Node *Scene::get_node(const char *name) const 3.184 -{ 3.185 - for(size_t i=0; i<nodes.size(); i++) { 3.186 - if(strcmp(nodes[i]->get_name(), name) == 0) { 3.187 - return nodes[i]; 3.188 - } 3.189 - } 3.190 - return 0; 3.191 -} 3.192 - 3.193 -int Scene::get_node_count() const 3.194 -{ 3.195 - return (int)nodes.size(); 3.196 -} 3.197 - 3.198 - 3.199 -bool Scene::load(goat3d_io *io) 3.200 -{ 3.201 - return false; 3.202 -} 3.203 - 3.204 -bool Scene::loadxml(goat3d_io *io) 3.205 -{ 3.206 - return false; 3.207 -} 3.208 - 3.209 -// Scene::save is defined in goat3d_write.cc 3.210 - 3.211 - 3.212 -void io_fprintf(goat3d_io *io, const char *fmt, ...) 3.213 -{ 3.214 - va_list ap; 3.215 - 3.216 - va_start(ap, fmt); 3.217 - io_vfprintf(io, fmt, ap); 3.218 - va_end(ap); 3.219 -} 3.220 - 3.221 - 3.222 -void io_vfprintf(goat3d_io *io, const char *fmt, va_list ap) 3.223 -{ 3.224 - char smallbuf[256]; 3.225 - char *buf = smallbuf; 3.226 - int sz = sizeof smallbuf; 3.227 - 3.228 - int retsz = vsnprintf(buf, sz - 1, fmt, ap); 3.229 - 3.230 - if(retsz >= sz) { 3.231 - /* C99 mandates that snprintf with a short count should return the 3.232 - * number of characters that *would* be printed. 3.233 - */ 3.234 - buf = new char[retsz + 1]; 3.235 - 3.236 - vsnprintf(buf, retsz, fmt, ap); 3.237 - 3.238 - } else if(retsz <= 0) { 3.239 - /* SUSv2 and microsoft specify that snprintf with a short count 3.240 - * returns an arbitrary value <= 0. So let's try allocating 3.241 - * bigger and bigger arrays until we find the correct size. 3.242 - */ 3.243 - sz = sizeof smallbuf; 3.244 - do { 3.245 - sz *= 2; 3.246 - if(buf != smallbuf) { 3.247 - delete [] buf; 3.248 - } 3.249 - buf = new char[sz + 1]; 3.250 - 3.251 - retsz = vsnprintf(buf, sz, fmt, ap); 3.252 - } while(retsz <= 0); 3.253 - } 3.254 - 3.255 - io->write(buf, retsz, io->cls); 3.256 - 3.257 - if(buf != smallbuf) { 3.258 - delete [] buf; 3.259 - } 3.260 - 3.261 -}
4.1 --- a/src/goat3d_writexml.cc Thu Sep 26 14:16:09 2013 +0300 4.2 +++ b/src/goat3d_writexml.cc Fri Sep 27 02:29:52 2013 +0300 4.3 @@ -1,6 +1,6 @@ 4.4 #include <stdarg.h> 4.5 #include "goat3d_impl.h" 4.6 -#include "chunk.h" 4.7 +#include "log.h" 4.8 #include "openctm.h" 4.9 4.10 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level); 4.11 @@ -76,7 +76,9 @@ 4.12 // then refer to that filename in the XML tags 4.13 xmlout(io, level, "<mesh>\n"); 4.14 xmlout(io, level + 1, "<name string=\"%s\"/>\n", mesh->name.c_str()); 4.15 - xmlout(io, level + 1, "<material string=\"%s\"/>\n", mesh->material->name.c_str()); 4.16 + if(mesh->material) { 4.17 + xmlout(io, level + 1, "<material string=\"%s\"/>\n", mesh->material->name.c_str()); 4.18 + } 4.19 xmlout(io, level + 1, "<file string=\"%s\"/>\n", mesh_filename); 4.20 xmlout(io, level, "</mesh>\n"); 4.21 return true; 4.22 @@ -145,6 +147,7 @@ 4.23 * probably in the comment field? 4.24 */ 4.25 4.26 + logmsg(LOG_INFO, "saving CTM mesh file: %s\n", fname); 4.27 ctmSave(ctm, fname); 4.28 4.29 ctmFreeContext(ctm);
5.1 --- a/src/log.cc Thu Sep 26 14:16:09 2013 +0300 5.2 +++ b/src/log.cc Fri Sep 27 02:29:52 2013 +0300 5.3 @@ -6,14 +6,13 @@ 5.4 5.5 void logmsg(int prio, const char *fmt, ...) 5.6 { 5.7 - fprintf(stderr, "goat3d error: "); 5.8 - 5.9 va_list ap; 5.10 5.11 - if(prio < goat_log_level) { 5.12 + if(goat_log_level < prio) { 5.13 return; 5.14 } 5.15 5.16 + fprintf(stderr, "goat3d: "); 5.17 va_start(ap, fmt); 5.18 vfprintf(stderr, fmt, ap); 5.19 va_end(ap);
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/scene.cc Fri Sep 27 02:29:52 2013 +0300 6.3 @@ -0,0 +1,268 @@ 6.4 +#include <stdarg.h> 6.5 +#include "goat3d.h" 6.6 +#include "goat3d_impl.h" 6.7 +#include "chunk.h" 6.8 + 6.9 +Scene::Scene() 6.10 + : name("unnamed"), ambient(0.05, 0.05, 0.05) 6.11 +{ 6.12 +} 6.13 + 6.14 +Scene::~Scene() 6.15 +{ 6.16 + clear(); 6.17 +} 6.18 + 6.19 +void Scene::clear() 6.20 +{ 6.21 + for(size_t i=0; i<materials.size(); i++) { 6.22 + delete materials[i]; 6.23 + } 6.24 + materials.clear(); 6.25 + 6.26 + for(size_t i=0; i<meshes.size(); i++) { 6.27 + delete meshes[i]; 6.28 + } 6.29 + meshes.clear(); 6.30 + 6.31 + for(size_t i=0; i<lights.size(); i++) { 6.32 + delete lights[i]; 6.33 + } 6.34 + lights.clear(); 6.35 + 6.36 + for(size_t i=0; i<cameras.size(); i++) { 6.37 + delete cameras[i]; 6.38 + } 6.39 + cameras.clear(); 6.40 + 6.41 + for(size_t i=0; i<nodes.size(); i++) { 6.42 + delete_node_tree(nodes[i]); 6.43 + } 6.44 + nodes.clear(); 6.45 + 6.46 + name = "unnamed"; 6.47 +} 6.48 + 6.49 +void Scene::set_name(const char *name) 6.50 +{ 6.51 + this->name = name; 6.52 +} 6.53 + 6.54 +const char *Scene::get_name() const 6.55 +{ 6.56 + return name.c_str(); 6.57 +} 6.58 + 6.59 +void Scene::set_ambient(const Vector3 &amb) 6.60 +{ 6.61 + ambient = amb; 6.62 +} 6.63 + 6.64 +const Vector3 &Scene::get_ambient() const 6.65 +{ 6.66 + return ambient; 6.67 +} 6.68 + 6.69 +void Scene::add_material(Material *mat) 6.70 +{ 6.71 + if(mat->name.empty()) { 6.72 + char buf[64]; 6.73 + sprintf(buf, "material%04d", (int)materials.size()); 6.74 + mat->name = std::string(buf); 6.75 + } 6.76 + materials.push_back(mat); 6.77 +} 6.78 + 6.79 +Material *Scene::get_material(int idx) const 6.80 +{ 6.81 + return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; 6.82 +} 6.83 + 6.84 +Material *Scene::get_material(const char *name) const 6.85 +{ 6.86 + for(size_t i=0; i<materials.size(); i++) { 6.87 + if(materials[i]->name == std::string(name)) { 6.88 + return materials[i]; 6.89 + } 6.90 + } 6.91 + return 0; 6.92 +} 6.93 + 6.94 +int Scene::get_material_count() const 6.95 +{ 6.96 + return (int)materials.size(); 6.97 +} 6.98 + 6.99 + 6.100 +void Scene::add_mesh(Mesh *mesh) 6.101 +{ 6.102 + if(mesh->name.empty()) { 6.103 + char buf[64]; 6.104 + sprintf(buf, "mesh%04d", (int)meshes.size()); 6.105 + mesh->name = std::string(buf); 6.106 + } 6.107 + meshes.push_back(mesh); 6.108 +} 6.109 + 6.110 +Mesh *Scene::get_mesh(int idx) const 6.111 +{ 6.112 + return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; 6.113 +} 6.114 + 6.115 +Mesh *Scene::get_mesh(const char *name) const 6.116 +{ 6.117 + for(size_t i=0; i<meshes.size(); i++) { 6.118 + if(meshes[i]->name == std::string(name)) { 6.119 + return meshes[i]; 6.120 + } 6.121 + } 6.122 + return 0; 6.123 +} 6.124 + 6.125 +int Scene::get_mesh_count() const 6.126 +{ 6.127 + return (int)meshes.size(); 6.128 +} 6.129 + 6.130 + 6.131 +void Scene::add_light(Light *light) 6.132 +{ 6.133 + lights.push_back(light); 6.134 +} 6.135 + 6.136 +Light *Scene::get_light(int idx) const 6.137 +{ 6.138 + return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; 6.139 +} 6.140 + 6.141 +Light *Scene::get_light(const char *name) const 6.142 +{ 6.143 + for(size_t i=0; i<lights.size(); i++) { 6.144 + if(lights[i]->name == std::string(name)) { 6.145 + return lights[i]; 6.146 + } 6.147 + } 6.148 + return 0; 6.149 +} 6.150 + 6.151 +int Scene::get_light_count() const 6.152 +{ 6.153 + return (int)lights.size(); 6.154 +} 6.155 + 6.156 + 6.157 +void Scene::add_camera(Camera *cam) 6.158 +{ 6.159 + cameras.push_back(cam); 6.160 +} 6.161 + 6.162 +Camera *Scene::get_camera(int idx) const 6.163 +{ 6.164 + return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; 6.165 +} 6.166 + 6.167 +Camera *Scene::get_camera(const char *name) const 6.168 +{ 6.169 + for(size_t i=0; i<cameras.size(); i++) { 6.170 + if(cameras[i]->name == std::string(name)) { 6.171 + return cameras[i]; 6.172 + } 6.173 + } 6.174 + return 0; 6.175 +} 6.176 + 6.177 +int Scene::get_camera_count() const 6.178 +{ 6.179 + return (int)cameras.size(); 6.180 +} 6.181 + 6.182 + 6.183 +void Scene::add_node(Node *node) 6.184 +{ 6.185 + nodes.push_back(node); 6.186 +} 6.187 + 6.188 +Node *Scene::get_node(int idx) const 6.189 +{ 6.190 + return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; 6.191 +} 6.192 + 6.193 +Node *Scene::get_node(const char *name) const 6.194 +{ 6.195 + for(size_t i=0; i<nodes.size(); i++) { 6.196 + if(strcmp(nodes[i]->get_name(), name) == 0) { 6.197 + return nodes[i]; 6.198 + } 6.199 + } 6.200 + return 0; 6.201 +} 6.202 + 6.203 +int Scene::get_node_count() const 6.204 +{ 6.205 + return (int)nodes.size(); 6.206 +} 6.207 + 6.208 + 6.209 +bool Scene::load(goat3d_io *io) 6.210 +{ 6.211 + return false; 6.212 +} 6.213 + 6.214 +bool Scene::loadxml(goat3d_io *io) 6.215 +{ 6.216 + return false; 6.217 +} 6.218 + 6.219 +// Scene::save is defined in goat3d_write.cc 6.220 + 6.221 + 6.222 +void io_fprintf(goat3d_io *io, const char *fmt, ...) 6.223 +{ 6.224 + va_list ap; 6.225 + 6.226 + va_start(ap, fmt); 6.227 + io_vfprintf(io, fmt, ap); 6.228 + va_end(ap); 6.229 +} 6.230 + 6.231 + 6.232 +void io_vfprintf(goat3d_io *io, const char *fmt, va_list ap) 6.233 +{ 6.234 + char smallbuf[256]; 6.235 + char *buf = smallbuf; 6.236 + int sz = sizeof smallbuf; 6.237 + 6.238 + int retsz = vsnprintf(buf, sz - 1, fmt, ap); 6.239 + 6.240 + if(retsz >= sz) { 6.241 + /* C99 mandates that snprintf with a short count should return the 6.242 + * number of characters that *would* be printed. 6.243 + */ 6.244 + buf = new char[retsz + 1]; 6.245 + 6.246 + vsnprintf(buf, retsz, fmt, ap); 6.247 + 6.248 + } else if(retsz <= 0) { 6.249 + /* SUSv2 and microsoft specify that snprintf with a short count 6.250 + * returns an arbitrary value <= 0. So let's try allocating 6.251 + * bigger and bigger arrays until we find the correct size. 6.252 + */ 6.253 + sz = sizeof smallbuf; 6.254 + do { 6.255 + sz *= 2; 6.256 + if(buf != smallbuf) { 6.257 + delete [] buf; 6.258 + } 6.259 + buf = new char[sz + 1]; 6.260 + 6.261 + retsz = vsnprintf(buf, sz, fmt, ap); 6.262 + } while(retsz <= 0); 6.263 + } 6.264 + 6.265 + io->write(buf, retsz, io->cls); 6.266 + 6.267 + if(buf != smallbuf) { 6.268 + delete [] buf; 6.269 + } 6.270 + 6.271 +}