Esempio n. 1
0
void VrmlNodeGroup::render(Viewer *viewer)
{
    if (!haveToRender())
    {
        return;
    }

    if (d_viewerObject && isModified())
    {
        viewer->removeObject(d_viewerObject);
        d_viewerObject = 0;
    }
    checkAndRemoveNodes(viewer);

    if (d_viewerObject)
        viewer->insertReference(d_viewerObject);

    else if (d_children.size() > 0)
    {
        int i, n = d_children.size();
        int nSensors = 0;

        d_viewerObject = viewer->beginObject(name(), 0, this);

        // Draw nodes that impact their siblings (DirectionalLights,
        // TouchSensors, any others? ...)
        for (i = 0; i < n; ++i)
        {
            VrmlNode *kid = d_children[i];

            //if ( kid->toLight() ) && ! (kid->toPointLight() || kid->toSpotLight()) )
            //  kid->render(viewer);
            //else
            if (kid && ((kid->toTouchSensor() && kid->toTouchSensor()->isEnabled()) || (kid->toPlaneSensor() && kid->toPlaneSensor()->isEnabled()) || (kid->toCylinderSensor() && kid->toCylinderSensor()->isEnabled()) || (kid->toSphereSensor() && kid->toSphereSensor()->isEnabled()) || (kid->toSpaceSensor() && kid->toSpaceSensor()->isEnabled())))
            {
                if (++nSensors == 1)
                    viewer->setSensitive(this);
            }
        }

        // Do the rest of the children (except the scene-level lights)
        for (i = 0; i < n; ++i)
        {
            if (d_children[i])
            {
                if (!(/*d_children[i]->toLight() ||*/
                      d_children[i]->toPlaneSensor() || d_children[i]->toCylinderSensor() || d_children[i]->toSpaceSensor() || d_children[i]->toTouchSensor()))
                    d_children[i]->render(viewer);
            }
        }

        // Turn off sensitivity
        if (nSensors > 0)
            viewer->setSensitive(0);

        viewer->endObject();
    }

    clearModified();
}
Esempio n. 2
0
void VrmlScene::replaceWorld( VrmlMFNode &nodes, VrmlNamespace *ns,
			      Doc *url, Doc *urlLocal )
{
  theSystem->debug("replaceWorld( url %s )\n", url->url());

  delete d_namespace;
  delete d_url;
  delete d_urlLocal;

  d_namespace = ns;
  d_url = url;
  d_urlLocal = urlLocal;

  // Clear bindable stacks.
  bindableRemoveAll( d_backgroundStack ); 
  bindableRemoveAll( d_fogStack ); 
  bindableRemoveAll( d_navigationInfoStack ); 
  bindableRemoveAll( d_viewpointStack );

  // Get rid of current world: pending events, nodes.
  flushEvents();
  d_nodes.removeChildren();

  // Do this to set the relative URL
  d_nodes.addToScene( (VrmlScene *) this, urlDoc()->url() );

  // Add the nodes to a Group and put the group in the scene.
  // This will load EXTERNPROTOs and Inlines.
  d_nodes.addChildren( nodes );

  // Send initial set_binds to bindable nodes
  double timeNow = theSystem->time();
  VrmlSFBool flag(true);
  VrmlNode *bindable = 0;	// compiler warning

  if (d_backgrounds->size() > 0 &&
      (bindable = d_backgrounds->front()) != 0)
    bindable->eventIn( timeNow, "set_bind", &flag );

  if (d_fogs->size() > 0 &&
      (bindable = d_fogs->front()) != 0)
    bindable->eventIn( timeNow, "set_bind", &flag );

  if (d_navigationInfos->size() > 0 &&
      (bindable = d_navigationInfos->front()) != 0)
    bindable->eventIn( timeNow, "set_bind", &flag );

  if (d_viewpoints->size() > 0 &&
      (bindable = d_viewpoints->front()) != 0)
    bindable->eventIn( timeNow, "set_bind", &flag );

  // Notify anyone interested that the world has changed
  doCallbacks( REPLACE_WORLD );

  setModified();
}
Esempio n. 3
0
bool VrmlScene::load(const char *url, const char *localCopy)
{
  // Look for '#Viewpoint' syntax. There ought to be a current
  // scene if this format is used.
  VrmlSFBool flag(true);
  if (*url == '#')
    {
      VrmlNode *vp = d_namespace ? d_namespace->findNode(url+1) : 0;

      // spec: ignore if named viewpoint not found
      if (vp)
	{
	  vp->eventIn( theSystem->time(), "set_bind", &flag );
	  setModified();
	}

      return true;
    }

  // Try to load a file. Prefer a local copy if available.
  Doc *tryUrl;
  if (localCopy)
    tryUrl = new Doc( localCopy, 0 );
  else
    tryUrl = new Doc( url, d_url);

  VrmlNamespace *newScope = new VrmlNamespace();
  VrmlMFNode *newNodes = readWrl( tryUrl, newScope );
  if ( newNodes )
    {
      Doc *sourceUrl = tryUrl, *urlLocal = 0;
      if (localCopy)
	{
	  sourceUrl = new Doc( url );
	  urlLocal = tryUrl;
	}
      
      replaceWorld( *newNodes, newScope, sourceUrl, urlLocal );
      delete newNodes;

      // Look for '#Viewpoint' syntax
      if ( sourceUrl->urlModifier() )
	{
	  VrmlNode *vp = d_namespace->findNode( sourceUrl->urlModifier()+1 );
	  double timeNow = theSystem->time();
	  if (vp)
	    vp->eventIn( timeNow, "set_bind", &flag );
	}

      return true;      // Success.
    }

  delete tryUrl;
  return false;
}
Esempio n. 4
0
void VrmlNodeGroup::checkAndRemoveNodes(Viewer *viewer)
{
    if (d_childrenToRemove.size())
    {
        viewer->beginObject(name(), 0, this);
        int i, n = d_childrenToRemove.size();
        for (i = 0; i < n; i++)
        {
            Viewer::Object child_viewerObject = 0;
            VrmlNode *kid = d_childrenToRemove[i];
            if (kid->toGeometry())
                child_viewerObject = kid->toGeometry()->getViewerObject();
            else if (kid->toGroup())
                child_viewerObject = kid->toGroup()->d_viewerObject;
            else if (kid->toProto())
                child_viewerObject = kid->toProto()->getViewerObject();
            else if (kid->toShape())
                child_viewerObject = kid->toShape()->getViewerObject();
            if (child_viewerObject)
                viewer->removeChild(child_viewerObject);
        }
        viewer->endObject();
    }
    while (d_childrenToRemove.size())
    {
        d_childrenToRemove.removeNode(d_childrenToRemove[0]);
    }
}
Esempio n. 5
0
void VrmlNodeGroup::accumulateTransform(VrmlNode *parent)
{
    d_parentTransform = parent;

    int i, n = d_children.size();

    for (i = 0; i < n; ++i)
    {
        VrmlNode *kid = d_children[i];
        if (kid)
            kid->accumulateTransform(parent);
    }
}
Esempio n. 6
0
void VrmlScene::sensitiveEvent( void *object,
				double timeStamp,
				bool isOver, bool isActive,
				double *point )
{
  VrmlNode *n = (VrmlNode *)object;

  if (n)
    {
      VrmlNodeAnchor *a = n->toAnchor();
      if ( a )
	{
	  // This should really be (isOver && !isActive && n->wasActive)
	  // (ie, button up over the anchor after button down over the anchor)
	  if (isActive && isOver)
	    {
	      a->activate();
	      //theSystem->inform("");
	    }
	  else if (isOver)
	    {
	      const char *description = a->description();
	      const char *url = a->url();
	      if (description && url)
		theSystem->inform("%s (%s)", description, url);
	      else if (description || url)
		theSystem->inform("%s", description ? description : url);
	      //else
	      //theSystem->inform("");
	    }
	  //else
	  //theSystem->inform("");
	}

      // The parent grouping node is registered for Touch/Drag Sensors
      else
	{
	  VrmlNodeGroup *g = n->toGroup();
	  if (g)
	    {
	      //theSystem->inform("");
	      g->activate( timeStamp, isOver, isActive, point );
	      setModified();
	    }
	}
      
    }

  //else
  //theSystem->inform("");
}
Esempio n. 7
0
// Set the value of one of the node fields.
void VrmlNodeGroup::setField(const char *fieldName,
                             const VrmlField &fieldValue)
{
    if
        TRY_FIELD(bboxCenter, SFVec3f)
    else if
        TRY_FIELD(bboxSize, SFVec3f)
    else if (!strcmp(fieldName, "children"))
    {
        if (fieldValue.toMFNode())
        {
            for (int i = 0; i < d_children.size(); i++)
            {
                if (d_children[i])
                {
                    d_children[i]->decreaseTraversalForce();
                    d_children[i]->parentList.remove(this);
                }
                else
                {
                    cerr << "VrmlNodeGroup::setField(children): had NULL child" << endl;
                }
            }

            d_children = (VrmlMFNode &)fieldValue;

            for (int i = 0; i < d_children.size(); i++)
            {
                VrmlNode *child = d_children[i];
                if (child == NULL)
                {
                    continue;
                }

                child->parentList.push_back(this);
                if (child->getTraversalForce() > 0)
                {
                    forceTraversal(false, child->getTraversalForce());
                }
            }
        }
        else
            System::the->error("Invalid type (%s) for %s field of %s node (expected %s).\n",
                               fieldValue.fieldTypeName(), "children", nodeType()->getName(), "MFNode");
    }
    else
        VrmlNodeChild::setField(fieldName, fieldValue);
}
Esempio n. 8
0
void VrmlNodeTransform::inverseTransform(Viewer *viewer)
{
    VrmlNode *parentTransform = getParentTransform();
    if (parentTransform)
        parentTransform->inverseTransform(viewer);

    // Build the inverse
    float trans[3] = {
        -d_translation.x(),
        -d_translation.y(),
        -d_translation.z()
    };
    float rot[4] = {
        d_rotation.x(),
        d_rotation.y(),
        d_rotation.z(),
        -d_rotation.r()
    };

    // Invert scale (1/x)
    float scale[3] = { d_scale.x(), d_scale.y(), d_scale.z() };
    if (!FPZERO(scale[0]))
        scale[0] = 1.0f / scale[0];
    if (!FPZERO(scale[1]))
        scale[1] = 1.0f / scale[1];
    if (!FPZERO(scale[2]))
        scale[2] = 1.0f / scale[2];

    // Apply transforms (this may need to be broken into separate
    // calls to perform the ops in reverse order...)
    viewer->setTransform(d_center.get(),
                         rot,
                         scale,
                         d_scaleOrientation.get(),
                         trans, true);
}
Esempio n. 9
0
void VrmlNodeGroup::addChildren(const VrmlMFNode &children)
{
    int nNow = d_children.size();
    int n = children.size();

    for (int i = 0; i < n; ++i)
    {
        VrmlNode *child = children[i];
        if (child == NULL)
        {
            continue;
        }

        child->parentList.push_back(this);
        if (child->getTraversalForce() > 0)
        {
            forceTraversal(false, child->getTraversalForce());
        }

        VrmlNodeProto *p = 0;

        // Add legal children and un-instantiated EXTERNPROTOs
        // Is it legal to add null children nodes?
        if (child == 0 || child->toChild() || ((p = child->toProto()) != 0 && p->size() == 0))
        {
            d_children.addNode(child);
            if (child)
            {
                child->addToScene(d_scene, d_relative.get());
                child->accumulateTransform(d_parentTransform);
            }
        }
        else
            System::the->error("Error: Attempt to add a %s node as a child of a %s node.\n",
                               child->nodeType()->getName(), nodeType()->getName());
    }

    if (nNow != d_children.size())
    {
        //??eventOut( d_scene->timeNow(), "children_changed", d_children );
        setModified();
    }
}
Esempio n. 10
0
VrmlNodeBackground *VrmlScene::bindableBackgroundTop()
{
  VrmlNode *b = bindableTop( d_backgroundStack );
  return b ? b->toBackground() : 0;
}
Esempio n. 11
0
//
// The update method is where the events are processed. It should be
// called after each frame is rendered.
//
bool VrmlScene::update( double timeStamp )
{
  if (timeStamp <= 0.0) timeStamp = theSystem->time();
  VrmlSFTime now( timeStamp );

  d_deltaTime = DEFAULT_DELTA;

  // Update each of the timers.
  VrmlNodeList::iterator i, end = d_timers->end();
  for (i = d_timers->begin(); i != end; ++i)
    {
      VrmlNodeTimeSensor *t = (*i)->toTimeSensor();
      if (t) t->update( now );
    }

  // Update each of the clips.
  end = d_audioClips->end();
  for (i = d_audioClips->begin(); i != end; ++i)
    {
      VrmlNodeAudioClip *c = (*i)->toAudioClip();
      if (c) c->update( now );
    }

  // Update each of the scripts.
  end = d_scripts->end();
  for (i = d_scripts->begin(); i != end; ++i)
    {
      VrmlNodeScript *s = (*i)->toScript();
      if (s) s->update( now );
    }

  // Update each of the movies.
  end = d_movies->end();
  for (i = d_movies->begin(); i != end; ++i)
    {
      VrmlNodeMovieTexture *m =  (*i)->toMovieTexture();
      if (m) m->update( now );
    }


  // Pass along events to their destinations
  while (d_firstEvent != d_lastEvent &&
	 ! d_pendingUrl && ! d_pendingNodes)
    {
      Event *e = &d_eventMem[d_firstEvent];
      d_firstEvent = (d_firstEvent+1) % MAXEVENTS;

      // Ensure that the node is in the scene graph
      VrmlNode *n = e->toNode;
      if (this != n->scene())
	{
	  theSystem->debug("VrmlScene::update: %s::%s is not in the scene graph yet.\n",
			   n->nodeType()->getName(), n->name());
	  n->addToScene((VrmlScene*)this, urlDoc()->url() );
	}
      n->eventIn(e->timeStamp, e->toEventIn, e->value);
      // this needs to change if event values are shared...
      delete e->value;
    }

  if (d_pendingNodes)
    {
      replaceWorld( *d_pendingNodes, d_pendingScope );
      delete d_pendingNodes;
      d_pendingNodes = 0;
      d_pendingScope = 0;
    }
  else if (d_pendingUrl)
    {
      (void) loadUrl( d_pendingUrl, d_pendingParameters );
      delete d_pendingUrl;
      delete d_pendingParameters;
      d_pendingUrl = 0;
      d_pendingParameters = 0;
    }

  // Signal a redisplay if necessary
  return isModified();
}
Esempio n. 12
0
void VrmlNodeTransform::inverseTransform(double *m)
{
    VrmlNode *parentTransform = getParentTransform();
    if (strncmp(name(), "StaticCave", 10) == 0)
    {
        Midentity(m);
    }
    else
    {
        if (parentTransform)
        {
            parentTransform->inverseTransform(m);
        }
        else
            Midentity(m);
    }

    // Invert this transform
    float rot[4] = {
        d_rotation.x(),
        d_rotation.y(),
        d_rotation.z(),
        -d_rotation.r()
    };
    float nsrot[4] = {
        d_scaleOrientation.x(),
        d_scaleOrientation.y(),
        d_scaleOrientation.z(),
        -d_scaleOrientation.r()
    };
    float srot[4] = {
        d_scaleOrientation.x(),
        d_scaleOrientation.y(),
        d_scaleOrientation.z(),
        d_scaleOrientation.r()
    };
    float trans[3] = { (-d_translation.x()), (-d_translation.y()), (-d_translation.z()) };
    float center[3] = { (d_center.x()), (d_center.y()), (d_center.z()) };
    float ncenter[3] = { (-d_center.x()), (-d_center.y()), (-d_center.z()) };
    double M[16];

    Mtrans(M, trans);
    MM(m, M);
    Mtrans(M, ncenter);
    MM(m, M);

    // Invert scale (1/x)
    float scale[3] = { d_scale.x(), d_scale.y(), d_scale.z() };
    if (!FPZERO(scale[0]))
        scale[0] = 1.0f / scale[0];
    if (!FPZERO(scale[1]))
        scale[1] = 1.0f / scale[1];
    if (!FPZERO(scale[2]))
        scale[2] = 1.0f / scale[2];

    Mrotation(M, rot);
    MM(m, M);

    if (!FPEQUAL(scale[0], 1.0) || !FPEQUAL(scale[1], 1.0) || !FPEQUAL(scale[2], 1.0))
    {
        //fprintf(stderr, "invTr: scale\n");
        if (!FPZERO(srot[3]))
        {
            //fprintf(stderr, "invTr: rot\n");
            Mrotation(M, nsrot);
            MM(m, M);
            Mscale(M, scale);
            MM(m, M);
            Mrotation(M, srot);
            MM(m, M);
        }
        else
        {
            Mscale(M, scale);
            MM(m, M);
        }
    }
    Mtrans(M, center);
    MM(m, M);
}
Esempio n. 13
0
Viewer::Object VrmlNodeILineSet::insertGeometry(Viewer *viewer)
{
    Viewer::Object obj = 0;
    if (d_coord.get())
    {
        VrmlMFVec3f &coord = d_coord.get()->toCoordinate()->coordinate();
        int nvert = coord.size();
        int ncoord = nvert;
        float *color = NULL;
        int nci = 0, *ci = NULL;
        int *localci = NULL;
        int *cdi = NULL, *localcdi = NULL;

        if (d_coordIndex.size() > 0)
        {
            cdi = &d_coordIndex[0];
            ncoord = d_coordIndex.size();
        }
        else
        {
            localcdi = new int[ncoord];
            cdi = localcdi;
            for (int i = 0; i < ncoord; i++)
            {
                cdi[i] = i;
            }
        }

        // check #colors is consistent with colorPerVtx, colorIndex...
        int componentsPerColor = 3;
        int cSize = -1;
        VrmlNode *colorNode = d_color.get();
        if (colorNode && (strcmp(colorNode->nodeType()->getName(), "ColorRGBA") == 0))
        {
            VrmlMFColorRGBA &c = d_color.get()->toColorRGBA()->color();
            color = &c[0][0];
            cSize = c.size();
            componentsPerColor = 4;
        }
        else if (d_color.get())
        {
            VrmlMFColor &c = d_color.get()->toColor()->color();
            color = &c[0][0];
            cSize = c.size();
        }
        if (cSize > -1)
        {
            nci = d_colorIndex.size();
            if (nci)
            {
                ci = d_colorIndex.get();
            }
            else
            {
                nci = cSize;
                localci = new int[cSize];
                ci = localci;
                for (int i = 0; i < nci; i++)
                {
                    ci[i] = i;
                }
            }
        }

        obj = viewer->insertLineSet(nvert, &coord[0][0],
                                    ncoord, cdi,
                                    d_colorPerVertex.get(),
                                    color, componentsPerColor,
                                    nci, ci, name());

        delete[] localcdi;
        delete[] localci;
    }

    if (d_color.get())
        d_color.get()->clearModified();
    if (d_coord.get())
        d_coord.get()->clearModified();

    return obj;
}
Esempio n. 14
0
void VrmlNodeGroup::activate(double time,
                             bool isOver, bool isActive,
                             double *p, double *M)
{
    int i, n = d_children.size();

    for (i = 0; i < n; ++i)
    {
        VrmlNode *kid = d_children[i];

        if (kid == NULL)
            continue;
        if (kid->toTouchSensor() && kid->toTouchSensor()->isEnabled())
        {
            kid->toTouchSensor()->activate(time, isOver, isActive, p);
            break;
        }
        else if (kid->toPlaneSensor() && kid->toPlaneSensor()->isEnabled())
        {
            kid->toPlaneSensor()->activate(time, isActive, p);
            break;
        }
        else if (kid->toSpaceSensor() && kid->toSpaceSensor()->isEnabled())
        {
            kid->toSpaceSensor()->activate(time, isActive, p, M);
            break;
        }
        else if (kid->toSphereSensor() && kid->toSphereSensor()->isEnabled())
        {
            kid->toSphereSensor()->activate(time, isActive, p);
            break;
        }
        else if (kid->toCylinderSensor() && kid->toCylinderSensor()->isEnabled())
        {
            kid->toCylinderSensor()->activate(time, isActive, p);
            break;
        }
    }
}
Esempio n. 15
0
VrmlNodeFog *VrmlScene::bindableFogTop()
{
  VrmlNode *f =  bindableTop( d_fogStack );
  return f ? f->toFog() : 0;
}
Esempio n. 16
0
void VrmlNodeProto::instantiate()
{
    System::the->debug("%s::%s instantiate\n", d_nodeType->getName(),
                       name());

    if (!d_nodes)
    {
        VrmlMFNode *protoNodes = d_nodeType->getImplementationNodes();
        int nNodes = protoNodes ? protoNodes->size() : 0;
        int i;

        d_scope = new VrmlNamespace();

        // Clear all flags - encountering a set flag during cloning
        // indicates a USEd node, which should be referenced rather
        // than cloned.
        for (i = 0; i < nNodes; ++i)
            protoNodes->get(i)->clearFlags();

        // Clone nodes
        // Those squeamish about broken encapsulations shouldn't look...
        d_nodes = new VrmlMFNode(nNodes, 0);
        VrmlNode **clone = d_nodes->get();
        for (i = 0; i < nNodes; ++i)
        {
            clone[i] = protoNodes->get(i)->clone(d_scope)->reference();
            clone[i]->parentList.push_back(this);
            if (clone[i]->getTraversalForce() > 0)
            {
                forceTraversal(false, clone[i]->getTraversalForce());
            }
        }

        // Copy internal (to the PROTO implementation) ROUTEs.
        for (i = 0; i < nNodes; ++i)
            protoNodes->get(i)->copyRoutes(d_scope);

        // Collect eventIns coming from outside the PROTO.
        // A list of eventIns along with their maps to local
        // nodes/eventIns is constructed for each instance.
        VrmlNodeType::FieldList &eventIns = d_nodeType->eventIns();
        VrmlNodeType::FieldList::iterator ev;
        VrmlNodeType::ISMap *ismap;
        VrmlNodeType::ISMap::const_iterator j;

        for (ev = eventIns.begin(); ev != eventIns.end(); ++ev)
        {
            EventDispatch *ed = new EventDispatch;
            char *eventName = (*ev)->name;

            ed->name = new char[strlen(eventName) + 1];
            strcpy(ed->name, eventName);
            ismap = &(*ev)->thisIS;
            d_eventDispatch.push_front(ed);

            for (j = ismap->begin(); j != ismap->end(); ++j)
            {
                VrmlNodeType::NodeFieldRec *nf = new VrmlNodeType::NodeFieldRec;
                nf->node = d_scope->findNode((*j)->node->name());
                nf->fieldName = new char[strlen((*j)->fieldName) + 1];
                strcpy(nf->fieldName, (*j)->fieldName);
                ed->ismap.push_front(nf);
            }
        }

        // Distribute eventOuts. Each eventOut ROUTE is added
        // directly to the local nodes that have IS'd the PROTO
        // eventOut.
        VrmlNodeType::FieldList &eventOuts = d_nodeType->eventOuts();
        for (Route *r = d_routes; r; r = r->next())
            for (ev = eventOuts.begin(); ev != eventOuts.end(); ++ev)
                if (strcmp((*ev)->name, r->fromEventOut()) == 0)
                {
                    ismap = &(*ev)->thisIS;
                    for (j = ismap->begin(); j != ismap->end(); ++j)
                    {
                        VrmlNode *n = d_scope->findNode((*j)->node->name());
                        if (n)
                            n->addRoute((*j)->fieldName,
                                        r->toNode(), r->toEventIn());
                    }
                }

        // Set IS'd field values in the implementation nodes to
        // the values specified in the instantiation.

        list<NameValueRec *>::iterator ifld;
        for (ifld = d_fields.begin(); ifld != d_fields.end(); ++ifld)
        {
            VrmlField *value = (*ifld)->value;
#ifdef DEBUG
            cerr << d_nodeType->getName() << "::" << name()
                 << " setting IS field " << (*ifld)->name;
            if (value)
                cerr << " to " << *value << endl;
            else
                cerr << " to null\n";
#endif
            if (!value)
                continue;
            if ((ismap = d_nodeType->getFieldISMap((*ifld)->name)) != 0)
            {
                for (j = ismap->begin(); j != ismap->end(); ++j)
                {
                    //    cerr << (*j)->node->name() << endl;
                    VrmlNode *n = d_scope->findNode((*j)->node->name());
#ifdef DEBUG
                    cerr << " on " << n->name() << "::" << (*j)->fieldName << endl;
#endif
                    if (n)
                        n->setField((*j)->fieldName, *value);
                }
            }
        }
    }

    d_instantiated = true;
}
Esempio n. 17
0
VrmlNodeNavigationInfo *VrmlScene::bindableNavigationInfoTop()
{
  VrmlNode *n = bindableTop( d_navigationInfoStack );
  return n ? n->toNavigationInfo() : 0;
}
Esempio n. 18
0
void ModelNodeSetImpl::extractChildNodes
(JointNodeSetPtr jointNodeSet, MFNode& childNodes, const ProtoIdSet acceptableProtoIds, const Matrix44& T)
{
    for(size_t i = 0; i < childNodes.size(); i++){
        VrmlNode* childNode = childNodes[i].get();
        const Matrix44* pT;
        if(childNode->isCategoryOf(GROUPING_NODE)){
            VrmlGroup* groupNode = static_cast<VrmlGroup*>(childNode);
            VrmlTransform* transformNode = dynamic_cast<VrmlTransform*>(groupNode);
            Matrix44 T2;
            if( transformNode ){
                Matrix44 Tlocal;
                calcTransformMatrix(transformNode, Tlocal);
                T2 = T * Tlocal;
                pT = &T2;
            } else {
                pT = &T;
            }
            extractChildNodes(jointNodeSet, groupNode->getChildren(), acceptableProtoIds, *pT);

        } else if(childNode->isCategoryOf(LIGHT_NODE)){
            jointNodeSet->lightNodes.push_back(std::make_pair(T,childNode));
        } else if(childNode->isCategoryOf(PROTO_INSTANCE_NODE)){

            VrmlProtoInstance* protoInstance = static_cast<VrmlProtoInstance*>(childNode);
            int id = PROTO_UNDEFINED;
            bool doTraverseChildren = false;
            ProtoIdSet acceptableChildProtoIds(acceptableProtoIds);

            const string& protoName = protoInstance->proto->protoName;
            ProtoNameToInfoMap::iterator p = protoNameToInfoMap.find(protoName);

            if(p == protoNameToInfoMap.end()){
                doTraverseChildren = true;
            } else {
                id = p->second.id;
                if(!acceptableProtoIds.test(id)){
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                }
            }

            messageIndent += 2;

            switch(id){
                
            case PROTO_JOINT:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->childJointNodeSets.push_back(addJointNodeSet(protoInstance));
                break;
                
            case PROTO_SENSOR:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->sensorNodes.push_back(protoInstance);
                putMessage(protoName + protoInstance->defName);
                break;
                
            case PROTO_HARDWARECOMPONENT:
                if(T != Matrix44::Identity())
                    throw ModelNodeSet::Exception(protoName + " node is not in a correct place.");
                jointNodeSet->hwcNodes.push_back(protoInstance);
                putMessage(protoName + protoInstance->defName);
                break;
                
            case PROTO_SEGMENT:
                {
                    jointNodeSet->segmentNodes.push_back(protoInstance);
                    jointNodeSet->transforms.push_back(T);
                    putMessage(string("Segment node ") + protoInstance->defName);

                    doTraverseChildren = true;
                    acceptableChildProtoIds.reset();
                    acceptableChildProtoIds.set(PROTO_SENSOR);
                }
                break;
                
            default:
                break;
            }

            if(doTraverseChildren){
                if (protoInstance->fields.count("children")){
                    MFNode& childNodes = protoInstance->fields["children"].mfNode();
                    extractChildNodes(jointNodeSet, childNodes, acceptableChildProtoIds, T);
                }
            }

            messageIndent -= 2;
        }
    }
}
Esempio n. 19
0
VrmlNodeViewpoint *VrmlScene::bindableViewpointTop()
{
  VrmlNode *t = bindableTop( d_viewpointStack );
  return t ? t->toViewpoint() : 0;
}