goat3d

view src/scene.cc @ 74:ab66cdabf6f2

loading scene files (no vis yet)
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 06 May 2014 13:26:52 +0300
parents 8970ca3d55e0
children 76dea247f75c
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 goat = 0;
29 }
31 Scene::~Scene()
32 {
33 clear();
34 }
36 void Scene::clear()
37 {
38 for(size_t i=0; i<materials.size(); i++) {
39 delete materials[i];
40 }
41 materials.clear();
43 for(size_t i=0; i<meshes.size(); i++) {
44 delete meshes[i];
45 }
46 meshes.clear();
48 for(size_t i=0; i<lights.size(); i++) {
49 delete lights[i];
50 }
51 lights.clear();
53 for(size_t i=0; i<cameras.size(); i++) {
54 delete cameras[i];
55 }
56 cameras.clear();
58 for(size_t i=0; i<nodes.size(); i++) {
59 delete nodes[i];
60 }
61 nodes.clear();
63 name = "unnamed";
64 }
66 void Scene::set_name(const char *name)
67 {
68 this->name = name;
69 }
71 const char *Scene::get_name() const
72 {
73 return name.c_str();
74 }
76 void Scene::set_ambient(const Vector3 &amb)
77 {
78 ambient = amb;
79 }
81 const Vector3 &Scene::get_ambient() const
82 {
83 return ambient;
84 }
86 void Scene::add_material(Material *mat)
87 {
88 if(mat->name.empty()) {
89 char buf[64];
90 sprintf(buf, "material%04d", (int)materials.size());
91 mat->name = std::string(buf);
92 }
93 materials.push_back(mat);
94 }
96 Material *Scene::get_material(int idx) const
97 {
98 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
99 }
101 Material *Scene::get_material(const char *name) const
102 {
103 for(size_t i=0; i<materials.size(); i++) {
104 if(materials[i]->name == std::string(name)) {
105 return materials[i];
106 }
107 }
108 return 0;
109 }
111 int Scene::get_material_count() const
112 {
113 return (int)materials.size();
114 }
117 void Scene::add_mesh(Mesh *mesh)
118 {
119 if(mesh->name.empty()) {
120 char buf[64];
121 sprintf(buf, "mesh%04d", (int)meshes.size());
122 mesh->name = std::string(buf);
123 }
124 meshes.push_back(mesh);
125 }
127 Mesh *Scene::get_mesh(int idx) const
128 {
129 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
130 }
132 Mesh *Scene::get_mesh(const char *name) const
133 {
134 for(size_t i=0; i<meshes.size(); i++) {
135 if(meshes[i]->name == std::string(name)) {
136 return meshes[i];
137 }
138 }
139 return 0;
140 }
142 int Scene::get_mesh_count() const
143 {
144 return (int)meshes.size();
145 }
148 void Scene::add_light(Light *light)
149 {
150 lights.push_back(light);
151 }
153 Light *Scene::get_light(int idx) const
154 {
155 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
156 }
158 Light *Scene::get_light(const char *name) const
159 {
160 for(size_t i=0; i<lights.size(); i++) {
161 if(lights[i]->name == std::string(name)) {
162 return lights[i];
163 }
164 }
165 return 0;
166 }
168 int Scene::get_light_count() const
169 {
170 return (int)lights.size();
171 }
174 void Scene::add_camera(Camera *cam)
175 {
176 cameras.push_back(cam);
177 }
179 Camera *Scene::get_camera(int idx) const
180 {
181 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
182 }
184 Camera *Scene::get_camera(const char *name) const
185 {
186 for(size_t i=0; i<cameras.size(); i++) {
187 if(cameras[i]->name == std::string(name)) {
188 return cameras[i];
189 }
190 }
191 return 0;
192 }
194 int Scene::get_camera_count() const
195 {
196 return (int)cameras.size();
197 }
200 void Scene::add_node(Node *node)
201 {
202 nodes.push_back(node);
203 }
205 Node *Scene::get_node(int idx) const
206 {
207 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
208 }
210 Node *Scene::get_node(const char *name) const
211 {
212 for(size_t i=0; i<nodes.size(); i++) {
213 if(strcmp(nodes[i]->get_name(), name) == 0) {
214 return nodes[i];
215 }
216 }
217 return 0;
218 }
220 int Scene::get_node_count() const
221 {
222 return (int)nodes.size();
223 }
225 // Scene::load is defined in goat3d_read.cc
226 // Scene::loadxml is defined in goat3d_readxml.cc
227 // Scene::save is defined in goat3d_write.cc
228 // Scene::savexml is defined in goat3d_writexml.cc
231 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
232 {
233 va_list ap;
235 va_start(ap, fmt);
236 io_vfprintf(io, fmt, ap);
237 va_end(ap);
238 }
241 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
242 {
243 char smallbuf[256];
244 char *buf = smallbuf;
245 int sz = sizeof smallbuf;
247 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
249 if(retsz >= sz) {
250 /* C99 mandates that snprintf with a short count should return the
251 * number of characters that *would* be printed.
252 */
253 buf = new char[retsz + 1];
255 vsnprintf(buf, retsz, fmt, ap);
257 } else if(retsz <= 0) {
258 /* SUSv2 and microsoft specify that snprintf with a short count
259 * returns an arbitrary value <= 0. So let's try allocating
260 * bigger and bigger arrays until we find the correct size.
261 */
262 sz = sizeof smallbuf;
263 do {
264 sz *= 2;
265 if(buf != smallbuf) {
266 delete [] buf;
267 }
268 buf = new char[sz + 1];
270 retsz = vsnprintf(buf, sz, fmt, ap);
271 } while(retsz <= 0);
272 }
274 io->write(buf, retsz, io->cls);
276 if(buf != smallbuf) {
277 delete [] buf;
278 }
280 }