LCOV - code coverage report
Current view: top level - scenegraph - vrml_interpolators.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 249 364 68.4 %
Date: 2021-04-29 23:48:07 Functions: 31 42 73.8 %

          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*/

Generated by: LCOV version 1.13