goat3d

annotate src/goat3d_writexml.cc @ 40:a5c5cec3cb88

- added mesh attribute and face append functions - added Int4 constructor - continued the blender exporter - fixed a bug in clean_filename which made it produce unterminated strings - renamed clean_filename to goat3d_clean_filename and made it extern - added call to goat3d_clean_filename in the mesh XML export code to cleanup ctm filenames
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 13 Oct 2013 10:14:19 +0300
parents 0fe02696fb1e
children 498ca7ac7047
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
nuclear@14 5 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level);
nuclear@14 6 static bool write_mesh(const Scene *scn, goat3d_io *io, const Mesh *mesh, int idx, int level);
nuclear@14 7 static bool write_light(const Scene *scn, goat3d_io *io, const Light *light, int level);
nuclear@14 8 static bool write_camera(const Scene *scn, goat3d_io *io, const Camera *cam, int level);
nuclear@14 9 static bool write_node(const Scene *scn, goat3d_io *io, const Node *node, int level);
nuclear@14 10 static void xmlout(goat3d_io *io, int level, const char *fmt, ...);
nuclear@14 11
nuclear@14 12 bool Scene::savexml(goat3d_io *io) const
nuclear@14 13 {
nuclear@14 14 xmlout(io, 0, "<scene>\n");
nuclear@14 15
nuclear@14 16 // write environment stuff
nuclear@14 17 xmlout(io, 1, "<env>\n");
nuclear@18 18 xmlout(io, 2, "<ambient float3=\"%g %g %g\"/>\n", ambient.x, ambient.y, ambient.z);
nuclear@18 19 xmlout(io, 1, "</env>\n\n");
nuclear@14 20
nuclear@14 21 for(size_t i=0; i<materials.size(); i++) {
nuclear@14 22 write_material(this, io, materials[i], 1);
nuclear@14 23 }
nuclear@14 24 for(size_t i=0; i<meshes.size(); i++) {
nuclear@14 25 write_mesh(this, io, meshes[i], i, 1);
nuclear@14 26 }
nuclear@14 27 for(size_t i=0; i<lights.size(); i++) {
nuclear@14 28 write_light(this, io, lights[i], 1);
nuclear@14 29 }
nuclear@14 30 for(size_t i=0; i<cameras.size(); i++) {
nuclear@14 31 write_camera(this, io, cameras[i], 1);
nuclear@14 32 }
nuclear@14 33 for(size_t i=0; i<nodes.size(); i++) {
nuclear@14 34 write_node(this, io, nodes[i], 1);
nuclear@14 35 }
nuclear@14 36
nuclear@14 37 xmlout(io, 0, "</scene>\n");
nuclear@14 38 return true;
nuclear@14 39 }
nuclear@14 40
nuclear@14 41 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level)
nuclear@14 42 {
nuclear@14 43 xmlout(io, level, "<mtl>\n");
nuclear@14 44 xmlout(io, level + 1, "<name string=\"%s\"/>\n", mat->name.c_str());
nuclear@14 45
nuclear@14 46 for(int i=0; i<mat->get_attrib_count(); i++) {
nuclear@14 47 xmlout(io, level + 1, "<attr>\n");
nuclear@14 48 xmlout(io, level + 2, "<name string=\"%s\"/>\n", mat->get_attrib_name(i));
nuclear@14 49
nuclear@14 50 const MaterialAttrib &attr = (*mat)[i];
nuclear@18 51 xmlout(io, level + 2, "<val float4=\"%g %g %g %g\"/>\n", attr.value.x,
nuclear@14 52 attr.value.y, attr.value.z, attr.value.w);
nuclear@14 53 if(!attr.map.empty()) {
nuclear@14 54 xmlout(io, level + 2, "<map string=\"%s\"/>\n", attr.map.c_str());
nuclear@14 55 }
nuclear@14 56 xmlout(io, level + 1, "</attr>\n");
nuclear@14 57 }
nuclear@18 58 xmlout(io, level, "</mtl>\n\n");
nuclear@14 59 return true;
nuclear@14 60 }
nuclear@14 61
nuclear@14 62 static bool write_mesh(const Scene *scn, goat3d_io *io, const Mesh *mesh, int idx, int level)
nuclear@14 63 {
nuclear@14 64 // first write the external (openctm) mesh file
nuclear@14 65 const char *prefix = scn->get_name();
nuclear@14 66 if(!prefix) {
nuclear@14 67 prefix = "goat";
nuclear@14 68 }
nuclear@14 69
nuclear@14 70 char *mesh_filename = (char*)alloca(strlen(prefix) + 32);
nuclear@14 71 sprintf(mesh_filename, "%s-mesh%04d.ctm", prefix, idx);
nuclear@14 72
nuclear@19 73 if(!mesh->save(mesh_filename)) {
nuclear@19 74 return false;
nuclear@19 75 }
nuclear@14 76
nuclear@14 77 // then refer to that filename in the XML tags
nuclear@14 78 xmlout(io, level, "<mesh>\n");
nuclear@14 79 xmlout(io, level + 1, "<name string=\"%s\"/>\n", mesh->name.c_str());
nuclear@17 80 if(mesh->material) {
nuclear@17 81 xmlout(io, level + 1, "<material string=\"%s\"/>\n", mesh->material->name.c_str());
nuclear@17 82 }
nuclear@40 83 xmlout(io, level + 1, "<file string=\"%s\"/>\n", goat3d_clean_filename(mesh_filename).c_str());
nuclear@18 84 xmlout(io, level, "</mesh>\n\n");
nuclear@14 85 return true;
nuclear@14 86 }
nuclear@14 87
nuclear@14 88 static bool write_light(const Scene *scn, goat3d_io *io, const Light *light, int level)
nuclear@14 89 {
nuclear@14 90 return true;
nuclear@14 91 }
nuclear@14 92
nuclear@14 93 static bool write_camera(const Scene *scn, goat3d_io *io, const Camera *cam, int level)
nuclear@14 94 {
nuclear@14 95 return true;
nuclear@14 96 }
nuclear@14 97
nuclear@14 98 static bool write_node(const Scene *scn, goat3d_io *io, const Node *node, int level)
nuclear@14 99 {
nuclear@30 100 xmlout(io, level, "<node>\n");
nuclear@30 101 xmlout(io, level + 1, "<name string=\"%s\"/>\n", node->get_name());
nuclear@30 102
nuclear@30 103 XFormNode *parent = node->get_parent();
nuclear@30 104 if(parent) {
nuclear@30 105 xmlout(io, level + 1, "<parent string=\"%s\"/>\n", parent->get_name());
nuclear@30 106 }
nuclear@30 107
nuclear@30 108 const char *type = 0;
nuclear@30 109 const Object *obj = node->get_object();
nuclear@30 110 if(dynamic_cast<const Mesh*>(obj)) {
nuclear@30 111 type = "mesh";
nuclear@30 112 } else if(dynamic_cast<const Light*>(obj)) {
nuclear@30 113 type = "light";
nuclear@30 114 } else if(dynamic_cast<const Camera*>(obj)) {
nuclear@30 115 type = "camera";
nuclear@30 116 }
nuclear@30 117
nuclear@30 118 if(type) {
nuclear@30 119 xmlout(io, level + 1, "<%s string=\"%s\"/>\n", type, obj->name.c_str());
nuclear@30 120 }
nuclear@30 121
nuclear@30 122 Vector3 pos = node->get_node_position();
nuclear@30 123 Quaternion rot = node->get_node_rotation();
nuclear@30 124 Vector3 scale = node->get_node_scaling();
nuclear@30 125 Vector3 pivot = node->get_pivot();
nuclear@30 126
nuclear@30 127 Matrix4x4 xform;
nuclear@30 128 node->get_node_xform(0, &xform);
nuclear@30 129
nuclear@30 130 xmlout(io, level + 1, "<pos float3=\"%g %g %g\"/>\n", pos.x, pos.y, pos.z);
nuclear@30 131 xmlout(io, level + 1, "<rot float4=\"%g %g %g %g\"/>\n", rot.v.x, rot.v.y, rot.v.z, rot.s);
nuclear@30 132 xmlout(io, level + 1, "<scale float3=\"%g %g %g\"/>\n", scale.x, scale.y, scale.z);
nuclear@30 133 xmlout(io, level + 1, "<pivot float3=\"%g %g %g\"/>\n", pivot.x, pivot.y, pivot.z);
nuclear@30 134
nuclear@30 135 xmlout(io, level + 1, "<matrix0 float4=\"%g %g %g %g\"/>\n", xform[0][0], xform[0][1], xform[0][2], xform[0][3]);
nuclear@30 136 xmlout(io, level + 1, "<matrix1 float4=\"%g %g %g %g\"/>\n", xform[1][0], xform[1][1], xform[1][2], xform[1][3]);
nuclear@30 137 xmlout(io, level + 1, "<matrix2 float4=\"%g %g %g %g\"/>\n", xform[2][0], xform[2][1], xform[2][2], xform[2][3]);
nuclear@30 138
nuclear@30 139 xmlout(io, level, "</node>\n");
nuclear@14 140 return true;
nuclear@14 141 }
nuclear@14 142
nuclear@14 143
nuclear@14 144 static void xmlout(goat3d_io *io, int level, const char *fmt, ...)
nuclear@14 145 {
nuclear@14 146 for(int i=0; i<level; i++) {
nuclear@14 147 io_fprintf(io, " ");
nuclear@14 148 }
nuclear@14 149
nuclear@14 150 va_list ap;
nuclear@14 151 va_start(ap, fmt);
nuclear@14 152 io_vfprintf(io, fmt, ap);
nuclear@14 153 va_end(ap);
nuclear@14 154 }