goat3d

view src/scene.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 1d85d7dd0038
children 498ca7ac7047
line source
1 #include <stdarg.h>
2 #include "goat3d.h"
3 #include "goat3d_impl.h"
4 #include "chunk.h"
6 Scene::Scene()
7 : name("unnamed"), ambient(0.05, 0.05, 0.05)
8 {
9 }
11 Scene::~Scene()
12 {
13 clear();
14 }
16 void Scene::clear()
17 {
18 for(size_t i=0; i<materials.size(); i++) {
19 delete materials[i];
20 }
21 materials.clear();
23 for(size_t i=0; i<meshes.size(); i++) {
24 delete meshes[i];
25 }
26 meshes.clear();
28 for(size_t i=0; i<lights.size(); i++) {
29 delete lights[i];
30 }
31 lights.clear();
33 for(size_t i=0; i<cameras.size(); i++) {
34 delete cameras[i];
35 }
36 cameras.clear();
38 for(size_t i=0; i<nodes.size(); i++) {
39 delete_node_tree(nodes[i]);
40 }
41 nodes.clear();
43 name = "unnamed";
44 }
46 void Scene::set_name(const char *name)
47 {
48 this->name = name;
49 }
51 const char *Scene::get_name() const
52 {
53 return name.c_str();
54 }
56 void Scene::set_ambient(const Vector3 &amb)
57 {
58 ambient = amb;
59 }
61 const Vector3 &Scene::get_ambient() const
62 {
63 return ambient;
64 }
66 void Scene::add_material(Material *mat)
67 {
68 if(mat->name.empty()) {
69 char buf[64];
70 sprintf(buf, "material%04d", (int)materials.size());
71 mat->name = std::string(buf);
72 }
73 materials.push_back(mat);
74 }
76 Material *Scene::get_material(int idx) const
77 {
78 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
79 }
81 Material *Scene::get_material(const char *name) const
82 {
83 for(size_t i=0; i<materials.size(); i++) {
84 if(materials[i]->name == std::string(name)) {
85 return materials[i];
86 }
87 }
88 return 0;
89 }
91 int Scene::get_material_count() const
92 {
93 return (int)materials.size();
94 }
97 void Scene::add_mesh(Mesh *mesh)
98 {
99 if(mesh->name.empty()) {
100 char buf[64];
101 sprintf(buf, "mesh%04d", (int)meshes.size());
102 mesh->name = std::string(buf);
103 }
104 meshes.push_back(mesh);
105 }
107 Mesh *Scene::get_mesh(int idx) const
108 {
109 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
110 }
112 Mesh *Scene::get_mesh(const char *name) const
113 {
114 for(size_t i=0; i<meshes.size(); i++) {
115 if(meshes[i]->name == std::string(name)) {
116 return meshes[i];
117 }
118 }
119 return 0;
120 }
122 int Scene::get_mesh_count() const
123 {
124 return (int)meshes.size();
125 }
128 void Scene::add_light(Light *light)
129 {
130 lights.push_back(light);
131 }
133 Light *Scene::get_light(int idx) const
134 {
135 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
136 }
138 Light *Scene::get_light(const char *name) const
139 {
140 for(size_t i=0; i<lights.size(); i++) {
141 if(lights[i]->name == std::string(name)) {
142 return lights[i];
143 }
144 }
145 return 0;
146 }
148 int Scene::get_light_count() const
149 {
150 return (int)lights.size();
151 }
154 void Scene::add_camera(Camera *cam)
155 {
156 cameras.push_back(cam);
157 }
159 Camera *Scene::get_camera(int idx) const
160 {
161 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
162 }
164 Camera *Scene::get_camera(const char *name) const
165 {
166 for(size_t i=0; i<cameras.size(); i++) {
167 if(cameras[i]->name == std::string(name)) {
168 return cameras[i];
169 }
170 }
171 return 0;
172 }
174 int Scene::get_camera_count() const
175 {
176 return (int)cameras.size();
177 }
180 void Scene::add_node(Node *node)
181 {
182 nodes.push_back(node);
183 }
185 Node *Scene::get_node(int idx) const
186 {
187 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
188 }
190 Node *Scene::get_node(const char *name) const
191 {
192 for(size_t i=0; i<nodes.size(); i++) {
193 if(strcmp(nodes[i]->get_name(), name) == 0) {
194 return nodes[i];
195 }
196 }
197 return 0;
198 }
200 int Scene::get_node_count() const
201 {
202 return (int)nodes.size();
203 }
206 bool Scene::load(goat3d_io *io)
207 {
208 return false;
209 }
211 // Scene::loadxml is defined in goat3d_readxml.cc
212 // Scene::save is defined in goat3d_write.cc
213 // Scene::savexml is defined in goat3d_writexml.cc
216 void io_fprintf(goat3d_io *io, const char *fmt, ...)
217 {
218 va_list ap;
220 va_start(ap, fmt);
221 io_vfprintf(io, fmt, ap);
222 va_end(ap);
223 }
226 void io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
227 {
228 char smallbuf[256];
229 char *buf = smallbuf;
230 int sz = sizeof smallbuf;
232 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
234 if(retsz >= sz) {
235 /* C99 mandates that snprintf with a short count should return the
236 * number of characters that *would* be printed.
237 */
238 buf = new char[retsz + 1];
240 vsnprintf(buf, retsz, fmt, ap);
242 } else if(retsz <= 0) {
243 /* SUSv2 and microsoft specify that snprintf with a short count
244 * returns an arbitrary value <= 0. So let's try allocating
245 * bigger and bigger arrays until we find the correct size.
246 */
247 sz = sizeof smallbuf;
248 do {
249 sz *= 2;
250 if(buf != smallbuf) {
251 delete [] buf;
252 }
253 buf = new char[sz + 1];
255 retsz = vsnprintf(buf, sz, fmt, ap);
256 } while(retsz <= 0);
257 }
259 io->write(buf, retsz, io->cls);
261 if(buf != smallbuf) {
262 delete [] buf;
263 }
265 }