animation blending #95

This commit is contained in:
Turanszki Janos
2020-04-17 23:11:59 +01:00
parent 272f279aff
commit 4f9e7b56ef
13 changed files with 158 additions and 39 deletions
@@ -523,6 +523,10 @@ Describes an orientation in 3D space.
- SetLooped(bool value)
- IsLooped() : bool result
- IsPlaying() : bool result
- SetTimer(float value)
- GetTimer() : float result
- SetAmount(float value)
- GetAmount() : float result
#### MaterialComponent
- SetBaseColor(Vector value)
+17
View File
@@ -56,6 +56,7 @@ AnimationWindow::AnimationWindow(EditorComponent* editor) : GUI(&editor->GetGUI(
else
{
animation->Play();
animation->amount = 0;
}
}
});
@@ -87,6 +88,20 @@ AnimationWindow::AnimationWindow(EditorComponent* editor) : GUI(&editor->GetGUI(
timerSlider->SetTooltip("Set the animation timer by hand.");
animWindow->AddWidget(timerSlider);
amountSlider = new wiSlider(0, 1, 0, 100000, "Amount: ");
amountSlider->SetSize(XMFLOAT2(250, 30));
amountSlider->SetPos(XMFLOAT2(x, y += step));
amountSlider->OnSlide([&](wiEventArgs args) {
AnimationComponent* animation = wiScene::GetScene().animations.GetComponent(entity);
if (animation != nullptr)
{
animation->amount = args.fValue;
}
});
amountSlider->SetEnabled(false);
amountSlider->SetTooltip("Set the animation blending amount by hand.");
animWindow->AddWidget(amountSlider);
animWindow->Translate(XMFLOAT3(100, 50, 0));
@@ -153,6 +168,7 @@ void AnimationWindow::Update()
if (animation.IsPlaying())
{
playButton->SetText("Pause");
animation.amount = wiMath::Lerp(animation.amount, 1, 0.1f);
}
else
{
@@ -163,5 +179,6 @@ void AnimationWindow::Update()
timerSlider->SetRange(0, animation.GetLength());
timerSlider->SetValue(animation.timer);
amountSlider->SetValue(animation.amount);
}
}
+1
View File
@@ -26,6 +26,7 @@ public:
wiButton* playButton;
wiButton* stopButton;
wiSlider* timerSlider;
wiSlider* amountSlider;
void Update();
};
+1
View File
@@ -1,5 +1,6 @@
This file contains changelog of wiArchive versions
44: Serialized AnimationComponent::amount
43: Serialized MeshComponent::vertex_windweights
42: Serialized hair particle sprite sheet properties
41: Serialized terrain blend materials in MeshComponent
+1 -1
View File
@@ -7,7 +7,7 @@
using namespace std;
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
uint64_t __archiveVersion = 43;
uint64_t __archiveVersion = 44;
// this is the version number of which below the archive is not compatible with the current version
uint64_t __archiveVersionBarrier = 22;
+21 -2
View File
@@ -1672,7 +1672,8 @@ namespace wiScene
float left = sampler.keyframe_times[keyLeft];
TransformComponent& transform = *transforms.GetComponent(channel.target);
TransformComponent& target_transform = *transforms.GetComponent(channel.target);
TransformComponent transform = target_transform;
if (sampler.mode == AnimationComponent::AnimationSampler::Mode::STEP || keyLeft == keyRight)
{
@@ -1741,7 +1742,25 @@ namespace wiScene
}
}
transform.SetDirty();
target_transform.SetDirty();
const float t = animation.amount;
const XMVECTOR aS = XMLoadFloat3(&target_transform.scale_local);
const XMVECTOR aR = XMLoadFloat4(&target_transform.rotation_local);
const XMVECTOR aT = XMLoadFloat3(&target_transform.translation_local);
const XMVECTOR bS = XMLoadFloat3(&transform.scale_local);
const XMVECTOR bR = XMLoadFloat4(&transform.rotation_local);
const XMVECTOR bT = XMLoadFloat3(&transform.translation_local);
const XMVECTOR S = XMVectorLerp(aS, bS, t);
const XMVECTOR R = XMQuaternionSlerp(aR, bR, t);
const XMVECTOR T = XMVectorLerp(aT, bT, t);
XMStoreFloat3(&target_transform.scale_local, S);
XMStoreFloat4(&target_transform.rotation_local, R);
XMStoreFloat3(&target_transform.translation_local, T);
}
+2 -1
View File
@@ -873,7 +873,8 @@ namespace wiScene
uint32_t _flags = LOOPED;
float start = 0;
float end = 0;
float timer = 0.0f;
float timer = 0;
float amount = 1;
struct AnimationChannel
{
+42
View File
@@ -1535,6 +1535,10 @@ Luna<AnimationComponent_BindLua>::FunctionType AnimationComponent_BindLua::metho
lunamethod(AnimationComponent_BindLua, IsLooped),
lunamethod(AnimationComponent_BindLua, IsPlaying),
lunamethod(AnimationComponent_BindLua, IsEnded),
lunamethod(AnimationComponent_BindLua, SetTimer),
lunamethod(AnimationComponent_BindLua, GetTimer),
lunamethod(AnimationComponent_BindLua, SetAmount),
lunamethod(AnimationComponent_BindLua, GetAmount),
{ NULL, NULL }
};
Luna<AnimationComponent_BindLua>::PropertyType AnimationComponent_BindLua::properties[] = {
@@ -1598,6 +1602,44 @@ int AnimationComponent_BindLua::IsEnded(lua_State* L)
wiLua::SSetBool(L, component->IsEnded());
return 1;
}
int AnimationComponent_BindLua::SetTimer(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
float value = wiLua::SGetFloat(L, 1);
component->timer = value;
}
else
{
wiLua::SError(L, "SetTimer(float value) not enough arguments!");
}
return 0;
}
int AnimationComponent_BindLua::GetTimer(lua_State* L)
{
wiLua::SSetFloat(L, component->timer);
return 1;
}
int AnimationComponent_BindLua::SetAmount(lua_State* L)
{
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
float value = wiLua::SGetFloat(L, 1);
component->amount = value;
}
else
{
wiLua::SError(L, "SetAmount(float value) not enough arguments!");
}
return 0;
}
int AnimationComponent_BindLua::GetAmount(lua_State* L)
{
wiLua::SSetFloat(L, component->amount);
return 1;
}
+4
View File
@@ -193,6 +193,10 @@ namespace wiScene_BindLua
int IsLooped(lua_State* L);
int IsPlaying(lua_State* L);
int IsEnded(lua_State* L);
int SetTimer(lua_State* L);
int GetTimer(lua_State* L);
int SetAmount(lua_State* L);
int GetAmount(lua_State* L);
};
class MaterialComponent_BindLua
+10
View File
@@ -636,6 +636,11 @@ namespace wiScene
archive >> end;
archive >> timer;
if (archive.GetVersion() >= 44)
{
archive >> amount;
}
size_t channelCount;
archive >> channelCount;
channels.resize(channelCount);
@@ -666,6 +671,11 @@ namespace wiScene
archive << end;
archive << timer;
if (archive.GetVersion() >= 44)
{
archive << amount;
}
archive << channels.size();
for (size_t i = 0; i < channels.size(); ++i)
{
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 39;
// minor bug fixes, alterations, refactors, updates
const int revision = 67;
const int revision = 68;
long GetVersion()
+46 -33
View File
@@ -40,6 +40,7 @@ Character = {
JUMP = 2,
},
state = STAND,
state_prev = STAND,
Create = function(self,entity)
self.model = entity
@@ -93,33 +94,30 @@ Character = {
Input = function(self)
if(self.state==self.states.STAND) then
local lookDir = Vector()
if(input.Down(KEYBOARD_BUTTON_LEFT) or input.Down(string.byte('A'))) then
lookDir = lookDir:Add( Vector(-1) )
end
if(input.Down(KEYBOARD_BUTTON_RIGHT) or input.Down(string.byte('D'))) then
lookDir = lookDir:Add( Vector(1) )
end
local lookDir = Vector()
if(input.Down(KEYBOARD_BUTTON_LEFT) or input.Down(string.byte('A'))) then
lookDir = lookDir:Add( Vector(-1) )
end
if(input.Down(KEYBOARD_BUTTON_RIGHT) or input.Down(string.byte('D'))) then
lookDir = lookDir:Add( Vector(1) )
end
if(input.Down(KEYBOARD_BUTTON_UP) or input.Down(string.byte('W'))) then
lookDir = lookDir:Add( Vector(0,0,1) )
end
if(input.Down(KEYBOARD_BUTTON_DOWN) or input.Down(string.byte('S'))) then
lookDir = lookDir:Add( Vector(0,0,-1) )
end
if(input.Down(KEYBOARD_BUTTON_UP) or input.Down(string.byte('W'))) then
lookDir = lookDir:Add( Vector(0,0,1) )
end
if(input.Down(KEYBOARD_BUTTON_DOWN) or input.Down(string.byte('S'))) then
lookDir = lookDir:Add( Vector(0,0,-1) )
end
local analog = input.GetAnalog(GAMEPAD_ANALOG_THUMBSTICK_L)
lookDir = vector.Add(lookDir, Vector(analog.GetX(), 0, analog.GetY()))
local analog = input.GetAnalog(GAMEPAD_ANALOG_THUMBSTICK_L)
lookDir = vector.Add(lookDir, Vector(analog.GetX(), 0, analog.GetY()))
if(lookDir:Length()>0) then
if(input.Down(KEYBOARD_BUTTON_LSHIFT) or input.Down(GAMEPAD_BUTTON_6)) then
self:MoveDirection(lookDir,self.moveSpeed*2)
else
self:MoveDirection(lookDir,self.moveSpeed)
end
if(lookDir:Length()>0) then
if(input.Down(KEYBOARD_BUTTON_LSHIFT) or input.Down(GAMEPAD_BUTTON_6)) then
self:MoveDirection(lookDir,self.moveSpeed*2)
else
self:MoveDirection(lookDir,self.moveSpeed)
end
end
if( input.Press(string.byte('J')) or input.Press(KEYBOARD_BUTTON_SPACE) or input.Press(GAMEPAD_BUTTON_2) ) then
@@ -157,7 +155,7 @@ Character = {
local target_transform = scene.Component_GetTransform(self.target)
-- gravity:
self.force = vector.Add(self.force, Vector(0,-9.8 * 10,0))
self.force = vector.Add(self.force, Vector(0,-9.8 * 20,0))
-- apply force:
self.velocity = vector.Add(self.velocity, vector.Multiply(self.force, getDeltaTime()))
@@ -165,18 +163,31 @@ Character = {
-- state and animation update
if(self.state == self.states.STAND) then
scene.Component_GetAnimation(self.idle_anim).Play()
scene.Component_GetAnimation(self.walk_anim).Stop()
self.state = self.states.STAND
local anim = scene.Component_GetAnimation(self.idle_anim)
anim.Play()
anim.SetAmount(math.lerp(anim.GetAmount(), 1, 0.1))
if(self.state ~= self.state_prev) then
anim.SetAmount(0)
end
elseif(self.state == self.states.WALK) then
scene.Component_GetAnimation(self.idle_anim).Stop()
scene.Component_GetAnimation(self.walk_anim).Play()
self.state = self.states.STAND
local anim = scene.Component_GetAnimation(self.walk_anim)
anim.Play()
anim.SetAmount(math.lerp(anim.GetAmount(), 1, 0.1))
if(self.state ~= self.state_prev) then
anim.SetAmount(0)
end
elseif(self.state == self.states.JUMP) then
scene.Component_GetAnimation(self.idle_anim).Play()
scene.Component_GetAnimation(self.walk_anim).Stop()
self.state = self.states.STAND
local anim = scene.Component_GetAnimation(self.idle_anim)
anim.Play()
anim.SetAmount(math.lerp(anim.GetAmount(), 1, 0.1))
if(self.state ~= self.state_prev) then
anim.SetAmount(0)
end
end
self.state_prev = self.state
-- front block shoots multiple rays in front to try to find obstruction
local rotations = {0, 3.1415*0.3, -3.1415*0.3}
@@ -228,7 +239,7 @@ Character = {
self.velocity.SetY(0) -- don't fall below ground
self.velocity = vector.Multiply(self.velocity, 0.8) -- slow down on ground
else
self.velocity = vector.Multiply(self.velocity, 0.96) -- slow down in air
self.velocity = vector.Multiply(self.velocity, 0.94) -- slow down in air
end
end
@@ -368,9 +379,11 @@ runProcess(function()
while true do
player:Input()
player:Update()
fixedupdate()
player:Input()
camera:Update()
+8 -1
View File
@@ -1181,7 +1181,9 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
end,
-- Starts a new state:
StartState = function(self, dst_state)
scene.Component_GetAnimation(self.states[dst_state].anim).Play()
local anim = scene.Component_GetAnimation(self.states[dst_state].anim)
anim.Play()
anim.SetAmount(0)
self.frame = 0
self.state = dst_state
self.hitconfirms = {}
@@ -1210,6 +1212,11 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
end
end
-- Animation blending:
local anim = scene.Component_GetAnimation(self.states[self.state].anim)
local anim_amount = anim.GetAmount()
anim.SetAmount(math.lerp(anim_amount, 1, 0.2))
-- Execute the currently active state:
local current_state = self.states[self.state]
if(current_state ~= nil) then