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) px->toggle = FALSE;
148 else px->toggle = TRUE;
149 if (oldBoolean != px->toggle) MARK_EVENT (node, offsetof (struct X3D_BooleanToggle, toggle));
150}
151
152/******************************************************************************/
153
154/******************************************************************************/
155
156
157/* see the spec for a description */
158void do_BooleanTrigger (void *node){
159 struct X3D_BooleanTrigger *px;
160
161 if (!node) return;
162 px = (struct X3D_BooleanTrigger *) node;
163
164 px->triggerTrue = TRUE; /* spec says that this is ALWAYS true */
165 MARK_EVENT (node, offsetof (struct X3D_BooleanTrigger, triggerTrue));
166}
167
168/******************************************************************************/
169/* see the spec for a description */
170
171/* WHAT ARE NEXT AND PREVIOUS FIELDS FOR???? NOT MENTIONED IN SPEC (AT LEAST
172REVISION FOUND WHEN IMPLEMENTING
173
174dug9 hypothesis Nov 19, 2017:
1751) get an index to use as key[index] and keyValue[index]
176option a)
177- take the current set_fraction value (leftover from any prior event)
178- if(previous)
179 round it down to the nearest key
180- if(next)
181 round it up to the nearest key
182- take the index of that key
183option b)
184- keep a private index field
185- initialize index to 0 when creating node
186- after each event, save closest index (for set_fraction event)
187-- or exact index if next,previous event
1882) increment/decrement index if next/prev set
189 - then clear next/prev
1903) use index
191 set_fraction = key[index]
192 fraction_changed = keyValue[index]
193Implementation
194- option choice: 1.b - looks easier to track for mulitple input paths set_,next,prev
195
196*/
197void do_IntegerSequencer (void *node){
198 struct X3D_IntegerSequencer *px;
199 int kin, kvin;
200 int *kVs;
201 int counter;
202 int oldValue;
203
204 if (!node) return;
205 px = (struct X3D_IntegerSequencer *) node;
206 kin = px->key.n;
207 kvin = px->keyValue.n;
208 kVs = px->keyValue.p;
209
210 //MARK_EVENT (node, offsetof (struct X3D_IntegerSequencer, value_changed));
211 oldValue = px->value_changed;
212
213 #ifdef SEVERBOSE
214 printf ("IntegerSequencer, kin %d kvin %d, sf %f vc %d\n",kin,kvin,px->set_fraction, px->value_changed);
215 #endif
216
217 /* make sure we have the keys and keyValues */
218 if ((kvin == 0) || (kin == 0)) {
219 px->value_changed = 0;
220 return;
221 }
222 if (kin>kvin) kin=kvin; /* means we don't use whole of keyValue, but... */
223 if(px->next || px->previous){
224 counter = px->_index;
225 if(px->next) counter += 1;
226 if(px->previous) counter -= 1;
227 counter = iwrap(counter,0,kin);
228 px->value_changed = px->keyValue.p[counter];
229 px->set_fraction = px->key.p[counter];
230 px->_index = counter;
231 px->next = FALSE; //clear
232 px->previous = FALSE;
233 }else{
234 /* set_fraction less than or greater than keys */
235 if (px->set_fraction <= px->key.p[0]) {
236 px->value_changed = kVs[0];
237 px->_index = 0;
238 } else if (px->set_fraction >= px->key.p[kin-1]) {
239 px->value_changed = kVs[kvin-1];
240 px->_index = kvin-1;
241 } else {
242 /* have to go through and find the key before */
243
244 counter=find_key(kin+1,(float)(px->set_fraction),px->key.p)-1;
245
246 /* bounds check */
247 if (counter >= px->keyValue.n) counter = px->keyValue.n-1;
248
249 px->value_changed = px->keyValue.p[counter];
250 px->_index = counter;
251 }
252 }
253 //if (oldValue != px->value_changed) {
254 MARK_EVENT (node, offsetof (struct X3D_IntegerSequencer, value_changed));
255 //}
256
257}
258
259/******************************************************************************/
260/* see the spec for a description */
261void do_IntegerTrigger (void *node){
262 struct X3D_IntegerTrigger *px;
263
264 if (!node) return;
265
266 px = (struct X3D_IntegerTrigger *) node;
267
268 //specs: "The value of set_boolean shall be ignored."
269 //if (px->set_boolean == TRUE) {
270 px->triggerValue = px->integerKey;
271 MARK_EVENT (node, offsetof (struct X3D_IntegerTrigger,triggerValue));
272 //} else {
274 //}
275
276
277
278}
279
280/******************************************************************************/
281/* see the spec for a description */
282void do_TimeTrigger (void *node){
283 struct X3D_TimeTrigger *px;
284
285 if (!node) return;
286 px = (struct X3D_TimeTrigger *) node;
287
288 px->triggerTime = TickTime();
289 MARK_EVENT (node, offsetof (struct X3D_TimeTrigger,triggerTime));
290}
291