aboutsummaryrefslogtreecommitdiff
path: root/samples/D3D12/src/WaveFrontReader.h
diff options
context:
space:
mode:
Diffstat (limited to 'samples/D3D12/src/WaveFrontReader.h')
-rw-r--r--samples/D3D12/src/WaveFrontReader.h541
1 files changed, 0 insertions, 541 deletions
diff --git a/samples/D3D12/src/WaveFrontReader.h b/samples/D3D12/src/WaveFrontReader.h
deleted file mode 100644
index f68f2bf..0000000
--- a/samples/D3D12/src/WaveFrontReader.h
+++ /dev/null
@@ -1,541 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: WaveFrontReader.h
-//
-// Code for loading basic mesh data from a WaveFront OBJ file
-//
-// http://en.wikipedia.org/wiki/Wavefront_.obj_file
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-// PARTICULAR PURPOSE.
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// http://go.microsoft.com/fwlink/?LinkID=324981
-//--------------------------------------------------------------------------------------
-
-#include <windows.h>
-
-#include <algorithm>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
-#pragma warning(push)
-#pragma warning(disable : 4005)
-#include <stdint.h>
-#pragma warning(pop)
-
-#include <directxmath.h>
-#include <directxcollision.h>
-
-template<class index_t>
-class WaveFrontReader
-{
-public:
- typedef index_t index_t;
-
- struct Vertex
- {
- DirectX::XMFLOAT3 position;
- DirectX::XMFLOAT3 normal;
- DirectX::XMFLOAT2 textureCoordinate;
- };
-
- WaveFrontReader() : hasNormals(false), hasTexcoords(false) {}
-
- HRESULT Load( _In_z_ const wchar_t* szFileName, bool ccw = true )
- {
- Clear();
-
- static const size_t MAX_POLY = 64;
-
- using namespace DirectX;
-
- std::wifstream InFile( szFileName );
- if( !InFile )
- return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
-
- WCHAR fname[_MAX_FNAME];
- _wsplitpath_s( szFileName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, nullptr, 0 );
-
- name = fname;
-
- std::vector<XMFLOAT3> positions;
- std::vector<XMFLOAT3> normals;
- std::vector<XMFLOAT2> texCoords;
-
- VertexCache vertexCache;
-
- Material defmat;
-
- wcscpy_s( defmat.strName, L"default" );
- materials.push_back( defmat );
-
- uint32_t curSubset = 0;
-
- WCHAR strCommand[256] = {0};
- WCHAR strMaterialFilename[MAX_PATH] = {0};
- for( ;; )
- {
- InFile >> strCommand;
- if( !InFile )
- break;
-
- if( 0 == wcscmp( strCommand, L"#" ) )
- {
- // Comment
- }
- else if( 0 == wcscmp( strCommand, L"v" ) )
- {
- // Vertex Position
- float x, y, z;
- InFile >> x >> y >> z;
- positions.push_back( XMFLOAT3( x, y, z ) );
- }
- else if( 0 == wcscmp( strCommand, L"vt" ) )
- {
- // Vertex TexCoord
- float u, v;
- InFile >> u >> v;
- texCoords.push_back( XMFLOAT2( u, v ) );
-
- hasTexcoords = true;
- }
- else if( 0 == wcscmp( strCommand, L"vn" ) )
- {
- // Vertex Normal
- float x, y, z;
- InFile >> x >> y >> z;
- normals.push_back( XMFLOAT3( x, y, z ) );
-
- hasNormals = true;
- }
- else if( 0 == wcscmp( strCommand, L"f" ) )
- {
- // Face
- UINT iPosition, iTexCoord, iNormal;
- Vertex vertex;
-
- DWORD faceIndex[ MAX_POLY ];
- size_t iFace = 0;
- for(;;)
- {
- if ( iFace >= MAX_POLY )
- {
- // Too many polygon verts for the reader
- return E_FAIL;
- }
-
- memset( &vertex, 0, sizeof( vertex ) );
-
- // OBJ format uses 1-based arrays
- InFile >> iPosition;
- if ( iPosition > positions.size() )
- return E_FAIL;
-
- vertex.position = positions[ iPosition - 1 ];
-
- if( '/' == InFile.peek() )
- {
- InFile.ignore();
-
- if( '/' != InFile.peek() )
- {
- // Optional texture coordinate
- InFile >> iTexCoord;
- if ( iTexCoord > texCoords.size() )
- return E_FAIL;
-
- vertex.textureCoordinate = texCoords[ iTexCoord - 1 ];
- }
-
- if( '/' == InFile.peek() )
- {
- InFile.ignore();
-
- // Optional vertex normal
- InFile >> iNormal;
- if ( iNormal > normals.size() )
- return E_FAIL;
-
- vertex.normal = normals[ iNormal - 1 ];
- }
- }
-
- // If a duplicate vertex doesn't exist, add this vertex to the Vertices
- // list. Store the index in the Indices array. The Vertices and Indices
- // lists will eventually become the Vertex Buffer and Index Buffer for
- // the mesh.
- DWORD index = AddVertex( iPosition, &vertex, vertexCache );
- if ( index == (DWORD)-1 )
- return E_OUTOFMEMORY;
-
-#pragma warning( suppress : 4127 )
- if ( sizeof(index_t) == 2 && ( index >= 0xFFFF ) )
- {
- // Too many indices for 16-bit IB!
- return E_FAIL;
- }
- else if ( sizeof(index_t) == 4 && ( index >= 0xFFFFFFFF ) )
- {
- // Too many indices for 32-bit IB!
- return E_FAIL;
- }
-
- faceIndex[ iFace ] = index;
- ++iFace;
-
- // Check for more face data or end of the face statement
- bool faceEnd = false;
- for(;;)
- {
- wchar_t p = InFile.peek();
-
- if ( '\n' == p || !InFile )
- {
- faceEnd = true;
- break;
- }
- else if ( isdigit( p ) )
- break;
-
- InFile.ignore();
- }
-
- if ( faceEnd )
- break;
- }
-
- if ( iFace < 3 )
- {
- // Need at least 3 points to form a triangle
- return E_FAIL;
- }
-
- // Convert polygons to triangles
- DWORD i0 = faceIndex[0];
- DWORD i1 = faceIndex[1];
-
- for( size_t j = 2; j < iFace; ++ j )
- {
- DWORD index = faceIndex[ j ];
- indices.push_back( static_cast<index_t>( i0 ) );
- if ( ccw )
- {
- indices.push_back( static_cast<index_t>( i1 ) );
- indices.push_back( static_cast<index_t>( index ) );
- }
- else
- {
- indices.push_back( static_cast<index_t>( index ) );
- indices.push_back( static_cast<index_t>( i1 ) );
- }
-
- attributes.push_back( curSubset );
-
- i1 = index;
- }
-
- assert( attributes.size()*3 == indices.size() );
- }
- else if( 0 == wcscmp( strCommand, L"mtllib" ) )
- {
- // Material library
- InFile >> strMaterialFilename;
- }
- else if( 0 == wcscmp( strCommand, L"usemtl" ) )
- {
- // Material
- WCHAR strName[MAX_PATH] = {0};
- InFile >> strName;
-
- bool bFound = false;
- uint32_t count = 0;
- for( auto it = materials.cbegin(); it != materials.cend(); ++it, ++count )
- {
- if( 0 == wcscmp( it->strName, strName ) )
- {
- bFound = true;
- curSubset = count;
- break;
- }
- }
-
- if( !bFound )
- {
- Material mat;
- curSubset = static_cast<uint32_t>( materials.size() );
- wcscpy_s( mat.strName, MAX_PATH - 1, strName );
- materials.push_back( mat );
- }
- }
- else
- {
- // Unimplemented or unrecognized command
- //OutputDebugStringW( strCommand );
- }
-
- InFile.ignore( 1000, '\n' );
- }
-
- // Cleanup
- InFile.close();
-
- BoundingBox::CreateFromPoints( bounds, positions.size(), &positions.front(), sizeof(XMFLOAT3) );
-
- // If an associated material file was found, read that in as well.
- if (0) //@jihoc if( *strMaterialFilename )
- {
- WCHAR ext[_MAX_EXT];
- _wsplitpath_s( strMaterialFilename, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT );
-
- WCHAR drive[_MAX_DRIVE];
- WCHAR dir[_MAX_DIR];
- _wsplitpath_s( szFileName, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0 );
-
- WCHAR szPath[ MAX_PATH ];
- _wmakepath_s( szPath, MAX_PATH, drive, dir, fname, ext );
-
- HRESULT hr = LoadMTL( szPath );
- if ( FAILED(hr) )
- return hr;
- }
-
- return S_OK;
- }
-
- HRESULT LoadMTL( _In_z_ const wchar_t* szFileName )
- {
- // Assumes MTL is in CWD along with OBJ
- std::wifstream InFile( szFileName );
- if( !InFile )
- return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
-
- auto curMaterial = materials.end();
-
- WCHAR strCommand[256] = {0};
- for( ;; )
- {
- InFile >> strCommand;
- if( !InFile )
- break;
-
- if( 0 == wcscmp( strCommand, L"newmtl" ) )
- {
- // Switching active materials
- WCHAR strName[MAX_PATH] = {0};
- InFile >> strName;
-
- curMaterial = materials.end();
- for( auto it = materials.begin(); it != materials.end(); ++it )
- {
- if( 0 == wcscmp( it->strName, strName ) )
- {
- curMaterial = it;
- break;
- }
- }
- }
-
- // The rest of the commands rely on an active material
- if( curMaterial == materials.end() )
- continue;
-
- if( 0 == wcscmp( strCommand, L"#" ) )
- {
- // Comment
- }
- else if( 0 == wcscmp( strCommand, L"Ka" ) )
- {
- // Ambient color
- float r, g, b;
- InFile >> r >> g >> b;
- curMaterial->vAmbient = XMFLOAT3( r, g, b );
- }
- else if( 0 == wcscmp( strCommand, L"Kd" ) )
- {
- // Diffuse color
- float r, g, b;
- InFile >> r >> g >> b;
- curMaterial->vDiffuse = XMFLOAT3( r, g, b );
- }
- else if( 0 == wcscmp( strCommand, L"Ks" ) )
- {
- // Specular color
- float r, g, b;
- InFile >> r >> g >> b;
- curMaterial->vSpecular = XMFLOAT3( r, g, b );
- }
- else if( 0 == wcscmp( strCommand, L"d" ) ||
- 0 == wcscmp( strCommand, L"Tr" ) )
- {
- // Alpha
- InFile >> curMaterial->fAlpha;
- }
- else if( 0 == wcscmp( strCommand, L"Ns" ) )
- {
- // Shininess
- int nShininess;
- InFile >> nShininess;
- curMaterial->nShininess = nShininess;
- }
- else if( 0 == wcscmp( strCommand, L"illum" ) )
- {
- // Specular on/off
- int illumination;
- InFile >> illumination;
- curMaterial->bSpecular = ( illumination == 2 );
- }
- else if( 0 == wcscmp( strCommand, L"map_Kd" ) )
- {
- // Texture
- InFile >> curMaterial->strTexture;
- }
- else
- {
- // Unimplemented or unrecognized command
- }
-
- InFile.ignore( 1000, L'\n' );
- }
-
- InFile.close();
-
- return S_OK;
- }
-
- void Clear()
- {
- vertices.clear();
- indices.clear();
- attributes.clear();
- materials.clear();
- name.clear();
- hasNormals = false;
- hasTexcoords = false;
-
- bounds.Center.x = bounds.Center.y = bounds.Center.z = 0.f;
- bounds.Extents.x = bounds.Extents.y = bounds.Extents.z = 0.f;
- }
-
- HRESULT LoadVBO( _In_z_ const wchar_t* szFileName )
- {
- Clear();
-
- WCHAR fname[_MAX_FNAME];
- _wsplitpath_s( szFileName, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, nullptr, 0 );
-
- name = fname;
-
- Material defmat;
- wcscpy_s( defmat.strName, L"default" );
- materials.push_back( defmat );
-
- std::ifstream vboFile(szFileName, std::ifstream::in | std::ifstream::binary);
- if ( !vboFile.is_open() )
- return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
-
- hasNormals = hasTexcoords = true;
-
- uint32_t numVertices = 0;
- uint32_t numIndices = 0;
-
- vboFile.read( reinterpret_cast<char*>( &numVertices ), sizeof(uint32_t ) );
- if ( !numVertices )
- return E_FAIL;
-
- vboFile.read( reinterpret_cast<char*>( &numIndices ), sizeof(uint32_t ) );
- if ( !numIndices )
- return E_FAIL;
-
- vertices.resize( numVertices );
- vboFile.read( reinterpret_cast<char*>( &vertices.front() ), sizeof(Vertex) * numVertices );
-
-#pragma warning( suppress : 4127 )
- if ( sizeof( index_t ) == 2 )
- {
- indices.resize( numIndices );
- vboFile.read( reinterpret_cast<char*>( &indices.front() ), sizeof(uint16_t) * numIndices );
- }
- else
- {
- std::vector<uint16_t> tmp;
- tmp.resize( numIndices );
- vboFile.read( reinterpret_cast<char*>( &tmp.front() ), sizeof(uint16_t) * numIndices );
-
- indices.reserve( numIndices );
- for( auto it = tmp.cbegin(); it != tmp.cend(); ++it )
- {
- indices.push_back( *it );
- }
- }
-
- BoundingBox::CreateFromPoints( bounds, vertices.size(), reinterpret_cast<const XMFLOAT3*>( &vertices.front() ), sizeof(Vertex) );
-
- vboFile.close();
-
- return S_OK;
- }
-
- struct Material
- {
- DirectX::XMFLOAT3 vAmbient;
- DirectX::XMFLOAT3 vDiffuse;
- DirectX::XMFLOAT3 vSpecular;
- uint32_t nShininess;
- float fAlpha;
-
- bool bSpecular;
-
- WCHAR strName[MAX_PATH];
- WCHAR strTexture[MAX_PATH];
-
- Material() :
- vAmbient( 0.2f, 0.2f, 0.2f ),
- vDiffuse( 0.8f, 0.8f, 0.8f ),
- vSpecular( 1.0f, 1.0f, 1.0f ),
- nShininess( 0 ),
- fAlpha( 1.f ),
- bSpecular( false )
- { memset(strName, 0, MAX_PATH); memset(strTexture, 0, MAX_PATH); }
- };
-
- std::vector<Vertex> vertices;
- std::vector<index_t> indices;
- std::vector<uint32_t> attributes;
- std::vector<Material> materials;
-
- std::wstring name;
- bool hasNormals;
- bool hasTexcoords;
-
- DirectX::BoundingBox bounds;
-
-private:
- typedef std::unordered_multimap<UINT, UINT> VertexCache;
-
- DWORD AddVertex( UINT hash, Vertex* pVertex, VertexCache& cache )
- {
- auto f = cache.equal_range( hash );
-
- for( auto it = f.first; it != f.second; ++it )
- {
- auto& tv = vertices[ it->second ];
-
- if ( 0 == memcmp( pVertex, &tv, sizeof(Vertex) ) )
- {
- return it->second;
- }
- }
-
- DWORD index = static_cast<UINT>( vertices.size() );
- vertices.push_back( *pVertex );
-
- VertexCache::value_type entry( hash, index );
- cache.insert( entry );
- return index;
- }
-};