void VrmlNodeTimeSensor::update(VrmlSFTime &inTime) { //VrmlSFTime timeNow( inTime ); if (fixedForTesting) { d_time.set(0.5); } else { d_time.set(inTime.get()); } if (d_enabled.get()) { if (d_lastTime > inTime.get()) d_lastTime = inTime.get(); // Become active at startTime if either the valid stopTime hasn't // passed or we are looping. if (!d_isActive.get() && d_startTime.get() <= d_time.get() && d_startTime.get() != d_lastStartTime && ((d_stopTime.get() < d_startTime.get() || d_stopTime.get() > d_time.get()) || d_loop.get())) { d_isActive.set(true); d_lastStartTime = d_startTime.get(); System::the->debug("TimeSensor.%s isActive TRUE\n", name()); // Start at first tick >= startTime eventOut(d_time.get(), "isActive", d_isActive); eventOut(d_time.get(), "time", d_time); d_fraction.set(0.0); eventOut(d_time.get(), "fraction_changed", d_fraction); eventOut(d_time.get(), "cycleTime", d_time); } // Running (active and enabled) else if (d_isActive.get()) { double f, cycleInt = d_cycleInterval.get(); bool deactivate = false; // Are we done? Choose min of stopTime or start + single cycle. if ((d_stopTime.get() > d_startTime.get() && d_stopTime.get() <= d_time.get()) || ((!d_loop.get()) && d_startTime.get() + cycleInt <= d_time.get())) { d_isActive.set(false); // Must respect stopTime/cycleInterval exactly if ((d_startTime.get() + cycleInt < d_stopTime.get()) || (d_stopTime.get() < d_startTime.get())) d_time = d_startTime.get() + cycleInt; else d_time = d_stopTime; //if(d_lastTime > d_time.get()) // otherwise, we forget to start if startTime is set to d_time //d_lastTime = d_time.get(); deactivate = true; d_startTime = 0.0; } if (cycleInt > 0.0 && d_time.get() > d_startTime.get()) { if (!d_loop.get()) { if ((d_time.get() - d_startTime.get()) > cycleInt) f = cycleInt; else f = (d_time.get() - d_startTime.get()); } else { f = fmod(d_time.get() - d_startTime.get(), cycleInt); } } else f = 0.0; // Fraction of cycle message //VrmlSFFloat fraction_changed( FPZERO(f) ? 1.0 : (f / cycleInt) ); d_fraction.set(FPZERO(f) ? 1.0f : (float)(f / cycleInt)); eventOut(d_time.get(), "fraction_changed", d_fraction); // Current time message eventOut(d_time.get(), "time", d_time); // End of cycle message (this may not miss cycles anymore) if (d_fraction.get() < oldFraction) { eventOut(d_time.get(), "cycleTime", d_time); } oldFraction = d_fraction.get(); if (deactivate) eventOut(d_time.get(), "isActive", d_isActive); } // Tell the scene this node needs quick updates while it is active. // Should check whether time, fraction_changed eventOuts are // being used, and set delta to cycleTime if not... if (d_isActive.get()) d_scene->setDelta(0.0); d_lastTime = d_time.get(); //inTime.get(); } }
void VrmlNodeMovieTexture::update( VrmlSFTime &timeNow ) { if ( isModified() ) { if (d_image) { const char *imageUrl = d_image->url(); int imageLen = (int)strlen(imageUrl); int i, nUrls = d_url.size(); for (i=0; i<nUrls; ++i) { int len = (int)strlen(d_url[i]); if ((strcmp(imageUrl, d_url[i]) == 0) || (imageLen > len && strcmp(imageUrl+imageLen-len, d_url[i]) == 0)) break; } // if (d_image->url() not in d_url list) ... if (i == nUrls) { delete d_image; d_image = 0; } } } // Load the movie if needed (should check startTime...) if (! d_image && d_url.size() > 0) { Doc relDoc( d_relativeUrl.get() ); Doc *rel = d_relativeUrl.get() ? &relDoc : d_scene->urlDoc(); d_image = new Image; if ( ! d_image->tryURLs( d_url.size(), d_url.get(), rel ) ) cerr << "Error: couldn't read MovieTexture from URL " << d_url << endl; int nFrames = d_image->nFrames(); d_duration = (nFrames >= 0) ? nFrames : -1; eventOut( timeNow.get(), "duration_changed", d_duration ); d_frame = (d_speed.get() >= 0) ? 0 : nFrames-1; //theSystem->debug("MovieTexture.%s loaded %d frames\n", name(), nFrames); } // No pictures to show if (! d_image || d_image->nFrames() == 0) return; // Become active at the first tick at or after startTime if either // the valid stopTime hasn't passed or we are looping. if (! d_isActive.get() && d_startTime.get() <= timeNow.get() && d_startTime.get() >= d_lastFrameTime && ( (d_stopTime.get() < d_startTime.get() || // valid stopTime d_stopTime.get() > timeNow.get()) || // hasn't passed d_loop.get() )) { //theSystem->debug("MovieTexture.%s::isActive TRUE\n", name()); d_isActive.set(true); eventOut( timeNow.get(), "isActive", d_isActive ); d_lastFrameTime = timeNow.get(); d_frame = (d_speed.get() >= 0) ? 0 : d_image->nFrames() - 1; setModified(); } // Check whether stopTime has passed else if ( d_isActive.get() && (( d_stopTime.get() > d_startTime.get() && d_stopTime.get() <= timeNow.get() ) || d_frame < 0)) { //theSystem->debug("MovieTexture.%s::isActive FALSE\n", name()); d_isActive.set(false); eventOut( timeNow.get(), "isActive", d_isActive ); setModified(); } // Check whether the frame should be advanced else if ( d_isActive.get() && d_lastFrameTime + fabs(double(d_speed.get())) <= timeNow.get() ) { if (d_speed.get() < 0.0) --d_frame; else ++d_frame; //theSystem->debug("MovieTexture.%s::frame %d\n", name(), d_frame); d_lastFrameTime = timeNow.get(); setModified(); } // Tell the scene when the next update is needed. if (d_isActive.get()) { double d = d_lastFrameTime + fabs(double(d_speed.get())) - timeNow.get(); d_scene->setDelta( 0.9 * d ); } }