nuclear@54: /* nuclear@54: goat3d - 3D scene, character, and animation file format library. nuclear@54: Copyright (C) 2013-2014 John Tsiombikas nuclear@54: nuclear@54: This program is free software: you can redistribute it and/or modify nuclear@54: it under the terms of the GNU Lesser General Public License as published by nuclear@54: the Free Software Foundation, either version 3 of the License, or nuclear@54: (at your option) any later version. nuclear@54: nuclear@54: This program is distributed in the hope that it will be useful, nuclear@54: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@54: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@54: GNU Lesser General Public License for more details. nuclear@54: nuclear@54: You should have received a copy of the GNU Lesser General Public License nuclear@54: along with this program. If not, see . nuclear@54: */ nuclear@14: #include nuclear@0: #include "goat3d.h" nuclear@0: #include "goat3d_impl.h" nuclear@9: #include "chunk.h" nuclear@0: nuclear@47: using namespace g3dimpl; nuclear@47: 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@17: if(mat->name.empty()) { nuclear@17: char buf[64]; nuclear@17: sprintf(buf, "material%04d", (int)materials.size()); nuclear@17: mat->name = std::string(buf); nuclear@17: } 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@17: if(mesh->name.empty()) { nuclear@17: char buf[64]; nuclear@17: sprintf(buf, "mesh%04d", (int)meshes.size()); nuclear@17: mesh->name = std::string(buf); nuclear@17: } 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@50: // Scene::load is defined in goat3d_read.cc nuclear@19: // Scene::loadxml is defined in goat3d_readxml.cc nuclear@14: // Scene::save is defined in goat3d_write.cc nuclear@19: // Scene::savexml is defined in goat3d_writexml.cc nuclear@9: nuclear@9: nuclear@47: void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...) nuclear@8: { nuclear@14: va_list ap; nuclear@9: nuclear@14: va_start(ap, fmt); nuclear@14: io_vfprintf(io, fmt, ap); nuclear@14: va_end(ap); nuclear@14: } nuclear@9: nuclear@9: nuclear@47: void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap) nuclear@14: { nuclear@14: char smallbuf[256]; nuclear@14: char *buf = smallbuf; nuclear@14: int sz = sizeof smallbuf; nuclear@9: nuclear@14: int retsz = vsnprintf(buf, sz - 1, fmt, ap); nuclear@9: nuclear@14: if(retsz >= sz) { nuclear@14: /* C99 mandates that snprintf with a short count should return the nuclear@14: * number of characters that *would* be printed. nuclear@14: */ nuclear@14: buf = new char[retsz + 1]; nuclear@9: nuclear@14: vsnprintf(buf, retsz, fmt, ap); nuclear@9: nuclear@14: } else if(retsz <= 0) { nuclear@14: /* SUSv2 and microsoft specify that snprintf with a short count nuclear@14: * returns an arbitrary value <= 0. So let's try allocating nuclear@14: * bigger and bigger arrays until we find the correct size. nuclear@14: */ nuclear@14: sz = sizeof smallbuf; nuclear@14: do { nuclear@14: sz *= 2; nuclear@14: if(buf != smallbuf) { nuclear@14: delete [] buf; nuclear@14: } nuclear@14: buf = new char[sz + 1]; nuclear@9: nuclear@14: retsz = vsnprintf(buf, sz, fmt, ap); nuclear@14: } while(retsz <= 0); nuclear@9: } nuclear@9: nuclear@15: io->write(buf, retsz, io->cls); nuclear@9: nuclear@14: if(buf != smallbuf) { nuclear@14: delete [] buf; nuclear@9: } nuclear@9: nuclear@9: }