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