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