goat3d

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