1 /*
2 * NodeScalarChaser.cpp
3 *
4 * Copyright (C) 2009 J. "MUFTI" Scheurich
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 <stdio.h>
23 #include "stdafx.h"
24
25 #include "NodeScalarChaser.h"
26 #include "Proto.h"
27 #include "FieldValue.h"
28 #include "SFTime.h"
29 #include "SFFloat.h"
30 #include "SFFloat.h"
31 #include "DuneApp.h"
32
ProtoScalarChaser(Scene * scene)33 ProtoScalarChaser::ProtoScalarChaser(Scene *scene)
34 : ChaserProto(scene, "ScalarChaser", SFFLOAT)
35 {
36 initialDestination.set(
37 addField(SFFLOAT, "initialDestination", new SFFloat(0)));
38 initialValue.set(
39 addField(SFFLOAT, "initialValue", new SFFloat(0)));
40 }
41
42 Node *
create(Scene * scene)43 ProtoScalarChaser::create(Scene *scene)
44 {
45 return new NodeScalarChaser(scene, this);
46 }
47
NodeScalarChaser(Scene * scene,Proto * def)48 NodeScalarChaser::NodeScalarChaser(Scene *scene, Proto *def)
49 : ChaserNode(scene, def)
50 {
51 m_lastTick = 0;
52 m_initialDestination_Field = getProto()->lookupEventIn(
53 "initialDestination");
54 m_initialValue_Field = getProto()->lookupEventIn("initialValue");
55 }
56
57 void
sendChasedEvent(int eventIn,double timestamp,FieldValue * value)58 NodeScalarChaser::sendChasedEvent(int eventIn, double timestamp,
59 FieldValue* value)
60 {
61 double now = timestamp;
62
63 if (eventIn == m_set_value_Field)
64 m_value = ((SFFloat *)value)->getValue();
65 else if (eventIn == m_initialDestination_Field)
66 initialDestination((SFFloat *)value);
67 else if (eventIn == m_initialValue_Field)
68 initialValue((SFFloat *)value);
69 else if (eventIn == m_set_destination_Field)
70 m_destination = ((SFFloat *)value)->getValue();
71
72 if (!m_lastTick) {
73 m_lastTick = now;
74 return;
75 }
76
77 double dduration = duration()->getValue();
78 float initDest = initialDestination()->getValue();
79 float initVal = initialValue()->getValue();
80
81 // throw out times and durations too old
82 for (int i = m_event_times.size() - 1; i > -1; i--)
83 if (m_event_times[i] < (now - dduration)) {
84 m_event_times.remove(i);
85 m_destinations.remove(i);
86 }
87 m_event_times.append(now);
88 m_destinations.append(m_destination);
89
90 float outputValue = initDest;
91 for (long i = 0; i < m_event_times.size(); i++) {
92 float dnmin1;
93 if (i == 0)
94 dnmin1 = initVal;
95 else
96 dnmin1 = m_destinations[i - 1];
97 float dn = m_destinations[i];
98 if ((now - m_event_times[i]) > dduration)
99 outputValue += dn - dnmin1;
100 else
101 outputValue += (dn - dnmin1) *
102 (1 - cos(M_PI * (now - m_event_times[i] /
103 dduration))) / 2;
104 }
105
106 sendEvent(m_value_changed_Field, timestamp, new SFFloat(outputValue));
107
108 m_lastTick= now;
109 }
110
111