goat3d
view src/goat3d.cc @ 9:04bb114fcf05
implementing Scene::save, lots to do still
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 23 Aug 2013 06:36:47 +0300 |
parents | cd71f0b92f44 |
children | 1f94a2107c64 |
line source
1 #include "goat3d.h"
2 #include "goat3d_impl.h"
3 #include "chunk.h"
5 Scene::Scene()
6 : name("unnamed"), ambient(0.05, 0.05, 0.05)
7 {
8 }
10 Scene::~Scene()
11 {
12 clear();
13 }
15 void Scene::clear()
16 {
17 for(size_t i=0; i<materials.size(); i++) {
18 delete materials[i];
19 }
20 materials.clear();
22 for(size_t i=0; i<meshes.size(); i++) {
23 delete meshes[i];
24 }
25 meshes.clear();
27 for(size_t i=0; i<lights.size(); i++) {
28 delete lights[i];
29 }
30 lights.clear();
32 for(size_t i=0; i<cameras.size(); i++) {
33 delete cameras[i];
34 }
35 cameras.clear();
37 for(size_t i=0; i<nodes.size(); i++) {
38 delete_node_tree(nodes[i]);
39 }
40 nodes.clear();
42 name = "unnamed";
43 }
45 void Scene::set_name(const char *name)
46 {
47 this->name = name;
48 }
50 const char *Scene::get_name() const
51 {
52 return name.c_str();
53 }
55 void Scene::set_ambient(const Vector3 &amb)
56 {
57 ambient = amb;
58 }
60 const Vector3 &Scene::get_ambient() const
61 {
62 return ambient;
63 }
65 void Scene::add_material(Material *mat)
66 {
67 materials.push_back(mat);
68 }
70 Material *Scene::get_material(int idx) const
71 {
72 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
73 }
75 Material *Scene::get_material(const char *name) const
76 {
77 for(size_t i=0; i<materials.size(); i++) {
78 if(materials[i]->name == std::string(name)) {
79 return materials[i];
80 }
81 }
82 return 0;
83 }
85 int Scene::get_material_count() const
86 {
87 return (int)materials.size();
88 }
91 void Scene::add_mesh(Mesh *mesh)
92 {
93 meshes.push_back(mesh);
94 }
96 Mesh *Scene::get_mesh(int idx) const
97 {
98 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
99 }
101 Mesh *Scene::get_mesh(const char *name) const
102 {
103 for(size_t i=0; i<meshes.size(); i++) {
104 if(meshes[i]->name == std::string(name)) {
105 return meshes[i];
106 }
107 }
108 return 0;
109 }
111 int Scene::get_mesh_count() const
112 {
113 return (int)meshes.size();
114 }
117 void Scene::add_light(Light *light)
118 {
119 lights.push_back(light);
120 }
122 Light *Scene::get_light(int idx) const
123 {
124 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
125 }
127 Light *Scene::get_light(const char *name) const
128 {
129 for(size_t i=0; i<lights.size(); i++) {
130 if(lights[i]->name == std::string(name)) {
131 return lights[i];
132 }
133 }
134 return 0;
135 }
137 int Scene::get_light_count() const
138 {
139 return (int)lights.size();
140 }
143 void Scene::add_camera(Camera *cam)
144 {
145 cameras.push_back(cam);
146 }
148 Camera *Scene::get_camera(int idx) const
149 {
150 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
151 }
153 Camera *Scene::get_camera(const char *name) const
154 {
155 for(size_t i=0; i<cameras.size(); i++) {
156 if(cameras[i]->name == std::string(name)) {
157 return cameras[i];
158 }
159 }
160 return 0;
161 }
163 int Scene::get_camera_count() const
164 {
165 return (int)cameras.size();
166 }
169 void Scene::add_node(Node *node)
170 {
171 nodes.push_back(node);
172 }
174 Node *Scene::get_node(int idx) const
175 {
176 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
177 }
179 Node *Scene::get_node(const char *name) const
180 {
181 for(size_t i=0; i<nodes.size(); i++) {
182 if(strcmp(nodes[i]->get_name(), name) == 0) {
183 return nodes[i];
184 }
185 }
186 return 0;
187 }
189 int Scene::get_node_count() const
190 {
191 return (int)nodes.size();
192 }
195 bool Scene::load(goat3d_io *io)
196 {
197 return false;
198 }
200 static long save_env(const Scene *scn, long offset, goat3d_io *io);
201 static long save_materials(const Scene *scn, long offset, goat3d_io *io);
202 static long save_material(const Material *mat, long offset, goat3d_io *io);
203 static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io);
204 static long save_meshes(const Scene *scn, long offset, goat3d_io *io);
205 static long save_lights(const Scene *scn, long offset, goat3d_io *io);
206 static long save_cameras(const Scene *scn, long offset, goat3d_io *io);
207 static long save_nodes(const Scene *scn, long offset, goat3d_io *io);
209 static long write_chunk_float(int id, float val, long offs, goat3d_io *io);
210 static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io);
211 static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io);
213 bool Scene::save(goat3d_io *io) const
214 {
215 long res;
217 ChunkHeader hdr;
218 hdr.id = CNK_SCENE;
219 hdr.size = sizeof hdr;
221 if((res = save_env(this, hdr.size, io)) < 0) {
222 return false;
223 }
224 hdr.size += res;
226 if((res = save_materials(this, hdr.size, io)) < 0) {
227 return false;
228 }
229 hdr.size += res;
231 if((res = save_meshes(this, hdr.size, io)) < 0) {
232 return false;
233 }
234 hdr.size += res;
236 if((res = save_lights(this, hdr.size, io)) < 0) {
237 return false;
238 }
239 hdr.size += res;
241 if((res = save_cameras(this, hdr.size, io)) < 0) {
242 return false;
243 }
244 hdr.size += res;
246 if((res = save_nodes(this, hdr.size, io)) < 0) {
247 return false;
248 }
249 hdr.size += res;
251 // now go back and write the root chunk
252 io->seek(0, SEEK_SET, io->cls);
253 if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) {
254 return false;
255 }
257 return true;
258 }
261 static long save_env(const Scene *scn, long offset, goat3d_io *io)
262 {
263 long res;
265 ChunkHeader hdr;
266 hdr.id = CNK_ENV;
267 hdr.size = sizeof hdr;
269 if((res = write_chunk_float3(CNK_ENV_AMBIENT, scn->get_ambient(), offset, io)) < 0) {
270 return -1;
271 }
272 hdr.size += res;
274 // TODO add fog chunk
276 io->seek(offset, SEEK_SET, io->cls);
277 if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) {
278 return -1;
279 }
280 return hdr.size;
281 }
283 static long save_materials(const Scene *scn, long offset, goat3d_io *io)
284 {
285 long res;
287 ChunkHeader hdr;
288 hdr.id = CNK_MTL_LIST;
289 hdr.size = sizeof hdr;
291 for(int i=0; i<scn->get_material_count(); i++) {
292 if((res = save_material(scn->get_material(i), offset + hdr.size, io)) < 0) {
293 return -1;
294 }
295 hdr.size += res;
296 }
298 io->seek(offset, SEEK_SET, io->cls);
299 if(io->write(&hdr, hdr.size, io->cls) < hdr.size) {
300 return -1;
301 }
302 return hdr.size;
303 }
305 static long save_material(const Material *mat, long offset, goat3d_io *io)
306 {
307 long res;
309 ChunkHeader hdr;
310 hdr.id = CNK_MTL;
311 hdr.size = sizeof hdr;
313 for(int i=0; i<mat->get_attrib_count(); i++) {
314 const char *name = mat->get_attrib_name(i);
315 if((res = save_mat_attrib(name, (*mat)[i], offset + hdr.size, io)) < 0) {
316 return -1;
317 }
318 hdr.size += res;
319 }
321 io->seek(offset, SEEK_SET, io->cls);
322 if(io->write(&hdr, hdr.size, io->cls) < hdr.size) {
323 return -1;
324 }
325 return hdr.size;
326 }
328 static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io)
329 {
330 long res;
332 ChunkHeader hdr;
333 hdr.id = CNK_MTL_ATTR;
334 hdr.size = sizeof hdr;
336 // TODO cont.
337 return -1;
338 }
340 static long save_meshes(const Scene *scn, long offset, goat3d_io *io)
341 {
342 return 0;
343 }
345 static long save_lights(const Scene *scn, long offset, goat3d_io *io)
346 {
347 return 0;
348 }
350 static long save_cameras(const Scene *scn, long offset, goat3d_io *io)
351 {
352 return 0;
353 }
355 static long save_nodes(const Scene *scn, long offset, goat3d_io *io)
356 {
357 return 0;
358 }
360 static long write_chunk_float(int id, float val, long offs, goat3d_io *io)
361 {
362 int size = sizeof(ChunkHeader) + sizeof val;
363 char *buf = (char*)alloca(size);
365 Chunk *c = (Chunk*)buf;
366 c->hdr.id = id;
367 c->hdr.size = size;
368 *(float*)c->data = val;
370 io->seek(offs, SEEK_SET, io->cls);
371 if(io->write(buf, size, io->cls) < size) {
372 return -1;
373 }
374 return size;
375 }
377 static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io)
378 {
379 int size = sizeof(ChunkHeader) + sizeof vec;
380 char *buf = (char*)alloca(size);
382 Chunk *c = (Chunk*)buf;
383 c->hdr.id = id;
384 c->hdr.size = size;
385 *(Vector3*)c->data = vec;
387 io->seek(offs, SEEK_SET, io->cls);
388 if(io->write(buf, size, io->cls) < size) {
389 return -1;
390 }
391 return size;
392 }
394 static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io)
395 {
396 int size = sizeof(ChunkHeader) + sizeof vec;
397 char *buf = (char*)alloca(size);
399 Chunk *c = (Chunk*)buf;
400 c->hdr.id = id;
401 c->hdr.size = size;
402 *(Vector4*)c->data = vec;
404 io->seek(offs, SEEK_SET, io->cls);
405 if(io->write(buf, size, io->cls) < size) {
406 return -1;
407 }
408 return size;
409 }