Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Ketsji/KX_IpoActuator.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp385
1 files changed, 208 insertions, 177 deletions
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index 7a894db6647..6234a5809f2 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -32,6 +32,8 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+#include <cmath>
+
#include "KX_IpoActuator.h"
#include "KX_GameObject.h"
@@ -39,6 +41,8 @@
#include <config.h>
#endif
+#include "KX_KetsjiEngine.h"
+
/* ------------------------------------------------------------------------- */
/* Type strings */
/* ------------------------------------------------------------------------- */
@@ -100,10 +104,11 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
PyTypeObject* T)
: SCA_IActuator(gameobj,T),
m_bNegativeEvent(false),
- m_starttime (starttime),
- m_endtime(endtime),
+ m_startframe (starttime),
+ m_endframe(endtime),
m_recurse(recurse),
m_localtime(starttime),
+ m_starttime(-1.0),
m_direction(1),
m_propname(propname),
m_ipo_as_force(ipo_as_force),
@@ -115,22 +120,35 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
void KX_IpoActuator::SetStart(float starttime)
{
- m_starttime=starttime;
+ m_startframe=starttime;
}
void KX_IpoActuator::SetEnd(float endtime)
{
- m_endtime=endtime;
+ m_endframe=endtime;
}
+void KX_IpoActuator::SetStartTime(float curtime)
+{
+ if (m_direction > 0)
+ m_starttime = curtime - (m_localtime - m_startframe)/KX_FIXED_FRAME_PER_SEC;
+ else
+ m_starttime = curtime - (m_endframe - m_localtime)/KX_FIXED_FRAME_PER_SEC;
+}
-bool KX_IpoActuator::Update(double curtime,double delta_time)
+void KX_IpoActuator::SetLocalTime(float curtime)
+{
+ float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC;
+ if (m_direction > 0)
+ m_localtime = m_startframe + delta_time;
+ else
+ m_localtime = m_endframe - delta_time;
+}
+
+bool KX_IpoActuator::Update(double curtime, bool frame)
{
- SCA_IActuator::Update(curtime,delta_time);
// result = true if animation has to be continued, false if animation stops
// maybe there are events for us in the queue !
-
-
bool bNegativeEvent = false;
int numevents = m_events.size();
@@ -138,10 +156,8 @@ bool KX_IpoActuator::Update(double curtime,double delta_time)
{
i--;
if ((*i)->GetNumber() == 0.0f)
- {
- int ka=0;
bNegativeEvent = true;
- }
+
(*i)->Release();
m_events.pop_back();
}
@@ -152,101 +168,195 @@ bool KX_IpoActuator::Update(double curtime,double delta_time)
}
- double start_smaller_then_end = ( m_starttime < m_endtime ? 1.0 : -1.0);
-
- double deltaframetime = start_smaller_then_end * delta_time * KX_FIXED_FRAME_PER_SEC;
+ double start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0);
bool result=true;
+ if (m_starttime < 0.0)
+ m_starttime = curtime;
switch (m_type)
{
case KX_ACT_IPO_PLAY:
+ {
+ // Check if playing forwards. result = ! finished
+ if (start_smaller_then_end > 0.0)
+ result = (m_localtime < m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
+ else
+ result = (m_localtime > m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
+
+ if (result)
{
-
- if (start_smaller_then_end > 0.0)
- result = (m_localtime < m_endtime && !(m_localtime == m_starttime && bNegativeEvent));
- else
- result = (m_localtime > m_endtime && !(m_localtime == m_starttime && bNegativeEvent));
- if (result)
- {
- m_localtime += m_direction * deltaframetime;
-
- /* Perform clamping */
- if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end))
- m_localtime=m_endtime;
-
- CIpoAction ipoaction(
- (KX_GameObject*)GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
- } else
- {
- m_localtime=m_starttime;
- m_direction=1;
- }
- break;
- }
- case KX_ACT_IPO_PINGPONG:
- {
- result = true;
- if (bNegativeEvent && ((m_localtime == m_starttime )|| (m_localtime == m_endtime)))
- {
- result = false;
- } else
- {
- m_localtime += m_direction * deltaframetime;
- }
-
- if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end)
- {
- m_localtime = m_starttime;
- result = false;
- m_direction = 1;
- }else
- if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end)
- {
- m_localtime = m_endtime;
- result = false;
- m_direction = -1;
- }
-
+ SetLocalTime(curtime);
+
+ /* Perform clamping */
+ if ((m_localtime*start_smaller_then_end)>(m_endframe*start_smaller_then_end))
+ m_localtime=m_endframe;
+
CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
+ (KX_GameObject*)GetParent(),
+ m_localtime,
m_recurse,
m_ipo_as_force,
m_force_ipo_local);
GetParent()->Execute(ipoaction);
- break;
+ } else
+ {
+ m_localtime=m_startframe;
+ m_starttime=curtime;
+ m_direction=1;
}
-
+ break;
+ }
+ case KX_ACT_IPO_PINGPONG:
+ {
+ result = true;
+ if (bNegativeEvent && ((m_localtime == m_startframe )|| (m_localtime == m_endframe)))
+ result = false;
+ else
+ SetLocalTime(curtime);
+
+ if (m_localtime*start_smaller_then_end < m_startframe*start_smaller_then_end)
+ {
+ m_localtime = m_startframe;
+ result = false;
+ m_direction = 1;
+ }
+ else if (m_localtime*start_smaller_then_end > m_endframe*start_smaller_then_end)
+ {
+ m_localtime = m_endframe;
+ result = false;
+ m_direction = -1;
+ }
+
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
case KX_ACT_IPO_FLIPPER:
+ {
+ result = true;
+ if (numevents)
+ {
+ if (bNegativeEvent)
+ m_direction = -1;
+ else
+ m_direction = 1;
+ SetStartTime(curtime);
+ }
+
+ SetLocalTime(curtime);
+
+ if (m_localtime*start_smaller_then_end > m_endframe*start_smaller_then_end)
+ {
+ m_localtime = m_endframe;
+ }
+ else if (m_localtime*start_smaller_then_end < m_startframe*start_smaller_then_end)
{
- result = true;
- if (numevents)
+ m_localtime = m_startframe;
+ result = false;
+ }
+
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
+
+ case KX_ACT_IPO_LOOPSTOP:
+ {
+ if (numevents)
+ {
+ if (bNegativeEvent)
+ {
+ result = false;
+ m_bNegativeEvent = false;
+ numevents = 0;
+ }
+ SetStartTime(curtime);
+ } // fall through to loopend, and quit the ipo animation immediatly
+ }
+ case KX_ACT_IPO_LOOPEND:
+ {
+ if (numevents){
+ if (bNegativeEvent){
+ m_bNegativeEvent = true;
+ }
+ }
+
+ if (bNegativeEvent && m_localtime == m_startframe){
+ result = false;
+ }
+ else{
+ if (m_localtime*start_smaller_then_end < m_endframe*start_smaller_then_end)
{
- if (bNegativeEvent)
- m_direction = -1;
+ SetLocalTime(curtime);
+ }
+ else{
+ if (!m_bNegativeEvent){
+ /* Perform wraparound */
+ SetLocalTime(curtime);
+ m_localtime = m_startframe + std::fmod(m_localtime, m_startframe - m_endframe);
+ SetStartTime(curtime);
+ }
else
- m_direction = 1;
+ {
+ /* Perform clamping */
+ m_localtime=m_endframe;
+ result = false;
+ m_bNegativeEvent = false;
+ }
}
+ }
+
+ CIpoAction ipoaction(
+ (KX_GameObject*) GetParent(),
+ m_localtime,
+ m_recurse,
+ m_ipo_as_force,
+ m_force_ipo_local);
+ GetParent()->Execute(ipoaction);
+ break;
+ }
+
+ case KX_ACT_IPO_KEY2KEY:
+ {
+ // not implemented yet
+ result = false;
+ break;
+ }
+
+ case KX_ACT_IPO_FROM_PROP:
+ {
+ result = !bNegativeEvent;
- m_localtime += m_direction * deltaframetime;
-
- if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end)
+ CValue* propval = GetParent()->GetProperty(m_propname);
+ if (propval)
+ {
+ float target = propval->GetNumber();
+ float delta_time = (curtime - m_starttime)*KX_FIXED_FRAME_PER_SEC;
+ if (target > m_localtime)
{
- m_localtime = m_endtime;
- } else
- if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end)
- {
- m_localtime = m_starttime;
- result = false;
- }
-
+ m_localtime += delta_time;
+ if (m_localtime > target)
+ m_localtime = target;
+ }
+ else
+ {
+ m_localtime -= delta_time;
+ if (m_localtime < target)
+ m_localtime = target;
+ }
+
CIpoAction ipoaction(
(KX_GameObject*) GetParent(),
m_localtime,
@@ -254,99 +364,20 @@ bool KX_IpoActuator::Update(double curtime,double delta_time)
m_ipo_as_force,
m_force_ipo_local);
GetParent()->Execute(ipoaction);
- break;
- }
- case KX_ACT_IPO_LOOPSTOP:
- {
- if (numevents)
- {
- if (bNegativeEvent)
- {
- result = false;
- m_bNegativeEvent = false;
- numevents = 0;
- }
- } // fall through to loopend, and quit the ipo animation immediatly
- }
-
- case KX_ACT_IPO_LOOPEND:
- {
- if (numevents){
- if (bNegativeEvent){
- m_bNegativeEvent = true;
- }
- }
-
- if (bNegativeEvent && m_localtime == m_starttime){
- result = false;
- }
- else{
- if (m_localtime*start_smaller_then_end < m_endtime*start_smaller_then_end){
- m_localtime += m_direction * deltaframetime;
- }
- else{
- if (!m_bNegativeEvent){
- /* Perform wraparound */
- float slop = m_localtime-m_endtime;
- float length = fabs(m_starttime-m_endtime);
- m_localtime = m_starttime + (slop - (int(slop/length)*(int(length))));
-
- }
- else
- {
- /* Perform clamping */
- if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end))
- m_localtime=m_endtime;
-
- result = false;
- m_bNegativeEvent = false;
- }
- }
- }
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
- break;
- }
- case KX_ACT_IPO_KEY2KEY:
+ } else
{
- // not implemented yet
result = false;
- break;
- }
- case KX_ACT_IPO_FROM_PROP:
- {
- result = !bNegativeEvent;
-
- CValue* propval = GetParent()->GetProperty(m_propname);
- if (propval)
- {
- m_localtime = propval->GetNumber();
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
-
- } else
- {
- result = false;
- }
- break;
}
+ break;
+ }
default:
- {
- result = false;
- }
+ result = false;
}
+
+ if (!result && m_type != KX_ACT_IPO_LOOPSTOP)
+ m_starttime = -1.0;
return result;
}
@@ -472,8 +503,8 @@ PyObject* KX_IpoActuator::PySet(PyObject* self,
case KX_ACT_IPO_LOOPSTOP:
case KX_ACT_IPO_LOOPEND:
m_type = modenum;
- m_starttime = startFrame;
- m_endtime = stopFrame;
+ m_startframe = startFrame;
+ m_endframe = stopFrame;
m_ipo_as_force = PyArgToBool(forceToggle);
break;
default:
@@ -516,7 +547,7 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self,
return NULL;
}
- m_starttime = startArg;
+ m_startframe = startArg;
Py_Return;
}
@@ -527,7 +558,7 @@ char KX_IpoActuator::GetStart_doc[] =
PyObject* KX_IpoActuator::PyGetStart(PyObject* self,
PyObject* args,
PyObject* kwds) {
- return PyFloat_FromDouble(m_starttime);
+ return PyFloat_FromDouble(m_startframe);
}
/* 6. setEnd: */
@@ -543,7 +574,7 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
return NULL;
}
- m_endtime = endArg;
+ m_endframe = endArg;
Py_Return;
}
@@ -554,7 +585,7 @@ char KX_IpoActuator::GetEnd_doc[] =
PyObject* KX_IpoActuator::PyGetEnd(PyObject* self,
PyObject* args,
PyObject* kwds) {
- return PyFloat_FromDouble(m_endtime);
+ return PyFloat_FromDouble(m_endframe);
}
/* 6. setIpoAsForce: */