V-ART
scene.cpp
Go to the documentation of this file.
1 
5 #include "vart/scene.h"
6 #include "vart/graphicobj.h"
7 #include "vart/transform.h"
8 #include "vart/picknamelocator.h"
9 
10 #include <cassert>
11 #ifdef VART_OGL
12 #include <GL/gl.h>
13 #endif
14 
15 using namespace std;
16 
17 VART::Scene::Scene() : background(VART::Color::BLACK()), currentCamera(cameras.end())
18 {
20 }
21 
23  list<VART::SceneNode*>::const_iterator objItr;
24  list<const VART::Light*>::const_iterator lightItr;
25 
26  // Recursively delete children
27  for (objItr = objects.begin(); objItr != objects.end(); ++objItr)
28  {
29  (*objItr)->AutoDeleteChildren();
30  if ((*objItr)->autoDelete)
31  delete (*objItr);
32  }
33  // Delete lights
34  for (lightItr = lights.begin(); lightItr != lights.end(); ++lightItr)
35  {
36  if ((*lightItr)->autoDelete)
37  delete (*lightItr);
38  }
39 }
40 
41 list<const VART::Light*> VART::Scene::GetLights() {
42  return lights;
43 }
44 
45 list<VART::Camera*> VART::Scene::GetCameras() {
46  return cameras;
47 }
48 
49 list<VART::SceneNode*> VART::Scene::GetObjects() {
50  return objects;
51 }
52 
54  lights.push_back(newLight);
55 }
56 
57 void VART::Scene::AddLight(const VART::Light& newLight) {
58  VART::Light* lightPtr = new VART::Light(newLight);
59  lightPtr->autoDelete = true;
60  lights.push_back(lightPtr);
61 }
62 
64  cameras.push_back( newCamera );
65  if (currentCamera == cameras.end())
66  currentCamera = cameras.begin();
67 }
68 
69 void VART::Scene::AddObject( VART::SceneNode* newObjectPtr ) {
70  objects.push_back( newObjectPtr );
71 }
72 
73 void VART::Scene::Unreference(const SceneNode* sceneNodePtr)
74 {
75  list<SceneNode*>::iterator iter = objects.begin();
76  bool unfinished = true;
77 
78  while (unfinished)
79  {
80  if (*iter == sceneNodePtr)
81  {
82  objects.erase(iter);
83  unfinished = false;
84  }
85  else
86  {
87  ++iter;
88  unfinished = (iter != objects.end());
89  }
90  }
91 }
92 
93 const VART::Light* VART::Scene::GetLight(const string& lightName) {
94  list<const VART::Light*>::const_iterator iter;
95  for (iter = lights.begin(); iter != lights.end(); ++iter) {
96  if( (*iter)->GetDescription() == lightName ) {
97  return (*iter);
98  }
99  }
100  return NULL;
101 }
102 
103 const VART::Camera* VART::Scene::GetCamera(const string& cameraName) {
104  list<VART::Camera*>::const_iterator iter;
105  for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
106  if( (*iter)->GetDescription() == cameraName ) {
107  return (*iter);
108  }
109  }
110  return NULL;
111 }
112 
113 void VART::Scene::SetCamera(const string& cameraName) {
114  list<Camera*>::const_iterator iter;
115  for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
116  if( (*iter)->GetDescription() == cameraName ) {
117  currentCamera = iter;
118  }
119  }
120 }
121 
122 VART::SceneNode* VART::Scene::GetObject(const string& objectName) const {
123  list<VART::SceneNode*>::const_iterator iter;
124 
125  assert(!objects.empty());
126  for (iter = objects.begin(); iter != objects.end(); ++iter) {
127  //cout << objectName << " is " << (*iter)->GetDescription() << "?" << endl;
128  if( (*iter)->GetDescription() == objectName ) {
129  return (*iter);
130  }
131  }
132  return NULL;
133 }
134 
135 // protected
136 VART::GraphicObj* VART::Scene::GetObject(unsigned int pickName)
137 // Finds and returns a pointer to object of given pick name
138 {
139  // Create a PickNameLocator
140  VART::PickNameLocator finder(pickName);
141  list<VART::SceneNode*>::const_iterator iter = objects.begin();
142  while ((iter != objects.end()) && (finder.NotFinished()))
143  {
144  (*iter)->LocateDepthFirst(&finder);
145  ++iter;
146  }
147  // If not found, returns NULL.
148  return const_cast<GraphicObj*>(finder.GetResult());
149 }
150 
151 VART::SceneNode* VART::Scene::GetObjectRec(const string& objectName) const {
152  VART::SceneNode* result;
153  list<VART::SceneNode*>::const_iterator iter;
154  for (iter = objects.begin(); iter != objects.end(); ++iter) {
155  if( (*iter)->GetDescription() == objectName )
156  return (*iter);
157  else
158  {
159  result = (*iter)->FindChildByName(objectName);
160  if (result)
161  return result;
162  }
163  }
164  return NULL;
165 }
166 
168  return background;
169 }
170 
172  background = color;
173 }
174 
175 // cameraPtr defauts to NULL
176 bool VART::Scene::DrawOGL(Camera* cameraPtr) const {
177 #ifdef VART_OGL
178  // LookAT
179  if (cameraPtr)
180  cameraPtr->DrawOGL();
181  else
182  {
183  assert(*currentCamera); // make sure there is a current camera
184  (*currentCamera)->DrawOGL();
185  }
186 
187  // FixMe: Lights need not be drawn every rendering cicle. They are should be drawn
188  // by a different method.
189  DrawLightsOGL();
190 
191  // Draw graphical objects
192  list<VART::SceneNode*>::const_iterator iter;
193  for (iter = objects.begin(); iter != objects.end(); ++iter)
194  {
195  (*iter)->DrawOGL();
196  }
197  if (bBox.visible)
198  bBox.DrawInstanceOGL();
199  return true;
200 #else
201  return false;
202 #endif
203 }
204 //}
205 
207 #ifdef VART_OGL
208  unsigned int lightID = 0;
209  list<const VART::Light*>::const_iterator iter;
210  for (iter = lights.begin(); iter != lights.end(); ++iter)
211  {
212  (*iter)->DrawOGL(lightID);
213  ++lightID;
214  }
215  return true;
216 #else
217  return false;
218 #endif
219 }
220 
222  if (currentCamera == cameras.end())
223  return NULL;
224  else
225  return *currentCamera;
226 }
227 
229  assert(!cameras.empty());
230  ++currentCamera;
231  if (currentCamera == cameras.end())
232  currentCamera = cameras.begin();
233  return *currentCamera;
234 }
235 
237  assert(!cameras.empty());
238  --currentCamera;
239  if (currentCamera == cameras.end())
240  --currentCamera;
241  return *currentCamera;
242 }
243 
244 void VART::Scene::SetCamerasAspectRatio(const std::string& cameraDescription, float newAspectRatio) {
245  list<VART::Camera*>::iterator iter;
246  for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
247  if( (*iter)->GetDescription() == cameraDescription ) {
248  (*iter)->SetAspectRatio(newAspectRatio);
249  break;
250  }
251  }
252 }
253 
254 void VART::Scene::SetAllCamerasAspectRatio(float newAspectRatio) {
255  list<VART::Camera*>::const_iterator iter;
256  for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
257  (*iter)->SetAspectRatio(newAspectRatio);
258  }
259 }
260 
261 void VART::Scene::ChangeAllCamerasViewVolume(float horScale, float verScale) {
262  list<VART::Camera*>::const_iterator iter = cameras.begin();
263  for (; iter != cameras.end(); ++iter) {
264  (*iter)->ScaleVisibleVolume(horScale, verScale);
265  }
266 }
267 
269  VART::BoundingBox box;
270  bool initBBox = false;
271  list<VART::SceneNode*>::const_iterator iter;
272  VART::GraphicObj* objPtr;
273  VART::Transform* transPtr;
274 
275  for (iter = objects.begin(); iter != objects.end(); ++iter) {
276  objPtr = dynamic_cast<VART::GraphicObj*>(*iter);
277  if (objPtr) { // object is a graphic object
278  objPtr->ComputeRecursiveBoundingBox();
279  if (initBBox)
280  bBox.MergeWith(objPtr->GetRecursiveBoundingBox());
281  else {
282  bBox.CopyGeometryFrom(objPtr->GetRecursiveBoundingBox());
283  initBBox = true;
284  }
285  }
286  else { // object is not a graphic object
287  transPtr = dynamic_cast<VART::Transform*>(*iter);
288  if (transPtr) { // object is a transform
289  if (transPtr->RecursiveBoundingBox(&box)) {
290  if (initBBox)
291  bBox.MergeWith(box);
292  else {
293  bBox.CopyGeometryFrom(box);
294  initBBox = true;
295  }
296  }
297  }
298  // If not a transform, then it must be a light. Ignore it.
299  }
300  }
301  bBox.ProcessCenter();
302  return initBBox;
303 }
304 
305 //~ void VART::Scene::ComputeBoundingBox() { //old version
306  //~ list<VART::SceneNode*>::const_iterator iter = objects.begin();
307  //~ const VART::GraphicObj* objPtr;
308  //~ bool notInitialized = true;
309 
310  //~ // Initialize the bounding box
311  //~ for (; (iter != objects.end()) && notInitialized; ++iter) {
312  //~ objPtr = dynamic_cast<const VART::GraphicObj*>(*iter);
313  //~ if (objPtr) // objPtr != NULL
314  //~ {
315  //~ bbox = objPtr->GetRecursiveBoundingBox();
316  //~ notInitialized = false;
317  //~ }
318  //~ }
319 
320  //~ // Merge the bounding box with other graphical objects
321  //~ for (; iter != objects.end(); ++iter) {
322  //~ objPtr = dynamic_cast<const VART::GraphicObj*>(*iter);
323  //~ if (objPtr) // objPtr != NULL
324  //~ bbox.MergeWith(objPtr->GetRecursiveBoundingBox());
325  //~ }
326 //~ }
327 
328 void VART::Scene::SetBoundingBox(double minX, double minY, double minZ,
329  double maxX, double maxY, double maxZ) {
330  bBox.SetBoundingBox(minX,minY,minZ,maxX,maxY,maxZ);
331  bBox.ProcessCenter();
332 }
333 
335 {
336  assert(*currentCamera); // make sure there is a current camera
337  ComputeBoundingBox();
338  VART::Point4D bBoxCenter = bBox.GetCenter();
339  cout << bBox << endl;
340  (*currentCamera)->SetTarget(bBoxCenter);
341  if ((*currentCamera)->GetProjectionType() == VART::Camera::PERSPECTIVE) {
342  double greaterEdgeBox = bBox.GetGreaterEdge();
343  (*currentCamera)->SetLocation(bBoxCenter+VART::Point4D(0,greaterEdgeBox*1.2,greaterEdgeBox*1.2,0));
344  (*currentCamera)->SetUp(VART::Point4D::Y());
345  (*currentCamera)->SetFarPlaneDistance(greaterEdgeBox*2.4);
346  }
347  else if ((*currentCamera)->GetProjectionType() == VART::Camera::ORTHOGRAPHIC) {
348  double edgeY = bBox.GetGreaterY();
349 
350  (*currentCamera)->SetLocation(bBoxCenter+VART::Point4D(0,edgeY,0,0));
351  (*currentCamera)->SetUp(VART::Point4D::X());
352  (*currentCamera)->SetVisibleVolumeHeight( bBox.GetGreaterX()-bBox.GetSmallerX() );
353  }
354  // FixMe: Not sure what to do with near plane distance
355  //~ (*currentCamera)->SetNearPlaneDistance();
356 }
357 
358 std::list<VART::SceneNode*> VART::Scene::GetAllSceneJoints()
359 {
360  cerr << "\aWarning: Scene::GetAllSceneJoints is deprecated. See documentation\n";
361  list<VART::SceneNode*> nodeList;
362  list<VART::SceneNode*>::const_iterator iter;
363 
364  for (iter = objects.begin(); iter != objects.end(); ++iter)
365  (*iter)->GetNodeTypeList( VART::SceneNode::JOINT, nodeList);
366 
367  return nodeList;
368 }
369 
371 {
372  cerr << "\aWarning: Scene::GetAllSceneTypeObject is deprecated. See documentation\n";
373  list<VART::SceneNode*> nodeList;
374  list<VART::SceneNode*>::const_iterator iter;
375 
376  for (iter = objects.begin(); iter != objects.end(); ++iter)
377  (*iter)->GetNodeTypeList( type, nodeList);
378 
379  return nodeList;
380 }
381 
382 void VART::Scene::Pick(int x, int y, list<GraphicObj*>* resultListPtr)
383 {
384 #ifdef VART_OGL
385  const static int SELECTION_BUFFER_SIZE = 512; // FixMe: find a better place to put this!
386 
387  resultListPtr->clear(); // remove old elements from list
388  // get viewport origin and extent
389  GLint viewport[4]; // viewport coordinates
390  glGetIntegerv(GL_VIEWPORT, viewport);
391  // set a memory region as OpenGL selection buffer
392  GLuint selectBuf[SELECTION_BUFFER_SIZE];
393  glSelectBuffer(SELECTION_BUFFER_SIZE, selectBuf);
394  // enter selection mode
395  glRenderMode(GL_SELECT);
396  // initialize name stack
397  glInitNames();
398  // Save zero at stack, to indicate "no selection".
399  glPushName(0);
400 
401  // create 5x5 pixel picking region near cursor location
402  glMatrixMode(GL_PROJECTION);
403  glLoadIdentity();
404  gluPickMatrix(static_cast<GLdouble>(x),
405  viewport[3]-static_cast<GLdouble>(y),
406  5.0, 5.0, viewport);
407  (*currentCamera)->SetMatrices();
408 
409  // "draw" graphical objects
410  list<VART::SceneNode*>::const_iterator iter = objects.begin();
411  for (; iter != objects.end(); ++iter)
412  (*iter)->DrawForPicking();
413 
414  glFlush();
415 
416  // get hits
417  // Each object counts as a hit. For instance, if we select some position where two legs of
418  // a humanoid are shown, with the floor as well, 3 hits will be generated:
419  // [floor,[human,leftleg],[human,rightleg]].
420  // FixMe: Implement a Pick that handles lists of lists such as [[floor],[human,leftleg]].
421  // FixMe: Compute Z coordinate of a hit -- very usefull.
422  GLint hits = glRenderMode(GL_RENDER); // number of primites picked
423  GLuint* selectBufPtr = selectBuf; // points at first element in buffer
424  GraphicObj* pickPtr;
425  unsigned int numNames;
426  unsigned int nameIndex;
427  while (hits > 0) // for each hit record...
428  {
429  numNames = selectBufPtr[0];
430  nameIndex = 3;
431  while (numNames > 0) // for each name in hit record...
432  {
433  GLuint pickName = selectBufPtr[nameIndex];
434  // Convert the pick name into a pointer
435  pickPtr = GetObject(pickName);
436  // Store the pointer in the list of results
437  if (pickPtr) // if found...
438  {
439  resultListPtr->push_back(pickPtr);
440  }
441  // FixMe: Warn if not found??
442  // Prepare for next iteration
443  ++nameIndex;
444  --numNames;
445  }
446  selectBufPtr += nameIndex;
447  --hits;
448  }
449 #else
450  cerr << "Error: Scene::Pick is not implemented for your render engine!" << endl;
451 #endif
452 }
453 
454 void VART::Scene::XmlPrintOn(ostream& os) const
455 {
456  list<VART::SceneNode*>::const_iterator iter;
457 
458  os << "<?xml version=\"1.0\"?>\n"
459  << "<!DOCTYPE scene SYSTEM \"vartScene.dtd\">\n"
460  << "<scene description=\"" << description << "\">\n";
461  for (iter = objects.begin(); iter != objects.end(); ++iter)
462  {
463  os << " <node>\n";
464  (*iter)->XmlPrintOn(os, 4);
465  os << " </node>\n";
466  }
467  os << "</scene>\n";
468 }
SceneNode * GetObject(const std::string &objectName) const
Searches an object by its description.
SceneNode * GetObjectRec(const std::string &objectName) const
Recursively searches an object by its description.
Definition: scene.cpp:151
Base class for objects that compose a scene graph.
Definition: scenenode.h:25
std::list< SceneNode * > GetObjects()
Definition: scene.cpp:49
Points and vectors using homogeneous coordinates.
Definition: point4d.h:22
Camera * GetCurrentCamera() const
Returns the current camera in the scene or NULL if no camera exists.
Definition: scene.cpp:221
Header file for V-ART class "GraphicObj".
std::list< SceneNode * > GetAllSceneJoints()
Get all scenenodes of type 'joint' in the scene.
Definition: scene.cpp:358
static const Point4D & Y()
The Y vector (0,1,0,0).
Definition: point4d.cpp:43
bool DrawLightsOGL() const
Set lights using OpenGL commands.
Definition: scene.cpp:206
void SetAllCamerasAspectRatio(float newAspectRatio)
Set the aspect ratio of all cameras.
Definition: scene.cpp:254
void ComputeRecursiveBoundingBox()
Computes the recursive bounding box.
Definition: graphicobj.cpp:63
const Camera * GetCamera(const std::string &cameraName)
Finds an camera by its description.
Definition: scene.cpp:103
Header file for V-ART class "Scene".
RGBA color representation.
Definition: color.h:24
Axis aligned bounding box.
Definition: boundingbox.h:23
std::list< SceneNode * > GetAllSceneTypeObject(SceneNode::TypeID type)
Get all scenenodes of type 'type' in the scene.
Definition: scene.cpp:370
const Camera * UsePreviousCamera()
Definition: scene.cpp:236
const Color & GetBackgroundColor()
Returns the background color.
Definition: scene.cpp:167
void SetColor(const Color &value)
Sets the bounding box color.
Definition: boundingbox.h:93
void AddCamera(Camera *newCamera)
Add a camera to the list of cameras.
Definition: scene.cpp:63
void ChangeAllCamerasViewVolume(float horScale, float verScale)
Changes the view volume of all cameras.
Definition: scene.cpp:261
virtual ~Scene()
Destructor.
Definition: scene.cpp:22
void SetBoundingBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ)
Sets the bounding box.
Definition: scene.cpp:328
const Camera * UseNextCamera()
Definition: scene.cpp:228
Geometric transformations.
Definition: transform.h:24
void AddLight(Light *newLight)
Adds a light to the list of lights.
Definition: scene.cpp:53
const Light * GetLight(const std::string &lightName)
Finds a light by its name.
Definition: scene.cpp:93
bool DrawOGL() const
Positions a camera using OpenGL commands.
Definition: camera.cpp:276
Virtual camera.
Definition: camera.h:16
std::list< Camera * > GetCameras()
Returns a list of cameras.
Definition: scene.cpp:45
virtual bool RecursiveBoundingBox(BoundingBox *bBox)
Returns the recursive bounding box.
Definition: transform.cpp:293
An scene node that is associated with a shape.
Definition: graphicobj.h:18
bool ComputeBoundingBox()
Computes the axis aligned bounding box of all objects.
Definition: scene.cpp:268
Header file for V-ART class "Transform".
static const Point4D & X()
The X vector (1,0,0,0).
Definition: point4d.cpp:37
Header file for V-ART class "PickNameLocator".
void AddObject(SceneNode *newObjectPtr)
Add a object to the scene.
Definition: scene.cpp:69
void XmlPrintOn(std::ostream &os) const
Outputs XML representation of the scene.
Definition: scene.cpp:454
void Pick(int x, int y, std::list< GraphicObj * > *resultListPtr)
Picks objects from viewport coordinates.
Definition: scene.cpp:382
SceneNode * FindChildByName(const std::string &name) const
Recusively searches its children for a given name.
Definition: scenenode.cpp:96
virtual bool DrawOGL(Camera *cameraPtr=NULL) const
Sets projection and draws graphics objects using OpenGL commands.
Definition: scene.cpp:176
void MakeCameraViewAll()
Fits the whole scene to drawing region.
Definition: scene.cpp:334
void SetCamerasAspectRatio(const std::string &cameraDescription, float newAspectRatio)
Set the aspect ratio of camera by its description.
Definition: scene.cpp:244
void SetCamera(const std::string &cameraName)
Sets the current camera by its description.
Definition: scene.cpp:113
void SetBackgroundColor(Color color)
Sets the background color.
Definition: scene.cpp:171
static const Color & WHITE()
White opaque color.
Definition: color.cpp:105
const BoundingBox & GetRecursiveBoundingBox() const
Returns the recursive bounding box.
Definition: graphicobj.h:58
std::list< const Light * > GetLights()
Definition: scene.cpp:41
void Unreference(const SceneNode *sceneNodePtr)
Removes an object from scene graph.
Definition: scene.cpp:73
Represents a light source.
Definition: light.h:22