goat3d

view src/scene.cc @ 58:d317eb4f83da

- made everything compile properly on windows again - removed libanim/libvmath, we'll use them as external dependencies - added new maxgoat_stub 3dsmax plugin project. Gets loaded as a max plugin and loads the actual maxgoat (and later maxgoat_anim) exporters on demand, to allow reloading the actual exporters without having to restart 3dsmax (which takes AGES).
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 25 Mar 2014 03:19:55 +0200
parents 498ca7ac7047
children dad392c710df 3751aabbc5b3
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 }
207 // Scene::load is defined in goat3d_read.cc
208 // Scene::loadxml is defined in goat3d_readxml.cc
209 // Scene::save is defined in goat3d_write.cc
210 // Scene::savexml is defined in goat3d_writexml.cc
213 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
214 {
215 va_list ap;
217 va_start(ap, fmt);
218 io_vfprintf(io, fmt, ap);
219 va_end(ap);
220 }
223 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
224 {
225 char smallbuf[256];
226 char *buf = smallbuf;
227 int sz = sizeof smallbuf;
229 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
231 if(retsz >= sz) {
232 /* C99 mandates that snprintf with a short count should return the
233 * number of characters that *would* be printed.
234 */
235 buf = new char[retsz + 1];
237 vsnprintf(buf, retsz, fmt, ap);
239 } else if(retsz <= 0) {
240 /* SUSv2 and microsoft specify that snprintf with a short count
241 * returns an arbitrary value <= 0. So let's try allocating
242 * bigger and bigger arrays until we find the correct size.
243 */
244 sz = sizeof smallbuf;
245 do {
246 sz *= 2;
247 if(buf != smallbuf) {
248 delete [] buf;
249 }
250 buf = new char[sz + 1];
252 retsz = vsnprintf(buf, sz, fmt, ap);
253 } while(retsz <= 0);
254 }
256 io->write(buf, retsz, io->cls);
258 if(buf != smallbuf) {
259 delete [] buf;
260 }
262 }