goat3d

view src/scene.cc @ 47:498ca7ac7047

- placed all the implementation stuff in the g3dimpl namespace - added animation stuff to the public API - started writing animation saving/loading
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 28 Dec 2013 06:47:39 +0200
parents b35427826b60
children 0be413ac2e0a
line source
1 #include <stdarg.h>
2 #include "goat3d.h"
3 #include "goat3d_impl.h"
4 #include "chunk.h"
6 using namespace g3dimpl;
8 Scene::Scene()
9 : name("unnamed"), ambient(0.05, 0.05, 0.05)
10 {
11 }
13 Scene::~Scene()
14 {
15 clear();
16 }
18 void Scene::clear()
19 {
20 for(size_t i=0; i<materials.size(); i++) {
21 delete materials[i];
22 }
23 materials.clear();
25 for(size_t i=0; i<meshes.size(); i++) {
26 delete meshes[i];
27 }
28 meshes.clear();
30 for(size_t i=0; i<lights.size(); i++) {
31 delete lights[i];
32 }
33 lights.clear();
35 for(size_t i=0; i<cameras.size(); i++) {
36 delete cameras[i];
37 }
38 cameras.clear();
40 for(size_t i=0; i<nodes.size(); i++) {
41 delete_node_tree(nodes[i]);
42 }
43 nodes.clear();
45 name = "unnamed";
46 }
48 void Scene::set_name(const char *name)
49 {
50 this->name = name;
51 }
53 const char *Scene::get_name() const
54 {
55 return name.c_str();
56 }
58 void Scene::set_ambient(const Vector3 &amb)
59 {
60 ambient = amb;
61 }
63 const Vector3 &Scene::get_ambient() const
64 {
65 return ambient;
66 }
68 void Scene::add_material(Material *mat)
69 {
70 if(mat->name.empty()) {
71 char buf[64];
72 sprintf(buf, "material%04d", (int)materials.size());
73 mat->name = std::string(buf);
74 }
75 materials.push_back(mat);
76 }
78 Material *Scene::get_material(int idx) const
79 {
80 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
81 }
83 Material *Scene::get_material(const char *name) const
84 {
85 for(size_t i=0; i<materials.size(); i++) {
86 if(materials[i]->name == std::string(name)) {
87 return materials[i];
88 }
89 }
90 return 0;
91 }
93 int Scene::get_material_count() const
94 {
95 return (int)materials.size();
96 }
99 void Scene::add_mesh(Mesh *mesh)
100 {
101 if(mesh->name.empty()) {
102 char buf[64];
103 sprintf(buf, "mesh%04d", (int)meshes.size());
104 mesh->name = std::string(buf);
105 }
106 meshes.push_back(mesh);
107 }
109 Mesh *Scene::get_mesh(int idx) const
110 {
111 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
112 }
114 Mesh *Scene::get_mesh(const char *name) const
115 {
116 for(size_t i=0; i<meshes.size(); i++) {
117 if(meshes[i]->name == std::string(name)) {
118 return meshes[i];
119 }
120 }
121 return 0;
122 }
124 int Scene::get_mesh_count() const
125 {
126 return (int)meshes.size();
127 }
130 void Scene::add_light(Light *light)
131 {
132 lights.push_back(light);
133 }
135 Light *Scene::get_light(int idx) const
136 {
137 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
138 }
140 Light *Scene::get_light(const char *name) const
141 {
142 for(size_t i=0; i<lights.size(); i++) {
143 if(lights[i]->name == std::string(name)) {
144 return lights[i];
145 }
146 }
147 return 0;
148 }
150 int Scene::get_light_count() const
151 {
152 return (int)lights.size();
153 }
156 void Scene::add_camera(Camera *cam)
157 {
158 cameras.push_back(cam);
159 }
161 Camera *Scene::get_camera(int idx) const
162 {
163 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
164 }
166 Camera *Scene::get_camera(const char *name) const
167 {
168 for(size_t i=0; i<cameras.size(); i++) {
169 if(cameras[i]->name == std::string(name)) {
170 return cameras[i];
171 }
172 }
173 return 0;
174 }
176 int Scene::get_camera_count() const
177 {
178 return (int)cameras.size();
179 }
182 void Scene::add_node(Node *node)
183 {
184 nodes.push_back(node);
185 }
187 Node *Scene::get_node(int idx) const
188 {
189 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
190 }
192 Node *Scene::get_node(const char *name) const
193 {
194 for(size_t i=0; i<nodes.size(); i++) {
195 if(strcmp(nodes[i]->get_name(), name) == 0) {
196 return nodes[i];
197 }
198 }
199 return 0;
200 }
202 int Scene::get_node_count() const
203 {
204 return (int)nodes.size();
205 }
208 bool Scene::load(goat3d_io *io)
209 {
210 return false;
211 }
213 // Scene::loadxml is defined in goat3d_readxml.cc
214 // Scene::save is defined in goat3d_write.cc
215 // Scene::savexml is defined in goat3d_writexml.cc
218 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
219 {
220 va_list ap;
222 va_start(ap, fmt);
223 io_vfprintf(io, fmt, ap);
224 va_end(ap);
225 }
228 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
229 {
230 char smallbuf[256];
231 char *buf = smallbuf;
232 int sz = sizeof smallbuf;
234 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
236 if(retsz >= sz) {
237 /* C99 mandates that snprintf with a short count should return the
238 * number of characters that *would* be printed.
239 */
240 buf = new char[retsz + 1];
242 vsnprintf(buf, retsz, fmt, ap);
244 } else if(retsz <= 0) {
245 /* SUSv2 and microsoft specify that snprintf with a short count
246 * returns an arbitrary value <= 0. So let's try allocating
247 * bigger and bigger arrays until we find the correct size.
248 */
249 sz = sizeof smallbuf;
250 do {
251 sz *= 2;
252 if(buf != smallbuf) {
253 delete [] buf;
254 }
255 buf = new char[sz + 1];
257 retsz = vsnprintf(buf, sz, fmt, ap);
258 } while(retsz <= 0);
259 }
261 io->write(buf, retsz, io->cls);
263 if(buf != smallbuf) {
264 delete [] buf;
265 }
267 }