Commit caf57593 authored by chili's avatar chili
Browse files

control transform of any node in model

parent 2c1c78d4
#include "Mesh.h" #include "Mesh.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include <unordered_map>
namespace dx = DirectX; namespace dx = DirectX;
...@@ -43,12 +44,16 @@ Node::Node( const std::string& name,std::vector<Mesh*> meshPtrs,const DirectX::X ...@@ -43,12 +44,16 @@ Node::Node( const std::string& name,std::vector<Mesh*> meshPtrs,const DirectX::X
meshPtrs( std::move( meshPtrs ) ), meshPtrs( std::move( meshPtrs ) ),
name( name ) name( name )
{ {
DirectX::XMStoreFloat4x4( &this->transform,transform ); dx::XMStoreFloat4x4( &baseTransform,transform );
dx::XMStoreFloat4x4( &appliedTransform,dx::XMMatrixIdentity() );
} }
void Node::Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd void Node::Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd
{ {
const auto built = DirectX::XMLoadFloat4x4( &transform ) * accumulatedTransform; const auto built =
dx::XMLoadFloat4x4( &baseTransform ) *
dx::XMLoadFloat4x4( &appliedTransform ) *
accumulatedTransform;
for( const auto pm : meshPtrs ) for( const auto pm : meshPtrs )
{ {
pm->Draw( gfx,built ); pm->Draw( gfx,built );
...@@ -65,7 +70,7 @@ void Node::AddChild( std::unique_ptr<Node> pChild ) noxnd ...@@ -65,7 +70,7 @@ void Node::AddChild( std::unique_ptr<Node> pChild ) noxnd
childPtrs.push_back( std::move( pChild ) ); childPtrs.push_back( std::move( pChild ) );
} }
void Node::ShowTree( int& nodeIndexTracked,std::optional<int>& selectedIndex ) const noexcept void Node::ShowTree( int& nodeIndexTracked,std::optional<int>& selectedIndex,Node*& pSelectedNode ) const noexcept
{ {
// nodeIndex serves as the uid for gui tree nodes, incremented throughout recursion // nodeIndex serves as the uid for gui tree nodes, incremented throughout recursion
const int currentNodeIndex = nodeIndexTracked; const int currentNodeIndex = nodeIndexTracked;
...@@ -77,15 +82,26 @@ void Node::ShowTree( int& nodeIndexTracked,std::optional<int>& selectedIndex ) c ...@@ -77,15 +82,26 @@ void Node::ShowTree( int& nodeIndexTracked,std::optional<int>& selectedIndex ) c
// if tree node expanded, recursively render all children // if tree node expanded, recursively render all children
if( ImGui::TreeNodeEx( (void*)(intptr_t)currentNodeIndex,node_flags,name.c_str() ) ) if( ImGui::TreeNodeEx( (void*)(intptr_t)currentNodeIndex,node_flags,name.c_str() ) )
{ {
selectedIndex = ImGui::IsItemClicked() ? currentNodeIndex : selectedIndex; // detecting / setting selected node
if( ImGui::IsItemClicked() )
{
selectedIndex = currentNodeIndex;
pSelectedNode = const_cast<Node*>(this);
}
for( const auto& pChild : childPtrs ) for( const auto& pChild : childPtrs )
{ {
pChild->ShowTree( nodeIndexTracked,selectedIndex ); pChild->ShowTree( nodeIndexTracked,selectedIndex,pSelectedNode );
} }
ImGui::TreePop(); ImGui::TreePop();
} }
} }
void Node::SetAppliedTransform( DirectX::FXMMATRIX transform ) noexcept
{
dx::XMStoreFloat4x4( &appliedTransform,transform );
}
// Model // Model
class ModelWindow // pImpl idiom, only defined in this .cpp class ModelWindow // pImpl idiom, only defined in this .cpp
...@@ -100,28 +116,39 @@ public: ...@@ -100,28 +116,39 @@ public:
if( ImGui::Begin( windowName ) ) if( ImGui::Begin( windowName ) )
{ {
ImGui::Columns( 2,nullptr,true ); ImGui::Columns( 2,nullptr,true );
root.ShowTree( nodeIndexTracker,selectedIndex ); root.ShowTree( nodeIndexTracker,selectedIndex,pSelectedNode );
ImGui::NextColumn(); ImGui::NextColumn();
if( pSelectedNode != nullptr )
{
auto& transform = transforms[*selectedIndex];
ImGui::Text( "Orientation" ); ImGui::Text( "Orientation" );
ImGui::SliderAngle( "Roll",&pos.roll,-180.0f,180.0f ); ImGui::SliderAngle( "Roll",&transform.roll,-180.0f,180.0f );
ImGui::SliderAngle( "Pitch",&pos.pitch,-180.0f,180.0f ); ImGui::SliderAngle( "Pitch",&transform.pitch,-180.0f,180.0f );
ImGui::SliderAngle( "Yaw",&pos.yaw,-180.0f,180.0f ); ImGui::SliderAngle( "Yaw",&transform.yaw,-180.0f,180.0f );
ImGui::Text( "Position" ); ImGui::Text( "Position" );
ImGui::SliderFloat( "X",&pos.x,-20.0f,20.0f ); ImGui::SliderFloat( "X",&transform.x,-20.0f,20.0f );
ImGui::SliderFloat( "Y",&pos.y,-20.0f,20.0f ); ImGui::SliderFloat( "Y",&transform.y,-20.0f,20.0f );
ImGui::SliderFloat( "Z",&pos.z,-20.0f,20.0f ); ImGui::SliderFloat( "Z",&transform.z,-20.0f,20.0f );
}
} }
ImGui::End(); ImGui::End();
} }
dx::XMMATRIX GetTransform() const noexcept dx::XMMATRIX GetTransform() const noexcept
{ {
return dx::XMMatrixRotationRollPitchYaw( pos.roll,pos.pitch,pos.yaw ) * const auto& transform = transforms.at( *selectedIndex );
dx::XMMatrixTranslation( pos.x,pos.y,pos.z ); return
dx::XMMatrixRotationRollPitchYaw( transform.roll,transform.pitch,transform.yaw ) *
dx::XMMatrixTranslation( transform.x,transform.y,transform.z );
}
Node* GetSelectedNode() const noexcept
{
return pSelectedNode;
} }
private: private:
std::optional<int> selectedIndex; std::optional<int> selectedIndex;
struct Node* pSelectedNode;
struct TransformParameters
{ {
float roll = 0.0f; float roll = 0.0f;
float pitch = 0.0f; float pitch = 0.0f;
...@@ -129,7 +156,8 @@ private: ...@@ -129,7 +156,8 @@ private:
float x = 0.0f; float x = 0.0f;
float y = 0.0f; float y = 0.0f;
float z = 0.0f; float z = 0.0f;
} pos; };
std::unordered_map<int,TransformParameters> transforms;
}; };
Model::Model( Graphics& gfx,const std::string fileName ) Model::Model( Graphics& gfx,const std::string fileName )
...@@ -152,7 +180,11 @@ Model::Model( Graphics& gfx,const std::string fileName ) ...@@ -152,7 +180,11 @@ Model::Model( Graphics& gfx,const std::string fileName )
void Model::Draw( Graphics& gfx ) const noxnd void Model::Draw( Graphics& gfx ) const noxnd
{ {
pRoot->Draw( gfx,pWindow->GetTransform() ); if( auto node = pWindow->GetSelectedNode() )
{
node->SetAppliedTransform( pWindow->GetTransform() );
}
pRoot->Draw( gfx,dx::XMMatrixIdentity() );
} }
void Model::ShowWindow( const char* windowName ) noexcept void Model::ShowWindow( const char* windowName ) noexcept
......
...@@ -21,17 +21,20 @@ private: ...@@ -21,17 +21,20 @@ private:
class Node class Node
{ {
friend class Model; friend class Model;
friend class ModelWindow;
public: public:
Node( const std::string& name,std::vector<Mesh*> meshPtrs,const DirectX::XMMATRIX& transform ) noxnd; Node( const std::string& name,std::vector<Mesh*> meshPtrs,const DirectX::XMMATRIX& transform ) noxnd;
void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd; void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noxnd;
void ShowTree( int& nodeIndex,std::optional<int>& selectedIndex ) const noexcept; void SetAppliedTransform( DirectX::FXMMATRIX transform ) noexcept;
private: private:
void AddChild( std::unique_ptr<Node> pChild ) noxnd; void AddChild( std::unique_ptr<Node> pChild ) noxnd;
void ShowTree( int& nodeIndex,std::optional<int>& selectedIndex,Node*& pSelectedNode ) const noexcept;
private: private:
std::string name; std::string name;
std::vector<std::unique_ptr<Node>> childPtrs; std::vector<std::unique_ptr<Node>> childPtrs;
std::vector<Mesh*> meshPtrs; std::vector<Mesh*> meshPtrs;
DirectX::XMFLOAT4X4 transform; DirectX::XMFLOAT4X4 baseTransform;
DirectX::XMFLOAT4X4 appliedTransform;
}; };
class Model class Model
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment