FreeWRL / FreeX3D 4.3.0
Component_EventUtils.c
1/*
2
3
4X3D Event Utilities 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
41
42/******************************************************************************/
43/* see the spec for a description. fields inputTrue and inputFalse are set in
44 VRMLNodes.pm and are never changed, ONLY MARK_EVENT is called when
45 appropriate. So, inputFalse will ALWAYS be false, BUT, the event will
46 be called when set_boolean is set to false. */
47
48void do_BooleanFilter (void *node){
49 struct X3D_BooleanFilter *px;
50
51 if (!node) return;
52 px = (struct X3D_BooleanFilter *) node;
53
54 if (px->set_boolean == TRUE) {
55 px->inputNegate = FALSE;
56 MARK_EVENT (node, offsetof (struct X3D_BooleanFilter, inputTrue));
57 MARK_EVENT (node, offsetof (struct X3D_BooleanFilter, inputNegate));
58 } else {
59 px->inputNegate = TRUE;
60 MARK_EVENT (node, offsetof (struct X3D_BooleanFilter, inputFalse));
61 MARK_EVENT (node, offsetof (struct X3D_BooleanFilter, inputNegate));
62 }
63}
64
65/******************************************************************************/
66/* see the spec for a description */
67
68/* WHAT ARE NEXT AND PREVIOUS FIELDS FOR???? NOT MENTIONED IN SPEC (AT LEAST
69REVISION FOUND WHEN IMPLEMENTING */
70int iwrap(int i, int istart, int iend);
71void do_BooleanSequencer (void *node){
72 struct X3D_BooleanSequencer *px;
73 int kin, kvin;
74 int *kVs;
75 int counter;
76 int oldValue;
77
78 if (!node) return;
79 px = (struct X3D_BooleanSequencer *) node;
80 kin = px->key.n;
81 kvin = px->keyValue.n;
82 kVs = px->keyValue.p;
83
84 oldValue = px->value_changed;
85
86
87 /* make sure we have the keys and keyValues */
88 if ((kvin == 0) || (kin == 0)) {
89 px->value_changed = 0; //(float) 0.0;
90 return;
91 }
92 if (kin>kvin) kin=kvin; /* means we don't use whole of keyValue, but... */
93
94 #ifdef SEVERBOSE
95 printf ("BooleanSequencer, kin %d kvin %d, vc %f\n",kin,kvin,px->value_changed);
96 printf (" and set_fraction is %f\n",px->set_fraction);
97 #endif
98 if(px->next || px->previous){
99 counter = px->_index;
100 if(px->next) counter += 1;
101 if(px->previous) counter -= 1;
102 counter = iwrap(counter,0,kin);
103 px->value_changed = px->keyValue.p[counter];
104 px->set_fraction = px->key.p[counter];
105 px->_index = counter;
106 px->next = FALSE; //clear
107 px->previous = FALSE;
108 }else{
109 /* set_fraction less than or greater than keys */
110 if (px->set_fraction <= px->key.p[0]) {
111 px->value_changed = kVs[0];
112 px->_index = 0;
113 } else if (px->set_fraction >= px->key.p[kin-1]) {
114 px->value_changed = kVs[kvin-1];
115 px->_index = kvin-1;
116 } else {
117 /* have to go through and find the key before */
118 counter=find_key(kin,(float)(px->set_fraction),px->key.p);
119 /* printf ("counter %d\n",counter); */
120 //px->value_changed = px->key.p[counter]; //yikes - key is a MF float
121 //should it be keyvalue? like integer_sequencer?:
122 /* bounds check */
123 if (counter >= px->keyValue.n) counter = px->keyValue.n-1;
124 px->value_changed = px->keyValue.p[counter];
125 px->_index = counter;
126 }
127 }
128 //maybe should be unconditional, in case downstream node is waiting for timestamp, not value?
129 //dug9: Not sure what's right
130 //if (oldValue != px->value_changed) {
131 MARK_EVENT (node, offsetof (struct X3D_BooleanSequencer, value_changed));
132 //}
133}
134
135
136/******************************************************************************/
137/* see the spec for a description */
138void do_BooleanToggle (void *node){
139 struct X3D_BooleanToggle *px;
140 int oldBoolean;
141
142 if (!node) return;
143 px = (struct X3D_BooleanToggle *) node;
144
145 oldBoolean = px->toggle;
146
147 if (px->set_boolean == TRUE) {
148 px->toggle = !px->toggle; // FALSE;
149 //else px->toggle = TRUE;
150 }
151 if (oldBoolean != px->toggle) MARK_EVENT (node, offsetof (struct X3D_BooleanToggle, toggle));
152}
153
154/******************************************************************************/
155
156/******************************************************************************/
157
158
159/* see the spec for a description */
160void do_BooleanTrigger (void *node){
161 struct X3D_BooleanTrigger *px;
162
163 if (!node) return;
164 px = (struct X3D_BooleanTrigger *) node;
165
166 px->triggerTrue = TRUE; /* spec says that this is ALWAYS true */
167 MARK_EVENT (node, offsetof (struct X3D_BooleanTrigger, triggerTrue));
168}
169
170/******************************************************************************/
171/* see the spec for a description */
172
173/* WHAT ARE NEXT AND PREVIOUS FIELDS FOR???? NOT MENTIONED IN SPEC (AT LEAST
174REVISION FOUND WHEN IMPLEMENTING
175
176dug9 hypothesis Nov 19, 2017:
1771) get an index to use as key[index] and keyValue[index]
178option a)
179- take the current set_fraction value (leftover from any prior event)
180- if(previous)
181 round it down to the nearest key
182- if(next)
183 round it up to the nearest key
184- take the index of that key
185option b)
186- keep a private index field
187- initialize index to 0 when creating node
188- after each event, save closest index (for set_fraction event)
189-- or exact index if next,previous event
1902) increment/decrement index if next/prev set
191 - then clear next/prev
1923) use index
193 set_fraction = key[index]
194 fraction_changed = keyValue[index]
195Implementation
196- option choice: 1.b - looks easier to track for mulitple input paths set_,next,prev
197
198*/
199void do_IntegerSequencer (void *node){
200 struct X3D_IntegerSequencer *px;
201 int kin, kvin;
202 int *kVs;
203 int counter;
204 int oldValue;
205
206 if (!node) return;
207 px = (struct X3D_IntegerSequencer *) node;
208 kin = px->key.n;
209 kvin = px->keyValue.n;
210 kVs = px->keyValue.p;
211
212 //MARK_EVENT (node, offsetof (struct X3D_IntegerSequencer, value_changed));
213 oldValue = px->value_changed;
214
215 #ifdef SEVERBOSE
216 printf ("IntegerSequencer, kin %d kvin %d, sf %f vc %d\n",kin,kvin,px->set_fraction, px->value_changed);
217 #endif
218
219 /* make sure we have the keys and keyValues */
220 if ((kvin == 0) || (kin == 0)) {
221 px->value_changed = 0;
222 return;
223 }
224 if (kin>kvin) kin=kvin; /* means we don't use whole of keyValue, but... */
225 if(px->next || px->previous){
226 counter = px->_index;
227 if(px->next) counter += 1;
228 if(px->previous) counter -= 1;
229 counter = iwrap(counter,0,kin);
230 px->value_changed = px->keyValue.p[counter];
231 px->set_fraction = px->key.p[counter];
232 px->_index = counter;
233 px->next = FALSE; //clear
234 px->previous = FALSE;
235 }else{
236 /* set_fraction less than or greater than keys */
237 if (px->set_fraction <= px->key.p[0]) {
238 px->value_changed = kVs[0];
239 px->_index = 0;
240 } else if (px->set_fraction >= px->key.p[kin-1]) {
241 px->value_changed = kVs[kvin-1];
242 px->_index = kvin-1;
243 } else {
244 /* have to go through and find the key before */
245
246 counter=find_key(kin+1,(float)(px->set_fraction),px->key.p)-1;
247
248 /* bounds check */
249 if (counter >= px->keyValue.n) counter = px->keyValue.n-1;
250
251 px->value_changed = px->keyValue.p[counter];
252 px->_index = counter;
253 }
254 }
255 //if (oldValue != px->value_changed) {
256 MARK_EVENT (node, offsetof (struct X3D_IntegerSequencer, value_changed));
257 //}
258
259}
260
261/******************************************************************************/
262/* see the spec for a description */
263void do_IntegerTrigger (void *node){
264 struct X3D_IntegerTrigger *px;
265
266 if (!node) return;
267
268 px = (struct X3D_IntegerTrigger *) node;
269
270 //specs: "The value of set_boolean shall be ignored."
271 //if (px->set_boolean == TRUE) {
272 px->triggerValue = px->integerKey;
273 MARK_EVENT (node, offsetof (struct X3D_IntegerTrigger,triggerValue));
274 //} else {
276 //}
277
278
279
280}
281
282/******************************************************************************/
283/* see the spec for a description */
284void do_TimeTrigger (void *node){
285 struct X3D_TimeTrigger *px;
286
287 if (!node) return;
288 px = (struct X3D_TimeTrigger *) node;
289
290 px->triggerTime = TickTime();
291 MARK_EVENT (node, offsetof (struct X3D_TimeTrigger,triggerTime));
292}
293