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