# HG changeset patch # User John Tsiombikas # Date 1380238192 -10800 # Node ID 1d85d7dd00380e55d22c49d3c14a5b40fbc29e87 # Parent cb6c1a945a11573acf97fc2c49bc3879bba9a095 goatprim done diff -r cb6c1a945a11 -r 1d85d7dd0038 generators/goatprim/main.c --- a/generators/goatprim/main.c Thu Sep 26 14:16:09 2013 +0300 +++ b/generators/goatprim/main.c Fri Sep 27 02:29:52 2013 +0300 @@ -1,78 +1,306 @@ #include +#include +#include +#include #include "goat3d.h" -static struct goat3d_mesh *create_box(void); +#define DEF_USUB 16 +#define DEF_VSUB 8 +#define DEF_SIZE 1.0 +#define DEF_OUTER 0.25 -int main(void) +enum { BOX, SPHERE, TORUS }; + +void gen_box(struct goat3d_mesh *mesh, float size); +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub); +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax); +void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub); +void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer, + int usub, int vsub, float umax, float vmin, float vmax); + + +int main(int argc, char **argv) { + int i, prim = BOX; + int usub = DEF_USUB; + int vsub = DEF_VSUB; + float size = DEF_SIZE; + float outer = DEF_OUTER; struct goat3d *goat; struct goat3d_material *mtl; struct goat3d_mesh *mesh; + const char *fname = 0; + + for(i=1; i, -rad , -inner (default: %g)\n", DEF_SIZE); + printf(" -outer torus outer radius (default: %g)\n", DEF_OUTER); + printf(" -usub subdivisions along the horizontal direction (default: %d)\n", DEF_USUB); + printf(" -vsub subdivisions along the vertical direction (default: %d)\n", DEF_VSUB); + printf(" -h, -help print usage information and exit\n"); + return 0; + + } else { + if(fname) { + fprintf(stderr, "unexpected argument: %s\n", argv[i]); + return 1; + } + fname = argv[i]; + } + } + + if(!fname) { + fname = "out.xml"; + } goat = goat3d_create(); + goat3d_set_name(goat, fname); mtl = goat3d_create_mtl(); goat3d_set_mtl_name(mtl, "mat"); goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, 1, 0, 0, 1); goat3d_add_mtl(goat, mtl); - mesh = create_box(); + mesh = goat3d_create_mesh(); + + switch(prim) { + case BOX: + gen_box(mesh, size); + break; + + case SPHERE: + gen_sphere(mesh, size, usub, vsub); + break; + + case TORUS: + gen_torus(mesh, size, outer, usub, vsub); + break; + + default: + return 1; + } + goat3d_set_mesh_mtl(mesh, mtl); goat3d_add_mesh(goat, mesh); goat3d_setopt(goat, GOAT3D_OPT_SAVEXML, 1); - goat3d_save(goat, "foo.xml"); + goat3d_save(goat, fname); goat3d_free(goat); return 0; } -static struct goat3d_mesh *create_box(void) +void gen_box(struct goat3d_mesh *mesh, float size) { - struct goat3d_mesh *mesh = goat3d_create_mesh(); + float hsz = size / 2.0; goat3d_begin(mesh, GOAT3D_QUADS); // +X goat3d_normal3f(1, 0, 0); - goat3d_vertex3f(-1, -1, 1); - goat3d_vertex3f(-1, -1, -1); - goat3d_vertex3f(-1, 1, -1); - goat3d_vertex3f(-1, 1, 1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(hsz, -hsz, hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(hsz, hsz, -hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(hsz, hsz, hsz); // -X goat3d_normal3f(-1, 0, 0); - goat3d_vertex3f(-1, -1, -1); - goat3d_vertex3f(-1, -1, 1); - goat3d_vertex3f(-1, 1, 1); - goat3d_vertex3f(-1, 1, -1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(-hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(-hsz, -hsz, hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(-hsz, hsz, hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(-hsz, hsz, -hsz); // +Y goat3d_normal3f(0, 1, 0); - goat3d_vertex3f(-1, 1, 1); - goat3d_vertex3f(1, 1, 1); - goat3d_vertex3f(1, 1, -1); - goat3d_vertex3f(-1, 1, -1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(-hsz, hsz, hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(hsz, hsz, hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(hsz, hsz, -hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(-hsz, hsz, -hsz); // -Y goat3d_normal3f(0, -1, 0); - goat3d_vertex3f(-1, -1, -1); - goat3d_vertex3f(1, -1, -1); - goat3d_vertex3f(1, -1, 1); - goat3d_vertex3f(-1, -1, 1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(-hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(hsz, -hsz, hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(-hsz, -hsz, hsz); // +Z goat3d_normal3f(0, 0, 1); - goat3d_vertex3f(-1, -1, 1); - goat3d_vertex3f(1, -1, 1); - goat3d_vertex3f(1, -1, 1); - goat3d_vertex3f(-1, -1, 1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(-hsz, -hsz, hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(hsz, -hsz, hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(hsz, hsz, hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(-hsz, hsz, hsz); // -Z goat3d_normal3f(0, 0, -1); - goat3d_vertex3f(-1, -1, 1); - goat3d_vertex3f(1, -1, 1); - goat3d_vertex3f(1, -1, -1); - goat3d_vertex3f(-1, -1, -1); + goat3d_texcoord2f(0, 0); + goat3d_vertex3f(hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 0); + goat3d_vertex3f(-hsz, -hsz, -hsz); + goat3d_texcoord2f(1, 1); + goat3d_vertex3f(-hsz, hsz, -hsz); + goat3d_texcoord2f(0, 1); + goat3d_vertex3f(hsz, hsz, -hsz); goat3d_end(); +} - return mesh; +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub) +{ + gen_sphere_part(mesh, rad, usub, vsub, 1.0, 1.0); } + +#define sphere_vertex(u, v) \ + do { \ + float x, y, z, theta, phi; \ + float costheta, sinphi; \ + theta = (u) * 2.0 * M_PI; \ + phi = (v) * M_PI; \ + costheta = cos(theta); \ + sinphi = sin(phi); \ + x = costheta * sinphi; \ + y = cos(phi); \ + z = sin(theta) * sinphi; \ + goat3d_normal3f(x, y, z); \ + goat3d_texcoord2f(u, v); \ + goat3d_vertex3f(rad * x, rad * y, rad * z); \ + } while(0) + +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax) +{ + int i, j; + float u, v, du, dv; + + if(usub < 3) usub = 3; + if(vsub < 3) vsub = 3; + + du = umax / (float)usub; + dv = vmax / (float)vsub; + + goat3d_begin(mesh, GOAT3D_QUADS); + + u = 0.0; + for(i=0; ivertices.size() / 3; + im_mesh->faces.resize(num_faces); + + int vidx = 0; + for(int i=0; ifaces[i].v[0] = vidx++; + im_mesh->faces[i].v[1] = vidx++; + im_mesh->faces[i].v[2] = vidx++; + } + } break; case GOAT3D_QUADS: - in_face_verts = 4; - out_face_verts = 6; - index_offs = quad_offs; + { + int num_quads = (int)im_mesh->vertices.size() / 4; + im_mesh->faces.resize(num_quads * 2); + + int vidx = 0; + for(int i=0; ifaces[i * 2].v[0] = vidx; + im_mesh->faces[i * 2].v[1] = vidx + 1; + im_mesh->faces[i * 2].v[2] = vidx + 2; + + im_mesh->faces[i * 2 + 1].v[0] = vidx; + im_mesh->faces[i * 2 + 1].v[1] = vidx + 2; + im_mesh->faces[i * 2 + 1].v[2] = vidx + 3; + + vidx += 4; + } + } break; default: return; }; - - num_faces = (int)im_mesh->vertices.size() / in_face_verts; - if(!num_faces) { - return; - } - - im_mesh->faces.resize(num_faces); - - int vidx = 0; - for(int i=0; ifaces[i].v[j] = vidx + index_offs[j]; - } - vidx += 4; - } } void goat3d_vertex3f(float x, float y, float z) @@ -424,21 +426,25 @@ void goat3d_normal3f(float x, float y, float z) { im_norm = Vector3(x, y, z); + im_use[GOAT3D_MESH_ATTR_NORMAL] = true; } void goat3d_tangent3f(float x, float y, float z) { im_tang = Vector3(x, y, z); + im_use[GOAT3D_MESH_ATTR_TANGENT] = true; } void goat3d_texcoord2f(float x, float y) { im_texcoord = Vector2(x, y); + im_use[GOAT3D_MESH_ATTR_TEXCOORD] = true; } void goat3d_skin_weight4f(float x, float y, float z, float w) { im_skinw = Vector4(x, y, z, w); + im_use[GOAT3D_MESH_ATTR_SKIN_WEIGHT] = true; } void goat3d_skin_matrix4i(int x, int y, int z, int w) @@ -447,16 +453,18 @@ im_skinmat.y = y; im_skinmat.z = z; im_skinmat.w = w; + im_use[GOAT3D_MESH_ATTR_SKIN_MATRIX] = true; } void goat3d_color3f(float x, float y, float z) { - im_color = Vector4(x, y, z, 1.0f); + goat3d_color4f(x, y, z, 1.0f); } void goat3d_color4f(float x, float y, float z, float w) { im_color = Vector4(x, y, z, w); + im_use[GOAT3D_MESH_ATTR_COLOR] = true; } void goat3d_add_mesh(struct goat3d *g, struct goat3d_mesh *mesh) diff -r cb6c1a945a11 -r 1d85d7dd0038 src/goat3d_scene.cc --- a/src/goat3d_scene.cc Thu Sep 26 14:16:09 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -#include -#include "goat3d.h" -#include "goat3d_impl.h" -#include "chunk.h" - -Scene::Scene() - : name("unnamed"), ambient(0.05, 0.05, 0.05) -{ -} - -Scene::~Scene() -{ - clear(); -} - -void Scene::clear() -{ - for(size_t i=0; iname = name; -} - -const char *Scene::get_name() const -{ - return name.c_str(); -} - -void Scene::set_ambient(const Vector3 &amb) -{ - ambient = amb; -} - -const Vector3 &Scene::get_ambient() const -{ - return ambient; -} - -void Scene::add_material(Material *mat) -{ - materials.push_back(mat); -} - -Material *Scene::get_material(int idx) const -{ - return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; -} - -Material *Scene::get_material(const char *name) const -{ - for(size_t i=0; iname == std::string(name)) { - return materials[i]; - } - } - return 0; -} - -int Scene::get_material_count() const -{ - return (int)materials.size(); -} - - -void Scene::add_mesh(Mesh *mesh) -{ - meshes.push_back(mesh); -} - -Mesh *Scene::get_mesh(int idx) const -{ - return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; -} - -Mesh *Scene::get_mesh(const char *name) const -{ - for(size_t i=0; iname == std::string(name)) { - return meshes[i]; - } - } - return 0; -} - -int Scene::get_mesh_count() const -{ - return (int)meshes.size(); -} - - -void Scene::add_light(Light *light) -{ - lights.push_back(light); -} - -Light *Scene::get_light(int idx) const -{ - return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; -} - -Light *Scene::get_light(const char *name) const -{ - for(size_t i=0; iname == std::string(name)) { - return lights[i]; - } - } - return 0; -} - -int Scene::get_light_count() const -{ - return (int)lights.size(); -} - - -void Scene::add_camera(Camera *cam) -{ - cameras.push_back(cam); -} - -Camera *Scene::get_camera(int idx) const -{ - return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; -} - -Camera *Scene::get_camera(const char *name) const -{ - for(size_t i=0; iname == std::string(name)) { - return cameras[i]; - } - } - return 0; -} - -int Scene::get_camera_count() const -{ - return (int)cameras.size(); -} - - -void Scene::add_node(Node *node) -{ - nodes.push_back(node); -} - -Node *Scene::get_node(int idx) const -{ - return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; -} - -Node *Scene::get_node(const char *name) const -{ - for(size_t i=0; iget_name(), name) == 0) { - return nodes[i]; - } - } - return 0; -} - -int Scene::get_node_count() const -{ - return (int)nodes.size(); -} - - -bool Scene::load(goat3d_io *io) -{ - return false; -} - -bool Scene::loadxml(goat3d_io *io) -{ - return false; -} - -// Scene::save is defined in goat3d_write.cc - - -void io_fprintf(goat3d_io *io, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - io_vfprintf(io, fmt, ap); - va_end(ap); -} - - -void io_vfprintf(goat3d_io *io, const char *fmt, va_list ap) -{ - char smallbuf[256]; - char *buf = smallbuf; - int sz = sizeof smallbuf; - - int retsz = vsnprintf(buf, sz - 1, fmt, ap); - - if(retsz >= sz) { - /* C99 mandates that snprintf with a short count should return the - * number of characters that *would* be printed. - */ - buf = new char[retsz + 1]; - - vsnprintf(buf, retsz, fmt, ap); - - } else if(retsz <= 0) { - /* SUSv2 and microsoft specify that snprintf with a short count - * returns an arbitrary value <= 0. So let's try allocating - * bigger and bigger arrays until we find the correct size. - */ - sz = sizeof smallbuf; - do { - sz *= 2; - if(buf != smallbuf) { - delete [] buf; - } - buf = new char[sz + 1]; - - retsz = vsnprintf(buf, sz, fmt, ap); - } while(retsz <= 0); - } - - io->write(buf, retsz, io->cls); - - if(buf != smallbuf) { - delete [] buf; - } - -} diff -r cb6c1a945a11 -r 1d85d7dd0038 src/goat3d_writexml.cc --- a/src/goat3d_writexml.cc Thu Sep 26 14:16:09 2013 +0300 +++ b/src/goat3d_writexml.cc Fri Sep 27 02:29:52 2013 +0300 @@ -1,6 +1,6 @@ #include #include "goat3d_impl.h" -#include "chunk.h" +#include "log.h" #include "openctm.h" static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level); @@ -76,7 +76,9 @@ // then refer to that filename in the XML tags xmlout(io, level, "\n"); xmlout(io, level + 1, "\n", mesh->name.c_str()); - xmlout(io, level + 1, "\n", mesh->material->name.c_str()); + if(mesh->material) { + xmlout(io, level + 1, "\n", mesh->material->name.c_str()); + } xmlout(io, level + 1, "\n", mesh_filename); xmlout(io, level, "\n"); return true; @@ -145,6 +147,7 @@ * probably in the comment field? */ + logmsg(LOG_INFO, "saving CTM mesh file: %s\n", fname); ctmSave(ctm, fname); ctmFreeContext(ctm); diff -r cb6c1a945a11 -r 1d85d7dd0038 src/log.cc --- a/src/log.cc Thu Sep 26 14:16:09 2013 +0300 +++ b/src/log.cc Fri Sep 27 02:29:52 2013 +0300 @@ -6,14 +6,13 @@ void logmsg(int prio, const char *fmt, ...) { - fprintf(stderr, "goat3d error: "); - va_list ap; - if(prio < goat_log_level) { + if(goat_log_level < prio) { return; } + fprintf(stderr, "goat3d: "); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); diff -r cb6c1a945a11 -r 1d85d7dd0038 src/scene.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/scene.cc Fri Sep 27 02:29:52 2013 +0300 @@ -0,0 +1,268 @@ +#include +#include "goat3d.h" +#include "goat3d_impl.h" +#include "chunk.h" + +Scene::Scene() + : name("unnamed"), ambient(0.05, 0.05, 0.05) +{ +} + +Scene::~Scene() +{ + clear(); +} + +void Scene::clear() +{ + for(size_t i=0; iname = name; +} + +const char *Scene::get_name() const +{ + return name.c_str(); +} + +void Scene::set_ambient(const Vector3 &amb) +{ + ambient = amb; +} + +const Vector3 &Scene::get_ambient() const +{ + return ambient; +} + +void Scene::add_material(Material *mat) +{ + if(mat->name.empty()) { + char buf[64]; + sprintf(buf, "material%04d", (int)materials.size()); + mat->name = std::string(buf); + } + materials.push_back(mat); +} + +Material *Scene::get_material(int idx) const +{ + return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; +} + +Material *Scene::get_material(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return materials[i]; + } + } + return 0; +} + +int Scene::get_material_count() const +{ + return (int)materials.size(); +} + + +void Scene::add_mesh(Mesh *mesh) +{ + if(mesh->name.empty()) { + char buf[64]; + sprintf(buf, "mesh%04d", (int)meshes.size()); + mesh->name = std::string(buf); + } + meshes.push_back(mesh); +} + +Mesh *Scene::get_mesh(int idx) const +{ + return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; +} + +Mesh *Scene::get_mesh(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return meshes[i]; + } + } + return 0; +} + +int Scene::get_mesh_count() const +{ + return (int)meshes.size(); +} + + +void Scene::add_light(Light *light) +{ + lights.push_back(light); +} + +Light *Scene::get_light(int idx) const +{ + return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; +} + +Light *Scene::get_light(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return lights[i]; + } + } + return 0; +} + +int Scene::get_light_count() const +{ + return (int)lights.size(); +} + + +void Scene::add_camera(Camera *cam) +{ + cameras.push_back(cam); +} + +Camera *Scene::get_camera(int idx) const +{ + return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; +} + +Camera *Scene::get_camera(const char *name) const +{ + for(size_t i=0; iname == std::string(name)) { + return cameras[i]; + } + } + return 0; +} + +int Scene::get_camera_count() const +{ + return (int)cameras.size(); +} + + +void Scene::add_node(Node *node) +{ + nodes.push_back(node); +} + +Node *Scene::get_node(int idx) const +{ + return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; +} + +Node *Scene::get_node(const char *name) const +{ + for(size_t i=0; iget_name(), name) == 0) { + return nodes[i]; + } + } + return 0; +} + +int Scene::get_node_count() const +{ + return (int)nodes.size(); +} + + +bool Scene::load(goat3d_io *io) +{ + return false; +} + +bool Scene::loadxml(goat3d_io *io) +{ + return false; +} + +// Scene::save is defined in goat3d_write.cc + + +void io_fprintf(goat3d_io *io, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + io_vfprintf(io, fmt, ap); + va_end(ap); +} + + +void io_vfprintf(goat3d_io *io, const char *fmt, va_list ap) +{ + char smallbuf[256]; + char *buf = smallbuf; + int sz = sizeof smallbuf; + + int retsz = vsnprintf(buf, sz - 1, fmt, ap); + + if(retsz >= sz) { + /* C99 mandates that snprintf with a short count should return the + * number of characters that *would* be printed. + */ + buf = new char[retsz + 1]; + + vsnprintf(buf, retsz, fmt, ap); + + } else if(retsz <= 0) { + /* SUSv2 and microsoft specify that snprintf with a short count + * returns an arbitrary value <= 0. So let's try allocating + * bigger and bigger arrays until we find the correct size. + */ + sz = sizeof smallbuf; + do { + sz *= 2; + if(buf != smallbuf) { + delete [] buf; + } + buf = new char[sz + 1]; + + retsz = vsnprintf(buf, sz, fmt, ap); + } while(retsz <= 0); + } + + io->write(buf, retsz, io->cls); + + if(buf != smallbuf) { + delete [] buf; + } + +}