Example #1
0
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 );
    }

}