1 /*
2 * NodeTimeSensor.cpp
3 *
4 * Copyright (C) 1999 Stephen F. White
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file "COPYING" for details); if
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include "stdafx.h"
24
25 #include "NodeTimeSensor.h"
26 #include "Proto.h"
27 #include "Scene.h"
28 #include "FieldValue.h"
29 #include "SFTime.h"
30 #include "SFBool.h"
31 #include "SFFloat.h"
32 #include "Field.h"
33 #include "ExposedField.h"
34
35 #ifndef DBL_MIN
36 # include <float.h>
37 #endif
38
ProtoTimeSensor(Scene * scene)39 ProtoTimeSensor::ProtoTimeSensor(Scene *scene)
40 : WonderlandExportProto(scene, "TimeSensor")
41 {
42 cycleInterval.set(
43 addExposedField(SFTIME, "cycleInterval", new SFTime(1.0),
44 new SFTime(DBL_MIN)));
45 setFieldFlags(cycleInterval, FF_4KIDS);
46
47 enabled.set(
48 addExposedField(SFBOOL, "enabled", new SFBool(true)));
49 setFieldFlags(enabled, EIF_WONDERLAND_SUPPORTED);
50
51 loop.set(
52 addExposedField(SFBOOL, "loop", new SFBool(false)));
53 setFieldFlags(loop, FF_4KIDS);
54
55 pauseTime.set(
56 addExposedField(SFTIME, "pauseTime", new SFTime(0.0)));
57 setFieldFlags(pauseTime, FF_X3D_ONLY);
58 resumeTime.set(
59 addExposedField(SFTIME, "resumeTime", new SFTime(0.0)));
60 setFieldFlags(resumeTime, FF_X3D_ONLY);
61 startTime.set(
62 addExposedField(SFTIME, "startTime", new SFTime(0.0f)));
63 setFieldFlags(startTime, EIF_RECOMMENDED | EIF_WONDERLAND_SUPPORTED);
64 stopTime.set(
65 addExposedField(SFTIME, "stopTime", new SFTime(0.0f)));
66 setFieldFlags(stopTime, EIF_RECOMMENDED | EIF_WONDERLAND_SUPPORTED);
67
68 first.set(
69 addExposedField(SFBOOL, "first", new SFBool(true)));
70 setFieldFlags(first, FF_X3DOM_ONLY);
71
72 firstCycle.set(
73 addExposedField(SFFLOAT, "firstCycle", new SFFloat(0.0f)));
74 setFieldFlags(firstCycle, FF_X3DOM_ONLY);
75
76 addEventOut(SFTIME, "cycleTime");
77 addEventOut(SFTIME, "elapsedTime", FF_X3D_ONLY);
78 fraction_changed.set(addEventOut(SFFLOAT, "fraction_changed",
79 EOF_RECOMMENDED | EOF_WONDERLAND_SUPPORTED));
80
81 addEventOut(SFBOOL, "isActive", EOF_WONDERLAND_SUPPORTED);
82 addEventOut(SFBOOL, "isPaused", FF_X3D_ONLY);
83 time.set(addEventOut(SFTIME, "time", EOF_WONDERLAND_SUPPORTED));
84 }
85
86 Node *
create(Scene * scene)87 ProtoTimeSensor::create(Scene *scene)
88 {
89 return new NodeTimeSensor(scene, this);
90 }
91
NodeTimeSensor(Scene * scene,Proto * def)92 NodeTimeSensor::NodeTimeSensor(Scene *scene, Proto *def)
93 : Node(scene, def)
94 {
95 m_active = false;
96 m_startTime = 0;
97 m_stopTime = 0;
98 m_delay = 0;
99 }
100
101 void
preDraw()102 NodeTimeSensor::preDraw()
103 {
104 if (enabled() && enabled()->getValue())
105 m_scene->addTimeSensor(this);
106 }
107
108 float
getFraction(double t)109 NodeTimeSensor::getFraction(double t)
110 {
111 float fraction = 0;
112
113 double dstopTime = m_stopTime + m_delay;
114
115 if (enabled()->getValue()) {
116 if ((t < m_stopTime) || ((m_stopTime <= m_startTime) &&
117 loop()->getValue()))
118 m_active = true;
119 if (t - m_startTime < m_delay)
120 m_active = false;
121 if (m_active) {
122 if ((t >= dstopTime) &&
123 dstopTime > m_startTime && !loop()->getValue()) {
124 m_active = false;
125 }
126 double temp = (t - m_startTime - m_delay) /
127 cycleInterval()->getValue();
128 fraction = temp - floor(temp);
129 if (fraction == 0.0 && (t > m_startTime))
130 fraction = 1.0;
131 }
132 }
133 return fraction;
134 }
135
136 void
setTime(double t)137 NodeTimeSensor::setTime(double t)
138 {
139 float fraction = getFraction(t);
140
141 sendEvent(fraction_changed_Field(), t, new SFFloat(fraction));
142 sendEvent(time_Field(), t, new SFTime(t));
143 }
144
145 void
checkStart(bool loop,double startTime,double stopTime,double t,double delay)146 NodeTimeSensor::checkStart(bool loop, double startTime, double stopTime,
147 double t, double delay)
148 {
149 if ((t < m_stopTime) || ((stopTime <= startTime) && loop)) {
150 m_active = true;
151 m_startTime = t + delay;
152 m_stopTime = stopTime;
153 } else {
154 m_active = false;
155 m_startTime = startTime + delay;
156 m_stopTime = stopTime;
157 }
158 m_delay = delay;
159 }
160
161 void
start(double t)162 NodeTimeSensor::start(double t)
163 {
164 checkStart(loop()->getValue(), startTime()->getValue(),
165 stopTime()->getValue(), t);
166 }
167
168 void
updateStart(int field,FieldValue * value,double t)169 NodeTimeSensor::updateStart(int field, FieldValue *value, double t)
170 {
171 if (m_scene)
172 if (m_scene->isParsing())
173 return;
174 checkStart(loop()->getValue(), startTime()->getValue(),
175 stopTime()->getValue(), t);
176 }
177
178 int
getProfile(void) const179 NodeTimeSensor::getProfile(void) const
180 {
181 return PROFILE_INTERCHANGE;
182 }
183
184
185 int
getComponentLevel(void) const186 NodeTimeSensor::getComponentLevel(void) const
187 {
188 if (hasOutput("isPaused"))
189 return 2;
190 if (!isDefault(pauseTime_Field()))
191 return 2;
192 if (!isDefault(resumeTime_Field()))
193 return 2;
194 return -1;
195 }
196
197 const char*
getComponentName(void) const198 NodeTimeSensor::getComponentName(void) const
199 {
200 static const char* name = "Time";
201 return name;
202 }
203
204
205
206
207
208