updated skinning, gui and started animation editor
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
#include "stdafx.h"
|
||||
#include "AnimationWindow.h"
|
||||
|
||||
|
||||
AnimationWindow::AnimationWindow(wiGUI* gui) :GUI(gui)
|
||||
{
|
||||
assert(GUI && "Invalid GUI!");
|
||||
|
||||
float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth();
|
||||
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
|
||||
|
||||
|
||||
animWindow = new wiWindow(GUI, "Animation Window");
|
||||
animWindow->SetSize(XMFLOAT2(700, 300));
|
||||
GUI->AddWidget(animWindow);
|
||||
|
||||
float x = 200;
|
||||
float y = 0;
|
||||
float step = 35;
|
||||
|
||||
actionsComboBox = new wiComboBox("Actions: ");
|
||||
actionsComboBox->SetSize(XMFLOAT2(400, 20));
|
||||
actionsComboBox->SetPos(XMFLOAT2(x, y += step));
|
||||
actionsComboBox->OnSelect([&](wiEventArgs args) {
|
||||
if (armature != nullptr && args.iValue >= 0)
|
||||
{
|
||||
armature->ChangeAction(args.sValue, blendSlider->GetValue());
|
||||
}
|
||||
});
|
||||
actionsComboBox->SetEnabled(false);
|
||||
actionsComboBox->SetTooltip("Choose an animation clip...");
|
||||
animWindow->AddWidget(actionsComboBox);
|
||||
|
||||
blendSlider = new wiSlider(0.0f, 60, 0, 100000, "Blend Frames: ");
|
||||
blendSlider->SetSize(XMFLOAT2(100, 30));
|
||||
blendSlider->SetPos(XMFLOAT2(x, y += step));
|
||||
blendSlider->OnSlide([&](wiEventArgs args) {
|
||||
// no operation, will only be queried
|
||||
});
|
||||
blendSlider->SetEnabled(false);
|
||||
blendSlider->SetTooltip("Adjust the blend length in frames when changing actions...");
|
||||
animWindow->AddWidget(blendSlider);
|
||||
|
||||
|
||||
animWindow->Translate(XMFLOAT3(100, 50, 0));
|
||||
animWindow->SetVisible(false);
|
||||
|
||||
SetArmature(nullptr);
|
||||
}
|
||||
|
||||
|
||||
AnimationWindow::~AnimationWindow()
|
||||
{
|
||||
SAFE_DELETE(animWindow);
|
||||
SAFE_DELETE(actionsComboBox);
|
||||
SAFE_DELETE(blendSlider);
|
||||
}
|
||||
|
||||
void AnimationWindow::SetArmature(Armature* armature)
|
||||
{
|
||||
this->armature = armature;
|
||||
|
||||
if (armature != nullptr)
|
||||
{
|
||||
actionsComboBox->ClearItems();
|
||||
actionsComboBox->SetEnabled(true);
|
||||
for (auto& x : armature->actions)
|
||||
{
|
||||
actionsComboBox->AddItem(x.name);
|
||||
}
|
||||
actionsComboBox->SetSelected(armature->GetPrimaryAnimation()->activeAction);
|
||||
blendSlider->SetEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionsComboBox->ClearItems();
|
||||
actionsComboBox->SetEnabled(false);
|
||||
blendSlider->SetEnabled(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
struct Armature;
|
||||
class wiGUI;
|
||||
class wiWindow;
|
||||
class wiLabel;
|
||||
class wiCheckBox;
|
||||
class wiSlider;
|
||||
class wiComboBox;
|
||||
|
||||
class AnimationWindow
|
||||
{
|
||||
public:
|
||||
AnimationWindow(wiGUI* gui);
|
||||
~AnimationWindow();
|
||||
|
||||
wiGUI* GUI;
|
||||
Armature* armature;
|
||||
void SetArmature(Armature* armature);
|
||||
|
||||
wiWindow* animWindow;
|
||||
wiComboBox* actionsComboBox;
|
||||
wiSlider* blendSlider;
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "EnvProbeWindow.h"
|
||||
#include "DecalWindow.h"
|
||||
#include "LightWindow.h"
|
||||
#include "AnimationWindow.h"
|
||||
|
||||
#include <Commdlg.h> // openfile
|
||||
#include <WinBase.h>
|
||||
@@ -240,6 +241,7 @@ void EditorComponent::Load()
|
||||
envProbeWnd = new EnvProbeWindow(&GetGUI());
|
||||
decalWnd = new DecalWindow(&GetGUI());
|
||||
lightWnd = new LightWindow(&GetGUI());
|
||||
animWnd = new AnimationWindow(&GetGUI());
|
||||
|
||||
float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth();
|
||||
float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight();
|
||||
@@ -336,6 +338,15 @@ void EditorComponent::Load()
|
||||
});
|
||||
GetGUI().AddWidget(lightWnd_Toggle);
|
||||
|
||||
wiButton* animWnd_Toggle = new wiButton("Animation");
|
||||
animWnd_Toggle->SetTooltip("Animation inspector window");
|
||||
animWnd_Toggle->SetPos(XMFLOAT2(x += step, screenH - 40));
|
||||
animWnd_Toggle->SetSize(XMFLOAT2(100, 40));
|
||||
animWnd_Toggle->OnClick([=](wiEventArgs args) {
|
||||
animWnd->animWindow->SetVisible(!animWnd->animWindow->IsVisible());
|
||||
});
|
||||
GetGUI().AddWidget(animWnd_Toggle);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -840,12 +851,14 @@ void EditorComponent::FixedUpdate()
|
||||
savedParents.erase(picked->object);
|
||||
picked->transform = picked->object->mesh->armature;
|
||||
savedParents.insert(pair<Transform*, Transform*>(picked->transform, picked->transform->parent));
|
||||
animWnd->SetArmature(picked->object->mesh->armature);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meshWnd->SetMesh(nullptr);
|
||||
materialWnd->SetMaterial(nullptr);
|
||||
animWnd->SetArmature(nullptr);
|
||||
}
|
||||
|
||||
if (picked->light != nullptr)
|
||||
@@ -1183,6 +1196,7 @@ void EditorComponent::Unload()
|
||||
SAFE_DELETE(cameraWnd);
|
||||
SAFE_DELETE(decalWnd);
|
||||
SAFE_DELETE(lightWnd);
|
||||
SAFE_DELETE(animWnd);
|
||||
|
||||
SAFE_DELETE(translator);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class RendererWindow;
|
||||
class EnvProbeWindow;
|
||||
class DecalWindow;
|
||||
class LightWindow;
|
||||
class AnimationWindow;
|
||||
|
||||
class EditorLoadingScreen : public LoadingScreenComponent
|
||||
{
|
||||
@@ -41,6 +42,7 @@ public:
|
||||
EnvProbeWindow* envProbeWnd;
|
||||
DecalWindow* decalWnd;
|
||||
LightWindow* lightWnd;
|
||||
AnimationWindow* animWnd;
|
||||
|
||||
Editor* main;
|
||||
EditorLoadingScreen* loader;
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AnimationWindow.h" />
|
||||
<ClInclude Include="CameraWindow.h" />
|
||||
<ClInclude Include="DecalWindow.h" />
|
||||
<ClInclude Include="Editor.h" />
|
||||
@@ -182,6 +183,7 @@
|
||||
<ClInclude Include="WorldWindow.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AnimationWindow.cpp" />
|
||||
<ClCompile Include="CameraWindow.cpp" />
|
||||
<ClCompile Include="DecalWindow.cpp" />
|
||||
<ClCompile Include="Editor.cpp" />
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<ClInclude Include="WorldWindow.h">
|
||||
<Filter>Code</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AnimationWindow.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CameraWindow.cpp">
|
||||
@@ -120,6 +121,7 @@
|
||||
<ClCompile Include="WorldWindow.cpp">
|
||||
<Filter>Code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AnimationWindow.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="small.ico">
|
||||
|
||||
@@ -17,16 +17,12 @@ inline void Skinning(inout float4 pos, inout float4 posPrev, inout float4 inNor,
|
||||
if(any(inWei))
|
||||
{
|
||||
bonetype sump = 0, sumpPrev = 0;
|
||||
float sumw = 0.0f;
|
||||
inWei = normalize(inWei);
|
||||
[unroll]
|
||||
for (uint i = 0; i < 4; i++)
|
||||
{
|
||||
sumw += inWei[i];
|
||||
sump += boneBuffer[(uint)inBon[i]].pose * inWei[i];
|
||||
sumpPrev += boneBuffer[(uint)inBon[i]].prev * inWei[i];
|
||||
}
|
||||
sump /= sumw;
|
||||
sumpPrev /= sumw;
|
||||
pos = mul(pos, sump);
|
||||
posPrev = mul(posPrev, sumpPrev);
|
||||
inNor.xyz = mul(inNor.xyz, (float3x3)sump);
|
||||
|
||||
@@ -2243,6 +2243,16 @@ void Mesh::CreateVertexArrays()
|
||||
vertices_Complete.resize(vertices.size());
|
||||
for (size_t i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
// normalize bone weights:
|
||||
float len = vertices[i].wei.x + vertices[i].wei.y + vertices[i].wei.z + vertices[i].wei.w;
|
||||
if (len > 0)
|
||||
{
|
||||
vertices[i].wei.x /= len;
|
||||
vertices[i].wei.y /= len;
|
||||
vertices[i].wei.z /= len;
|
||||
vertices[i].wei.w /= len;
|
||||
}
|
||||
// copy the vertex to the unskinned vertex array:
|
||||
vertices_Complete[i].pos = vertices[i].pos;
|
||||
vertices_Complete[i].nor = vertices[i].nor;
|
||||
vertices_Complete[i].tex = vertices[i].tex;
|
||||
|
||||
+30
-36
@@ -1308,68 +1308,62 @@ Vertex wiRenderer::TransformVertex(const Mesh* mesh, const SkinnedVertex& vertex
|
||||
,vertex.bon.z
|
||||
,vertex.bon.w};
|
||||
XMMATRIX sump;
|
||||
if(inWei[0] || inWei[1] || inWei[2] || inWei[3]){
|
||||
sump = XMMATRIX(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||
float sumw = 0;
|
||||
for(unsigned int i=0;i<4;i++){
|
||||
sumw += inWei[i];
|
||||
sump += XMLoadFloat4x4( &mesh->armature->boneCollection[int(inBon[i])]->boneRelativity ) * inWei[i];
|
||||
if (inWei[0] || inWei[1] || inWei[2] || inWei[3])
|
||||
{
|
||||
sump = XMMATRIX(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
sump += XMLoadFloat4x4(&mesh->armature->boneCollection[int(inBon[i])]->boneRelativity) * inWei[i];
|
||||
}
|
||||
if(sumw) sump/=sumw;
|
||||
|
||||
//sump = XMMatrixTranspose(sump);
|
||||
}
|
||||
else
|
||||
{
|
||||
sump = XMMatrixIdentity();
|
||||
}
|
||||
|
||||
//sump*=mat;
|
||||
sump = XMMatrixMultiply(sump, mat);
|
||||
|
||||
XMFLOAT3 transformedP,transformedN;
|
||||
XMStoreFloat3( &transformedP,XMVector3Transform(pos,sump) );
|
||||
XMStoreFloat3(&transformedP, XMVector3Transform(pos, sump));
|
||||
|
||||
sump.r[3]=XMVectorSetX(sump.r[3],0);
|
||||
sump.r[3]=XMVectorSetY(sump.r[3],0);
|
||||
sump.r[3]=XMVectorSetZ(sump.r[3],0);
|
||||
//sump.r[3].m128_f32[0]=sump.r[3].m128_f32[1]=sump.r[3].m128_f32[2]=0;
|
||||
XMStoreFloat3( &transformedN,XMVector3Normalize(XMVector3Transform(nor,sump)));
|
||||
XMStoreFloat3(&transformedN, XMVector3Normalize(XMVector3TransformNormal(nor, sump)));
|
||||
|
||||
Vertex retV(transformedP);
|
||||
retV.nor = XMFLOAT4(transformedN.x, transformedN.y, transformedN.z,retV.nor.w);
|
||||
retV.nor = XMFLOAT4(transformedN.x, transformedN.y, transformedN.z, retV.nor.w);
|
||||
retV.tex = vertex.tex;
|
||||
retV.pre=XMFLOAT4(0,0,0,1);
|
||||
retV.pre = XMFLOAT4(0, 0, 0, 1);
|
||||
|
||||
return retV;
|
||||
}
|
||||
XMFLOAT3 wiRenderer::VertexVelocity(const Mesh* mesh, const int& vertexI){
|
||||
XMVECTOR pos = XMLoadFloat4( &mesh->vertices[vertexI].pos );
|
||||
float inWei[4]={mesh->vertices[vertexI].wei.x
|
||||
XMFLOAT3 wiRenderer::VertexVelocity(const Mesh* mesh, const int& vertexI)
|
||||
{
|
||||
XMVECTOR pos = XMLoadFloat4(&mesh->vertices[vertexI].pos);
|
||||
float inWei[4] = { mesh->vertices[vertexI].wei.x
|
||||
,mesh->vertices[vertexI].wei.y
|
||||
,mesh->vertices[vertexI].wei.z
|
||||
,mesh->vertices[vertexI].wei.w};
|
||||
float inBon[4]={mesh->vertices[vertexI].bon.x
|
||||
,mesh->vertices[vertexI].wei.w };
|
||||
float inBon[4] = { mesh->vertices[vertexI].bon.x
|
||||
,mesh->vertices[vertexI].bon.y
|
||||
,mesh->vertices[vertexI].bon.z
|
||||
,mesh->vertices[vertexI].bon.w};
|
||||
,mesh->vertices[vertexI].bon.w };
|
||||
XMMATRIX sump;
|
||||
XMMATRIX sumpPrev;
|
||||
if(inWei[0] || inWei[1] || inWei[2] || inWei[3]){
|
||||
sump = sumpPrev = XMMATRIX(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||
float sumw = 0;
|
||||
for(unsigned int i=0;i<4;i++){
|
||||
sumw += inWei[i];
|
||||
sump += XMLoadFloat4x4( &mesh->armature->boneCollection[int(inBon[i])]->boneRelativity ) * inWei[i];
|
||||
sumpPrev += XMLoadFloat4x4( &mesh->armature->boneCollection[int(inBon[i])]->boneRelativityPrev ) * inWei[i];
|
||||
}
|
||||
if(sumw){
|
||||
sump/=sumw;
|
||||
sumpPrev/=sumw;
|
||||
if (inWei[0] || inWei[1] || inWei[2] || inWei[3])
|
||||
{
|
||||
sump = sumpPrev = XMMATRIX(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
sump += XMLoadFloat4x4(&mesh->armature->boneCollection[int(inBon[i])]->boneRelativity) * inWei[i];
|
||||
sumpPrev += XMLoadFloat4x4(&mesh->armature->boneCollection[int(inBon[i])]->boneRelativityPrev) * inWei[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sump = sumpPrev = XMMatrixIdentity();
|
||||
}
|
||||
|
||||
XMFLOAT3 velocity;
|
||||
XMStoreFloat3( &velocity,GetGameSpeed()*XMVectorSubtract(XMVector3Transform(pos,sump),XMVector3Transform(pos,sumpPrev)) );
|
||||
XMStoreFloat3(&velocity, GetGameSpeed()*XMVectorSubtract(XMVector3Transform(pos, sump), XMVector3Transform(pos, sumpPrev)));
|
||||
return velocity;
|
||||
}
|
||||
void wiRenderer::Update()
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace wiVersion
|
||||
// minor features, major updates
|
||||
const int minor = 9;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 59;
|
||||
const int revision = 60;
|
||||
|
||||
|
||||
long GetVersion()
|
||||
|
||||
@@ -892,8 +892,17 @@ void wiComboBox::SetSelected(int index)
|
||||
|
||||
wiEventArgs args;
|
||||
args.iValue = selected;
|
||||
args.sValue = GetItemText(selected);
|
||||
onSelect(args);
|
||||
}
|
||||
string wiComboBox::GetItemText(int index)
|
||||
{
|
||||
if (index >= 0)
|
||||
{
|
||||
return items[index];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
int wiComboBox::GetSelected()
|
||||
{
|
||||
return selected;
|
||||
|
||||
@@ -18,6 +18,7 @@ struct wiEventArgs
|
||||
bool bValue;
|
||||
int iValue;
|
||||
XMFLOAT4 color;
|
||||
string sValue;
|
||||
};
|
||||
|
||||
class wiWidget : public Transform
|
||||
@@ -195,6 +196,7 @@ public:
|
||||
|
||||
void SetSelected(int index);
|
||||
int GetSelected();
|
||||
string GetItemText(int index);
|
||||
|
||||
virtual void Update(wiGUI* gui) override;
|
||||
virtual void Render(wiGUI* gui) override;
|
||||
|
||||
Reference in New Issue
Block a user