3 * Copyright (C) 2011 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "overlayframe.h"
26 #include "scenegraph.h"
30 #define PRINT_INDENT for(int i = 0; i < indent; i++) printf(" ");
33 SceneNode::SceneNode()
38 SceneNode::SceneNode(const char *title)
41 strcpy(this->title, title);
44 SceneNode::SceneNode(VFrame *image, int private_image, float x, float y)
48 if(this->image) this->private_image = private_image;
53 SceneNode::~SceneNode()
55 nodes.remove_all_objects();
56 if(private_image) delete image;
59 void SceneNode::reset()
63 x = y = z = rx = ry = rz = 0;
72 void SceneNode::append(SceneNode *node)
75 node->scene = this->scene;
79 void SceneNode::copy_ref(SceneNode *node)
81 if(private_image) delete image;
92 hidden = node->hidden;
97 SceneNode* SceneNode::get_node(int number)
99 return nodes.get(number);
102 int SceneNode::get_memory_usage()
105 return image->get_memory_usage();
110 void SceneNode::render(VFrame *frame, int do_camera)
113 if(debug) printf("SceneNode::render %d this=%p title=%s image=%p x=%f y=%f frame=%p do_camera=%d\n",
133 parent->transform_coord(&x, &y, &sx, &sy, &ry);
135 if(do_camera) scene->transform_camera(frame,
142 if(debug) printf("SceneNode::render %d at_y=%f\n",
144 ((SceneCamera*)scene->cameras.get(0))->at_y);
146 // Render everything into a temporary, then overlay the temporary
147 // if(!EQUIV(ry, 0) || get_flip())
149 temp = new VFrame(image->get_w(), image->get_h(), image->get_color_model(), 0);
151 if(debug) printf("SceneNode::render %d\n", __LINE__);
154 // 1st comes our image
155 temp->copy_from(image);
157 // Then come the subnodes without camera transforms
158 if(debug) printf("SceneNode::render %d this=%p nodes=%d\n", __LINE__, this, nodes.size());
159 for(int i = 0; i < nodes.size(); i++)
160 nodes.get(i)->render(temp, 0);
164 if(debug) printf("SceneNode::render %d\n", __LINE__);
166 // Then comes rotation into temp2
170 src = temp2 = new VFrame(image->get_w(), image->get_h(), image->get_color_model(), 0);
171 if(!scene->affine) scene->affine = new AffineEngine(scene->cpus, scene->cpus);
172 scene->affine->rotate(temp2, temp, ry);
173 if(debug) printf("SceneNode::render %d ry=%f\n", __LINE__, ry);
176 // Then comes flipping
180 if(debug) printf("SceneNode::render %d src=%p x=%f y=%f sx=%f sy=%f\n",
181 __LINE__, src, x, y, sx, sy);
182 // Overlay on the output frame
183 if(!scene->overlayer) scene->overlayer = new OverlayFrame(scene->cpus);
187 scene->overlayer->overlay(frame,
193 frame->get_w() - x - image->get_w() * sx,
196 y + image->get_h() * sy,
203 if(debug) printf("SceneNode::render %d image=%p src=%p frame=%p\n",
208 scene->overlayer->overlay(frame,
216 x + image->get_w() * sx,
217 y + image->get_h() * sy,
223 if(debug) printf("SceneNode::render %d\n", __LINE__);
228 for(int i = 0; i < nodes.size(); i++)
229 nodes.get(i)->render(frame, 1);
232 if(debug) printf("SceneNode::render %d this=%p title=%s\n", __LINE__, this, title);
234 if(temp) delete temp;
235 if(temp2) delete temp2;
238 int SceneNode::get_flip()
241 if(parent && !parent->image) return parent->get_flip();
246 void SceneNode::transform_coord(
254 // if(!EQUIV(this->ry, 0))
256 // float pivot_x = 0;
257 // float pivot_y = 0;
260 // pivot_x = image->get_w() / 2;
261 // pivot_y = image->get_h() / 2;
264 // float rel_x = *x - pivot_x;
265 // float rel_y = *y - pivot_y;
266 // float angle = atan2(rel_y, rel_x);
267 // float mag = sqrt(rel_x * rel_x + rel_y * rel_y);
268 // angle += this->ry * 2 * M_PI / 360;
269 // *x = mag * cos(angle) + pivot_x;
270 // *y = mag * sin(angle) + pivot_y;
273 // Nodes with images reset the transformation
287 // Accumulate rotation
292 parent->transform_coord(x, y, sx, sy, ry);
297 void SceneNode::dump(int indent)
300 printf("SceneNode::dump %d this=%p title=%s\n", __LINE__, this, title);
302 printf(" image=%p private_image=%d hidden=%d flip=%d\n",
308 printf(" x=%f y=%f z=%f sz=%f sy=%f sz=%f rx=%f ry=%f rz=%f\n",
309 x, y, z, sz, sy, sz, rx, ry, rz);
311 printf(" nodes=%d\n", nodes.size());
312 for(int i = 0; i < nodes.size(); i++)
314 nodes.get(i)->dump(indent + 4);
322 SceneGraph::SceneGraph() : VFrameScene()
329 SceneGraph::~SceneGraph()
331 nodes.remove_all_objects();
332 cameras.remove_all_objects();
338 SceneNode* SceneGraph::get_node(int number)
340 return nodes.get(number);
343 void SceneGraph::append(SceneNode *node)
350 void SceneGraph::append_camera(SceneNode *node)
353 cameras.append(node);
356 void SceneGraph::render(VFrame *frame, int cpus)
359 if(debug) printf("SceneGraph::render %d\n", __LINE__);
364 for(int i = 0; i < nodes.size(); i++)
366 nodes.get(i)->render(frame, 1);
370 void SceneGraph::transform_camera(VFrame *frame,
379 SceneCamera *camera = (SceneCamera*)cameras.get(current_camera);
383 *x = frame->get_w() - *x;
390 *sx *= camera->scale;
391 *sy *= camera->scale;
395 *x = frame->get_w() - *x;
400 void SceneGraph::dump()
403 printf("SceneGraph::dump %d cameras=%d\n", __LINE__, cameras.size());
404 for(int i = 0; i < cameras.size(); i++)
405 cameras.get(i)->dump(indent);
406 printf("SceneGraph::dump %d nodes=%d\n", __LINE__, nodes.size());
407 for(int i = 0; i < nodes.size(); i++)
408 nodes.get(i)->dump(indent);
417 SceneTransform::SceneTransform() : SceneNode()
421 SceneTransform::~SceneTransform()
429 SceneLight::SceneLight() : SceneNode()
433 SceneLight::~SceneLight()
443 SceneCamera::SceneCamera() : SceneNode()
445 at_x = at_y = at_z = 0;
449 SceneCamera::~SceneCamera()
453 void SceneCamera::dump(int indent)
456 printf("SceneCamera::dump %d this=%p\n", __LINE__, this);
458 printf(" at_x=%f at_y=%f at_z=%f scale=%f\n",
468 SceneMaterial::SceneMaterial() : SceneNode()
475 SceneMaterial::~SceneMaterial()
486 SceneShape::SceneShape() : SceneNode()
488 pivot_x = pivot_y = pivot_z = 0;
491 SceneShape::~SceneShape()
502 SceneCylinder::SceneCylinder() : SceneShape()
506 SceneCylinder::~SceneCylinder()
513 SceneSphere::SceneSphere() : SceneShape()
518 SceneSphere::~SceneSphere()
525 SceneBox::SceneBox() : SceneShape()
530 SceneBox::~SceneBox()