Commit 2a5d18ff authored by chili's avatar chili
Browse files

node parsing model system beginnings

parent d219ca73
...@@ -10,9 +10,6 @@ ...@@ -10,9 +10,6 @@
#include "Surface.h" #include "Surface.h"
#include "GDIPlusManager.h" #include "GDIPlusManager.h"
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
namespace dx = DirectX; namespace dx = DirectX;
...@@ -23,74 +20,6 @@ App::App() ...@@ -23,74 +20,6 @@ App::App()
wnd( 800,600,"The Donkey Fart Box" ), wnd( 800,600,"The Donkey Fart Box" ),
light( wnd.Gfx() ) light( wnd.Gfx() )
{ {
class Factory
{
public:
Factory( Graphics& gfx )
:
gfx( gfx )
{}
std::unique_ptr<Drawable> operator()()
{
const DirectX::XMFLOAT3 mat = { cdist( rng ),cdist( rng ),cdist( rng ) };
switch( sdist( rng ) )
{
case 0:
return std::make_unique<Box>(
gfx,rng,adist,ddist,
odist,rdist,bdist,mat
);
case 1:
return std::make_unique<Cylinder>(
gfx,rng,adist,ddist,odist,
rdist,bdist,tdist
);
case 2:
return std::make_unique<Pyramid>(
gfx,rng,adist,ddist,odist,
rdist,tdist
);
case 3:
return std::make_unique<SkinnedBox>(
gfx,rng,adist,ddist,
odist,rdist
);
case 4:
return std::make_unique<AssTest>(
gfx,rng,adist,ddist,
odist,rdist,mat,1.5f
);
default:
assert( false && "impossible drawable option in factory" );
return {};
}
}
private:
Graphics& gfx;
std::mt19937 rng{ std::random_device{}() };
std::uniform_int_distribution<int> sdist{ 0,4 };
std::uniform_real_distribution<float> adist{ 0.0f,PI * 2.0f };
std::uniform_real_distribution<float> ddist{ 0.0f,PI * 0.5f };
std::uniform_real_distribution<float> odist{ 0.0f,PI * 0.08f };
std::uniform_real_distribution<float> rdist{ 6.0f,20.0f };
std::uniform_real_distribution<float> bdist{ 0.4f,3.0f };
std::uniform_real_distribution<float> cdist{ 0.0f,1.0f };
std::uniform_int_distribution<int> tdist{ 3,30 };
};
drawables.reserve( nDrawables );
std::generate_n( std::back_inserter( drawables ),nDrawables,Factory{ wnd.Gfx() } );
// init box pointers for editing instance parameters
for( auto& pd : drawables )
{
if( auto pb = dynamic_cast<Box*>(pd.get()) )
{
boxes.push_back( pb );
}
}
wnd.Gfx().SetProjection( dx::XMMatrixPerspectiveLH( 1.0f,3.0f / 4.0f,0.5f,40.0f ) ); wnd.Gfx().SetProjection( dx::XMMatrixPerspectiveLH( 1.0f,3.0f / 4.0f,0.5f,40.0f ) );
} }
...@@ -101,82 +30,17 @@ void App::DoFrame() ...@@ -101,82 +30,17 @@ void App::DoFrame()
wnd.Gfx().SetCamera( cam.GetMatrix() ); wnd.Gfx().SetCamera( cam.GetMatrix() );
light.Bind( wnd.Gfx(),cam.GetMatrix() ); light.Bind( wnd.Gfx(),cam.GetMatrix() );
// render geometry nano.Draw( wnd.Gfx() );
for( auto& d : drawables )
{
d->Update( wnd.kbd.KeyIsPressed( VK_SPACE ) ? 0.0f : dt );
d->Draw( wnd.Gfx() );
}
light.Draw( wnd.Gfx() ); light.Draw( wnd.Gfx() );
// imgui windows // imgui windows
SpawnSimulationWindow();
cam.SpawnControlWindow(); cam.SpawnControlWindow();
light.SpawnControlWindow(); light.SpawnControlWindow();
SpawnBoxWindowManagerWindow();
SpawnBoxWindows();
// present // present
wnd.Gfx().EndFrame(); wnd.Gfx().EndFrame();
} }
void App::SpawnSimulationWindow() noexcept
{
if( ImGui::Begin( "Simulation Speed" ) )
{
ImGui::SliderFloat( "Speed Factor",&speed_factor,0.0f,6.0f,"%.4f",3.2f );
ImGui::Text( "%.3f ms/frame (%.1f FPS)",1000.0f / ImGui::GetIO().Framerate,ImGui::GetIO().Framerate );
ImGui::Text( "Status: %s",wnd.kbd.KeyIsPressed( VK_SPACE ) ? "PAUSED" : "RUNNING (hold spacebar to pause)" );
}
ImGui::End();
}
void App::SpawnBoxWindowManagerWindow() noexcept
{
if( ImGui::Begin( "Boxes" ) )
{
using namespace std::string_literals;
const auto preview = comboBoxIndex ? std::to_string( *comboBoxIndex ) : "Choose a box..."s;
if( ImGui::BeginCombo( "Box Number",preview.c_str() ) )
{
for( int i = 0; i < boxes.size(); i++ )
{
const bool selected = *comboBoxIndex == i;
if( ImGui::Selectable( std::to_string( i ).c_str(),selected ) )
{
comboBoxIndex = i;
}
if( selected )
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
if( ImGui::Button( "Spawn Control Window" ) && comboBoxIndex )
{
boxControlIds.insert( *comboBoxIndex );
comboBoxIndex.reset();
}
}
ImGui::End();
}
void App::SpawnBoxWindows() noexcept
{
for( auto i = boxControlIds.begin(); i != boxControlIds.end(); )
{
if( !boxes[*i]->SpawnControlWindow( *i,wnd.Gfx() ) )
{
i = boxControlIds.erase( i );
}
else
{
i++;
}
}
}
App::~App() App::~App()
{} {}
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ImguiManager.h" #include "ImguiManager.h"
#include "Camera.h" #include "Camera.h"
#include "PointLight.h" #include "PointLight.h"
#include "Model.h"
#include <set> #include <set>
class App class App
...@@ -15,19 +16,12 @@ public: ...@@ -15,19 +16,12 @@ public:
~App(); ~App();
private: private:
void DoFrame(); void DoFrame();
void SpawnSimulationWindow() noexcept;
void SpawnBoxWindowManagerWindow() noexcept;
void SpawnBoxWindows() noexcept;
private: private:
ImguiManager imgui; ImguiManager imgui;
Window wnd; Window wnd;
ChiliTimer timer; ChiliTimer timer;
std::vector<std::unique_ptr<class Drawable>> drawables;
std::vector<class Box*> boxes;
float speed_factor = 1.0f; float speed_factor = 1.0f;
Camera cam; Camera cam;
PointLight light; PointLight light;
static constexpr size_t nDrawables = 180; Model nano{ wnd.Gfx(),"Models\\nanosuit.obj" };
std::optional<int> comboBoxIndex;
std::set<int> boxControlIds;
}; };
\ No newline at end of file
...@@ -13,7 +13,8 @@ public: ...@@ -13,7 +13,8 @@ public:
Drawable( const Drawable& ) = delete; Drawable( const Drawable& ) = delete;
virtual DirectX::XMMATRIX GetTransformXM() const noexcept = 0; virtual DirectX::XMMATRIX GetTransformXM() const noexcept = 0;
void Draw( Graphics& gfx ) const noexcept(!IS_DEBUG); void Draw( Graphics& gfx ) const noexcept(!IS_DEBUG);
virtual void Update( float dt ) noexcept = 0; virtual void Update( float dt ) noexcept
{}
virtual ~Drawable() = default; virtual ~Drawable() = default;
protected: protected:
template<class T> template<class T>
......
#pragma once
#include "DrawableBase.h"
#include "BindableBase.h"
#include "Vertex.h"
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
class Mesh : public DrawableBase<Mesh>
{
public:
Mesh( Graphics& gfx,std::vector<std::unique_ptr<Bindable>> bindPtrs )
{
if( !IsStaticInitialized() )
{
AddStaticBind( std::make_unique<Topology>( gfx,D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ) );
}
for( auto& pb : bindPtrs )
{
if( auto pi = dynamic_cast<IndexBuffer*>(pb.get()) )
{
AddIndexBuffer( std::unique_ptr<IndexBuffer>{ pi } );
pb.release();
}
else
{
AddBind( std::move( pb ) );
}
}
AddBind( std::make_unique<TransformCbuf>( gfx,*this ) );
}
void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noexcept( !IS_DEBUG )
{
DirectX::XMStoreFloat4x4( &transform,accumulatedTransform );
Drawable::Draw( gfx );
}
DirectX::XMMATRIX GetTransformXM() const noexcept override
{
return DirectX::XMLoadFloat4x4( &transform );
}
private:
mutable DirectX::XMFLOAT4X4 transform;
};
class Node
{
friend class Model;
public:
Node( std::vector<Mesh*> meshPtrs,const DirectX::XMMATRIX& transform ) noexcept(!IS_DEBUG)
:
meshPtrs( std::move( meshPtrs ) )
{
DirectX::XMStoreFloat4x4( &this->transform,transform );
}
void Draw( Graphics& gfx,DirectX::FXMMATRIX accumulatedTransform ) const noexcept(!IS_DEBUG)
{
const auto built = DirectX::XMLoadFloat4x4( &transform ) * accumulatedTransform;
for( const auto pm : meshPtrs )
{
pm->Draw( gfx,built );
}
for( const auto& pc : childPtrs )
{
pc->Draw( gfx,built );
}
}
private:
void AddChild( std::unique_ptr<Node> pChild ) noexcept(!IS_DEBUG)
{
assert( pChild );
childPtrs.push_back( std::move( pChild ) );
}
private:
std::vector<std::unique_ptr<Node>> childPtrs;
std::vector<Mesh*> meshPtrs;
DirectX::XMFLOAT4X4 transform;
};
class Model
{
public:
Model( Graphics& gfx,const std::string fileName )
{
Assimp::Importer imp;
const auto pScene = imp.ReadFile( fileName.c_str(),
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices
);
for( size_t i = 0; i < pScene->mNumMeshes; i++ )
{
meshPtrs.push_back( ParseMesh( gfx,*pScene->mMeshes[i] ) );
}
pRoot = ParseNode( *pScene->mRootNode );
}
static std::unique_ptr<Mesh> ParseMesh( Graphics& gfx,const aiMesh& mesh )
{
namespace dx = DirectX;
using hw3dexp::VertexLayout;
hw3dexp::VertexBuffer vbuf( std::move(
VertexLayout{}
.Append( VertexLayout::Position3D )
.Append( VertexLayout::Normal )
) );
for( unsigned int i = 0; i < mesh.mNumVertices; i++ )
{
vbuf.EmplaceBack(
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mVertices[i]),
*reinterpret_cast<dx::XMFLOAT3*>(&mesh.mNormals[i])
);
}
std::vector<unsigned short> indices;
indices.reserve( mesh.mNumFaces * 3 );
for( unsigned int i = 0; i < mesh.mNumFaces; i++ )
{
const auto& face = mesh.mFaces[i];
assert( face.mNumIndices == 3 );
indices.push_back( face.mIndices[0] );
indices.push_back( face.mIndices[1] );
indices.push_back( face.mIndices[2] );
}
std::vector<std::unique_ptr<Bindable>> bindablePtrs;
bindablePtrs.push_back( std::make_unique<VertexBuffer>( gfx,vbuf ) );
bindablePtrs.push_back( std::make_unique<IndexBuffer>( gfx,indices ) );
auto pvs = std::make_unique<VertexShader>( gfx,L"PhongVS.cso" );
auto pvsbc = pvs->GetBytecode();
bindablePtrs.push_back( std::move( pvs ) );
bindablePtrs.push_back( std::make_unique<PixelShader>( gfx,L"PhongPS.cso" ) );
bindablePtrs.push_back( std::make_unique<InputLayout>( gfx,vbuf.GetLayout().GetD3DLayout(),pvsbc ) );
struct PSMaterialConstant
{
DirectX::XMFLOAT3 color = { 0.6f,0.6f,0.8f };
float specularIntensity = 0.6f;
float specularPower = 30.0f;
float padding[3];
} pmc;
bindablePtrs.push_back( std::make_unique<PixelConstantBuffer<PSMaterialConstant>>( gfx,pmc,1u ) );
return std::make_unique<Mesh>( gfx,std::move( bindablePtrs ) );
}
std::unique_ptr<Node> ParseNode( const aiNode& node )
{
namespace dx = DirectX;
const auto transform = dx::XMMatrixTranspose( dx::XMLoadFloat4x4(
reinterpret_cast<const dx::XMFLOAT4X4*>(&node.mTransformation)
) );
std::vector<Mesh*> curMeshPtrs;
curMeshPtrs.reserve( node.mNumMeshes );
for( size_t i = 0; i < node.mNumMeshes; i++ )
{
const auto meshIdx = node.mMeshes[i];
curMeshPtrs.push_back( meshPtrs.at( meshIdx ).get() );
}
auto pNode = std::make_unique<Node>( std::move( curMeshPtrs ),transform );
for( size_t i = 0; i < node.mNumChildren; i++ )
{
pNode->AddChild( ParseNode( *node.mChildren[i] ) );
}
return pNode;
}
void Draw( Graphics& gfx ) const
{
pRoot->Draw( gfx,DirectX::XMMatrixIdentity() );
}
private:
std::unique_ptr<Node> pRoot;
std::vector<std::unique_ptr<Mesh>> meshPtrs;
};
\ No newline at end of file
...@@ -167,6 +167,7 @@ ...@@ -167,6 +167,7 @@
<ClInclude Include="IndexedTriangleList.h" /> <ClInclude Include="IndexedTriangleList.h" />
<ClInclude Include="InputLayout.h" /> <ClInclude Include="InputLayout.h" />
<ClInclude Include="Keyboard.h" /> <ClInclude Include="Keyboard.h" />
<ClInclude Include="Model.h" />
<ClInclude Include="PointLight.h" /> <ClInclude Include="PointLight.h" />
<ClInclude Include="Pyramid.h" /> <ClInclude Include="Pyramid.h" />
<ClInclude Include="SolidSphere.h" /> <ClInclude Include="SolidSphere.h" />
......
...@@ -329,6 +329,9 @@ ...@@ -329,6 +329,9 @@
<ClInclude Include="Vertex.h"> <ClInclude Include="Vertex.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Model.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="hw3d.rc"> <ResourceCompile Include="hw3d.rc">
......
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