goat3d

annotate src/scene.cc @ 54:dad392c710df

added copyright headers and license files + readme
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Apr 2014 08:50:36 +0300
parents 0be413ac2e0a
children 8970ca3d55e0
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@0 28 }
nuclear@0 29
nuclear@0 30 Scene::~Scene()
nuclear@0 31 {
nuclear@0 32 clear();
nuclear@0 33 }
nuclear@0 34
nuclear@0 35 void Scene::clear()
nuclear@0 36 {
nuclear@0 37 for(size_t i=0; i<materials.size(); i++) {
nuclear@0 38 delete materials[i];
nuclear@0 39 }
nuclear@0 40 materials.clear();
nuclear@0 41
nuclear@0 42 for(size_t i=0; i<meshes.size(); i++) {
nuclear@0 43 delete meshes[i];
nuclear@0 44 }
nuclear@0 45 meshes.clear();
nuclear@0 46
nuclear@0 47 for(size_t i=0; i<lights.size(); i++) {
nuclear@0 48 delete lights[i];
nuclear@0 49 }
nuclear@0 50 lights.clear();
nuclear@0 51
nuclear@0 52 for(size_t i=0; i<cameras.size(); i++) {
nuclear@0 53 delete cameras[i];
nuclear@0 54 }
nuclear@0 55 cameras.clear();
nuclear@0 56
nuclear@12 57 for(size_t i=0; i<nodes.size(); i++) {
nuclear@12 58 delete_node_tree(nodes[i]);
nuclear@0 59 }
nuclear@12 60 nodes.clear();
nuclear@0 61
nuclear@0 62 name = "unnamed";
nuclear@0 63 }
nuclear@0 64
nuclear@0 65 void Scene::set_name(const char *name)
nuclear@0 66 {
nuclear@0 67 this->name = name;
nuclear@0 68 }
nuclear@0 69
nuclear@0 70 const char *Scene::get_name() const
nuclear@0 71 {
nuclear@0 72 return name.c_str();
nuclear@0 73 }
nuclear@8 74
nuclear@8 75 void Scene::set_ambient(const Vector3 &amb)
nuclear@8 76 {
nuclear@8 77 ambient = amb;
nuclear@8 78 }
nuclear@8 79
nuclear@8 80 const Vector3 &Scene::get_ambient() const
nuclear@8 81 {
nuclear@8 82 return ambient;
nuclear@8 83 }
nuclear@8 84
nuclear@8 85 void Scene::add_material(Material *mat)
nuclear@8 86 {
nuclear@17 87 if(mat->name.empty()) {
nuclear@17 88 char buf[64];
nuclear@17 89 sprintf(buf, "material%04d", (int)materials.size());
nuclear@17 90 mat->name = std::string(buf);
nuclear@17 91 }
nuclear@8 92 materials.push_back(mat);
nuclear@8 93 }
nuclear@8 94
nuclear@8 95 Material *Scene::get_material(int idx) const
nuclear@8 96 {
nuclear@8 97 return idx >=0 && idx < (int)materials.size() ? materials[idx] : 0;
nuclear@8 98 }
nuclear@8 99
nuclear@8 100 Material *Scene::get_material(const char *name) const
nuclear@8 101 {
nuclear@8 102 for(size_t i=0; i<materials.size(); i++) {
nuclear@8 103 if(materials[i]->name == std::string(name)) {
nuclear@8 104 return materials[i];
nuclear@8 105 }
nuclear@8 106 }
nuclear@8 107 return 0;
nuclear@8 108 }
nuclear@8 109
nuclear@9 110 int Scene::get_material_count() const
nuclear@9 111 {
nuclear@9 112 return (int)materials.size();
nuclear@9 113 }
nuclear@9 114
nuclear@9 115
nuclear@8 116 void Scene::add_mesh(Mesh *mesh)
nuclear@8 117 {
nuclear@17 118 if(mesh->name.empty()) {
nuclear@17 119 char buf[64];
nuclear@17 120 sprintf(buf, "mesh%04d", (int)meshes.size());
nuclear@17 121 mesh->name = std::string(buf);
nuclear@17 122 }
nuclear@8 123 meshes.push_back(mesh);
nuclear@8 124 }
nuclear@8 125
nuclear@8 126 Mesh *Scene::get_mesh(int idx) const
nuclear@8 127 {
nuclear@8 128 return idx >= 0 && idx < (int)meshes.size() ? meshes[idx] : 0;
nuclear@8 129 }
nuclear@8 130
nuclear@8 131 Mesh *Scene::get_mesh(const char *name) const
nuclear@8 132 {
nuclear@8 133 for(size_t i=0; i<meshes.size(); i++) {
nuclear@8 134 if(meshes[i]->name == std::string(name)) {
nuclear@8 135 return meshes[i];
nuclear@8 136 }
nuclear@8 137 }
nuclear@8 138 return 0;
nuclear@8 139 }
nuclear@8 140
nuclear@9 141 int Scene::get_mesh_count() const
nuclear@9 142 {
nuclear@9 143 return (int)meshes.size();
nuclear@9 144 }
nuclear@9 145
nuclear@9 146
nuclear@8 147 void Scene::add_light(Light *light)
nuclear@8 148 {
nuclear@8 149 lights.push_back(light);
nuclear@8 150 }
nuclear@8 151
nuclear@8 152 Light *Scene::get_light(int idx) const
nuclear@8 153 {
nuclear@8 154 return idx >= 0 && idx < (int)lights.size() ? lights[idx] : 0;
nuclear@8 155 }
nuclear@8 156
nuclear@8 157 Light *Scene::get_light(const char *name) const
nuclear@8 158 {
nuclear@8 159 for(size_t i=0; i<lights.size(); i++) {
nuclear@8 160 if(lights[i]->name == std::string(name)) {
nuclear@8 161 return lights[i];
nuclear@8 162 }
nuclear@8 163 }
nuclear@8 164 return 0;
nuclear@8 165 }
nuclear@8 166
nuclear@9 167 int Scene::get_light_count() const
nuclear@9 168 {
nuclear@9 169 return (int)lights.size();
nuclear@9 170 }
nuclear@9 171
nuclear@9 172
nuclear@8 173 void Scene::add_camera(Camera *cam)
nuclear@8 174 {
nuclear@8 175 cameras.push_back(cam);
nuclear@8 176 }
nuclear@8 177
nuclear@8 178 Camera *Scene::get_camera(int idx) const
nuclear@8 179 {
nuclear@8 180 return idx >= 0 && idx < (int)cameras.size() ? cameras[idx] : 0;
nuclear@8 181 }
nuclear@8 182
nuclear@8 183 Camera *Scene::get_camera(const char *name) const
nuclear@8 184 {
nuclear@8 185 for(size_t i=0; i<cameras.size(); i++) {
nuclear@8 186 if(cameras[i]->name == std::string(name)) {
nuclear@8 187 return cameras[i];
nuclear@8 188 }
nuclear@8 189 }
nuclear@8 190 return 0;
nuclear@8 191 }
nuclear@8 192
nuclear@9 193 int Scene::get_camera_count() const
nuclear@9 194 {
nuclear@9 195 return (int)cameras.size();
nuclear@9 196 }
nuclear@9 197
nuclear@9 198
nuclear@8 199 void Scene::add_node(Node *node)
nuclear@8 200 {
nuclear@8 201 nodes.push_back(node);
nuclear@8 202 }
nuclear@8 203
nuclear@8 204 Node *Scene::get_node(int idx) const
nuclear@8 205 {
nuclear@8 206 return idx >= 0 && idx < (int)nodes.size() ? nodes[idx] : 0;
nuclear@8 207 }
nuclear@8 208
nuclear@8 209 Node *Scene::get_node(const char *name) const
nuclear@8 210 {
nuclear@8 211 for(size_t i=0; i<nodes.size(); i++) {
nuclear@8 212 if(strcmp(nodes[i]->get_name(), name) == 0) {
nuclear@8 213 return nodes[i];
nuclear@8 214 }
nuclear@8 215 }
nuclear@8 216 return 0;
nuclear@8 217 }
nuclear@8 218
nuclear@9 219 int Scene::get_node_count() const
nuclear@9 220 {
nuclear@9 221 return (int)nodes.size();
nuclear@9 222 }
nuclear@9 223
nuclear@50 224 // Scene::load is defined in goat3d_read.cc
nuclear@19 225 // Scene::loadxml is defined in goat3d_readxml.cc
nuclear@14 226 // Scene::save is defined in goat3d_write.cc
nuclear@19 227 // Scene::savexml is defined in goat3d_writexml.cc
nuclear@9 228
nuclear@9 229
nuclear@47 230 void g3dimpl::io_fprintf(goat3d_io *io, const char *fmt, ...)
nuclear@8 231 {
nuclear@14 232 va_list ap;
nuclear@9 233
nuclear@14 234 va_start(ap, fmt);
nuclear@14 235 io_vfprintf(io, fmt, ap);
nuclear@14 236 va_end(ap);
nuclear@14 237 }
nuclear@9 238
nuclear@9 239
nuclear@47 240 void g3dimpl::io_vfprintf(goat3d_io *io, const char *fmt, va_list ap)
nuclear@14 241 {
nuclear@14 242 char smallbuf[256];
nuclear@14 243 char *buf = smallbuf;
nuclear@14 244 int sz = sizeof smallbuf;
nuclear@9 245
nuclear@14 246 int retsz = vsnprintf(buf, sz - 1, fmt, ap);
nuclear@9 247
nuclear@14 248 if(retsz >= sz) {
nuclear@14 249 /* C99 mandates that snprintf with a short count should return the
nuclear@14 250 * number of characters that *would* be printed.
nuclear@14 251 */
nuclear@14 252 buf = new char[retsz + 1];
nuclear@9 253
nuclear@14 254 vsnprintf(buf, retsz, fmt, ap);
nuclear@9 255
nuclear@14 256 } else if(retsz <= 0) {
nuclear@14 257 /* SUSv2 and microsoft specify that snprintf with a short count
nuclear@14 258 * returns an arbitrary value <= 0. So let's try allocating
nuclear@14 259 * bigger and bigger arrays until we find the correct size.
nuclear@14 260 */
nuclear@14 261 sz = sizeof smallbuf;
nuclear@14 262 do {
nuclear@14 263 sz *= 2;
nuclear@14 264 if(buf != smallbuf) {
nuclear@14 265 delete [] buf;
nuclear@14 266 }
nuclear@14 267 buf = new char[sz + 1];
nuclear@9 268
nuclear@14 269 retsz = vsnprintf(buf, sz, fmt, ap);
nuclear@14 270 } while(retsz <= 0);
nuclear@9 271 }
nuclear@9 272
nuclear@15 273 io->write(buf, retsz, io->cls);
nuclear@9 274
nuclear@14 275 if(buf != smallbuf) {
nuclear@14 276 delete [] buf;
nuclear@9 277 }
nuclear@9 278
nuclear@9 279 }