FreeWRL/FreeX3D  3.0.0
Component_Time.c
1 /*
2 
3 
4 X3D 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) {*/
80 void 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