Commit 7b5a8d68 authored by chili's avatar chili
Browse files

geometric primitives

parent e1087340
...@@ -8,10 +8,10 @@ App::App() ...@@ -8,10 +8,10 @@ App::App()
{ {
std::mt19937 rng( std::random_device{}() ); std::mt19937 rng( std::random_device{}() );
std::uniform_real_distribution<float> adist( 0.0f,3.1415f * 2.0f ); std::uniform_real_distribution<float> adist( 0.0f,3.1415f * 2.0f );
std::uniform_real_distribution<float> ddist( 0.0f,3.1415f * 2.0f ); std::uniform_real_distribution<float> ddist( 0.0f,3.1415f * 1.0f );
std::uniform_real_distribution<float> odist( 0.0f,3.1415f * 0.3f ); std::uniform_real_distribution<float> odist( 0.0f,3.1415f * 0.08f );
std::uniform_real_distribution<float> rdist( 6.0f,20.0f ); std::uniform_real_distribution<float> rdist( 6.0f,20.0f );
for( auto i = 0; i < 80; i++ ) for( auto i = 0; i < 180; i++ )
{ {
boxes.push_back( std::make_unique<Box>( boxes.push_back( std::make_unique<Box>(
wnd.Gfx(),rng,adist, wnd.Gfx(),rng,adist,
......
#include "Box.h" #include "Box.h"
#include "BindableBase.h" #include "BindableBase.h"
#include "GraphicsThrowMacros.h" #include "GraphicsThrowMacros.h"
#include "Sphere.h"
Box::Box( Graphics& gfx, Box::Box( Graphics& gfx,
std::mt19937& rng, std::mt19937& rng,
...@@ -20,29 +22,18 @@ Box::Box( Graphics& gfx, ...@@ -20,29 +22,18 @@ Box::Box( Graphics& gfx,
theta( adist( rng ) ), theta( adist( rng ) ),
phi( adist( rng ) ) phi( adist( rng ) )
{ {
namespace dx = DirectX;
if( !IsStaticInitialized() ) if( !IsStaticInitialized() )
{ {
struct Vertex struct Vertex
{ {
struct dx::XMFLOAT3 pos;
{
float x;
float y;
float z;
} pos;
}; };
const std::vector<Vertex> vertices = auto model = Sphere::Make<Vertex>();
{ model.Transform( dx::XMMatrixScaling( 1.0f,1.0f,1.2f ) );
{ -1.0f,-1.0f,-1.0f },
{ 1.0f,-1.0f,-1.0f }, AddStaticBind( std::make_unique<VertexBuffer>( gfx,model.vertices ) );
{ -1.0f,1.0f,-1.0f },
{ 1.0f,1.0f,-1.0f },
{ -1.0f,-1.0f,1.0f },
{ 1.0f,-1.0f,1.0f },
{ -1.0f,1.0f,1.0f },
{ 1.0f,1.0f,1.0f },
};
AddStaticBind( std::make_unique<VertexBuffer>( gfx,vertices ) );
auto pvs = std::make_unique<VertexShader>( gfx,L"VertexShader.cso" ); auto pvs = std::make_unique<VertexShader>( gfx,L"VertexShader.cso" );
auto pvsbc = pvs->GetBytecode(); auto pvsbc = pvs->GetBytecode();
...@@ -50,16 +41,7 @@ Box::Box( Graphics& gfx, ...@@ -50,16 +41,7 @@ Box::Box( Graphics& gfx,
AddStaticBind( std::make_unique<PixelShader>( gfx,L"PixelShader.cso" ) ); AddStaticBind( std::make_unique<PixelShader>( gfx,L"PixelShader.cso" ) );
const std::vector<unsigned short> indices = AddStaticIndexBuffer( std::make_unique<IndexBuffer>( gfx,model.indices ) );
{
0,2,1, 2,3,1,
1,3,5, 3,7,5,
2,6,3, 3,6,7,
4,5,7, 4,7,6,
0,4,2, 2,4,6,
0,1,4, 1,5,4
};
AddStaticIndexBuffer( std::make_unique<IndexBuffer>( gfx,indices ) );
struct ConstantBuffer2 struct ConstantBuffer2
{ {
......
#pragma once
#include <math.h>
constexpr float PI = 3.14159265f;
constexpr double PI_D = 3.1415926535897932;
template <typename T>
constexpr auto sq( const T& x )
{
return x * x;
}
template<typename T>
T wrap_angle( T theta )
{
const T modded = fmod( theta,(T)2.0 * (T)PI_D );
return (modded > (T)PI_D) ?
(modded - (T)2.0 * (T)PI_D) :
modded;
}
template<typename T>
constexpr T interpolate( const T& src,const T& dst,float alpha )
{
return src + (dst - src) * alpha;
}
template<typename T>
constexpr T to_rad( T deg )
{
return deg * PI / (T)180.0;
}
\ No newline at end of file
#pragma once
#include "IndexedTriangleList.h"
#include <DirectXMath.h>
#include "ChiliMath.h"
class Cone
{
public:
template<class V>
static IndexedTriangleList<V> MakeTesselated( int longDiv )
{
namespace dx = DirectX;
assert( longDiv >= 3 );
const auto base = dx::XMVectorSet( 1.0f,0.0f,-1.0f,0.0f );
const float longitudeAngle = 2.0f * PI / longDiv;
// base vertices
std::vector<V> vertices;
for( int iLong = 0; iLong < longDiv; iLong++ )
{
vertices.emplace_back();
auto v = dx::XMVector3Transform(
base,
dx::XMMatrixRotationZ( longitudeAngle * iLong )
);
dx::XMStoreFloat3( &vertices.back().pos,v );
}
// the center
vertices.emplace_back();
vertices.back().pos = { 0.0f,0.0f,-1.0f };
const auto iCenter = (unsigned short)(vertices.size() - 1);
// the tip :darkness:
vertices.emplace_back();
vertices.back().pos = { 0.0f,0.0f,1.0f };
const auto iTip = (unsigned short)(vertices.size() - 1);
// base indices
std::vector<unsigned short> indices;
for( unsigned short iLong = 0; iLong < longDiv; iLong++ )
{
indices.push_back( iCenter );
indices.push_back( (iLong + 1) % longDiv );
indices.push_back( iLong );
}
// cone indices
for( unsigned short iLong = 0; iLong < longDiv; iLong++ )
{
indices.push_back( iLong );
indices.push_back( (iLong + 1) % longDiv );
indices.push_back( iTip );
}
return { std::move( vertices ),std::move( indices ) };
}
template<class V>
static IndexedTriangleList<V> Make()
{
return MakeTesselated<V>( 24 );
}
};
\ No newline at end of file
#pragma once
#include "IndexedTriangleList.h"
#include <DirectXMath.h>
class Cube
{
public:
template<class V>
static IndexedTriangleList<V> Make()
{
namespace dx = DirectX;
constexpr float side = 1.0f / 2.0f;
std::vector<dx::XMFLOAT3> vertices;
vertices.emplace_back( -side,-side,-side ); // 0
vertices.emplace_back( side,-side,-side ); // 1
vertices.emplace_back( -side,side,-side ); // 2
vertices.emplace_back( side,side,-side ); // 3
vertices.emplace_back( -side,-side,side ); // 4
vertices.emplace_back( side,-side,side ); // 5
vertices.emplace_back( -side,side,side ); // 6
vertices.emplace_back( side,side,side ); // 7
std::vector<V> verts( vertices.size() );
for( size_t i = 0; i < vertices.size(); i++ )
{
verts[i].pos = vertices[i];
}
return{
std::move( verts ),{
0,2,1, 2,3,1,
1,3,5, 3,7,5,
2,6,3, 3,6,7,
4,5,7, 4,7,6,
0,4,2, 2,4,6,
0,1,4, 1,5,4
}
};
}
};
\ No newline at end of file
#pragma once
#include <vector>
#include <DirectXMath.h>
template<class T>
class IndexedTriangleList
{
public:
IndexedTriangleList() = default;
IndexedTriangleList( std::vector<T> verts_in,std::vector<unsigned short> indices_in )
:
vertices( std::move( verts_in ) ),
indices( std::move( indices_in ) )
{
assert( vertices.size() > 2 );
assert( indices.size() % 3 == 0 );
}
void Transform( DirectX::FXMMATRIX matrix )
{
for( auto& v : vertices )
{
const DirectX::XMVECTOR pos = DirectX::XMLoadFloat3( &v.pos );
DirectX::XMStoreFloat3(
&v.pos,
DirectX::XMVector3Transform( pos,matrix )
);
}
}
public:
std::vector<T> vertices;
std::vector<unsigned short> indices;
};
\ No newline at end of file
...@@ -5,5 +5,5 @@ cbuffer CBuf ...@@ -5,5 +5,5 @@ cbuffer CBuf
float4 main( uint tid : SV_PrimitiveID ) : SV_Target float4 main( uint tid : SV_PrimitiveID ) : SV_Target
{ {
return face_colors[tid/2]; return face_colors[(tid/2) % 6];
} }
\ No newline at end of file
#pragma once
#include <vector>
#include <array>
#include "IndexedTriangleList.h"
#include "ChiliMath.h"
class Plane
{
public:
template<class V>
static IndexedTriangleList<V> MakeTesselated( int divisions_x,int divisions_y )
{
namespace dx = DirectX;
assert( divisions_x >= 1 );
assert( divisions_y >= 1 );
constexpr float width = 2.0f;
constexpr float height = 2.0f;
const int nVertices_x = divisions_x + 1;
const int nVertices_y = divisions_y + 1;
std::vector<V> vertices( nVertices_x * nVertices_y );
{
const float side_x = width / 2.0f;
const float side_y = height / 2.0f;
const float divisionSize_x = width / float( divisions_x );
const float divisionSize_y = height / float( divisions_y );
const auto bottomLeft = dx::XMVectorSet( -side_x,-side_y,0.0f,0.0f );
for( int y = 0,i = 0; y < nVertices_y; y++ )
{
const float y_pos = float( y ) * divisionSize_y;
for( int x = 0; x < nVertices_x; x++,i++ )
{
const auto v = dx::XMVectorAdd(
bottomLeft,
dx::XMVectorSet( float( x ) * divisionSize_x,y_pos,0.0f,0.0f )
);
dx::XMStoreFloat3( &vertices[i].pos,v );
}
}
}
std::vector<unsigned short> indices;
indices.reserve( sq( divisions_x * divisions_y ) * 6 );
{
const auto vxy2i = [nVertices_x]( size_t x,size_t y )
{
return (unsigned short)(y * nVertices_x + x);
};
for( size_t y = 0; y < divisions_y; y++ )
{
for( size_t x = 0; x < divisions_x; x++ )
{
const std::array<unsigned short,4> indexArray =
{ vxy2i( x,y ),vxy2i( x + 1,y ),vxy2i( x,y + 1 ),vxy2i( x + 1,y + 1 ) };
indices.push_back( indexArray[0] );
indices.push_back( indexArray[2] );
indices.push_back( indexArray[1] );
indices.push_back( indexArray[1] );
indices.push_back( indexArray[2] );
indices.push_back( indexArray[3] );
}
}
}
return{ std::move( vertices ),std::move( indices ) };
}
template<class V>
static IndexedTriangleList<V> Make()
{
return MakeTesselated<V>( 1,1 );
}
};
\ No newline at end of file
#pragma once
#include "IndexedTriangleList.h"
#include <DirectXMath.h>
#include "ChiliMath.h"
class Prism
{
public:
template<class V>
static IndexedTriangleList<V> MakeTesselated( int longDiv )
{
namespace dx = DirectX;
assert( longDiv >= 3 );
const auto base = dx::XMVectorSet( 1.0f,0.0f,-1.0f,0.0f );
const auto offset = dx::XMVectorSet( 0.0f,0.0f,2.0f,0.0f );
const float longitudeAngle = 2.0f * PI / longDiv;
// near center
std::vector<V> vertices;
vertices.emplace_back();
vertices.back().pos = { 0.0f,0.0f,-1.0f };
const auto iCenterNear = (unsigned short)(vertices.size() - 1);
// far center
vertices.emplace_back();
vertices.back().pos = { 0.0f,0.0f,1.0f };
const auto iCenterFar = (unsigned short)(vertices.size() - 1);
// base vertices
for( int iLong = 0; iLong < longDiv; iLong++ )
{
// near base
{
vertices.emplace_back();
auto v = dx::XMVector3Transform(
base,
dx::XMMatrixRotationZ( longitudeAngle * iLong )
);
dx::XMStoreFloat3( &vertices.back().pos,v );
}
// far base
{
vertices.emplace_back();
auto v = dx::XMVector3Transform(
base,
dx::XMMatrixRotationZ( longitudeAngle * iLong )
);
v = dx::XMVectorAdd( v,offset );
dx::XMStoreFloat3( &vertices.back().pos,v );
}
}
// side indices
std::vector<unsigned short> indices;
for( unsigned short iLong = 0; iLong < longDiv; iLong++ )
{
const auto i = iLong * 2;
const auto mod = longDiv * 2;
indices.push_back( i + 2 );
indices.push_back( (i + 2) % mod + 2 );
indices.push_back( i + 1 + 2 );
indices.push_back( (i + 2) % mod + 2 );
indices.push_back( (i + 3) % mod + 2 );
indices.push_back( i + 1 + 2 );
}
// base indices
for( unsigned short iLong = 0; iLong < longDiv; iLong++ )
{
const auto i = iLong * 2;
const auto mod = longDiv * 2;
indices.push_back( i + 2 );
indices.push_back( iCenterNear );
indices.push_back( (i + 2) % mod + 2 );
indices.push_back( iCenterFar );
indices.push_back( i + 1 + 2 );
indices.push_back( (i + 3) % mod + 2 );
}
return { std::move( vertices ),std::move( indices ) };
}
template<class V>
static IndexedTriangleList<V> Make()
{
return MakeTesselated<V>( 24 );
}
};
\ No newline at end of file
#pragma once
#include "IndexedTriangleList.h"
#include <DirectXMath.h>
#include "ChiliMath.h"
class Sphere
{
public:
template<class V>
static IndexedTriangleList<V> MakeTesselated( int latDiv,int longDiv )
{
namespace dx = DirectX;
assert( latDiv >= 3 );
assert( longDiv >= 3 );
constexpr float radius = 1.0f;
const auto base = dx::XMVectorSet( 0.0f,0.0f,radius,0.0f );
const float lattitudeAngle = PI / latDiv;
const float longitudeAngle = 2.0f * PI / longDiv;
std::vector<V> vertices;
for( int iLat = 1; iLat < latDiv; iLat++ )
{
const auto latBase = dx::XMVector3Transform(
base,
dx::XMMatrixRotationX( lattitudeAngle * iLat )
);
for( int iLong = 0; iLong < longDiv; iLong++ )
{
vertices.emplace_back();
auto v = dx::XMVector3Transform(
latBase,
dx::XMMatrixRotationZ( longitudeAngle * iLong )
);
dx::XMStoreFloat3( &vertices.back().pos,v );
}
}
// add the cap vertices
const auto iNorthPole = (unsigned short)vertices.size();
vertices.emplace_back();
dx::XMStoreFloat3( &vertices.back().pos,base );
const auto iSouthPole = (unsigned short)vertices.size();
vertices.emplace_back();
dx::XMStoreFloat3( &vertices.back().pos,dx::XMVectorNegate( base ) );
const auto calcIdx = [latDiv,longDiv]( unsigned short iLat,unsigned short iLong )
{ return iLat * longDiv + iLong; };
std::vector<unsigned short> indices;
for( unsigned short iLat = 0; iLat < latDiv - 2; iLat++ )
{
for( unsigned short iLong = 0; iLong < longDiv - 1; iLong++ )
{
indices.push_back( calcIdx( iLat,iLong ) );
indices.push_back( calcIdx( iLat + 1,iLong ) );
indices.push_back( calcIdx( iLat,iLong + 1 ) );
indices.push_back( calcIdx( iLat,iLong + 1 ) );
indices.push_back( calcIdx( iLat + 1,iLong ) );
indices.push_back( calcIdx( iLat + 1,iLong + 1 ) );
}
// wrap band
indices.push_back( calcIdx( iLat,longDiv - 1 ) );
indices.push_back( calcIdx( iLat + 1,longDiv - 1 ) );
indices.push_back( calcIdx( iLat,0 ) );
indices.push_back( calcIdx( iLat,0 ) );
indices.push_back( calcIdx( iLat + 1,longDiv - 1 ) );
indices.push_back( calcIdx( iLat + 1,0 ) );
}
// cap fans
for( unsigned short iLong = 0; iLong < longDiv - 1; iLong++ )
{
// north
indices.push_back( iNorthPole );
indices.push_back( calcIdx( 0,iLong ) );
indices.push_back( calcIdx( 0,iLong + 1 ) );
// south
indices.push_back( calcIdx( latDiv - 2,iLong + 1 ) );
indices.push_back( calcIdx( latDiv - 2,iLong ) );
indices.push_back( iSouthPole );
}
// wrap triangles
// north
indices.push_back( iNorthPole );
indices.push_back( calcIdx( 0,longDiv - 1 ) );
indices.push_back( calcIdx( 0,0 ) );
// south
indices.push_back( calcIdx( latDiv - 2,0 ) );
indices.push_back( calcIdx( latDiv - 2,longDiv - 1 ) );
indices.push_back( iSouthPole );
return { std::move( vertices ),std::move( indices ) };
}
template<class V>
static IndexedTriangleList<V> Make()
{
return MakeTesselated<V>( 12,24 );
}
};
\ No newline at end of file
...@@ -175,9 +175,12 @@ ...@@ -175,9 +175,12 @@
<ClInclude Include="BindableBase.h" /> <ClInclude Include="BindableBase.h" />
<ClInclude Include="Box.h" /> <ClInclude Include="Box.h" />
<ClInclude Include="ChiliException.h" /> <ClInclude Include="ChiliException.h" />
<ClInclude Include="ChiliMath.h" />
<ClInclude Include="ChiliTimer.h" /> <ClInclude Include="ChiliTimer.h" />
<ClInclude Include="ChiliWin.h" /> <ClInclude Include="ChiliWin.h" />
<ClInclude Include="Cone.h" />
<ClInclude Include="ConstantBuffers.h" /> <ClInclude Include="ConstantBuffers.h" />
<ClInclude Include="Cube.h" />
<ClInclude Include="Drawable.h" /> <ClInclude Include="Drawable.h" />
<ClInclude Include="DrawableBase.h" /> <ClInclude Include="DrawableBase.h" />
<ClInclude Include="dxerr.h" /> <ClInclude Include="dxerr.h" />
...@@ -185,11 +188,15 @@ ...@@ -185,11 +188,15 @@
<ClInclude Include="Graphics.h" /> <ClInclude Include="Graphics.h" />
<ClInclude Include="GraphicsThrowMacros.h" /> <ClInclude Include="GraphicsThrowMacros.h" />
<ClInclude Include="IndexBuffer.h" /> <ClInclude Include="IndexBuffer.h" />
<ClInclude Include="IndexedTriangleList.h" />
<ClInclude Include="InputLayout.h" /> <ClInclude Include="InputLayout.h" />
<ClInclude Include="Keyboard.h" /> <ClInclude Include="Keyboard.h" />
<ClInclude Include="Mouse.h" /> <ClInclude Include="Mouse.h" />
<ClInclude Include="PixelShader.h" /> <ClInclude Include="PixelShader.h" />
<ClInclude Include="Plane.h" />
<ClInclude Include="Prism.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="Sphere.h" />
<ClInclude Include="Topology.h" /> <ClInclude Include="Topology.h" />
<ClInclude Include="TransformCbuf.h" /> <ClInclude Include="TransformCbuf.h" />
<ClInclude Include="VertexBuffer.h" /> <ClInclude Include="VertexBuffer.h" />
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
<Filter Include="Source Files\Drawable"> <Filter Include="Source Files\Drawable">
<UniqueIdentifier>{43a2ba1f-f562-4758-9a91-b3da2e14ed89}</UniqueIdentifier> <UniqueIdentifier>{43a2ba1f-f562-4758-9a91-b3da2e14ed89}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\Geometry">
<UniqueIdentifier>{59371286-4d7e-4419-ad85-f20c1b8261ff}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="WinMain.cpp"> <ClCompile Include="WinMain.cpp">
...@@ -182,6 +185,27 @@ ...@@ -182,6 +185,27 @@
<ClInclude Include="WindowsThrowMacros.h"> <ClInclude Include="WindowsThrowMacros.h">
<Filter>Header Files\Macros</Filter> <Filter>Header Files\Macros</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="IndexedTriangleList.h">
<Filter>Header Files\Geometry</Filter>
</ClInclude>
<ClInclude Include="Plane.h">
<Filter>Header Files\Geometry</Filter>
</ClInclude>
<ClInclude Include="Sphere.h">
<Filter>Header Files\Geometry</Filter>
</ClInclude>
<ClInclude Include="Cube.h">
<Filter>Header Files\Geometry</Filter>
</ClInclude>
<ClInclude Include="ChiliMath.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Cone.h">
<Filter>Header Files\Geometry</Filter>
</ClInclude>
<ClInclude Include="Prism.h">
<Filter>Header Files\Geometry</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