Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / Scene Graph sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 :
27 : #include <gpac/internal/scenegraph_dev.h>
28 : #include <gpac/nodes_mpeg4.h>
29 : #include <gpac/nodes_x3d.h>
30 :
31 :
32 : GF_EXPORT
33 2362 : SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction)
34 : {
35 : SFRotation res;
36 : Fixed newa, olda;
37 2362 : Bool stzero = ( ABS(kv1.q) < FIX_EPSILON) ? 1 : 0;
38 2362 : Bool endzero = ( ABS(kv2.q) < FIX_EPSILON) ? 1 : 0;
39 2362 : Fixed testa = gf_mulfix(kv1.x, kv2.x) + gf_mulfix(kv1.y, kv2.y) + gf_mulfix(kv1.y, kv2.y);
40 :
41 2362 : if (testa>= 0) {
42 2362 : res.x = kv1.x + gf_mulfix(fraction, kv2.x-kv1.x);
43 2362 : res.y = kv1.y + gf_mulfix(fraction, kv2.y-kv1.y);
44 2362 : res.z = kv1.z + gf_mulfix(fraction, kv2.z-kv1.z);
45 : newa = kv2.q;
46 : } else {
47 0 : res.x = kv1.x + gf_mulfix(fraction, -kv2.x -kv1.x);
48 0 : res.y = kv1.y + gf_mulfix(fraction, -kv2.y-kv1.y);
49 0 : res.z = kv1.z + gf_mulfix(fraction, -kv2.z-kv1.z);
50 0 : newa = -kv2.q;
51 : }
52 : olda = kv1.q;
53 2362 : if (stzero || endzero) {
54 1334 : res.x = stzero ? kv2.x : kv1.x;
55 1334 : res.y = stzero ? kv2.y : kv1.y;
56 1334 : res.z = stzero ? kv2.z : kv1.z;
57 : }
58 2362 : res.q = olda + gf_mulfix(fraction, newa - olda);
59 2362 : if (res.q > GF_2PI) {
60 0 : res.q -= GF_2PI;
61 2362 : } else if (res.q < GF_2PI) {
62 2362 : res.q += GF_2PI;
63 : }
64 2362 : return res;
65 : }
66 :
67 : #ifndef GPAC_DISABLE_VRML
68 :
69 : static Fixed Interpolate(Fixed keyValue1, Fixed keyValue2, Fixed fraction)
70 : {
71 30127 : return gf_mulfix(keyValue2 - keyValue1, fraction) + keyValue1;
72 : }
73 :
74 : static Fixed GetInterpolateFraction(Fixed key1, Fixed key2, Fixed fraction)
75 : {
76 17193 : Fixed keyDiff = key2 - key1;
77 : assert((fraction >= key1) && (fraction <= key2));
78 17193 : if (ABS(keyDiff) < FIX_EPSILON) return 0;
79 17193 : return gf_divfix(fraction - key1, keyDiff);
80 : }
81 :
82 300 : static void CI2D_SetFraction(GF_Node *n, GF_Route *route)
83 : {
84 : Fixed frac;
85 : u32 numElemPerKey, i, j;
86 : M_CoordinateInterpolator2D *_this = (M_CoordinateInterpolator2D *) n;
87 :
88 300 : if (! _this->key.count) return;
89 300 : if (_this->keyValue.count % _this->key.count) return;
90 :
91 300 : numElemPerKey = _this->keyValue.count / _this->key.count;
92 : //set size
93 300 : if (_this->value_changed.count != numElemPerKey)
94 0 : gf_sg_vrml_mf_alloc(&_this->value_changed, GF_SG_VRML_MFVEC2F, numElemPerKey);
95 :
96 :
97 300 : if (_this->set_fraction < _this->key.vals[0]) {
98 0 : for (i=0; i<numElemPerKey; i++)
99 0 : _this->value_changed.vals[i] = _this->keyValue.vals[i];
100 300 : } else if (_this->set_fraction > _this->key.vals[_this->key.count - 1]) {
101 0 : for (i=0; i<numElemPerKey; i++)
102 0 : _this->value_changed.vals[i] = _this->keyValue.vals[(_this->keyValue.count) - numElemPerKey + i];
103 : } else {
104 265 : for (j = 1; j < _this->key.count; j++) {
105 : // Find the key values the fraction lies between
106 562 : if ( _this->set_fraction < _this->key.vals[j-1]) continue;
107 562 : if (_this->set_fraction >= _this->key.vals[j]) continue;
108 :
109 : frac = GetInterpolateFraction(_this->key.vals[j-1], _this->key.vals[j], _this->set_fraction);
110 1483 : for (i=0; i<numElemPerKey; i++) {
111 2372 : _this->value_changed.vals[i].x = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].x,
112 1186 : _this->keyValue.vals[(j)*numElemPerKey + i].x,
113 : frac);
114 2372 : _this->value_changed.vals[i].y = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].y,
115 1186 : _this->keyValue.vals[(j)*numElemPerKey + i].y,
116 : frac);
117 : }
118 : break;
119 : }
120 : }
121 : //invalidate
122 300 : gf_node_event_out(n, 3);//"value_changed"
123 : }
124 :
125 2 : Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node)
126 : {
127 2 : node->on_set_fraction = CI2D_SetFraction;
128 :
129 2 : if (node->key.count && !(node->keyValue.count % node->key.count) ) {
130 : u32 numElemPerKey, i;
131 2 : numElemPerKey = node->keyValue.count / node->key.count;
132 2 : gf_sg_vrml_mf_alloc(&node->value_changed, GF_SG_VRML_MFVEC2F, numElemPerKey);
133 10 : for (i=0; i<numElemPerKey; i++)
134 8 : node->value_changed.vals[i] = node->keyValue.vals[i];
135 : }
136 2 : return 1;
137 : }
138 :
139 302 : static Bool CI_SetFraction(Fixed fraction, MFVec3f *vals, MFFloat *key, MFVec3f *keyValue)
140 : {
141 : Fixed frac;
142 : u32 numElemPerKey, i, j;
143 :
144 302 : if (! key->count) return 0;
145 302 : if (keyValue->count % key->count) return 0;
146 :
147 302 : numElemPerKey = keyValue->count / key->count;
148 :
149 302 : if (vals->count != numElemPerKey) gf_sg_vrml_mf_alloc(vals, GF_SG_VRML_MFVEC3F, numElemPerKey);
150 :
151 302 : if (fraction < key->vals[0]) {
152 0 : for (i=0; i<numElemPerKey; i++)
153 0 : vals->vals[i] = keyValue->vals[i];
154 302 : } else if (fraction > key->vals[key->count - 1]) {
155 0 : for (i=0; i<numElemPerKey; i++)
156 0 : vals->vals[i] = keyValue->vals[(keyValue->count) - numElemPerKey + i];
157 : } else {
158 0 : for (j = 1; j < key->count; j++) {
159 : // Find the key values the fraction lies between
160 302 : if (fraction < key->vals[j-1]) continue;
161 302 : if (fraction >= key->vals[j]) continue;
162 :
163 : frac = GetInterpolateFraction(key->vals[j-1], key->vals[j], fraction);
164 906 : for (i=0; i<numElemPerKey; i++) {
165 1208 : vals->vals[i].x = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].x,
166 604 : keyValue->vals[(j)*numElemPerKey + i].x,
167 : frac);
168 1208 : vals->vals[i].y = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].y,
169 604 : keyValue->vals[(j)*numElemPerKey + i].y,
170 : frac);
171 1208 : vals->vals[i].z = Interpolate(keyValue->vals[(j-1)*numElemPerKey + i].z,
172 604 : keyValue->vals[(j)*numElemPerKey + i].z,
173 : frac);
174 : }
175 : break;
176 : }
177 : }
178 : return 1;
179 : }
180 :
181 :
182 150 : static void CoordInt_SetFraction(GF_Node *n, GF_Route *route)
183 : {
184 : M_CoordinateInterpolator *_this = (M_CoordinateInterpolator *) n;
185 :
186 150 : if (CI_SetFraction(_this->set_fraction, &_this->value_changed, &_this->key, &_this->keyValue))
187 150 : gf_node_event_out(n, 3);//"value_changed"
188 150 : }
189 :
190 1 : Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n)
191 : {
192 1 : n->on_set_fraction = CoordInt_SetFraction;
193 1 : CI_SetFraction(0, &n->value_changed, &n->key, &n->keyValue);
194 1 : return 1;
195 : }
196 :
197 150 : static void NormInt_SetFraction(GF_Node *n, GF_Route *route)
198 : {
199 : u32 i;
200 : M_NormalInterpolator *_this = (M_NormalInterpolator *) n;
201 :
202 150 : if (!CI_SetFraction(_this->set_fraction, &_this->value_changed, &_this->key, &_this->keyValue)) return;
203 : /*renorm*/
204 300 : for (i=0; i<_this->value_changed.count; i++) {
205 300 : gf_vec_norm(&_this->value_changed.vals[i]);
206 : }
207 150 : gf_node_event_out(n, 3);//"value_changed"
208 : }
209 :
210 1 : Bool InitNormalInterpolator(M_NormalInterpolator *n)
211 : {
212 1 : n->on_set_fraction = NormInt_SetFraction;
213 1 : CI_SetFraction(0, &n->value_changed, &n->key, &n->keyValue);
214 1 : return 1;
215 : }
216 :
217 755 : static void ColorInt_SetFraction(GF_Node *node, GF_Route *route)
218 : {
219 : u32 i;
220 : Fixed frac;
221 : M_ColorInterpolator *_this = (M_ColorInterpolator *)node;
222 :
223 :
224 755 : if (! _this->key.count) return;
225 755 : if (_this->keyValue.count != _this->key.count) return;
226 :
227 : // The given fraction is less than the specified range
228 755 : if (_this->set_fraction < _this->key.vals[0]) {
229 0 : _this->value_changed = _this->keyValue.vals[0];
230 755 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
231 8 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
232 : } else {
233 225 : for (i=1; i<_this->key.count; i++) {
234 : // Find the key values the fraction lies between
235 972 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
236 972 : if (_this->set_fraction >= _this->key.vals[i]) continue;
237 :
238 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
239 1494 : _this->value_changed.red = Interpolate(_this->keyValue.vals[i-1].red,
240 747 : _this->keyValue.vals[i].red,
241 : frac);
242 1494 : _this->value_changed.green = Interpolate(_this->keyValue.vals[i-1].green,
243 : _this->keyValue.vals[i].green,
244 : frac);
245 1494 : _this->value_changed.blue = Interpolate(_this->keyValue.vals[i-1].blue,
246 : _this->keyValue.vals[i].blue,
247 : frac);
248 747 : break;
249 : }
250 : }
251 755 : gf_node_event_out(node, 3);//"value_changed"
252 : }
253 :
254 6 : Bool InitColorInterpolator(M_ColorInterpolator *node)
255 : {
256 6 : node->on_set_fraction = ColorInt_SetFraction;
257 6 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
258 6 : return 1;
259 : }
260 :
261 :
262 5836 : static void PosInt2D_SetFraction(GF_Node *node, GF_Route *route)
263 : {
264 : M_PositionInterpolator2D *_this = (M_PositionInterpolator2D *)node;
265 : u32 i;
266 : Fixed frac;
267 :
268 5836 : if (! _this->key.count) return;
269 5836 : if (_this->keyValue.count != _this->key.count) return;
270 :
271 : // The given fraction is less than the specified range
272 5836 : if (_this->set_fraction < _this->key.vals[0]) {
273 0 : _this->value_changed = _this->keyValue.vals[0];
274 5836 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
275 57 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
276 : } else {
277 2291 : for (i=1; i<_this->key.count; i++) {
278 : // Find the key values the fraction lies between
279 8070 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
280 8070 : if (_this->set_fraction >= _this->key.vals[i]) continue;
281 :
282 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
283 11558 : _this->value_changed.x = Interpolate(_this->keyValue.vals[i-1].x, _this->keyValue.vals[i].x, frac);
284 11558 : _this->value_changed.y = Interpolate(_this->keyValue.vals[i-1].y, _this->keyValue.vals[i].y, frac);
285 5779 : break;
286 : }
287 : }
288 5836 : gf_node_event_out(node, 3);//"value_changed"
289 : }
290 :
291 408 : Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node)
292 : {
293 408 : node->on_set_fraction = PosInt2D_SetFraction;
294 408 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
295 408 : return 1;
296 : }
297 :
298 1427 : static void PosInt_SetFraction(GF_Node *node, GF_Route *route)
299 : {
300 : u32 i;
301 : Fixed frac;
302 : M_PositionInterpolator *_this = (M_PositionInterpolator *)node;
303 :
304 1427 : if (! _this->key.count) return;
305 1427 : if (_this->keyValue.count != _this->key.count) return;
306 :
307 : // The given fraction is less than the specified range
308 1427 : if (_this->set_fraction < _this->key.vals[0]) {
309 0 : _this->value_changed = _this->keyValue.vals[0];
310 1427 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
311 9 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
312 : } else {
313 809 : for (i=1; i<_this->key.count; i++) {
314 : // Find the key values the fraction lies between
315 2227 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
316 2227 : if (_this->set_fraction >= _this->key.vals[i]) continue;
317 :
318 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
319 2836 : _this->value_changed.x = Interpolate(_this->keyValue.vals[i-1].x, _this->keyValue.vals[i].x, frac);
320 2836 : _this->value_changed.y = Interpolate(_this->keyValue.vals[i-1].y, _this->keyValue.vals[i].y, frac);
321 2836 : _this->value_changed.z = Interpolate(_this->keyValue.vals[i-1].z, _this->keyValue.vals[i].z, frac);
322 1418 : break;
323 : }
324 : }
325 1427 : gf_node_event_out(node, 3);//"value_changed"
326 : }
327 :
328 11 : Bool InitPositionInterpolator(M_PositionInterpolator *node)
329 : {
330 11 : node->on_set_fraction = PosInt_SetFraction;
331 11 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
332 11 : return 1;
333 : }
334 :
335 6149 : static void ScalarInt_SetFraction(GF_Node *node, GF_Route *route)
336 : {
337 : M_ScalarInterpolator *_this = (M_ScalarInterpolator *)node;
338 : u32 i;
339 : Fixed frac;
340 :
341 6149 : if (! _this->key.count) return;
342 6149 : if (_this->keyValue.count != _this->key.count) return;
343 :
344 : // The given fraction is less than the specified range
345 6149 : if (_this->set_fraction < _this->key.vals[0]) {
346 0 : _this->value_changed = _this->keyValue.vals[0];
347 6149 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
348 59 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
349 : } else {
350 2422 : for (i=1; i<_this->key.count; i++) {
351 : // Find the key values the fraction lies between
352 8512 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
353 8512 : if (_this->set_fraction >= _this->key.vals[i]) continue;
354 :
355 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
356 12180 : _this->value_changed = Interpolate(_this->keyValue.vals[i-1], _this->keyValue.vals[i], frac);
357 6090 : break;
358 : }
359 : }
360 6149 : gf_node_event_out(node, 3);//"value_changed"
361 : }
362 68 : Bool InitScalarInterpolator(M_ScalarInterpolator *node)
363 : {
364 68 : node->on_set_fraction = ScalarInt_SetFraction;
365 68 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
366 68 : return 1;
367 : }
368 :
369 :
370 2283 : static void OrientInt_SetFraction(GF_Node *node, GF_Route *route)
371 : {
372 : u32 i;
373 : Fixed frac;
374 : M_OrientationInterpolator *_this = (M_OrientationInterpolator *)node;
375 :
376 2283 : if (! _this->key.count) return;
377 2283 : if (_this->keyValue.count != _this->key.count) return;
378 :
379 : // The given fraction is less than the specified range
380 2283 : if (_this->set_fraction < _this->key.vals[0]) {
381 0 : _this->value_changed = _this->keyValue.vals[0];
382 2283 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
383 23 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
384 : } else {
385 1119 : for (i=1; i<_this->key.count; i++) {
386 : // Find the key values the fraction lies between
387 3379 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
388 3379 : if (_this->set_fraction >= _this->key.vals[i]) continue;
389 :
390 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
391 2260 : _this->value_changed = gf_sg_sfrotation_interpolate(_this->keyValue.vals[i-1], _this->keyValue.vals[i], frac);
392 2260 : break;
393 : }
394 : }
395 2283 : gf_node_event_out(node, 3);//"value_changed"
396 : }
397 :
398 18 : Bool InitOrientationInterpolator(M_OrientationInterpolator *node)
399 : {
400 18 : node->on_set_fraction = OrientInt_SetFraction;
401 18 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
402 18 : return 1;
403 : }
404 :
405 150 : static void CI4D_SetFraction(GF_Node *n, GF_Route *route)
406 : {
407 : Fixed frac;
408 : u32 numElemPerKey, i, j;
409 : M_CoordinateInterpolator4D *_this = (M_CoordinateInterpolator4D *) n;
410 :
411 150 : if (! _this->key.count) return;
412 150 : if (_this->keyValue.count % _this->key.count) return;
413 :
414 150 : numElemPerKey = _this->keyValue.count / _this->key.count;
415 : //set size
416 150 : if (_this->value_changed.count != numElemPerKey)
417 0 : gf_sg_vrml_mf_alloc(&_this->value_changed, GF_SG_VRML_MFVEC4F, numElemPerKey);
418 :
419 :
420 150 : if (_this->set_fraction < _this->key.vals[0]) {
421 0 : for (i=0; i<numElemPerKey; i++)
422 0 : _this->value_changed.vals[i] = _this->keyValue.vals[i];
423 150 : } else if (_this->set_fraction > _this->key.vals[_this->key.count - 1]) {
424 0 : for (i=0; i<numElemPerKey; i++)
425 0 : _this->value_changed.vals[i] = _this->keyValue.vals[(_this->keyValue.count) - numElemPerKey + i];
426 : } else {
427 0 : for (j = 1; j < _this->key.count; j++) {
428 : // Find the key values the fraction lies between
429 150 : if ( _this->set_fraction < _this->key.vals[j-1]) continue;
430 150 : if (_this->set_fraction >= _this->key.vals[j]) continue;
431 :
432 : frac = GetInterpolateFraction(_this->key.vals[j-1], _this->key.vals[j], _this->set_fraction);
433 450 : for (i=0; i<numElemPerKey; i++) {
434 600 : _this->value_changed.vals[i].x = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].x,
435 300 : _this->keyValue.vals[(j)*numElemPerKey + i].x,
436 : frac);
437 600 : _this->value_changed.vals[i].y = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].y,
438 300 : _this->keyValue.vals[(j)*numElemPerKey + i].y,
439 : frac);
440 600 : _this->value_changed.vals[i].z = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].z,
441 300 : _this->keyValue.vals[(j)*numElemPerKey + i].z,
442 : frac);
443 600 : _this->value_changed.vals[i].q = Interpolate(_this->keyValue.vals[(j-1)*numElemPerKey + i].q,
444 300 : _this->keyValue.vals[(j)*numElemPerKey + i].q,
445 : frac);
446 : }
447 : break;
448 : }
449 : }
450 : //invalidate
451 150 : gf_node_event_out(n, 3);//"value_changed"
452 : }
453 :
454 1 : Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node)
455 : {
456 1 : node->on_set_fraction = CI4D_SetFraction;
457 :
458 1 : if (node->key.count && !(node->keyValue.count % node->key.count)) {
459 1 : u32 i, numElemPerKey = node->keyValue.count / node->key.count;
460 1 : gf_sg_vrml_mf_alloc(&node->value_changed, GF_SG_VRML_MFVEC4F, numElemPerKey);
461 3 : for (i=0; i<numElemPerKey; i++)
462 2 : node->value_changed.vals[i] = node->keyValue.vals[i];
463 : }
464 1 : return 1;
465 : }
466 :
467 150 : static void PI4D_SetFraction(GF_Node *node, GF_Route *route)
468 : {
469 : u32 i;
470 : Fixed frac;
471 : M_PositionInterpolator4D *_this = (M_PositionInterpolator4D *)node;
472 :
473 150 : if (! _this->key.count) return;
474 150 : if (_this->keyValue.count != _this->key.count) return;
475 :
476 : // The given fraction is less than the specified range
477 150 : if (_this->set_fraction < _this->key.vals[0]) {
478 0 : _this->value_changed = _this->keyValue.vals[0];
479 150 : } else if (_this->set_fraction >= _this->key.vals[_this->key.count-1]) {
480 0 : _this->value_changed = _this->keyValue.vals[_this->keyValue.count-1];
481 : } else {
482 0 : for (i=1; i<_this->key.count; i++) {
483 : // Find the key values the fraction lies between
484 150 : if (_this->set_fraction < _this->key.vals[i-1]) continue;
485 150 : if (_this->set_fraction >= _this->key.vals[i]) continue;
486 :
487 : frac = GetInterpolateFraction(_this->key.vals[i-1], _this->key.vals[i], _this->set_fraction);
488 300 : _this->value_changed.x = Interpolate(_this->keyValue.vals[i-1].x, _this->keyValue.vals[i].x, frac);
489 300 : _this->value_changed.y = Interpolate(_this->keyValue.vals[i-1].y, _this->keyValue.vals[i].y, frac);
490 300 : _this->value_changed.z = Interpolate(_this->keyValue.vals[i-1].z, _this->keyValue.vals[i].z, frac);
491 300 : _this->value_changed.q = Interpolate(_this->keyValue.vals[i-1].q, _this->keyValue.vals[i].q, frac);
492 150 : break;
493 : }
494 : }
495 150 : gf_node_event_out(node, 3);//"value_changed"
496 : }
497 :
498 1 : Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node)
499 : {
500 1 : node->on_set_fraction = PI4D_SetFraction;
501 1 : if (node->keyValue.count) node->value_changed = node->keyValue.vals[0];
502 1 : return 1;
503 : }
504 :
505 :
506 :
507 : #ifndef GPAC_DISABLE_X3D
508 :
509 0 : static void BooleanFilter_setValue(GF_Node *n, GF_Route *route)
510 : {
511 : X_BooleanFilter *bf = (X_BooleanFilter *)n;
512 0 : if (!bf->set_boolean) {
513 0 : bf->inputFalse = 1;
514 0 : gf_node_event_out(n, 1/*"inputFalse"*/);
515 : }
516 0 : if (bf->set_boolean) {
517 0 : bf->inputTrue = 1;
518 0 : gf_node_event_out(n, 3/*"inputTrue"*/);
519 : }
520 0 : bf->inputNegate = bf->set_boolean ? 0 : 1;
521 0 : gf_node_event_out(n, 2/*"inputNegate"*/);
522 0 : }
523 :
524 1 : void InitBooleanFilter(GF_Node *n)
525 : {
526 : X_BooleanFilter *bf = (X_BooleanFilter *)n;
527 1 : bf->on_set_boolean = BooleanFilter_setValue;
528 1 : }
529 :
530 0 : static void BooleanSequencer_setFraction(GF_Node *n, GF_Route *route)
531 : {
532 : u32 i;
533 : X_BooleanSequencer *bs = (X_BooleanSequencer*)n;
534 0 : if (! bs->key.count) return;
535 0 : if (bs->keyValue.count != bs->key.count) return;
536 :
537 0 : if (bs->set_fraction < bs->key.vals[0]) {
538 0 : bs->value_changed = bs->keyValue.vals[0];
539 0 : } else if (bs->set_fraction >= bs->key.vals[bs->key.count-1]) {
540 0 : bs->value_changed = bs->keyValue.vals[bs->keyValue.count-1];
541 : } else {
542 0 : for (i=1; i<bs->key.count; i++) {
543 0 : if (bs->set_fraction < bs->key.vals[i-1]) continue;
544 0 : if (bs->set_fraction >= bs->key.vals[i]) continue;
545 0 : bs->value_changed = bs->keyValue.vals[i-1];
546 0 : break;
547 : }
548 : }
549 0 : gf_node_event_out(n, 3);//"value_changed"
550 : }
551 :
552 0 : static void BooleanSequencer_setNext(GF_Node *n, GF_Route *route)
553 : {
554 : s32 *prev_val, val;
555 : X_BooleanSequencer *bs = (X_BooleanSequencer*)n;
556 0 : if (!bs->next) return;
557 :
558 0 : prev_val = (s32 *)n->sgprivate->UserPrivate;
559 0 : val = (*prev_val + 1) % bs->keyValue.count;
560 0 : *prev_val = val;
561 0 : bs->value_changed = bs->keyValue.vals[val];
562 0 : gf_node_event_out(n, 3);//"value_changed"
563 : }
564 :
565 0 : static void BooleanSequencer_setPrevious(GF_Node *n, GF_Route *route)
566 : {
567 : s32 *prev_val, val;
568 : X_BooleanSequencer *bs = (X_BooleanSequencer*)n;
569 0 : if (!bs->previous) return;
570 :
571 0 : prev_val = (s32 *)n->sgprivate->UserPrivate;
572 0 : val = (*prev_val - 1);
573 0 : if (val<0) val += bs->keyValue.count;
574 0 : val %= bs->keyValue.count;
575 0 : *prev_val = val;
576 0 : bs->value_changed = bs->keyValue.vals[val];
577 0 : gf_node_event_out(n, 3);//"value_changed"
578 : }
579 155 : static void DestroyBooleanSequencer(GF_Node *n, void *eff, Bool is_destroy)
580 : {
581 155 : if (is_destroy) {
582 1 : s32 *st = (s32 *) gf_node_get_private(n);
583 1 : gf_free(st);
584 : }
585 155 : }
586 1 : void InitBooleanSequencer(GF_Node *n)
587 : {
588 : X_BooleanSequencer *bs = (X_BooleanSequencer*)n;
589 1 : bs->on_next = BooleanSequencer_setNext;
590 1 : bs->on_previous = BooleanSequencer_setPrevious;
591 1 : bs->on_set_fraction = BooleanSequencer_setFraction;
592 1 : n->sgprivate->UserPrivate = gf_malloc(sizeof(s32));
593 1 : *(s32 *)n->sgprivate->UserPrivate = 0;
594 1 : n->sgprivate->UserCallback = DestroyBooleanSequencer;
595 1 : }
596 :
597 0 : static void BooleanToggle_setValue(GF_Node *n, GF_Route *route)
598 : {
599 : X_BooleanToggle *bt = (X_BooleanToggle *)n;
600 0 : if (bt->set_boolean) {
601 0 : bt->toggle = !bt->toggle;
602 0 : gf_node_event_out(n, 1/*"toggle"*/);
603 : }
604 0 : }
605 1 : void InitBooleanToggle(GF_Node *n)
606 : {
607 : X_BooleanToggle *bt = (X_BooleanToggle *)n;
608 1 : bt->on_set_boolean = BooleanToggle_setValue;
609 1 : }
610 :
611 0 : static void BooleanTrigger_setTime(GF_Node *n, GF_Route *route)
612 : {
613 : X_BooleanTrigger *bt = (X_BooleanTrigger *)n;
614 0 : bt->triggerTrue = 1;
615 0 : gf_node_event_out(n, 1/*"triggerTrue"*/);
616 0 : }
617 1 : void InitBooleanTrigger(GF_Node *n)
618 : {
619 : X_BooleanTrigger *bt = (X_BooleanTrigger *)n;
620 1 : bt->on_set_triggerTime = BooleanTrigger_setTime;
621 1 : }
622 :
623 0 : static void IntegerSequencer_setFraction(GF_Node *n, GF_Route *route)
624 : {
625 : u32 i;
626 : X_IntegerSequencer *is = (X_IntegerSequencer *)n;
627 0 : if (! is->key.count) return;
628 0 : if (is->keyValue.count != is->key.count) return;
629 :
630 0 : if (is->set_fraction < is->key.vals[0]) {
631 0 : is->value_changed = is->keyValue.vals[0];
632 0 : } else if (is->set_fraction >= is->key.vals[is->key.count-1]) {
633 0 : is->value_changed = is->keyValue.vals[is->keyValue.count-1];
634 : } else {
635 0 : for (i=1; i<is->key.count; i++) {
636 0 : if (is->set_fraction < is->key.vals[i-1]) continue;
637 0 : if (is->set_fraction >= is->key.vals[i]) continue;
638 0 : is->value_changed = is->keyValue.vals[i-1];
639 0 : break;
640 : }
641 : }
642 0 : gf_node_event_out(n, 3);//"value_changed"
643 : }
644 :
645 0 : static void IntegerSequencer_setNext(GF_Node *n, GF_Route *route)
646 : {
647 : s32 *prev_val, val;
648 : X_IntegerSequencer *is = (X_IntegerSequencer*)n;
649 0 : if (!is->next) return;
650 :
651 0 : prev_val = (s32 *)n->sgprivate->UserPrivate;
652 0 : val = (*prev_val + 1) % is->keyValue.count;
653 0 : *prev_val = val;
654 0 : is->value_changed = is->keyValue.vals[val];
655 0 : gf_node_event_out(n, 3);//"value_changed"
656 : }
657 :
658 0 : static void IntegerSequencer_setPrevious(GF_Node *n, GF_Route *route)
659 : {
660 : s32 *prev_val, val;
661 : X_IntegerSequencer *is = (X_IntegerSequencer *)n;
662 0 : if (!is->previous) return;
663 :
664 0 : prev_val = (s32 *)n->sgprivate->UserPrivate;
665 0 : val = (*prev_val - 1);
666 0 : if (val<0) val += is->keyValue.count;
667 0 : val %= is->keyValue.count;
668 0 : *prev_val = val;
669 0 : is->value_changed = is->keyValue.vals[val];
670 0 : gf_node_event_out(n, 3);//"value_changed"
671 : }
672 155 : static void DestroyIntegerSequencer(GF_Node *n, void *eff, Bool is_destroy)
673 : {
674 155 : if (is_destroy) {
675 1 : s32 *st = (s32 *)gf_node_get_private(n);
676 1 : gf_free(st);
677 : }
678 155 : }
679 1 : void InitIntegerSequencer(GF_Node *n)
680 : {
681 : X_IntegerSequencer *bs = (X_IntegerSequencer *)n;
682 1 : bs->on_next = IntegerSequencer_setNext;
683 1 : bs->on_previous = IntegerSequencer_setPrevious;
684 1 : bs->on_set_fraction = IntegerSequencer_setFraction;
685 1 : n->sgprivate->UserPrivate = gf_malloc(sizeof(s32));
686 1 : *(s32 *)n->sgprivate->UserPrivate = 0;
687 1 : n->sgprivate->UserCallback = DestroyIntegerSequencer;
688 1 : }
689 :
690 0 : static void IntegerTrigger_setTrigger(GF_Node *n, GF_Route *route)
691 : {
692 : X_IntegerTrigger *it = (X_IntegerTrigger *)n;
693 0 : if (it->set_boolean) {
694 0 : it->triggerValue = it->integerKey;
695 0 : gf_node_event_out(n, 2/*"triggerValue"*/);
696 : }
697 0 : }
698 1 : void InitIntegerTrigger(GF_Node *n)
699 : {
700 : X_IntegerTrigger *it = (X_IntegerTrigger *)n;
701 1 : it->on_set_boolean = IntegerTrigger_setTrigger;
702 1 : }
703 :
704 0 : static void TimeTrigger_setTrigger(GF_Node *n, GF_Route *route)
705 : {
706 : X_TimeTrigger *tt = (X_TimeTrigger *)n;
707 0 : tt->triggerTime = gf_node_get_scene_time(n);
708 0 : gf_node_event_out(n, 1/*"triggerTime"*/);
709 0 : }
710 1 : void InitTimeTrigger(GF_Node *n)
711 : {
712 : X_TimeTrigger *tt = (X_TimeTrigger*)n;
713 1 : tt->on_set_boolean = TimeTrigger_setTrigger;
714 1 : }
715 :
716 : #endif /*GPAC_DISABLE_X3D*/
717 :
718 :
719 : #endif /*GPAC_DISABLE_VRML*/
|