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(),
151 image->get_color_model());
153 if(debug) printf("SceneNode::render %d\n", __LINE__);
156 // 1st comes our image
157 temp->copy_from(image);
159 // Then come the subnodes without camera transforms
160 if(debug) printf("SceneNode::render %d this=%p nodes=%d\n", __LINE__, this, nodes.size());
161 for(int i = 0; i < nodes.size(); i++)
162 nodes.get(i)->render(temp, 0);
166 if(debug) printf("SceneNode::render %d\n", __LINE__);
168 // Then comes rotation into temp2
172 src = temp2 = new VFrame(image->get_w(),
174 image->get_color_model());
175 if(!scene->affine) scene->affine =
176 new AffineEngine(scene->cpus, scene->cpus);
177 scene->affine->rotate(temp2,
180 if(debug) printf("SceneNode::render %d ry=%f\n", __LINE__, ry);
183 // Then comes flipping
187 if(debug) printf("SceneNode::render %d src=%p x=%f y=%f sx=%f sy=%f\n",
195 // Overlay on the output frame
196 if(!scene->overlayer) scene->overlayer = new OverlayFrame(scene->cpus);
200 scene->overlayer->overlay(frame,
206 frame->get_w() - x - image->get_w() * sx,
209 y + image->get_h() * sy,
216 if(debug) printf("SceneNode::render %d image=%p src=%p frame=%p\n",
221 scene->overlayer->overlay(frame,
229 x + image->get_w() * sx,
230 y + image->get_h() * sy,
236 if(debug) printf("SceneNode::render %d\n", __LINE__);
241 for(int i = 0; i < nodes.size(); i++)
242 nodes.get(i)->render(frame, 1);
245 if(debug) printf("SceneNode::render %d this=%p title=%s\n", __LINE__, this, title);
247 if(temp) delete temp;
248 if(temp2) delete temp2;
251 int SceneNode::get_flip()
254 if(parent && !parent->image) return parent->get_flip();
259 void SceneNode::transform_coord(
267 // if(!EQUIV(this->ry, 0))
269 // float pivot_x = 0;
270 // float pivot_y = 0;
273 // pivot_x = image->get_w() / 2;
274 // pivot_y = image->get_h() / 2;
277 // float rel_x = *x - pivot_x;
278 // float rel_y = *y - pivot_y;
279 // float angle = atan2(rel_y, rel_x);
280 // float mag = sqrt(rel_x * rel_x + rel_y * rel_y);
281 // angle += this->ry * 2 * M_PI / 360;
282 // *x = mag * cos(angle) + pivot_x;
283 // *y = mag * sin(angle) + pivot_y;
286 // Nodes with images reset the transformation
300 // Accumulate rotation
305 parent->transform_coord(x, y, sx, sy, ry);
310 void SceneNode::dump(int indent)
313 printf("SceneNode::dump %d this=%p title=%s\n", __LINE__, this, title);
315 printf(" image=%p private_image=%d hidden=%d flip=%d\n",
321 printf(" x=%f y=%f z=%f sz=%f sy=%f sz=%f rx=%f ry=%f rz=%f\n",
322 x, y, z, sz, sy, sz, rx, ry, rz);
324 printf(" nodes=%d\n", nodes.size());
325 for(int i = 0; i < nodes.size(); i++)
327 nodes.get(i)->dump(indent + 4);
335 SceneGraph::SceneGraph() : VFrameScene()
342 SceneGraph::~SceneGraph()
344 nodes.remove_all_objects();
345 cameras.remove_all_objects();
351 SceneNode* SceneGraph::get_node(int number)
353 return nodes.get(number);
356 void SceneGraph::append(SceneNode *node)
363 void SceneGraph::append_camera(SceneNode *node)
366 cameras.append(node);
369 void SceneGraph::render(VFrame *frame, int cpus)
372 if(debug) printf("SceneGraph::render %d\n", __LINE__);
377 for(int i = 0; i < nodes.size(); i++)
379 nodes.get(i)->render(frame, 1);
383 void SceneGraph::transform_camera(VFrame *frame,
392 SceneCamera *camera = (SceneCamera*)cameras.get(current_camera);
396 *x = frame->get_w() - *x;
403 *sx *= camera->scale;
404 *sy *= camera->scale;
408 *x = frame->get_w() - *x;
413 void SceneGraph::dump()
416 printf("SceneGraph::dump %d cameras=%d\n", __LINE__, cameras.size());
417 for(int i = 0; i < cameras.size(); i++)
418 cameras.get(i)->dump(indent);
419 printf("SceneGraph::dump %d nodes=%d\n", __LINE__, nodes.size());
420 for(int i = 0; i < nodes.size(); i++)
421 nodes.get(i)->dump(indent);
430 SceneTransform::SceneTransform() : SceneNode()
434 SceneTransform::~SceneTransform()
442 SceneLight::SceneLight() : SceneNode()
446 SceneLight::~SceneLight()
456 SceneCamera::SceneCamera() : SceneNode()
458 at_x = at_y = at_z = 0;
462 SceneCamera::~SceneCamera()
466 void SceneCamera::dump(int indent)
469 printf("SceneCamera::dump %d this=%p\n", __LINE__, this);
471 printf(" at_x=%f at_y=%f at_z=%f scale=%f\n",
481 SceneMaterial::SceneMaterial() : SceneNode()
488 SceneMaterial::~SceneMaterial()
499 SceneShape::SceneShape() : SceneNode()
501 pivot_x = pivot_y = pivot_z = 0;
504 SceneShape::~SceneShape()
515 SceneCylinder::SceneCylinder() : SceneShape()
519 SceneCylinder::~SceneCylinder()
526 SceneSphere::SceneSphere() : SceneShape()
531 SceneSphere::~SceneSphere()
538 SceneBox::SceneBox() : SceneShape()
543 SceneBox::~SceneBox()