# HG changeset patch # User John Tsiombikas # Date 1377229007 -10800 # Node ID 04bb114fcf0518694dbbdffbaa2dad66c0276987 # Parent cd71f0b92f442a8b16097adbdd627de0a8847c5c implementing Scene::save, lots to do still diff -r cd71f0b92f44 -r 04bb114fcf05 src/chunk.h --- a/src/chunk.h Wed Aug 21 05:52:28 2013 +0300 +++ b/src/chunk.h Fri Aug 23 06:36:47 2013 +0300 @@ -1,6 +1,8 @@ #ifndef CHUNK_H_ #define CHUNK_H_ +#include + enum { CNK_INVALID, // this shouldn't appear in files CNK_SCENE, // the root chunk @@ -100,6 +102,8 @@ MAX_NUM_CHUNKS }; +#define UNKNOWN_SIZE ((uint32_t)0xbaadf00d) + struct ChunkHeader { uint32_t id; uint32_t size; @@ -110,4 +114,6 @@ char data[1]; }; + + #endif // CHUNK_H_ diff -r cd71f0b92f44 -r 04bb114fcf05 src/goat3d.cc --- a/src/goat3d.cc Wed Aug 21 05:52:28 2013 +0300 +++ b/src/goat3d.cc Fri Aug 23 06:36:47 2013 +0300 @@ -1,5 +1,6 @@ #include "goat3d.h" #include "goat3d_impl.h" +#include "chunk.h" Scene::Scene() : name("unnamed"), ambient(0.05, 0.05, 0.05) @@ -81,6 +82,12 @@ return 0; } +int Scene::get_material_count() const +{ + return (int)materials.size(); +} + + void Scene::add_mesh(Mesh *mesh) { meshes.push_back(mesh); @@ -101,6 +108,12 @@ return 0; } +int Scene::get_mesh_count() const +{ + return (int)meshes.size(); +} + + void Scene::add_light(Light *light) { lights.push_back(light); @@ -121,6 +134,12 @@ return 0; } +int Scene::get_light_count() const +{ + return (int)lights.size(); +} + + void Scene::add_camera(Camera *cam) { cameras.push_back(cam); @@ -141,6 +160,12 @@ return 0; } +int Scene::get_camera_count() const +{ + return (int)cameras.size(); +} + + void Scene::add_node(Node *node) { nodes.push_back(node); @@ -161,12 +186,224 @@ return 0; } +int Scene::get_node_count() const +{ + return (int)nodes.size(); +} + + bool Scene::load(goat3d_io *io) { return false; } +static long save_env(const Scene *scn, long offset, goat3d_io *io); +static long save_materials(const Scene *scn, long offset, goat3d_io *io); +static long save_material(const Material *mat, long offset, goat3d_io *io); +static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io); +static long save_meshes(const Scene *scn, long offset, goat3d_io *io); +static long save_lights(const Scene *scn, long offset, goat3d_io *io); +static long save_cameras(const Scene *scn, long offset, goat3d_io *io); +static long save_nodes(const Scene *scn, long offset, goat3d_io *io); + +static long write_chunk_float(int id, float val, long offs, goat3d_io *io); +static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io); +static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io); + bool Scene::save(goat3d_io *io) const { - return false; + long res; + + ChunkHeader hdr; + hdr.id = CNK_SCENE; + hdr.size = sizeof hdr; + + if((res = save_env(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + if((res = save_materials(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + if((res = save_meshes(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + if((res = save_lights(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + if((res = save_cameras(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + if((res = save_nodes(this, hdr.size, io)) < 0) { + return false; + } + hdr.size += res; + + // now go back and write the root chunk + io->seek(0, SEEK_SET, io->cls); + if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) { + return false; + } + + return true; } + + +static long save_env(const Scene *scn, long offset, goat3d_io *io) +{ + long res; + + ChunkHeader hdr; + hdr.id = CNK_ENV; + hdr.size = sizeof hdr; + + if((res = write_chunk_float3(CNK_ENV_AMBIENT, scn->get_ambient(), offset, io)) < 0) { + return -1; + } + hdr.size += res; + + // TODO add fog chunk + + io->seek(offset, SEEK_SET, io->cls); + if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) { + return -1; + } + return hdr.size; +} + +static long save_materials(const Scene *scn, long offset, goat3d_io *io) +{ + long res; + + ChunkHeader hdr; + hdr.id = CNK_MTL_LIST; + hdr.size = sizeof hdr; + + for(int i=0; iget_material_count(); i++) { + if((res = save_material(scn->get_material(i), offset + hdr.size, io)) < 0) { + return -1; + } + hdr.size += res; + } + + io->seek(offset, SEEK_SET, io->cls); + if(io->write(&hdr, hdr.size, io->cls) < hdr.size) { + return -1; + } + return hdr.size; +} + +static long save_material(const Material *mat, long offset, goat3d_io *io) +{ + long res; + + ChunkHeader hdr; + hdr.id = CNK_MTL; + hdr.size = sizeof hdr; + + for(int i=0; iget_attrib_count(); i++) { + const char *name = mat->get_attrib_name(i); + if((res = save_mat_attrib(name, (*mat)[i], offset + hdr.size, io)) < 0) { + return -1; + } + hdr.size += res; + } + + io->seek(offset, SEEK_SET, io->cls); + if(io->write(&hdr, hdr.size, io->cls) < hdr.size) { + return -1; + } + return hdr.size; +} + +static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io) +{ + long res; + + ChunkHeader hdr; + hdr.id = CNK_MTL_ATTR; + hdr.size = sizeof hdr; + + // TODO cont. + return -1; +} + +static long save_meshes(const Scene *scn, long offset, goat3d_io *io) +{ + return 0; +} + +static long save_lights(const Scene *scn, long offset, goat3d_io *io) +{ + return 0; +} + +static long save_cameras(const Scene *scn, long offset, goat3d_io *io) +{ + return 0; +} + +static long save_nodes(const Scene *scn, long offset, goat3d_io *io) +{ + return 0; +} + +static long write_chunk_float(int id, float val, long offs, goat3d_io *io) +{ + int size = sizeof(ChunkHeader) + sizeof val; + char *buf = (char*)alloca(size); + + Chunk *c = (Chunk*)buf; + c->hdr.id = id; + c->hdr.size = size; + *(float*)c->data = val; + + io->seek(offs, SEEK_SET, io->cls); + if(io->write(buf, size, io->cls) < size) { + return -1; + } + return size; +} + +static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io) +{ + int size = sizeof(ChunkHeader) + sizeof vec; + char *buf = (char*)alloca(size); + + Chunk *c = (Chunk*)buf; + c->hdr.id = id; + c->hdr.size = size; + *(Vector3*)c->data = vec; + + io->seek(offs, SEEK_SET, io->cls); + if(io->write(buf, size, io->cls) < size) { + return -1; + } + return size; +} + +static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io) +{ + int size = sizeof(ChunkHeader) + sizeof vec; + char *buf = (char*)alloca(size); + + Chunk *c = (Chunk*)buf; + c->hdr.id = id; + c->hdr.size = size; + *(Vector4*)c->data = vec; + + io->seek(offs, SEEK_SET, io->cls); + if(io->write(buf, size, io->cls) < size) { + return -1; + } + return size; +} diff -r cd71f0b92f44 -r 04bb114fcf05 src/goat3d.h --- a/src/goat3d.h Wed Aug 21 05:52:28 2013 +0300 +++ b/src/goat3d.h Fri Aug 23 06:36:47 2013 +0300 @@ -9,8 +9,8 @@ struct goat3d_io { void *cls; /* closure data */ - size_t (*read)(void *buf, size_t bytes, void *uptr); - size_t (*write)(void *buf, size_t bytes, void *uptr); + ssize_t (*read)(void *buf, size_t bytes, void *uptr); + ssize_t (*write)(void *buf, size_t bytes, void *uptr); long (*seek)(long offs, int whence, void *uptr); }; diff -r cd71f0b92f44 -r 04bb114fcf05 src/goat3d_impl.h --- a/src/goat3d_impl.h Wed Aug 21 05:52:28 2013 +0300 +++ b/src/goat3d_impl.h Fri Aug 23 06:36:47 2013 +0300 @@ -36,22 +36,27 @@ void add_material(Material *mat); Material *get_material(int idx) const; Material *get_material(const char *name) const; + int get_material_count() const; void add_mesh(Mesh *mesh); Mesh *get_mesh(int idx) const; Mesh *get_mesh(const char *name) const; + int get_mesh_count() const; void add_light(Light *light); Light *get_light(int idx) const; Light *get_light(const char *name) const; + int get_light_count() const; void add_camera(Camera *cam); Camera *get_camera(int idx) const; Camera *get_camera(const char *name) const; + int get_camera_count() const; void add_node(Node *node); Node *get_node(int idx) const; Node *get_node(const char *name) const; + int get_node_count() const; bool load(goat3d_io *io); bool save(goat3d_io *io) const; diff -r cd71f0b92f44 -r 04bb114fcf05 src/material.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/material.cc Fri Aug 23 06:36:47 2013 +0300 @@ -0,0 +1,54 @@ +#include "material.h" + +int Material::get_attrib_count() const +{ + return (int)attrib.size(); +} + +const char *Material::get_attrib_name(int idx) const +{ + if(idx < 0 || idx >= get_attrib_count()) { + return 0; + } + + std::map::const_iterator it = attrib.begin(); + for(int i=0; ifirst.c_str(); +} + +MaterialAttrib &Material::operator [](int idx) +{ + if(idx < 0 || idx >= get_attrib_count()) { + return def_attr; + } + + std::map::iterator it = attrib.begin(); + for(int i=0; isecond; +} + +const MaterialAttrib &Material::operator [](int idx) const +{ + if(idx < 0 || idx >= get_attrib_count()) { + return def_attr; + } + + std::map::const_iterator it = attrib.begin(); + for(int i=0; isecond; +} + +MaterialAttrib &Material::operator [](const std::string &name) +{ + return attrib[name]; +} + +const MaterialAttrib &Material::operator [](const std::string &name) const +{ + std::map::const_iterator it; + if((it = attrib.find(name)) != attrib.end()) { + return it->second; + } + return def_attr; +} + diff -r cd71f0b92f44 -r 04bb114fcf05 src/material.h --- a/src/material.h Wed Aug 21 05:52:28 2013 +0300 +++ b/src/material.h Fri Aug 23 06:36:47 2013 +0300 @@ -28,19 +28,14 @@ public: std::string name; - MaterialAttrib &operator [](const std::string &name) - { - return attrib[name]; - } + int get_attrib_count() const; + const char *get_attrib_name(int idx) const; - const MaterialAttrib &operator [](const std::string &name) const - { - std::map::const_iterator it; - if((it = attrib.find(name)) != attrib.end()) { - return it->second; - } - return def_attr; - } + MaterialAttrib &operator [](int idx); + const MaterialAttrib &operator [](int idx) const; + + MaterialAttrib &operator [](const std::string &name); + const MaterialAttrib &operator [](const std::string &name) const; }; #endif // MATERIAL_H_