goat3d

view src/goat3d.cc @ 11:d1cebaf1d5c9

ok wtf
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 26 Aug 2013 05:42:30 +0300
parents 1f94a2107c64
children be15ba7c5483
line source
1 #include "goat3d.h"
2 #include "goat3d_impl.h"
3 #include "chunk.h"
4 #include "node.h"
6 Scene::Scene()
7 : name("unnamed"), ambient(0.05, 0.05, 0.05)
8 {
9 }
11 Scene::~Scene()
12 {
13 clear();
14 }
16 void Scene::clear()
17 {
18 for(size_t i=0; i<materials.size(); i++) {
19 delete materials[i];
20 }
21 materials.clear();
23 for(size_t i=0; i<meshes.size(); i++) {
24 delete meshes[i];
25 }
26 meshes.clear();
28 for(size_t i=0; i<lights.size(); i++) {
29 delete lights[i];
30 }
31 lights.clear();
33 for(size_t i=0; i<cameras.size(); i++) {
34 delete cameras[i];
35 }
36 cameras.clear();
38 for(size_t i=0; i<objects.size(); i++) {
39 delete_node_tree(objects[i]);
40 }
41 objects.clear();
43 name = "unnamed";
44 }
46 void Scene::set_name(const char *name)
47 {
48 this->name = name;
49 }
51 const char *Scene::get_name() const
52 {
53 return name.c_str();
54 }
56 void Scene::set_ambient(const Vector3 &amb)
57 {
58 ambient = amb;
59 }
61 const Vector3 &Scene::get_ambient() const
62 {
63 return ambient;
64 }
66 void Scene::add_material(Material *mat)
67 {
68 materials.push_back(mat);
69 }
71 Material *Scene::get_material(int idx) const
72 {
73 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
74 }
76 Material *Scene::get_material(const char *name) const
77 {
78 for(size_t i=0; i<materials.size(); i++) {
79 if(materials[i]->name == std::string(name)) {
80 return materials[i];
81 }
82 }
83 return 0;
84 }
86 int Scene::get_material_count() const
87 {
88 return (int)materials.size();
89 }
92 void Scene::add_mesh(Mesh *mesh)
93 {
94 meshes.push_back(mesh);
95 }
97 Mesh *Scene::get_mesh(int idx) const
98 {
99 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
100 }
102 Mesh *Scene::get_mesh(const char *name) const
103 {
104 for(size_t i=0; i<meshes.size(); i++) {
105 if(meshes[i]->name == std::string(name)) {
106 return meshes[i];
107 }
108 }
109 return 0;
110 }
112 int Scene::get_mesh_count() const
113 {
114 return (int)meshes.size();
115 }
118 void Scene::add_light(Light *light)
119 {
120 lights.push_back(light);
121 }
123 Light *Scene::get_light(int idx) const
124 {
125 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
126 }
128 Light *Scene::get_light(const char *name) const
129 {
130 for(size_t i=0; i<lights.size(); i++) {
131 if(lights[i]->name == std::string(name)) {
132 return lights[i];
133 }
134 }
135 return 0;
136 }
138 int Scene::get_light_count() const
139 {
140 return (int)lights.size();
141 }
144 void Scene::add_camera(Camera *cam)
145 {
146 cameras.push_back(cam);
147 }
149 Camera *Scene::get_camera(int idx) const
150 {
151 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
152 }
154 Camera *Scene::get_camera(const char *name) const
155 {
156 for(size_t i=0; i<cameras.size(); i++) {
157 if(cameras[i]->name == std::string(name)) {
158 return cameras[i];
159 }
160 }
161 return 0;
162 }
164 int Scene::get_camera_count() const
165 {
166 return (int)cameras.size();
167 }
170 void Scene::add_node(Node *node)
171 {
172 nodes.push_back(node);
173 }
175 Node *Scene::get_node(int idx) const
176 {
177 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
178 }
180 Node *Scene::get_node(const char *name) const
181 {
182 for(size_t i=0; i<nodes.size(); i++) {
183 if(strcmp(nodes[i]->get_name(), name) == 0) {
184 return nodes[i];
185 }
186 }
187 return 0;
188 }
190 int Scene::get_node_count() const
191 {
192 return (int)nodes.size();
193 }
196 bool Scene::load(goat3d_io *io)
197 {
198 return false;
199 }
201 static long save_env(const Scene *scn, long offset, goat3d_io *io);
202 static long save_materials(const Scene *scn, long offset, goat3d_io *io);
203 static long save_material(const Material *mat, long offset, goat3d_io *io);
204 static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io);
205 static long save_meshes(const Scene *scn, long offset, goat3d_io *io);
206 static long save_lights(const Scene *scn, long offset, goat3d_io *io);
207 static long save_cameras(const Scene *scn, long offset, goat3d_io *io);
208 static long save_nodes(const Scene *scn, long offset, goat3d_io *io);
210 static long write_chunk_float(int id, float val, long offs, goat3d_io *io);
211 static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io);
212 static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io);
214 bool Scene::save(goat3d_io *io) const
215 {
216 long res;
218 ChunkHeader hdr;
219 hdr.id = CNK_SCENE;
220 hdr.size = sizeof hdr;
222 if((res = save_env(this, hdr.size, io)) < 0) {
223 return false;
224 }
225 hdr.size += res;
227 if((res = save_materials(this, hdr.size, io)) < 0) {
228 return false;
229 }
230 hdr.size += res;
232 if((res = save_meshes(this, hdr.size, io)) < 0) {
233 return false;
234 }
235 hdr.size += res;
237 if((res = save_lights(this, hdr.size, io)) < 0) {
238 return false;
239 }
240 hdr.size += res;
242 if((res = save_cameras(this, hdr.size, io)) < 0) {
243 return false;
244 }
245 hdr.size += res;
247 if((res = save_nodes(this, hdr.size, io)) < 0) {
248 return false;
249 }
250 hdr.size += res;
252 // now go back and write the root chunk
253 io->seek(0, SEEK_SET, io->cls);
254 if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) {
255 return false;
256 }
258 return true;
259 }
262 static long save_env(const Scene *scn, long offset, goat3d_io *io)
263 {
264 long res;
266 ChunkHeader hdr;
267 hdr.id = CNK_ENV;
268 hdr.size = sizeof hdr;
270 if((res = write_chunk_float3(CNK_ENV_AMBIENT, scn->get_ambient(), offset, io)) < 0) {
271 return -1;
272 }
273 hdr.size += res;
275 // TODO add fog chunk
277 io->seek(offset, SEEK_SET, io->cls);
278 if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) {
279 return -1;
280 }
281 return hdr.size;
282 }
284 static long save_materials(const Scene *scn, long offset, goat3d_io *io)
285 {
286 long res;
288 ChunkHeader hdr;
289 hdr.id = CNK_MTL_LIST;
290 hdr.size = sizeof hdr;
292 for(int i=0; i<scn->get_material_count(); i++) {
293 if((res = save_material(scn->get_material(i), offset + hdr.size, io)) < 0) {
294 return -1;
295 }
296 hdr.size += res;
297 }
299 io->seek(offset, SEEK_SET, io->cls);
300 if(io->write(&hdr, hdr.size, io->cls) < hdr.size) {
301 return -1;
302 }
303 return hdr.size;
304 }
306 static long save_material(const Material *mat, long offset, goat3d_io *io)
307 {
308 long res;
310 ChunkHeader hdr;
311 hdr.id = CNK_MTL;
312 hdr.size = sizeof hdr;
314 for(int i=0; i<mat->get_attrib_count(); i++) {
315 const char *name = mat->get_attrib_name(i);
316 if((res = save_mat_attrib(name, (*mat)[i], offset + hdr.size, io)) < 0) {
317 return -1;
318 }
319 hdr.size += res;
320 }
322 io->seek(offset, SEEK_SET, io->cls);
323 if(io->write(&hdr, hdr.size, io->cls) < hdr.size) {
324 return -1;
325 }
326 return hdr.size;
327 }
329 static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io)
330 {
331 long res;
333 ChunkHeader hdr;
334 hdr.id = CNK_MTL_ATTR;
335 hdr.size = sizeof hdr;
337 // TODO cont.
338 return -1;
339 }
341 static long save_meshes(const Scene *scn, long offset, goat3d_io *io)
342 {
343 return 0;
344 }
346 static long save_lights(const Scene *scn, long offset, goat3d_io *io)
347 {
348 return 0;
349 }
351 static long save_cameras(const Scene *scn, long offset, goat3d_io *io)
352 {
353 return 0;
354 }
356 static long save_nodes(const Scene *scn, long offset, goat3d_io *io)
357 {
358 return 0;
359 }
361 static long write_chunk_float(int id, float val, long offs, goat3d_io *io)
362 {
363 int size = sizeof(ChunkHeader) + sizeof val;
364 char *buf = (char*)alloca(size);
366 Chunk *c = (Chunk*)buf;
367 c->hdr.id = id;
368 c->hdr.size = size;
369 *(float*)c->data = val;
371 io->seek(offs, SEEK_SET, io->cls);
372 if(io->write(buf, size, io->cls) < size) {
373 return -1;
374 }
375 return size;
376 }
378 static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io)
379 {
380 int size = sizeof(ChunkHeader) + sizeof vec;
381 char *buf = (char*)alloca(size);
383 Chunk *c = (Chunk*)buf;
384 c->hdr.id = id;
385 c->hdr.size = size;
386 *(Vector3*)c->data = vec;
388 io->seek(offs, SEEK_SET, io->cls);
389 if(io->write(buf, size, io->cls) < size) {
390 return -1;
391 }
392 return size;
393 }
395 static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io)
396 {
397 int size = sizeof(ChunkHeader) + sizeof vec;
398 char *buf = (char*)alloca(size);
400 Chunk *c = (Chunk*)buf;
401 c->hdr.id = id;
402 c->hdr.size = size;
403 *(Vector4*)c->data = vec;
405 io->seek(offs, SEEK_SET, io->cls);
406 if(io->write(buf, size, io->cls) < size) {
407 return -1;
408 }
409 return size;
410 }