1
0
forked from 0ad/0ad

Fix actor viewer animation offsetting.

Fix attack animation drifts.

This was SVN commit r7612.
This commit is contained in:
Ykkrosh 2010-06-05 22:23:28 +00:00
parent 5982c07002
commit 23c92b7fe3
11 changed files with 54 additions and 42 deletions

View File

@ -34,7 +34,8 @@ Timer.prototype.OnUpdate = function(msg)
var t = this.timers[id];
var cmp = Engine.QueryInterface(t[0], t[1]);
try {
cmp[t[2]](t[4]);
var lateness = this.time - t[3];
cmp[t[2]](t[4], lateness);
} catch (e) {
var stack = e.stack.trimRight().replace(/^/mg, ' '); // indent the stack trace
print("Error in timer on entity "+t[0]+", IID "+t[1]+", function "+t[2]+": "+e+"\n"+stack+"\n");
@ -45,8 +46,9 @@ Timer.prototype.OnUpdate = function(msg)
}
/**
* Create a new timer, which will call the 'funcname' method with argument 'data'
* Create a new timer, which will call the 'funcname' method with arguments (data, lateness)
* on the 'iid' component of the 'ent' entity, after at least 'time' milliseconds.
* 'lateness' is how late the timer is executed after the specified time (in milliseconds).
* Returns a non-zero id that can be passed to CancelTimer.
*/
Timer.prototype.SetTimeout = function(ent, iid, funcname, time, data)

View File

