goat3d

annotate src/scene.cc @ 74:ab66cdabf6f2

loading scene files (no vis yet)
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 06 May 2014 13:26:52 +0300
parents 8970ca3d55e0
children 76dea247f75c
rev   line source
nuclear@54 1 /*
nuclear@54 2 goat3d - 3D scene, character, and animation file format library.
nuclear@54 3 Copyright (C) 2013-2014 John Tsiombikas <nuclear@member.fsf.org>
nuclear@54 4
nuclear@54 5 This program is free software: you can redistribute it and/or modify
nuclear@54 6 it under the terms of the GNU Lesser General Public License as published by
nuclear@54 7 the Free Software Foundation, either version 3 of the License, or
nuclear@54 8 (at your option) any later version.
nuclear@54 9
nuclear@54 10 This program is distributed in the hope that it will be useful,
nuclear@54 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@54 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@54 13 GNU Lesser General Public License for more details.
nuclear@54 14
nuclear@54 15 You should have received a copy of the GNU Lesser General Public License
nuclear@54 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@54 17 */
nuclear@14 18 #include <stdarg.h>
nuclear@0 19 #include "goat3d.h"
nuclear@0 20 #include "goat3d_impl.h"
nuclear@9 21 #include "chunk.h"
nuclear@0 22
nuclear@47 23 using namespace g3dimpl;
nuclear@47 24
nuclear@0 25 Scene::Scene()
nuclear@0 26 : name("unnamed"), ambient(0.05, 0.05, 0.05)
nuclear@0 27 {
nuclear@74 28 goat = 0;
nuclear@0 29 }
nuclear@0 30
nuclear@0 31 Scene::~Scene()
nuclear@0 32 {
nuclear@0 33 clear();
nuclear@0 34 }
nuclear@0 35
nuclear@0 36 void Scene::clear()
nuclear@0 37 {
nuclear@0 38 for(size_t i=0; i<materials.size(); i++) {
nuclear@0 39 delete materials[i];
nuclear@0 40 }
nuclear@0 41 materials.clear();
nuclear@0 42
nuclear@0 43 for(size_t i=0; i<meshes.size(); i++) {
nuclear@0 44 delete meshes[i];
nuclear@0 45 }
nuclear@0 46 meshes.clear();
nuclear@0 47
nuclear@0 48 for(size_t i=0; i<lights.size(); i++) {
nuclear@0 49 delete lights[i];
nuclear@0 50 }
nuclear@0 51 lights.clear();
nuclear@0 52
nuclear@0 53 for(size_t i=0; i<cameras.size(); i++) {
nuclear@0 54 delete cameras[i];
nuclear@0 55 }
nuclear@0 56 cameras.clear();
nuclear@0 57
nuclear@12 58 for(size_t i=0; i<nodes.size(); i++) {
nuclear@66 59 delete nodes[i];
nuclear@0 60 }
nuclear@12 61 nodes.clear();
nuclear@0 62
nuclear@0 63 name = "unnamed";
nuclear@0 64 }
nuclear@0 65
nuclear@0 66 void Scene::set_name(const char *name)
nuclear@0 67 {
nuclear@0 68 this->name = name;
nuclear@0 69 }
nuclear@0 70
nuclear@0 71 const char *Scene::get_name() const
nuclear@0 72 {
nuclear@0 73 return name.c_str();
nuclear@0 74 }
nuclear@8 75
nuclear@8 76 void Scene::set_ambient(const Vector3 &amb)
nuclear@8 77 {
nuclear@8 78 ambient = amb;
nuclear@8 79 }
nuclear@8 80
nuclear@8 81 const Vector3 &Scene::get_ambient() const
nuclear@8 82 {
nuclear@8 83 return ambient;
nuclear@8 84 }
nuclear@8 85
nuclear@8 86 void Scene::add_material(Material *mat)
nuclear@8 87 {
nuclear@17 88 if(mat->name.empty()) {
nuclear@17 89 char buf[64];
nuclear@17 90 sprintf(buf, "material%04d", (int)materials.size());
nuclear@17 91 mat->name = std::string(buf);
nuclear@17 92 }
nuclear@8 93 materials.push_back(mat);
nuclear@8 94 }
nuclear@8 95
nuclear@8 96 Material *Scene::get_material(int idx) const
nuclear@8 97 {
nuclear@8 98 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
nuclear@8 99 }
nuclear@8 100
nuclear@8 101 Material *Scene::get_material(const char *name) const
nuclear@8 102 {
nuclear@8 103 for(size_t i=0; i<materials.size(); i++) {
nuclear@8 104 if(materials[i]->name == std::string(name)) {
nuclear@8 105 return materials[i];
nuclear@8 106 }
nuclear@8 107 }
nuclear@8 108 return 0;
nuclear@8 109 }
nuclear@8 110
nuclear@9 111 int Scene::get_material_count() const
nuclear@9 112 {
nuclear@9 113 return (int)materials.size();
nuclear@9 114 }
nuclear@9 115
nuclear@9 116
nuclear@8 117 void Scene::add_mesh(Mesh *mesh)
nuclear@8 118 {
nuclear@17 119 if(mesh->name.empty()) {
nuclear@17 120 char buf[64];
nuclear@17 121 sprintf(buf, "mesh%04d", (int)meshes.size());
nuclear@17 122 mesh->name = std::string(buf);
nuclear@17 123 }
nuclear@8 124 meshes.push_back(mesh);
nuclear@8 125 }
nuclear@8 126
nuclear@8 127 Mesh *Scene::get_mesh(int idx) const
nuclear@8 128 {
nuclear@8 129 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
nuclear@8 130 }
nuclear@8 131
nuclear@8 132 Mesh *Scene::get_mesh(const char *name) const
nuclear@8 133 {
nuclear@8 134 for(size_t i=0; i<meshes.size(); i++) {
nuclear@8 135 if(meshes[i]->name == std::string(name)) {
nuclear@8 136 return meshes[i];
nuclear@8 137 }
nuclear@8 138 }
nuclear@8 139 return 0;
nuclear@8 140 }
nuclear@8 141
nuclear@9 142 int Scene::get_mesh_count() const
nuclear@9 143 {
nuclear@9 144 return (int)meshes.size();
nuclear@9 145 }
nuclear@9 146
nuclear@9 147
nuclear@8 148 void Scene::add_light(Light *light)
nuclear@8 149 {
nuclear@8 150 lights.push_back(light);
nuclear@8 151 }
nuclear@8 152
nuclear@8 153 Light *Scene::get_light(int idx) const
nuclear@8 154 {
nuclear@8 155 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
nuclear@8 156 }
nuclear@8 157
nuclear@8 158 Light *Scene::get_light(const char *name) const
nuclear@8 159 {
nuclear@8 160 for(size_t i=0; i<lights.size(); i++) {
nuclear@8 161 if(lights[i]->name == std::string(name)) {
nuclear@8 162 return lights[i];
nuclear@8 163 }
nuclear@8 164 }
nuclear@8 165 return 0;
nuclear@8 166 }
nuclear@8 167
nuclear@9 168 int Scene::get_light_count() const
nuclear@9 169 {
nuclear@9 170 return (int)lights.size();
nuclear@9 171 }
nuclear@9 172
nuclear@9 173
nuclear@8 174 void Scene::add_camera(Camera *cam)
nuclear@8 175 {
nuclear@8 176 cameras.push_back(cam);
nuclear@8 177 }
nuclear@8 178
nuclear@8 179 Camera *Scene::get_camera(int idx) const
nuclear@8 180 {
nuclear@8 181 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
nuclear@8 182 }
nuclear@8 183
nuclear@8 184 Camera *Scene::get_camera(const char *name) const
nuclear@8 185 {
nuclear@8 186 for(size_t i=0; i<cameras.size(); i++) {
nuclear@8 187 if(cameras[i]->name == std::string(name)) {
nuclear@8 188 return cameras[i];
nuclear@8 189 }
nuclear@8 190 }
nuclear@8 191 return 0;
nuclear@8 192 }
nuclear@8 193
nuclear@9 194 int Scene::get_camera_count() const
nuclear@9 195 {
nuclear@9 196 return (int)cameras.size();
nuclear@9 197 }
nuclear@9 198
nuclear@9 199
nuclear@8 200 void Scene::add_node(Node *node)
nuclear@8 201 {
nuclear@8 202 nodes.push_back(node);
nuclear@8 203 }
nuclear@8 204
nuclear@8 205 Node *Scene::get_node(int idx) const
nuclear@8 206 {
nuclear@8 207 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
nuclear@8 208 }
nuclear@8 209
nuclear@8 210 Node *Scene::get_node(const char *name) const
nuclear@8 211 {
nuclear@8 212 for(size_t i=0; i<nodes.size(); i++) {
nuclear@8 213 if(strcmp(nodes[i]->get_name(), name) == 0) {
nuclear@8 214 return nodes[i];
nuclear@8 215 }
nuclear@8 216 }
nuclear@8 217 return 0;
nuclear@8 218 }
nuclear@8 219
nuclear@9 220 int Scene::get_node_count() const
nuclear@9 221 {
nuclear@9 222 return (int)nodes.size();
nuclear@9 223 }
nuclear@9 224
nuclear@50 225 // Scene::load is defined in goat3d_read.cc
nuclear@19 226 // Scene::loadxml is defined in goat3d_readxml.cc
nuclear@14 227 // Scene::save is defined in goat3d_write.cc
nuclear@19 228 // Scene::savexml is defined in goat3d_writexml.cc
nuclear@9 229
nuclear@9 230
nuclear@47 231 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
nuclear@8 232 {
nuclear@14 233 va_list ap;
nuclear@9 234
nuclear@14 235 va_start(ap, fmt);
nuclear@14 236 io_vfprintf(io, fmt, ap);
nuclear@14 237 va_end(ap);
nuclear@14 238 }
nuclear@9 239
nuclear@9 240
nuclear@47 241 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
nuclear@14 242 {
nuclear@14 243 char smallbuf[256];
nuclear@14 244 char *buf = smallbuf;
nuclear@14 245 int sz = sizeof smallbuf;
nuclear@9 246
nuclear@14 247 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
nuclear@9 248
nuclear@14 249 if(retsz >= sz) {
nuclear@14 250 /* C99 mandates that snprintf with a short count should return the
nuclear@14 251 * number of characters that *would* be printed.
nuclear@14 252 */
nuclear@14 253 buf = new char[retsz + 1];
nuclear@9 254
nuclear@14 255 vsnprintf(buf, retsz, fmt, ap);
nuclear@9 256
nuclear@14 257 } else if(retsz <= 0) {
nuclear@14 258 /* SUSv2 and microsoft specify that snprintf with a short count
nuclear@14 259 * returns an arbitrary value <= 0. So let's try allocating
nuclear@14 260 * bigger and bigger arrays until we find the correct size.
nuclear@14 261 */
nuclear@14 262 sz = sizeof smallbuf;
nuclear@14 263 do {
nuclear@14 264 sz *= 2;
nuclear@14 265 if(buf != smallbuf) {
nuclear@14 266 delete [] buf;
nuclear@14 267 }
nuclear@14 268 buf = new char[sz + 1];
nuclear@9 269
nuclear@14 270 retsz = vsnprintf(buf, sz, fmt, ap);
nuclear@14 271 } while(retsz <= 0);
nuclear@9 272 }
nuclear@9 273
nuclear@15 274 io->write(buf, retsz, io->cls);
nuclear@9 275
nuclear@14 276 if(buf != smallbuf) {
nuclear@14 277 delete [] buf;
nuclear@9 278 }
nuclear@9 279
nuclear@9 280 }