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(); }
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; }
// // 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(); }