FreeWRL / FreeX3D 4.3.0
Component_Time.c
1/*
2
3
4X3D Time Component
5
6*/
7
8
9/****************************************************************************
10 This file is part of the FreeWRL/FreeX3D Distribution.
11
12 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13
14 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26****************************************************************************/
27
28
29
30#include <config.h>
31#include <system.h>
32#include <display.h>
33#include <internal.h>
34
35#include <libFreeWRL.h>
36
37#include "../vrml_parser/Structs.h"
38#include "../vrml_parser/CRoutes.h"
39#include "../main/headers.h"
40#include "../input/SensInterps.h"
41
42
43//void do_active_inactive (
44// int *act, /* pointer to are we active or not? */
45// double *inittime, /* pointer to nodes inittime */
46// double *startt, /* pointer to nodes startTime */
47// double *stopt, /* pointer to nodes stop time */
48// int loop, /* nodes loop field */
49// double myDuration, /* duration of cycle */
50// double speed, /* speed field */
51// double elapsedTime /* cumulative non-paused time */
52//);
53
54/*
55 Nov 2016 before:
56 - verifying against NIST http://www.web3d.org/x3d/content/examples/ConformanceNist/Sensors/TimeSensor/index.html
57 x win32 desktop fails 6 nist tests ie:
58 stopeqstartlooptrue.x3d- freewrl doesn't animate when world is loaded, starts 5 seconds after
59 stopgtstartloopfalse.x3d - freewrl wrong on startup - moves 4 seconds
60 x time was 0 on startup, should be time since 1970 ie 1479495634.873 seconds
61 - android, uwp: NIST working properly, (android 1970, uwp something > 0 on startup)
62 - created pause_resume.x3d example: NIST has no pause/resume examnple,
63 x and not web3d member so don't have full test suite)
64 - sample pause_resume.x3d works properly with vivaty, octaga
65 x pause_resume has no effect in freewrl
66 x looks like __inittime is set 0 on startup and never changed
67 Nov 2016 CHANGES:
68 0. fixed win32 desktop ticktime to secconds from 1970
69 1. added pause resume snippet from do_audiotick / do_movietexturetick
70 2. added __lasttime to help compute cumulative elapsedTime
71 3. sent/marked elapsedTime events as per spec
72 4. set __inittime to TickTime on startup
73 Nov 2016 after:
74 Nist tests: pass
75 pause_rexume.x3d: pass
76*/
77
78
79/* void do_TimeSensorTick (struct X3D_TimeSensor *node) {*/
80void do_TimeSensorTick ( void *ptr) {
81 struct X3D_TimeSensor *node = (struct X3D_TimeSensor *)ptr;
82 double duration;
83 int oldstatus;
84 double myFrac;
85 double frac;
86
87 /* are we not enabled */
88 if (!node) return;
89
90 if(node->__inittime == 0.0)
91 node->__inittime = TickTime();
92
93 if (node->__oldEnabled != node->enabled) {
94 node->__oldEnabled = node->enabled;
95 MARK_EVENT(X3D_NODE(node),offsetof (struct X3D_TimeSensor, enabled));
96 }
97 if (!node->enabled) {
98 if (node->isActive) {
99 node->isActive=0;
100 MARK_EVENT (ptr, offsetof(struct X3D_TimeSensor, isActive));
101 }
102 return;
103 }
104
105 /* can we possibly have started yet? */
106 if(TickTime() < node->startTime) {
107 return;
108 }
109
110 oldstatus = node->isActive;
111 duration = node->cycleInterval;
112
113 /* call common time sensor routine */
114 /*
115 printf ("cycleInterval %f \n",node->cycleInterval);
116
117 uncomment the following to ensure that the gcc bug
118 in calling doubles/floats in here is not causing us
119 problems again...
120
121 static int count = 0;
122 if(count == 0){
123 printf ("calling ");
124 printf ("act %d ",node->isActive);
125 printf ("initt %lf ",node->__inittime);
126 printf ("startt %lf ",node->startTime);
127 printf ("stopt %lf ",node->stopTime);
128 printf ("loop %d ",node->loop);
129 printf ("duration %f ",(float) duration);
130 printf ("speed %f\n",(float) 1.0);
131 }
132 count++;
133 */
134
135
136 do_active_inactive (
137 &node->isActive, &node->__inittime, &node->startTime,
138 &node->stopTime,node->loop,duration, 1.0,node->elapsedTime);
139
140 /* MARK_SFNODE_INOUT_EVENT(node->metadata, node->__oldmetadata, offsetof (struct X3D_TimeSensor, metadata)) */
141
142 /* now process if we have changed states */
143 if (oldstatus != node->isActive) {
144 if (node->isActive == 1) {
145 /* force code below to generate event */
146 node->__ctflag = 10.0;
147 node->__lasttime = TickTime();
148 node->elapsedTime = 0.0;
149 }
150 /* push @e, [$t, "isActive", node->{isActive}]; */
151 MARK_EVENT (ptr, offsetof(struct X3D_TimeSensor, isActive));
152 }
153
154
155 if(node->isActive){
156 if(node->pauseTime > node->startTime){
157 if( node->resumeTime < node->pauseTime && !node->isPaused){
158 node->isPaused = TRUE;
159 MARK_EVENT (X3D_NODE(node), offsetof(struct X3D_TimeSensor, isPaused));
160 }else if(node->resumeTime > node->pauseTime && node->isPaused){
161 node->isPaused = FALSE;
162 node->__lasttime = TickTime();
163 MARK_EVENT (X3D_NODE(node), offsetof(struct X3D_TimeSensor, isPaused));
164 }
165 }
166 }
167
168 if(node->isActive == 1 && node->isPaused == FALSE) {
169 /* set time field */
170 node->time = TickTime();
171 MARK_EVENT (ptr, offsetof(struct X3D_TimeSensor, time));
172 node->elapsedTime += node->time - node->__lasttime;
173 node->__lasttime = node->time;
174 /* calculate what fraction we should be */
175 //myTime = (TickTime() - node->startTime) / duration;
176 myFrac = node->elapsedTime / duration;
177 if (node->loop) {
178 frac = myFrac - (int) myFrac;
179 } else {
180 frac = (myFrac > 1 ? 1 : myFrac);
181 }
182
183 #ifdef SEVERBOSE
184 printf ("TimeSensor myFrac %f frac %f dur %f\n", myFrac,frac,duration);
185 #endif
186
187 /* cycleTime events once at start, and once every loop. */
188 if (frac < node->__ctflag) {
189 /* push @e, [$t, cycleTime, $TickTime]; */
190 node->cycleTime = TickTime();
191 MARK_EVENT (ptr, offsetof(struct X3D_TimeSensor, cycleTime));
192 }
193 node->__ctflag = frac;
194
195 node->fraction_changed = (float) frac;
196 MARK_EVENT (ptr, offsetof(struct X3D_TimeSensor, fraction_changed));
197
198 }
199}
200