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