time.C

Go to the documentation of this file.
00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
00018  */
00019 
00026 #include <math.h>
00027 
00028 #include <iostream>
00029 
00030 #include <archon/x3d/server/field_type.H>
00031 #include <archon/x3d/server/field.H>
00032 #include <archon/x3d/server/time.H>
00033 #include <archon/x3d/server/scene.H>
00034 #include <archon/x3d/server/server.H>
00035 
00036 namespace Archon
00037 {
00038   namespace X3D
00039   {
00040     const NodeType *TimeDependentNode::type = 0;
00041     const NodeType *TimeSensor::type = 0;
00042 
00043     void initializeTimeComponent()
00044     {
00045       vector<const FieldBase *> fields;
00046 
00047       // TimeDependentNode
00048 
00049       fields.push_back(newEventOut("isPaused", SFBool::type,
00050                                    &TimeDependentNode::isPaused,
00051                                    &TimeDependentNode::isPausedChanged));
00052       fields.push_back(newEventOut("elapsedTime", SFTime::type,
00053                                    &TimeDependentNode::elapsedTime,
00054                                    &TimeDependentNode::elapsedTimeChanged));
00055       fields.push_back(newExposedField("loop", SFBool::type,
00056                                        &TimeDependentNode::loop,
00057                                        &TimeDependentNode::loopChanged,
00058                                        &TimeDependentNode::loopStamp));
00059       fields.push_back(newExposedField("numLoops", SFFloat::type,
00060                                        &TimeDependentNode::numLoops,
00061                                        &TimeDependentNode::numLoopsChanged,
00062                                        &TimeDependentNode::numLoopsStamp));
00063       fields.push_back(newExposedField("startTime", SFTime::type,
00064                                        &TimeDependentNode::startTime,
00065                                        &TimeDependentNode::startTimeChanged,
00066                                        &TimeDependentNode::startTimeStamp));
00067       fields.push_back(newExposedField("stopTime", SFTime::type,
00068                                        &TimeDependentNode::stopTime,
00069                                        &TimeDependentNode::stopTimeChanged,
00070                                        &TimeDependentNode::stopTimeStamp));
00071       fields.push_back(newExposedField("pauseTime", SFTime::type,
00072                                        &TimeDependentNode::pauseTime,
00073                                        &TimeDependentNode::pauseTimeChanged,
00074                                        &TimeDependentNode::pauseTimeStamp));
00075       fields.push_back(newExposedField("resumeTime", SFTime::type,
00076                                        &TimeDependentNode::resumeTime,
00077                                        &TimeDependentNode::resumeTimeChanged,
00078                                        &TimeDependentNode::resumeTimeStamp));
00079       TimeDependentNode::type =
00080         NodeType::newAbstract("TimeDependentNode", false,
00081                               &fields, ChildNode::type);
00082       fields.clear();
00083 
00084 
00085       // TimeSensor
00086 
00087       fields.push_back(newExposedField("cycleInterval", SFTime::type,
00088                                        &TimeSensor::cycleInterval,
00089                                        &TimeSensor::cycleIntervalChanged,
00090                                        &TimeSensor::cycleIntervalStamp));
00091       fields.push_back(newEventOut("cycleTime", SFTime::type,
00092                                    &TimeSensor::cycleTime,
00093                                    &TimeSensor::cycleTimeChanged));
00094       fields.push_back(newEventOut("fraction_changed", SFFloat::type,
00095                                    &TimeSensor::fraction,
00096                                    &TimeSensor::fractionChanged));
00097       fields.push_back(newEventOut("time", SFTime::type,
00098                                    &TimeSensor::time,
00099                                    &TimeSensor::timeChanged));
00100       TimeSensor::type =
00101         NodeType::newConcrete("TimeSensor", "children", TimeSensor::instantiate,
00102                               &fields, TimeDependentNode::type, SensorNode::type);
00103       fields.clear();
00104     }
00105 
00115     void TimeSensor::tick()
00116     {
00117       if(!getEnabled()) return;
00118       Time now = context->server->getNextTimeStamp();
00119       if(!isActive)
00120       {
00121         if(now<startTime ||
00122            now>=stopTime && stopTime > startTime ||
00123            now>=startTime+cycleInterval && !loop) return;
00124 
00125         // Activate
00126         isActive = true;
00127 
00128         // Skip an integer number of cycleInterval's so that we arrive
00129         // at the greatest cycleTime less than now. This seems to give
00130         // undesired effects for TimeSensors with startTime=0 (think
00131         // it over agian)
00132         long double phase;
00133         long double period;
00134         Time t=now-startTime;
00135         t.get(phase);
00136         cycleInterval.get(period);
00137         cycleTime = startTime + Time(floor(double(phase/period)) * double(period));
00138 
00139         {
00140           Event event(new SimpleValue<bool>(SFBool::type, isActive), now);
00141           isActiveChanged.cascadeEvent(&event);
00142         }
00143         {
00144           Event event(new SimpleValue<Time>(SFTime::type, cycleTime), now); 
00145           cycleTimeChanged.cascadeEvent(&event);
00146         }
00147 
00148         //cerr << "Activated '" << getName() << "'\n";
00149       }
00150       else if(now>=stopTime && stopTime > startTime ||
00151               now>=cycleTime+cycleInterval && !loop)
00152       {
00153         // Deactivate
00154         time = loop ? stopTime : min(stopTime, cycleTime+cycleInterval);
00155         fraction = 1;
00156         isActive = false;
00157 
00158         {
00159           Event event(new SimpleValue<Time>(SFTime::type, time), now); 
00160           timeChanged.cascadeEvent(&event);
00161         }
00162         {
00163           Event event(new SimpleValue<double>(SFFloat::type, fraction), now); 
00164           fractionChanged.cascadeEvent(&event);
00165         }
00166         {
00167           Event event(new SimpleValue<bool>(SFBool::type, isActive), now);
00168           isActiveChanged.cascadeEvent(&event);
00169         }
00170         //cerr << "De-activated '" << getName() << "'\n";
00171         return;
00172       }
00173 
00174       if(now>=cycleTime+cycleInterval)
00175       {
00176         // Next loop
00177         cycleTime += cycleInterval;
00178 
00179         Event event(new SimpleValue<Time>(SFTime::type, cycleTime), now); 
00180         cycleTimeChanged.cascadeEvent(&event);
00181       }
00182 
00183       long double phase;
00184       long double period;
00185       Time t = now-cycleTime;
00186       t.get(phase);
00187       cycleInterval.get(period);
00188 
00189       time = now;
00190       fraction = phase/period;
00191 
00192       {
00193         Event event(new SimpleValue<Time>(SFTime::type, time), now); 
00194         timeChanged.cascadeEvent(&event);
00195       }
00196       {
00197         Event event(new SimpleValue<double>(SFFloat::type, fraction), now); 
00198         fractionChanged.cascadeEvent(&event);
00199       }
00200     }
00201   }
00202 }

Generated on Sun Jul 30 22:55:45 2006 for Archon by  doxygen 1.4.4