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 }
|