@ -351,7 +351,8 @@ UnitAI.prototype.SetAnimationSync = function(actiontime, repeattime)
if (!cmpVisual)
return;
cmpVisual.SetAnimationSync(actiontime, repeattime);
cmpVisual.SetAnimationSyncRepeat(repeattime);
cmpVisual.SetAnimationSyncOffset(actiontime);
};
/**
@ -365,7 +366,7 @@ UnitAI.prototype.MoveToTarget = function(target, range)
return cmpMotion.MoveToAttackRange(target, range.min, range.max);
};
UnitAI.prototype.AttackTimeout = function(data)
UnitAI.prototype.AttackTimeout = function(data, lateness)
{
// If we stopped attacking before this timeout, then don't do any processing here
if (this.state != STATE_ATTACKING)
@ -386,10 +387,10 @@ UnitAI.prototype.AttackTimeout = function(data)
var timers = cmpAttack.GetTimers(this.attackType);
this.attackRechargeTime = cmpTimer.GetTime() + timers.recharge;
this.attackTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "AttackTimeout", timers.repeat, data);
this.attackTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "AttackTimeout", timers.repeat - lateness, data);
};
UnitAI.prototype.RepairTimeout = function(data)
UnitAI.prototype.RepairTimeout = function(data, lateness)
{
// If we stopped repairing before this timeout, then don't do any processing here
if (this.state != STATE_REPAIRING)
@ -415,10 +416,10 @@ UnitAI.prototype.RepairTimeout = function(data)
// Set a timer to gather again
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.repairTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "RepairTimeout", 1000, data);
this.repairTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "RepairTimeout", 1000 - lateness, data);
};
UnitAI.prototype.GatherTimeout = function(data)
UnitAI.prototype.GatherTimeout = function(data, lateness)
{
// If we stopped gathering before this timeout, then don't do any processing here
if (this.state != STATE_GATHERING)
@ -444,7 +445,7 @@ UnitAI.prototype.GatherTimeout = function(data)
// Set a timer to gather again
var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
this.gatherTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "GatherTimeout", 1000, data);
this.gatherTimer = cmpTimer.SetTimeout(this.entity, IID_UnitAI, "GatherTimeout", 1000 - lateness, data);
};
Engine.RegisterComponentType(IID_UnitAI, "UnitAI", UnitAI);

View File

@ -244,7 +244,7 @@ function init(window, bottomWindow)
actorViewer.controls.push(animationBoxBox);
var animationBox = new wxStaticBoxSizer(animationBoxBox, wxOrientation.VERTICAL);
var animationSelector = new wxChoice(bottomWindow, -1, wxDefaultPosition, wxDefaultSize,
[ "build", "corpse", "death",
[ "build", "death",
"gather_fruit", "gather_grain", "gather_meat", "gather_metal", "gather_stone", "gather_wood",
"idle", "melee", "run", "walk" ] // TODO: this list should come from the actor
);

View File

@ -64,16 +64,6 @@ CUnit* CUnit::Create(const CStrW& actorName, const std::set<CStr>& selections, C
return new CUnit(obj, objectManager, actorSelections);
}
void CUnit::SetAnimationState(const CStr& name, bool once, float speed, float desync, bool keepSelection, const CStrW& soundgroup)
{
m_Animation->SetAnimationState(name, once, speed, desync, keepSelection, soundgroup);
}
void CUnit::SetAnimationSync(float actionTime, float repeatTime)
{
m_Animation->SetAnimationSync(actionTime, repeatTime);
}
void CUnit::UpdateModel(float frameTime)
{
m_Animation->Update(frameTime*1000.0f);

View File

@ -60,11 +60,7 @@ public:
// get unit's model data
CModel& GetModel() const { return *m_Model; }
/// See CUnitAnimation::SetAnimationState
void SetAnimationState(const CStr& name, bool once, float speed, float desync, bool keepSelection, const CStrW& soundgroup);
/// See CUnitAnimation::SetAnimationSync
void SetAnimationSync(float actionTime, float repeatTime);
CUnitAnimation& GetAnimation() { return *m_Animation; }
/**
* Update the model's animation.

View File

@ -100,10 +100,13 @@ void CUnitAnimation::SetAnimationState(const CStr& name, bool once, float speed,
ReloadUnit();
}
void CUnitAnimation::SetAnimationSync(float actionTime, float repeatTime)
void CUnitAnimation::SetAnimationSyncRepeat(float repeatTime)
{
m_SyncRepeatTime = repeatTime;
}
void CUnitAnimation::SetAnimationSyncOffset(float actionTime)
{
// Update all the synced prop models to each coincide with actionTime
for (std::vector<SModelAnimState>::iterator it = m_AnimStates.begin(); it != m_AnimStates.end(); ++it)
{
@ -119,7 +122,7 @@ void CUnitAnimation::SetAnimationSync(float actionTime, float repeatTime)
if (!hasActionPos)
continue;
float speed = duration / repeatTime;
float speed = duration / m_SyncRepeatTime;
// Need to offset so that start+actionTime*speed = actionPos
float start = actionPos - actionTime*speed;

View File

@ -58,13 +58,19 @@ public:
void SetAnimationState(const CStr& name, bool once, float speed, float desync, bool keepSelection, const CStrW& actionSound);
/**
* Adjust the timing of the current animation, so that Update(actionTime) will advance it
* to the 'action' point defined in the actor, and so that Update(repeatTime) will do a
* Adjust the speed of the current animation, so that Update(repeatTime) will do a
* complete animation loop.
* @param actionTime time between now and when the action should occur, in msec
* @param repeatTime time for complete loop of animation, in msec
*/
void SetAnimationSync(float actionTime, float repeatTime);
void SetAnimationSyncRepeat(float repeatTime);
/**
* Adjust the offset of the current animation, so that Update(actionTime) will advance it
* to the 'action' point defined in the actor.
* This must be called after SetAnimationSyncRepeat sets the speed.
* @param actionTime time between now and when the action should occur, in msec
*/
void SetAnimationSyncOffset(float actionTime);
/**
* Advance the animation state.

View File

@ -28,6 +28,7 @@
#include "graphics/ObjectBase.h"
#include "graphics/ObjectEntry.h"
#include "graphics/Unit.h"
#include "graphics/UnitAnimation.h"
#include "graphics/UnitManager.h"
#include "lib/utf8.h"
#include "maths/Matrix3D.h"
@ -229,17 +230,25 @@ public:
m_AnimDesync = 0.05f; // TODO: make this an argument
m_AnimSyncRepeatTime = 0.0f;
m_Unit->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed, m_AnimDesync, false, m_SoundGroup.c_str());
m_Unit->GetAnimation().SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed, m_AnimDesync, false, m_SoundGroup.c_str());
}
virtual void SetAnimationSync(float actiontime, float repeattime)
virtual void SetAnimationSyncRepeat(float repeattime)
{
if (!m_Unit)
return;
m_AnimSyncRepeatTime = repeattime;
m_Unit->SetAnimationSync(actiontime, m_AnimSyncRepeatTime);
m_Unit->GetAnimation().SetAnimationSyncRepeat(m_AnimSyncRepeatTime);
}
virtual void SetAnimationSyncOffset(float actiontime)
{
if (!m_Unit)
return;
m_Unit->GetAnimation().SetAnimationSyncOffset(actiontime);
}
virtual void SetShadingColour(fixed r, fixed g, fixed b, fixed a)
@ -274,11 +283,11 @@ public:
m_Unit->SetID(GetEntityId());
m_Unit->SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed, m_AnimDesync, false, m_SoundGroup.c_str());
m_Unit->GetAnimation().SetAnimationState(m_AnimName, m_AnimOnce, m_AnimSpeed, m_AnimDesync, false, m_SoundGroup.c_str());
// We'll lose the exact synchronisation but we should at least make sure it's going at the correct rate
if (m_AnimSyncRepeatTime != 0.0f)
m_Unit->SetAnimationSync(0.0f, m_AnimSyncRepeatTime);
m_Unit->GetAnimation().SetAnimationSyncRepeat(m_AnimSyncRepeatTime);
m_Unit->GetModel().SetShadingColor(shading);

View File

@ -23,6 +23,7 @@
BEGIN_INTERFACE_WRAPPER(Visual)
DEFINE_INTERFACE_METHOD_4("SelectAnimation", void, ICmpVisual, SelectAnimation, std::string, bool, float, std::wstring)
DEFINE_INTERFACE_METHOD_2("SetAnimationSync", void, ICmpVisual, SetAnimationSync, float, float)
DEFINE_INTERFACE_METHOD_1("SetAnimationSyncRepeat", void, ICmpVisual, SetAnimationSyncRepeat, float)
DEFINE_INTERFACE_METHOD_1("SetAnimationSyncOffset", void, ICmpVisual, SetAnimationSyncOffset, float)
DEFINE_INTERFACE_METHOD_4("SetShadingColour", void, ICmpVisual, SetShadingColour, fixed, fixed, fixed, fixed)
END_INTERFACE_WRAPPER(Visual)

View File

@ -73,12 +73,16 @@ public:
virtual void SelectAnimation(std::string name, bool once, float speed, std::wstring soundgroup) = 0;
/**
* Adjust the timing (offset and speed) of the current animation, so it can match
* simulation events.
* @param actiontime time between now and when the 'action' event should occur, in msec
* Adjust the speed of the current animation, so it can match simulation events.
* @param repeattime time for complete loop of animation, in msec
*/
virtual void SetAnimationSync(float actiontime, float repeattime) = 0;
virtual void SetAnimationSyncRepeat(float repeattime) = 0;
/**
* Adjust the offset of the current animation, so it can match simulation events.
* @param actiontime time between now and when the 'action' event should occur, in msec
*/
virtual void SetAnimationSyncOffset(float actiontime) = 0;
/**
* Set the shading colour that will be modulated with the model's textures.

View File

@ -239,7 +239,7 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation)
// TODO: SetEntitySelection(anim)
cmpVisual->SelectAnimation(anim, false, speed, soundgroup);
if (repeattime)
cmpVisual->SetAnimationSync(0.f, repeattime);
cmpVisual->SetAnimationSyncRepeat(repeattime);
}
}