Пример #1
0
/*!
The SLRefGroup::shapeInit checks the validity of the referenced node. To avoid 
endless loops a refShape node is not allowed to refShape its ancestors. An 
ancestor of a refShape node is group node followed along the previous pointers 
with lower depth than the depth of the refShape node.
*/
void SLRefGroup::shapeInit(SLSceneView* sv)
{  
   // cummulate wm with referenced wm
   SLShape* ref = (SLShape*)_refGroup; 
   _wm *= ref->m();
   _wmI.setMatrix(_wm.inverse());
   _wmN.setMatrix(_wmI.mat3());
   _wmN.transpose();
   
   // check circular references
   SLNode* parent = this->parent();
   while (parent)
   {  if (parent==_refGroup)
         SL_EXIT_MSG("Reference node produces a never ending loop.");
      parent = parent->parent();
   }
   
   // set transparency flag
   _aabb.hasAlpha(((SLShape*)_refGroup)->aabb()->hasAlpha());
   
   // delete all child references
   if (_first) deleteAll();
      
   // loop through the referenced group and add a SLRefShape or SLRefGroup
   SLNode* current = ((SLGroup*)_refGroup)->first();
   while (current)
   {  if (typeid(*current)==typeid(SLGroup))
           addNode(new SLRefGroup((SLGroup*)current, name()+"_"+current->name()));
      else addNode(new SLRefShape((SLShape*)current, name()+"_"+current->name()));
      ((SLShape*)_last)->wm(_wm);
      ((SLShape*)_last)->depth(depth()+1);
      ((SLShape*)_last)->shapeInit(sv);
      current = current->next();
   }
}
Пример #2
0
/*!
SLGroup::shapeDraw loops over all child nodes and calls the their draw method.
Groups are only traversed for opaque objects. Transparent objects are rendere
extra afterwards.
*/
void SLGroup::shapeDraw(SLSceneView* sv)
{  SLNode* current = _first;
   
   while (current)
   {  current->draw(sv);   
      current = current->next();
   }
}
Пример #3
0
/*!
SLGroup::shapeCopy loops over all child nodes and calls their copy method.
A new group with all copied child node is returned.
*/
SLShape* SLGroup::shapeCopy()
{  SLGroup* copy = new SLGroup(name());
   SLNode* current = _first;
   
   while (current)
   {  copy->addNode(current->copy());
      current = current->next();
   }
   return copy;
}
Пример #4
0
/*!
SLRefGroup::shapeHit calls the shapeHit method of the referenced group.
*/
SLbool SLRefGroup::shapeHit(SLRay* ray)
{  
   // loop through child references an hit each
   SLNode* current = _first;
   SLbool wasHit = false;
   while (current)
   {  if (((SLShape*)current)->hit(ray) && !wasHit) wasHit = true;
      current = current->next();
   }
   return wasHit;
}
Пример #5
0
/*!
SLGroup::getNode finds a node by a name
*/
SLNode* SLGroup::getNode(SLstring name) 
{  SLNode* current = _first;
   
   while (current)
   {  if(current->name() == name) return current;
      if (typeid(*current)==typeid(SLGroup))
      {  SLNode* found = ((SLGroup*)current)->getNode(name);
         if (found) return found;
      }
      current = current->next();
   }
   return 0;
}
Пример #6
0
/*!
SLGroup::buildAABB() loops over all child nodes and merges their AABB
to the axis aligned bounding box of the group.
*/
SLAABBox& SLGroup::buildAABB()
{  SLNode* current = _first;
   
   // empty the groups AABB    
   _aabb.minWS(SLVec3f( FLT_MAX, FLT_MAX, FLT_MAX));
   _aabb.maxWS(SLVec3f(-FLT_MAX,-FLT_MAX,-FLT_MAX));

   while (current)
   {  _aabb.merge(current->buildAABB());
      current = current->next();
   }
   
   _aabb.fromWStoOS(_aabb.minWS(), _aabb.maxWS(), _wmI);
   return _aabb;
}
Пример #7
0
/*!
SLGroup::shapeInit loops over all child nodes and calls their init method with
an incremented depth. While looping it must be checked that all child nodes
have a depth equal the groups depth + 1.
*/
void SLGroup::shapeInit(SLSceneView* sv)
{  SLNode* current = _first;
   while (current)
   {  if (current->depth() && current->depth() != depth()+1) 
      {  SL_EXIT_MSG("Scenegraph is not directed acyclic. There is a loop.");
      }
      current->init(sv, depth()+1);
      
      // Set transparent flags of the group
      if (!_aabb.hasAlpha() && ((SLShape*)current)->aabb()->hasAlpha())
         _aabb.hasAlpha(true); 
         
      current = current->next();
   }
}
Пример #8
0
/*!
SLGroup::intersect loops over all child nodes of the group and calls their
intersect method.  
*/
SLbool SLGroup::shapeHit(SLRay* ray)
{  assert(ray != 0);

   SLNode* current = _first;
   SLbool wasHit = false;
   while (current)
   {  
      // do not test origin node for shadow rays 
      if (!(current==ray->originShape && ray->type==SHADOW))
      {  if (current->hit(ray) && !wasHit) wasHit = true;
      }
      
      if (ray->isShaded()) return true;
      current = current->next();
   }
   return wasHit;
}
Пример #9
0
/*!
SLGroup::updateStats updates the statistic counters of a group. 
Be aware that when you add, insert or delete nodes in group only the 
numChildren counter is updated automatically. For the correct counters of the 
root3D group you have to call its updateStats method first. 
Achtung: the light node is counted in numShapes and numLights.
*/
void SLGroup::updateStats(SLGroup* parent)
{  SLNode* current = _first;
   numBytes      = 0;
   numBytesAccel = 0;
   numGroups     = 1;
   numShapes     = 0;
   numRefShapes  = 0;
   numLights     = 0;
   numTriangles  = 0;
   numRTTriangles= 0;
   numRTVertices = 0;
   numVoxels     = 0;
   numVoxEmpty   = 0;
   numVoxMaxTria = 0;
   

   while (current)
   {  current->updateStats(this);
      current = current->next();
   }
   
   if (parent)
   {  ((SLGroup*)parent)->numBytes      += numBytes;
      ((SLGroup*)parent)->numBytesAccel += numBytesAccel;
      ((SLGroup*)parent)->numGroups     += numGroups;
      ((SLGroup*)parent)->numShapes     += numShapes;
      ((SLGroup*)parent)->numRefShapes  += numRefShapes;
      ((SLGroup*)parent)->numTriangles  += numTriangles;
      ((SLGroup*)parent)->numRTTriangles+= numRTTriangles;
      ((SLGroup*)parent)->numRTVertices += numRTVertices;
      ((SLGroup*)parent)->numVoxels     += numVoxels;
      ((SLGroup*)parent)->numVoxEmpty   += numVoxEmpty;
      if (numVoxMaxTria > ((SLGroup*)parent)->numVoxMaxTria)
         ((SLGroup*)parent)->numVoxMaxTria = numVoxMaxTria;
   }
}