1 /*
2  * Interpolator.cpp
3  *
4  * Copyright (C) 1999 Stephen F. White
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 #include "stdafx.h"
23 
24 #include "Interpolator.h"
25 #include "FieldValue.h"
26 #include "MFFloat.h"
27 #include "Scene.h"
28 #include "MFieldCommand.h"
29 #include "FieldCommand.h"
30 #include "CommandList.h"
31 #include "InputDeviceTime.h"
32 #include "Field.h"
33 #include "swt.h"
34 #include "NodeCurveAnimation.h"
35 #include "NodeTimeSensor.h"
36 
ProtoInterpolator(Scene * scene,const char * name,int keyType,int keysType,FieldValue * defaultValue)37 ProtoInterpolator::ProtoInterpolator(Scene *scene, const char *name,
38                                      int keyType, int keysType,
39                                      FieldValue *defaultValue)
40   : WonderlandExportProto(scene, name)
41 {
42     addEventIn(SFFLOAT, "set_fraction", EIF_RECOMMENDED);
43     key.set(addExposedField(MFFLOAT, "key", new MFFloat()));
44     keyValue.set(addExposedField(keysType, "keyValue", defaultValue));
45     addEventOut(keyType, "value_changed", EOF_RECOMMENDED);
46 }
47 
Interpolator(Scene * scene,Proto * def)48 Interpolator::Interpolator(Scene *scene, Proto *def)
49   : Node(scene, def)
50 {
51     m_fraction = 0.0f;
52     m_oldRecordedFraction = 1.0f;
53     m_set_fractionField.set(getProto()->lookupEventIn("set_fraction"));
54     m_keyField.set(((ProtoInterpolator *)def)->key);
55     m_keyValueField.set(((ProtoInterpolator *)def)->keyValue);
56     m_value_changedField.set(getProto()->lookupEventOut("value_changed"));
57 }
58 
59 int
getNumKeys() const60 Interpolator::getNumKeys() const
61 {
62     MFFloat *key = (MFFloat *) getField(m_keyField);
63 
64     return key->getSize();
65 }
66 
67 float
getKey(int index) const68 Interpolator::getKey(int index) const
69 {
70     MFFloat *key = (MFFloat *) getField(m_keyField);
71     if (index < key->getSize()) {
72         return key->getValue(index);
73     } else {
74         return 0.0f;
75     }
76 }
77 
78 float
getKeyValue(int channel,int index) const79 Interpolator::getKeyValue(int channel, int index) const
80 {
81     MFFloat *keyValue = (MFFloat *) getField(m_keyValueField);
82     int i = index * getNumChannels() + channel;
83     if (i < keyValue->getSize()) {
84         return keyValue->getValue(i);
85     } else {
86         return 0.0f;
87     }
88 }
89 
90 void
setKey(int index,float value)91 Interpolator::setKey(int index, float value)
92 {
93     MFFloat *key = (MFFloat *) getField(m_keyField);
94 
95     key->setValue(index, value);
96     m_scene->OnFieldChange(this, m_keyField, index);
97 }
98 
99 void
setKeyValue(int channel,int index,float value)100 Interpolator::setKeyValue(int channel, int index, float value)
101 {
102     MFFloat *keyValue = (MFFloat *) getField(m_keyValueField);
103 
104     keyValue->setValue(index * getNumChannels() + channel, value);
105     m_scene->OnFieldChange(this, m_keyValueField, index);
106 }
107 
108 
109 void
backupKey(int index)110 Interpolator::backupKey(int index)
111 {
112     CommandList *list = new CommandList();
113 
114     list->append(new MFieldCommand(this, m_keyField, index));
115     list->append(new MFieldCommand(this, m_keyValueField, index));
116     m_scene->add(list);
117 }
118 
119 void
backup(CommandList * list)120 Interpolator::backup(CommandList *list)
121 {
122     int pos = findKeyInclusive(m_fraction);
123 
124     if ((getNumKeys() > 0) && (pos > -1) && (pos != getNumKeys())) {
125         list->append(new MFieldCommand(this, m_keyField, pos));
126         list->append(new MFieldCommand(this, m_keyValueField, pos));
127     }
128     list->append(new FieldCommand(this, m_keyField));
129     list->append(new FieldCommand(this, m_keyValueField));
130 }
131 
132 //
133 // findKey() - return the closest key stricty greater than the given value,
134 //             or n if none found
135 //
136 
137 int
findKey(float value) const138 Interpolator::findKey(float value) const
139 {
140     MFFloat *key = (MFFloat *) getField(m_keyField);
141     int i, numKeys = key->getSize();
142 
143     for (i = 0; i < numKeys; i++) {
144         float k = key->getValue(i);
145         if (k > value) {
146            break;
147         }
148         if (k >= 1.0) {
149            break;
150         }
151     }
152     return i;
153 }
154 
155 //
156 // findLessKey() - return the closest key stricty less than the given value,
157 //                 or n if none found
158 //
159 
160 int
findLessKey(float value) const161 Interpolator::findLessKey(float value) const
162 {
163     MFFloat *key = (MFFloat *) getField(m_keyField);
164     int i, numKeys = key->getSize();
165 
166     for (i = 0; i < numKeys; i++) {
167         float k = key->getValue(i);
168         if (k >= value) {
169             return i - 1;
170         }
171         if (k >= 1.0) {
172            break;
173         }
174     }
175     return i;
176 }
177 
178 //
179 // findKeyInclusive() - return the closest key greater than or equal to
180 //                      the given value, or numKeys if none found
181 //
182 
183 int
findKeyInclusive(float value) const184 Interpolator::findKeyInclusive(float value) const
185 {
186     MFFloat *key = (MFFloat *) getField(m_keyField);
187     int numKeys = key->getSize();
188     int i = numKeys;
189 
190     for (i = 0; i < numKeys; i++) {
191         float k = key->getValue(i);
192         if (k >= value) break;
193     }
194     return i;
195 }
196 
197 //
198 // findKeyExclusive() - return the closest key greater than given value,
199 //                      or numKeys+1 if none found
200 
201 int
findKeyExclusive(float value) const202 Interpolator::findKeyExclusive(float value) const
203 {
204     MFFloat *key = (MFFloat *) getField(m_keyField);
205     int i, numKeys = key->getSize();
206 
207     for (i = 0; i < numKeys; i++) {
208         float k = key->getValue(i);
209         if (k > value) return(i);
210     }
211     return numKeys+1;
212 }
213 
214 
215 bool
getNearestKeys(float k,float * k1,float * k2,int * pos1,int * pos2)216 Interpolator::getNearestKeys(float k, float *k1, float *k2, int *pos1, int *pos2)
217 {
218     MFFloat *key = (MFFloat *) getField(m_keyField);
219     int numKeys = key->getSize();
220 
221     if (numKeys == 0) {
222         return false;
223     }
224 
225     int pos = findKey(k);
226 
227     if (pos == 0) {
228         *k1 = 0.0f;
229         *pos1 = 0;
230     } else {
231         *k1 = key->getValue(pos - 1);
232         *pos1 = pos - 1;
233     }
234 
235     if (pos == numKeys) {
236         *k2 = 1.0f;
237         *pos2 = numKeys-1;
238     } else {
239         *k2 = key->getValue(pos);
240         *pos2 = pos;
241     }
242     return true;
243 }
244 
245 void
receiveEvent(int eventIn,double timestamp,FieldValue * value)246 Interpolator::receiveEvent(int eventIn, double timestamp, FieldValue *value)
247 {
248     if (eventIn == m_set_fractionField) {
249         float fraction=((SFFloat *) value)->getValue();
250         sendInterpolatedEvent(timestamp, fraction);
251     } else
252         Node::receiveEvent(eventIn, timestamp, value);
253 }
254 
255 FieldValue *
getInterpolatedFieldValue(float k)256 Interpolator::getInterpolatedFieldValue(float k)
257 {
258     m_fraction = k;
259     float *values = new float[getNumChannels()];
260     interpolate(k, values);
261     FieldValue *val = createKey(values);
262     val->ref();
263     return val;
264 }
265 
266 void
sendInterpolatedEvent(double timestamp,float k)267 Interpolator::sendInterpolatedEvent(double timestamp, float k)
268 {
269     sendEvent(m_value_changedField, timestamp, getInterpolatedFieldValue(k));
270 }
271 
272 void
sendInterpolatedValue(double timestamp,float k)273 Interpolator::sendInterpolatedValue(double timestamp, float k)
274 {
275     sendInterpolatedEvent(timestamp,k);
276     // send same values to all Interpolators driven by the same EventIn
277     int eventInField = lookupEventIn("set_fraction", false);
278     if (eventInField == INVALID_INDEX) {
279        swDebugf("Problem: Interpolater without set_fraction ???\n");
280        return;
281     }
282     // for all EventIn's
283     SocketList::Iterator* in;
284     for (in = m_inputs[eventInField].first(); in != NULL; in = in->next()) {
285        Node *eventInSrcNode = in->item().getNode();
286        int eventInSrcEventOutIndex = in->item().getField();
287        // for all EventOuts of Node of EventIn
288        SocketList::Iterator* out;
289        for (out = eventInSrcNode->getOutput(eventInSrcEventOutIndex).first();
290             out != NULL; out = out->next())
291            if (out->item().getNode() != this) {
292                // is node a Interpolator ?
293                Node *node = out->item().getNode();
294                Interpolator* Inod = dynamic_cast_Interpolator(node);
295                if (Inod != NULL)
296                    Inod->sendInterpolatedEvent(timestamp, k);
297                else if (node->getType() == DUNE_CURVE_ANIMATION) {
298                    NodeCurveAnimation *curve = (NodeCurveAnimation *)node;
299                    int eventIn = curve->getFraction_Field();
300                    SFFloat *fraction = new SFFloat(k);
301                    curve->receiveEvent(eventIn, k, fraction);
302                }
303            }
304     }
305 }
306 
307 void
interpolate(float key,float * values)308 Interpolator::interpolate(float key, float *values)
309 {
310     MFFloat *keyValue = (MFFloat *) getField(m_keyValueField);
311     int numChannels = getNumChannels();
312 
313     float key1 = 0.0;
314     float key2 = 1.0;
315     int   pos1 = 0;
316     int   pos2 = 0;
317 
318     if (keyValue->getSize() == 0) {
319         for (int i = 0; i < numChannels; i++) {
320             values[i] = 0.0f;
321         }
322         return;
323     }
324 
325     getNearestKeys(key, &key1, &key2, &pos1, &pos2);
326 
327     const float *value = keyValue->getValues();
328 
329     float alpha;
330 
331     if (key1 == key2) {
332         alpha = 0.0;
333     } else {
334         alpha = (key - key1) / (key2 - key1);
335     }
336 
337     for (int i = 0; i < numChannels; i++) {
338         float val1 = value[pos1 * numChannels + i];
339         float val2 = value[pos2 * numChannels + i];
340         values[i] = val1 + (val2 - val1) * alpha;
341     }
342 }
343 
344 void
insertKey(int pos,float key,const float * values,int numValues)345 Interpolator::insertKey(int pos, float key, const float *values, int numValues)
346 {
347     MFFloat *keys = (MFFloat *) getField(m_keyField);
348     MFFloat *keyValues = (MFFloat *) getField(m_keyValueField);
349     int numKeys = keys->getSize();
350     int numChannels = numValues;
351 
352     keys->insertSFValue(pos, key);
353     #pragma omp for
354     for (int j = 0; j < numChannels; j++)
355          if (values == NULL)
356              keyValues->insertSFValue(pos * numChannels + j, 0.0f);
357          else
358              keyValues->insertSFValue(pos * numChannels + j, values[j]);
359 }
360 
361 void
insertKey(int pos,float key,const float * values)362 Interpolator::insertKey(int pos, float key, const float *values)
363 {
364     insertKey(pos, key, values, getNumChannels());
365 }
366 
367 void
deleteKeys(int start,int end)368 Interpolator::deleteKeys(int start, int end)
369 {
370     MFFloat *key = (MFFloat *) getField(m_keyField);
371     MFFloat *keyValue = (MFFloat *) getField(m_keyValueField);
372     int numKeys = key->getSize();
373     int numChannels = getNumChannels();
374 
375     if (key->getSize() * numChannels != keyValue->getSize())
376         return;
377 
378     if (end > numKeys - 1)
379         end = numKeys -1;
380 
381     for (int i = end; i >= start; i--) {
382         key->removeSFValue(i);
383         #pragma omp for
384         for (int j = 0; j < numChannels; j++)
385             keyValue->removeMFFloatSFValue(i * numChannels);
386     }
387 }
388 
389 void
recordValue(int key,FieldValue * value)390 Interpolator::recordValue(int key, FieldValue *value)
391 {
392     MFFloat *keyValue = (MFFloat *) getField(m_keyValueField);
393     keyValue->setSFValue(key, value);
394 }
395 
396 //
397 // recordKey() -- record a key at the current position (m_fraction)
398 //
399 
400 void
recordKey(FieldValue * value,bool isrunning)401 Interpolator::recordKey(FieldValue *value, bool isrunning)
402 {
403     MFFloat *keys = (MFFloat *) getField(m_keyField);
404     MFFloat *keyValues = (MFFloat *) getField(m_keyValueField);
405     int numChannels = getNumChannels();
406 
407     if (keys->getSize() * numChannels != keyValues->getSize())
408         return;
409 
410     int key = findKeyInclusive(m_fraction);
411 
412     if (isrunning) {
413         int oldKey = findKey(m_oldRecordedFraction);
414         int maxOldKey = findKey(m_fraction - 0.01f);
415         if (maxOldKey > oldKey)
416             oldKey = maxOldKey;
417         if ((oldKey != -1) && (key > oldKey)) {
418             deleteKeys(oldKey, key);
419             key = oldKey;
420         }
421     }
422     if (key == getNumKeys() || !EQUALF(getKey(key), m_fraction)) {
423         // no exact key found, create one
424 
425         insertKey(key, m_fraction, NULL);
426     }
427     recordValue(key, value);
428     m_scene->OnFieldChange(this, m_keyField);
429     m_scene->OnFieldChange(this, m_keyValueField);
430     if (isrunning)
431         m_oldRecordedFraction = m_fraction;
432 }
433 
434 void
removeKeys(float firstFraction,float lastFraction)435 Interpolator::removeKeys(float firstFraction, float lastFraction)
436 {
437     int firstKey = findKey(firstFraction);
438     int lastKey = findLessKey(lastFraction);
439     int numKeys = getNumKeys();
440 
441     if ((firstKey <= lastKey) &&
442         (firstKey > -1) && (firstKey < numKeys) &&
443         (lastKey > -1) && (lastKey < numKeys)) {
444         deleteKeys(firstKey, lastKey);
445         recordKey(getInterpolatedFieldValue(firstFraction), true);
446     }
447 }
448 
449 void
removeOldKeys(double currentTime,double oldTime)450 Interpolator::removeOldKeys(double currentTime, double oldTime)
451 {
452     MyArray<Node *> timeSensors =
453         m_scene->searchTimeSensorInInterpolator(this);
454     // only handle first timeSensor
455     if (timeSensors.size() > 0) {
456         NodeTimeSensor *timeSensor = (NodeTimeSensor *)timeSensors[0];
457         float firstFraction = timeSensor->getFraction(oldTime);
458         float lastFraction = timeSensor->getFraction(currentTime);
459         if (lastFraction < firstFraction) {
460             removeKeys(firstFraction, 1.0f);
461             removeKeys(0.0f, lastFraction);
462          } else {
463             removeKeys(firstFraction, lastFraction);
464         }
465     }
466 }
467 
468 //
469 // this is a ugly "dynamic_cast<Interpolator *>(Node* node)"
470 // but works with compilers without or defect rtti implementations...
471 //
472 
473 Interpolator *
dynamic_cast_Interpolator(Node * node)474 dynamic_cast_Interpolator(Node* node)
475 {
476     if (node == NULL)
477        return NULL;
478     if (node->isInterpolator())
479        return (Interpolator *)(void *)node;
480     else
481        return NULL;
482 }
483 
484