nuclear@0: #include "goat3d.h" nuclear@0: #include "goat3d_impl.h" nuclear@9: #include "chunk.h" nuclear@0: nuclear@0: Scene::Scene() nuclear@0: : name("unnamed"), ambient(0.05, 0.05, 0.05) nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: Scene::~Scene() nuclear@0: { nuclear@0: clear(); nuclear@0: } nuclear@0: nuclear@0: void Scene::clear() nuclear@0: { nuclear@0: for(size_t i=0; iname = name; nuclear@0: } nuclear@0: nuclear@0: const char *Scene::get_name() const nuclear@0: { nuclear@0: return name.c_str(); nuclear@0: } nuclear@8: nuclear@8: void Scene::set_ambient(const Vector3 &amb) nuclear@8: { nuclear@8: ambient = amb; nuclear@8: } nuclear@8: nuclear@8: const Vector3 &Scene::get_ambient() const nuclear@8: { nuclear@8: return ambient; nuclear@8: } nuclear@8: nuclear@8: void Scene::add_material(Material *mat) nuclear@8: { nuclear@8: materials.push_back(mat); nuclear@8: } nuclear@8: nuclear@8: Material *Scene::get_material(int idx) const nuclear@8: { nuclear@8: return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0; nuclear@8: } nuclear@8: nuclear@8: Material *Scene::get_material(const char *name) const nuclear@8: { nuclear@8: for(size_t i=0; iname == std::string(name)) { nuclear@8: return materials[i]; nuclear@8: } nuclear@8: } nuclear@8: return 0; nuclear@8: } nuclear@8: nuclear@9: int Scene::get_material_count() const nuclear@9: { nuclear@9: return (int)materials.size(); nuclear@9: } nuclear@9: nuclear@9: nuclear@8: void Scene::add_mesh(Mesh *mesh) nuclear@8: { nuclear@8: meshes.push_back(mesh); nuclear@8: } nuclear@8: nuclear@8: Mesh *Scene::get_mesh(int idx) const nuclear@8: { nuclear@8: return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0; nuclear@8: } nuclear@8: nuclear@8: Mesh *Scene::get_mesh(const char *name) const nuclear@8: { nuclear@8: for(size_t i=0; iname == std::string(name)) { nuclear@8: return meshes[i]; nuclear@8: } nuclear@8: } nuclear@8: return 0; nuclear@8: } nuclear@8: nuclear@9: int Scene::get_mesh_count() const nuclear@9: { nuclear@9: return (int)meshes.size(); nuclear@9: } nuclear@9: nuclear@9: nuclear@8: void Scene::add_light(Light *light) nuclear@8: { nuclear@8: lights.push_back(light); nuclear@8: } nuclear@8: nuclear@8: Light *Scene::get_light(int idx) const nuclear@8: { nuclear@8: return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0; nuclear@8: } nuclear@8: nuclear@8: Light *Scene::get_light(const char *name) const nuclear@8: { nuclear@8: for(size_t i=0; iname == std::string(name)) { nuclear@8: return lights[i]; nuclear@8: } nuclear@8: } nuclear@8: return 0; nuclear@8: } nuclear@8: nuclear@9: int Scene::get_light_count() const nuclear@9: { nuclear@9: return (int)lights.size(); nuclear@9: } nuclear@9: nuclear@9: nuclear@8: void Scene::add_camera(Camera *cam) nuclear@8: { nuclear@8: cameras.push_back(cam); nuclear@8: } nuclear@8: nuclear@8: Camera *Scene::get_camera(int idx) const nuclear@8: { nuclear@8: return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0; nuclear@8: } nuclear@8: nuclear@8: Camera *Scene::get_camera(const char *name) const nuclear@8: { nuclear@8: for(size_t i=0; iname == std::string(name)) { nuclear@8: return cameras[i]; nuclear@8: } nuclear@8: } nuclear@8: return 0; nuclear@8: } nuclear@8: nuclear@9: int Scene::get_camera_count() const nuclear@9: { nuclear@9: return (int)cameras.size(); nuclear@9: } nuclear@9: nuclear@9: nuclear@8: void Scene::add_node(Node *node) nuclear@8: { nuclear@8: nodes.push_back(node); nuclear@8: } nuclear@8: nuclear@8: Node *Scene::get_node(int idx) const nuclear@8: { nuclear@8: return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0; nuclear@8: } nuclear@8: nuclear@8: Node *Scene::get_node(const char *name) const nuclear@8: { nuclear@8: for(size_t i=0; iget_name(), name) == 0) { nuclear@8: return nodes[i]; nuclear@8: } nuclear@8: } nuclear@8: return 0; nuclear@8: } nuclear@8: nuclear@9: int Scene::get_node_count() const nuclear@9: { nuclear@9: return (int)nodes.size(); nuclear@9: } nuclear@9: nuclear@9: nuclear@8: bool Scene::load(goat3d_io *io) nuclear@8: { nuclear@8: return false; nuclear@8: } nuclear@8: nuclear@9: static long save_env(const Scene *scn, long offset, goat3d_io *io); nuclear@9: static long save_materials(const Scene *scn, long offset, goat3d_io *io); nuclear@9: static long save_material(const Material *mat, long offset, goat3d_io *io); nuclear@9: static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io); nuclear@9: static long save_meshes(const Scene *scn, long offset, goat3d_io *io); nuclear@9: static long save_lights(const Scene *scn, long offset, goat3d_io *io); nuclear@9: static long save_cameras(const Scene *scn, long offset, goat3d_io *io); nuclear@9: static long save_nodes(const Scene *scn, long offset, goat3d_io *io); nuclear@9: nuclear@9: static long write_chunk_float(int id, float val, long offs, goat3d_io *io); nuclear@9: static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io); nuclear@9: static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io); nuclear@9: nuclear@8: bool Scene::save(goat3d_io *io) const nuclear@8: { nuclear@9: long res; nuclear@9: nuclear@9: ChunkHeader hdr; nuclear@9: hdr.id = CNK_SCENE; nuclear@9: hdr.size = sizeof hdr; nuclear@9: nuclear@9: if((res = save_env(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: if((res = save_materials(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: if((res = save_meshes(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: if((res = save_lights(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: if((res = save_cameras(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: if((res = save_nodes(this, hdr.size, io)) < 0) { nuclear@9: return false; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: // now go back and write the root chunk nuclear@9: io->seek(0, SEEK_SET, io->cls); nuclear@9: if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) { nuclear@9: return false; nuclear@9: } nuclear@9: nuclear@9: return true; nuclear@8: } nuclear@9: nuclear@9: nuclear@9: static long save_env(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: long res; nuclear@9: nuclear@9: ChunkHeader hdr; nuclear@9: hdr.id = CNK_ENV; nuclear@9: hdr.size = sizeof hdr; nuclear@9: nuclear@9: if((res = write_chunk_float3(CNK_ENV_AMBIENT, scn->get_ambient(), offset, io)) < 0) { nuclear@9: return -1; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: nuclear@9: // TODO add fog chunk nuclear@9: nuclear@9: io->seek(offset, SEEK_SET, io->cls); nuclear@9: if(io->write(&hdr, sizeof hdr, io->cls) < (ssize_t)sizeof hdr) { nuclear@9: return -1; nuclear@9: } nuclear@9: return hdr.size; nuclear@9: } nuclear@9: nuclear@9: static long save_materials(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: long res; nuclear@9: nuclear@9: ChunkHeader hdr; nuclear@9: hdr.id = CNK_MTL_LIST; nuclear@9: hdr.size = sizeof hdr; nuclear@9: nuclear@9: for(int i=0; iget_material_count(); i++) { nuclear@9: if((res = save_material(scn->get_material(i), offset + hdr.size, io)) < 0) { nuclear@9: return -1; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: } nuclear@9: nuclear@9: io->seek(offset, SEEK_SET, io->cls); nuclear@9: if(io->write(&hdr, hdr.size, io->cls) < hdr.size) { nuclear@9: return -1; nuclear@9: } nuclear@9: return hdr.size; nuclear@9: } nuclear@9: nuclear@9: static long save_material(const Material *mat, long offset, goat3d_io *io) nuclear@9: { nuclear@9: long res; nuclear@9: nuclear@9: ChunkHeader hdr; nuclear@9: hdr.id = CNK_MTL; nuclear@9: hdr.size = sizeof hdr; nuclear@9: nuclear@9: for(int i=0; iget_attrib_count(); i++) { nuclear@9: const char *name = mat->get_attrib_name(i); nuclear@9: if((res = save_mat_attrib(name, (*mat)[i], offset + hdr.size, io)) < 0) { nuclear@9: return -1; nuclear@9: } nuclear@9: hdr.size += res; nuclear@9: } nuclear@9: nuclear@9: io->seek(offset, SEEK_SET, io->cls); nuclear@9: if(io->write(&hdr, hdr.size, io->cls) < hdr.size) { nuclear@9: return -1; nuclear@9: } nuclear@9: return hdr.size; nuclear@9: } nuclear@9: nuclear@9: static long save_mat_attrib(const char *name, const MaterialAttrib &attr, long offset, goat3d_io *io) nuclear@9: { nuclear@9: long res; nuclear@9: nuclear@9: ChunkHeader hdr; nuclear@9: hdr.id = CNK_MTL_ATTR; nuclear@9: hdr.size = sizeof hdr; nuclear@9: nuclear@9: // TODO cont. nuclear@9: return -1; nuclear@9: } nuclear@9: nuclear@9: static long save_meshes(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: return 0; nuclear@9: } nuclear@9: nuclear@9: static long save_lights(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: return 0; nuclear@9: } nuclear@9: nuclear@9: static long save_cameras(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: return 0; nuclear@9: } nuclear@9: nuclear@9: static long save_nodes(const Scene *scn, long offset, goat3d_io *io) nuclear@9: { nuclear@9: return 0; nuclear@9: } nuclear@9: nuclear@9: static long write_chunk_float(int id, float val, long offs, goat3d_io *io) nuclear@9: { nuclear@9: int size = sizeof(ChunkHeader) + sizeof val; nuclear@9: char *buf = (char*)alloca(size); nuclear@9: nuclear@9: Chunk *c = (Chunk*)buf; nuclear@9: c->hdr.id = id; nuclear@9: c->hdr.size = size; nuclear@9: *(float*)c->data = val; nuclear@9: nuclear@9: io->seek(offs, SEEK_SET, io->cls); nuclear@9: if(io->write(buf, size, io->cls) < size) { nuclear@9: return -1; nuclear@9: } nuclear@9: return size; nuclear@9: } nuclear@9: nuclear@9: static long write_chunk_float3(int id, const Vector3 &vec, long offs, goat3d_io *io) nuclear@9: { nuclear@9: int size = sizeof(ChunkHeader) + sizeof vec; nuclear@9: char *buf = (char*)alloca(size); nuclear@9: nuclear@9: Chunk *c = (Chunk*)buf; nuclear@9: c->hdr.id = id; nuclear@9: c->hdr.size = size; nuclear@9: *(Vector3*)c->data = vec; nuclear@9: nuclear@9: io->seek(offs, SEEK_SET, io->cls); nuclear@9: if(io->write(buf, size, io->cls) < size) { nuclear@9: return -1; nuclear@9: } nuclear@9: return size; nuclear@9: } nuclear@9: nuclear@9: static long write_chunk_float4(int id, const Vector4 &vec, long offs, goat3d_io *io) nuclear@9: { nuclear@9: int size = sizeof(ChunkHeader) + sizeof vec; nuclear@9: char *buf = (char*)alloca(size); nuclear@9: nuclear@9: Chunk *c = (Chunk*)buf; nuclear@9: c->hdr.id = id; nuclear@9: c->hdr.size = size; nuclear@9: *(Vector4*)c->data = vec; nuclear@9: nuclear@9: io->seek(offs, SEEK_SET, io->cls); nuclear@9: if(io->write(buf, size, io->cls) < size) { nuclear@9: return -1; nuclear@9: } nuclear@9: return size; nuclear@9: }