goat3d

annotate src/goat3d_writexml.cc @ 17:1d85d7dd0038

goatprim done
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Sep 2013 02:29:52 +0300
parents f1b4c27382ce
children bdfc8dd14965
rev   line source
nuclear@14 1 #include <stdarg.h>
nuclear@14 2 #include "goat3d_impl.h"
nuclear@17 3 #include "log.h"
nuclear@14 4 #include "openctm.h"
nuclear@14 5
nuclear@14 6 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level);
nuclear@14 7 static bool write_mesh(const Scene *scn, goat3d_io *io, const Mesh *mesh, int idx, int level);
nuclear@14 8 static void write_ctm_mesh(const Mesh *mesh, const char *fname);
nuclear@14 9 static bool write_light(const Scene *scn, goat3d_io *io, const Light *light, int level);
nuclear@14 10 static bool write_camera(const Scene *scn, goat3d_io *io, const Camera *cam, int level);
nuclear@14 11 static bool write_node(const Scene *scn, goat3d_io *io, const Node *node, int level);
nuclear@14 12 static void xmlout(goat3d_io *io, int level, const char *fmt, ...);
nuclear@14 13
nuclear@14 14 bool Scene::savexml(goat3d_io *io) const
nuclear@14 15 {
nuclear@14 16 xmlout(io, 0, "<scene>\n");
nuclear@14 17
nuclear@14 18 // write environment stuff
nuclear@14 19 xmlout(io, 1, "<env>\n");
nuclear@14 20 xmlout(io, 1, "</env>\n");
nuclear@14 21
nuclear@14 22 for(size_t i=0; i<materials.size(); i++) {
nuclear@14 23 write_material(this, io, materials[i], 1);
nuclear@14 24 }
nuclear@14 25 for(size_t i=0; i<meshes.size(); i++) {
nuclear@14 26 write_mesh(this, io, meshes[i], i, 1);
nuclear@14 27 }
nuclear@14 28 for(size_t i=0; i<lights.size(); i++) {
nuclear@14 29 write_light(this, io, lights[i], 1);
nuclear@14 30 }
nuclear@14 31 for(size_t i=0; i<cameras.size(); i++) {
nuclear@14 32 write_camera(this, io, cameras[i], 1);
nuclear@14 33 }
nuclear@14 34 for(size_t i=0; i<nodes.size(); i++) {
nuclear@14 35 write_node(this, io, nodes[i], 1);
nuclear@14 36 }
nuclear@14 37
nuclear@14 38 xmlout(io, 0, "</scene>\n");
nuclear@14 39 return true;
nuclear@14 40 }
nuclear@14 41
nuclear@14 42 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level)
nuclear@14 43 {
nuclear@14 44 xmlout(io, level, "<mtl>\n");
nuclear@14 45 xmlout(io, level + 1, "<name string=\"%s\"/>\n", mat->name.c_str());
nuclear@14 46
nuclear@14 47 for(int i=0; i<mat->get_attrib_count(); i++) {
nuclear@14 48 xmlout(io, level + 1, "<attr>\n");
nuclear@14 49 xmlout(io, level + 2, "<name string=\"%s\"/>\n", mat->get_attrib_name(i));
nuclear@14 50
nuclear@14 51 const MaterialAttrib &attr = (*mat)[i];
nuclear@15 52 xmlout(io, level + 2, "<val float4=\"%.3f %.3f %.3f %.3f\"/>\n", attr.value.x,
nuclear@14 53 attr.value.y, attr.value.z, attr.value.w);
nuclear@14 54 if(!attr.map.empty()) {
nuclear@14 55 xmlout(io, level + 2, "<map string=\"%s\"/>\n", attr.map.c_str());
nuclear@14 56 }
nuclear@14 57 xmlout(io, level + 1, "</attr>\n");
nuclear@14 58 }
nuclear@14 59 xmlout(io, level, "</mtl>\n");
nuclear@14 60 return true;
nuclear@14 61 }
nuclear@14 62
nuclear@14 63 static bool write_mesh(const Scene *scn, goat3d_io *io, const Mesh *mesh, int idx, int level)
nuclear@14 64 {
nuclear@14 65 // first write the external (openctm) mesh file
nuclear@14 66 const char *prefix = scn->get_name();
nuclear@14 67 if(!prefix) {
nuclear@14 68 prefix = "goat";
nuclear@14 69 }
nuclear@14 70
nuclear@14 71 char *mesh_filename = (char*)alloca(strlen(prefix) + 32);
nuclear@14 72 sprintf(mesh_filename, "%s-mesh%04d.ctm", prefix, idx);
nuclear@14 73
nuclear@14 74 write_ctm_mesh(mesh, mesh_filename);
nuclear@14 75
nuclear@14 76 // then refer to that filename in the XML tags
nuclear@14 77 xmlout(io, level, "<mesh>\n");
nuclear@14 78 xmlout(io, level + 1, "<name string=\"%s\"/>\n", mesh->name.c_str());
nuclear@17 79 if(mesh->material) {
nuclear@17 80 xmlout(io, level + 1, "<material string=\"%s\"/>\n", mesh->material->name.c_str());
nuclear@17 81 }
nuclear@14 82 xmlout(io, level + 1, "<file string=\"%s\"/>\n", mesh_filename);
nuclear@14 83 xmlout(io, level, "</mesh>\n");
nuclear@14 84 return true;
nuclear@14 85 }
nuclear@14 86
nuclear@14 87 static void write_ctm_mesh(const Mesh *mesh, const char *fname)
nuclear@14 88 {
nuclear@14 89 int vnum = (int)mesh->vertices.size();
nuclear@14 90
nuclear@14 91 CTMcontext ctm = ctmNewContext(CTM_EXPORT);
nuclear@14 92
nuclear@14 93 // vertices, normals, and face-vertex indices
nuclear@14 94 ctmDefineMesh(ctm, &mesh->vertices[0].x, vnum, (CTMuint*)mesh->faces[0].v,
nuclear@14 95 mesh->faces.size(), mesh->normals.empty() ? 0 : &mesh->normals[0].x);
nuclear@14 96
nuclear@14 97 // texture coordinates
nuclear@14 98 if(!mesh->texcoords.empty()) {
nuclear@15 99 ctmAddUVMap(ctm, &mesh->texcoords[0].x, "texcoord", 0);
nuclear@14 100 }
nuclear@14 101
nuclear@14 102 // vertex colors
nuclear@14 103 if(!mesh->colors.empty()) {
nuclear@14 104 ctmAddAttribMap(ctm, &mesh->colors[0].x, "color");
nuclear@14 105 }
nuclear@14 106
nuclear@14 107 // skin weights
nuclear@14 108 if(!mesh->skin_weights.empty()) {
nuclear@14 109 ctmAddAttribMap(ctm, &mesh->skin_weights[0].x, "skin_weight");
nuclear@14 110 }
nuclear@14 111
nuclear@14 112 // if either of the non-float4 attributes are present we need to make a tmp array
nuclear@14 113 CTMfloat *attr_array = 0;
nuclear@14 114 if(!mesh->tangents.empty() || !mesh->skin_matrices.empty()) {
nuclear@14 115 attr_array = new CTMfloat[vnum * 4 * sizeof *attr_array];
nuclear@14 116 }
nuclear@14 117
nuclear@14 118 // tangents
nuclear@14 119 if(!mesh->tangents.empty()) {
nuclear@14 120 CTMfloat *ptr = attr_array;
nuclear@14 121
nuclear@14 122 for(int i=0; i<vnum; i++) {
nuclear@14 123 *ptr++ = mesh->tangents[i].x;
nuclear@14 124 *ptr++ = mesh->tangents[i].y;
nuclear@14 125 *ptr++ = mesh->tangents[i].z;
nuclear@14 126 *ptr++ = 1.0;
nuclear@14 127 }
nuclear@14 128 ctmAddAttribMap(ctm, attr_array, "tangent");
nuclear@14 129 }
nuclear@14 130
nuclear@14 131 // skin matrix indices (4 per vertex)
nuclear@14 132 if(!mesh->skin_matrices.empty()) {
nuclear@14 133 CTMfloat *ptr = attr_array;
nuclear@14 134
nuclear@14 135 for(int i=0; i<vnum; i++) {
nuclear@14 136 *ptr++ = (float)mesh->skin_matrices[i].x;
nuclear@14 137 *ptr++ = (float)mesh->skin_matrices[i].y;
nuclear@14 138 *ptr++ = (float)mesh->skin_matrices[i].z;
nuclear@14 139 *ptr++ = (float)mesh->skin_matrices[i].w;
nuclear@14 140 }
nuclear@14 141 ctmAddAttribMap(ctm, attr_array, "skin_matrix");
nuclear@14 142 }
nuclear@14 143
nuclear@14 144 delete [] attr_array;
nuclear@14 145
nuclear@14 146 /* TODO find a way to specify the nodes participating in the skinning of this mesh
nuclear@14 147 * probably in the comment field?
nuclear@14 148 */
nuclear@14 149
nuclear@17 150 logmsg(LOG_INFO, "saving CTM mesh file: %s\n", fname);
nuclear@14 151 ctmSave(ctm, fname);
nuclear@14 152
nuclear@14 153 ctmFreeContext(ctm);
nuclear@14 154 }
nuclear@14 155
nuclear@14 156 static bool write_light(const Scene *scn, goat3d_io *io, const Light *light, int level)
nuclear@14 157 {
nuclear@14 158 return true;
nuclear@14 159 }
nuclear@14 160
nuclear@14 161 static bool write_camera(const Scene *scn, goat3d_io *io, const Camera *cam, int level)
nuclear@14 162 {
nuclear@14 163 return true;
nuclear@14 164 }
nuclear@14 165
nuclear@14 166 static bool write_node(const Scene *scn, goat3d_io *io, const Node *node, int level)
nuclear@14 167 {
nuclear@14 168 return true;
nuclear@14 169 }
nuclear@14 170
nuclear@14 171
nuclear@14 172 static void xmlout(goat3d_io *io, int level, const char *fmt, ...)
nuclear@14 173 {
nuclear@14 174 for(int i=0; i<level; i++) {
nuclear@14 175 io_fprintf(io, " ");
nuclear@14 176 }
nuclear@14 177
nuclear@14 178 va_list ap;
nuclear@14 179 va_start(ap, fmt);
nuclear@14 180 io_vfprintf(io, fmt, ap);
nuclear@14 181 va_end(ap);
nuclear@14 182 }