goat3d

view src/scene.cc @ 69:66cd8266f078

fixed animation export
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 21 Apr 2014 03:44:10 +0300
parents 3751aabbc5b3 dad392c710df
children ab66cdabf6f2
line source
1 /*
2 goat3d - 3D scene, character, and animation file format library.
3 Copyright (C) 2013-2014 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <stdarg.h>
19 #include "goat3d.h"
20 #include "goat3d_impl.h"
21 #include "chunk.h"
23 using namespace g3dimpl;
25 Scene::Scene()
26 : name("unnamed"), ambient(0.05, 0.05, 0.05)
27 {
28 }
30 Scene::~Scene()
31 {
32 clear();
33 }
35 void Scene::clear()
36 {
37 for(size_t i=0; i<materials.size(); i++) {
38 delete materials[i];
39 }
40 materials.clear();
42 for(size_t i=0; i<meshes.size(); i++) {
43 delete meshes[i];
44 }
45 meshes.clear();
47 for(size_t i=0; i<lights.size(); i++) {
48 delete lights[i];
49 }
50 lights.clear();
52 for(size_t i=0; i<cameras.size(); i++) {
53 delete cameras[i];
54 }
55 cameras.clear();
57 for(size_t i=0; i<nodes.size(); i++) {
58 delete nodes[i];
59 }
60 nodes.clear();
62 name = "unnamed";
63 }
65 void Scene::set_name(const char *name)
66 {
67 this->name = name;
68 }
70 const char *Scene::get_name() const
71 {
72 return name.c_str();
73 }
75 void Scene::set_ambient(const Vector3 &amb)
76 {
77 ambient = amb;
78 }
80 const Vector3 &Scene::get_ambient() const
81 {
82 return ambient;
83 }
85 void Scene::add_material(Material *mat)
86 {
87 if(mat->name.empty()) {
88 char buf[64];
89 sprintf(buf, "material%04d", (int)materials.size());
90 mat->name = std::string(buf);
91 }
92 materials.push_back(mat);
93 }
95 Material *Scene::get_material(int idx) const
96 {
97 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
98 }
100 Material *Scene::get_material(const char *name) const
101 {
102 for(size_t i=0; i<materials.size(); i++) {
103 if(materials[i]->name == std::string(name)) {
104 return materials[i];
105 }
106 }
107 return 0;
108 }
110 int Scene::get_material_count() const
111 {
112 return (int)materials.size();
113 }
116 void Scene::add_mesh(Mesh *mesh)
117 {
118 if(mesh->name.empty()) {
119 char buf[64];
120 sprintf(buf, "mesh%04d", (int)meshes.size());
121 mesh->name = std::string(buf);
122 }
123 meshes.push_back(mesh);
124 }
126 Mesh *Scene::get_mesh(int idx) const
127 {
128 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
129 }
131 Mesh *Scene::get_mesh(const char *name) const
132 {
133 for(size_t i=0; i<meshes.size(); i++) {
134 if(meshes[i]->name == std::string(name)) {
135 return meshes[i];
136 }
137 }
138 return 0;
139 }
141 int Scene::get_mesh_count() const
142 {
143 return (int)meshes.size();
144 }
147 void Scene::add_light(Light *light)
148 {
149 lights.push_back(light);
150 }
152 Light *Scene::get_light(int idx) const
153 {
154 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
155 }
157 Light *Scene::get_light(const char *name) const
158 {
159 for(size_t i=0; i<lights.size(); i++) {
160 if(lights[i]->name == std::string(name)) {
161 return lights[i];
162 }
163 }
164 return 0;
165 }
167 int Scene::get_light_count() const
168 {
169 return (int)lights.size();
170 }
173 void Scene::add_camera(Camera *cam)
174 {
175 cameras.push_back(cam);
176 }
178 Camera *Scene::get_camera(int idx) const
179 {
180 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
181 }
183 Camera *Scene::get_camera(const char *name) const
184 {
185 for(size_t i=0; i<cameras.size(); i++) {
186 if(cameras[i]->name == std::string(name)) {
187 return cameras[i];
188 }
189 }
190 return 0;
191 }
193 int Scene::get_camera_count() const
194 {
195 return (int)cameras.size();
196 }
199 void Scene::add_node(Node *node)
200 {
201 nodes.push_back(node);
202 }
204 Node *Scene::get_node(int idx) const
205 {
206 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
207 }
209 Node *Scene::get_node(const char *name) const
210 {
211 for(size_t i=0; i<nodes.size(); i++) {
212 if(strcmp(nodes[i]->get_name(), name) == 0) {
213 return nodes[i];
214 }
215 }
216 return 0;
217 }
219 int Scene::get_node_count() const
220 {
221 return (int)nodes.size();
222 }
224 // Scene::load is defined in goat3d_read.cc
225 // Scene::loadxml is defined in goat3d_readxml.cc
226 // Scene::save is defined in goat3d_write.cc
227 // Scene::savexml is defined in goat3d_writexml.cc
230 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
231 {
232 va_list ap;
234 va_start(ap, fmt);
235 io_vfprintf(io, fmt, ap);
236 va_end(ap);
237 }
240 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
241 {
242 char smallbuf[256];
243 char *buf = smallbuf;
244 int sz = sizeof smallbuf;
246 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
248 if(retsz >= sz) {
249 /* C99 mandates that snprintf with a short count should return the
250 * number of characters that *would* be printed.
251 */
252 buf = new char[retsz + 1];
254 vsnprintf(buf, retsz, fmt, ap);
256 } else if(retsz <= 0) {
257 /* SUSv2 and microsoft specify that snprintf with a short count
258 * returns an arbitrary value <= 0. So let's try allocating
259 * bigger and bigger arrays until we find the correct size.
260 */
261 sz = sizeof smallbuf;
262 do {
263 sz *= 2;
264 if(buf != smallbuf) {
265 delete [] buf;
266 }
267 buf = new char[sz + 1];
269 retsz = vsnprintf(buf, sz, fmt, ap);
270 } while(retsz <= 0);
271 }
273 io->write(buf, retsz, io->cls);
275 if(buf != smallbuf) {
276 delete [] buf;
277 }
279 }