//-------------------------------------------------------------------------------- GeometryPtr GeometryLoaderDX11::loadStanfordPlyFile( std::wstring filename, bool withAdjacency ) { // Get the file path to the models FileSystem fs; filename = fs.GetModelsFolder() + filename; // Load the contents of the file std::ifstream fin; // Open the file and read the MS3D header data fin.open( filename.c_str(), std::ios::in ); if(!fin.is_open()) { // signal error - bad filename? throw new std::exception( "Could not open file" ); } // Parse the input std::string txt; // Read in header std::getline(fin, txt); if( 0 != txt.compare( "ply" ) ) { // signal error - not a PLY format file throw new std::exception( "File does not contain the correct header - 'PLY' expected." ); } std::getline(fin, txt); if( 0 != txt.compare( "format ascii 1.0" ) ) { // signal error - not a format of PLY that this code supports throw new std::exception( "File is not correct format - ASCII 1.0 expected." ); } std::vector< PlyElementDesc > elements; // Read in the rest of the header while(fin.is_open() && !fin.eof()) { // Grab the next line of the header std::getline(fin, txt); // If we're at the end then stop processing if(0 == txt.compare("end_header")) { break; } // If this line is a comment, skip to the next line else if(0 == txt.compare(0, 7, "comment")) { continue; } // If this line is an element, process it else if(0 == txt.compare(0, 7, "element")) { elements.push_back(ParsePLYElementHeader( txt, fin )); } // Otherwise, wtf? else { throw new std::exception("File header contains unexpected line beginning"); } } // Read all the raw data for( std::vector< PlyElementDesc >::iterator it = elements.begin(); it != elements.end(); ++it) { (*it).data = ReadPLYElementData(fin, *it); } // Create a resource to contain the geometry GeometryPtr MeshPtr = GeometryPtr( new GeometryDX11() ); // Convert data to D3D11 format int elemIdx = -1; // Pull out all the vertex data if(-1 < (elemIdx = FindPlyElementIndex(elements, "vertex"))) { PlyElementDesc d = elements.at( elemIdx ); // Has positions? int xIdx = FindPlyElementPropertyIndex( d.dataFormat, "x" ); int yIdx = FindPlyElementPropertyIndex( d.dataFormat, "y" ); int zIdx = FindPlyElementPropertyIndex( d.dataFormat, "z" ); if ((-1 != xIdx) && (-1 != yIdx) && (-1 != zIdx)) { VertexElementDX11 *pPositions = new VertexElementDX11( 3, d.elementCount ); pPositions->m_SemanticName = VertexElementDX11::PositionSemantic; pPositions->m_uiSemanticIndex = 0; pPositions->m_Format = DXGI_FORMAT_R32G32B32_FLOAT; pPositions->m_uiInputSlot = 0; pPositions->m_uiAlignedByteOffset = 0; pPositions->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pPositions->m_uiInstanceDataStepRate = 0; Vector3f* pRawPos = pPositions->Get3f( 0 ); for(int v = 0; v < d.elementCount; ++v) { void** raw = d.data.at(v); float x = *reinterpret_cast<float*>(raw[xIdx]); float y = *reinterpret_cast<float*>(raw[yIdx]); float z = *reinterpret_cast<float*>(raw[zIdx]); pRawPos[v] = Vector3f( x, y, z ); } MeshPtr->AddElement( pPositions ); } // Has normals? int nxIdx = FindPlyElementPropertyIndex( d.dataFormat, "nx" ); int nyIdx = FindPlyElementPropertyIndex( d.dataFormat, "ny" ); int nzIdx = FindPlyElementPropertyIndex( d.dataFormat, "nz" ); if ((-1 != nxIdx) && (-1 != nyIdx) && (-1 != nzIdx)) { VertexElementDX11 *pNormals = new VertexElementDX11( 3, d.elementCount ); pNormals->m_SemanticName = VertexElementDX11::NormalSemantic; pNormals->m_uiSemanticIndex = 0; pNormals->m_Format = DXGI_FORMAT_R32G32B32_FLOAT; pNormals->m_uiInputSlot = 0; pNormals->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pNormals->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pNormals->m_uiInstanceDataStepRate = 0; Vector3f* pRawNorms = pNormals->Get3f( 0 ); for(int v = 0; v < d.elementCount; ++v) { void** raw = d.data.at(v); float x = *reinterpret_cast<float*>(raw[nxIdx]); float y = *reinterpret_cast<float*>(raw[nyIdx]); float z = *reinterpret_cast<float*>(raw[nzIdx]); pRawNorms[v] = Vector3f( x, y, z ); } MeshPtr->AddElement( pNormals ); } } else { throw new std::exception("Expected a 'vertex' element, but not found"); } // Pull out all the face index data if(-1 < (elemIdx = FindPlyElementIndex(elements, "face"))) { PlyElementDesc d = elements.at( elemIdx ); // Firstly, assert that the format is correct if((1 != d.dataFormat.size()) && d.dataFormat.at(0).isList && (0 == d.dataFormat.at(0).type.compare("uint"))) { // Expect a single list of integers throw new std::exception("Expected 'face' to be a single list of integers per-face"); } // Secondly, assert that each list is of the same dimension int faceSize = -1; for(int f = 0; f < d.elementCount; ++f) { void** raw = d.data.at(f); PlyDataArray<int>* idxs = reinterpret_cast<PlyDataArray<int>*>(raw[0]); if( -1 == faceSize) faceSize = idxs->length; else if(faceSize != idxs->length) throw new std::exception("Expected each face to have the same number of indexes"); } if(withAdjacency) { MeshPtr->SetPrimitiveType( (D3D11_PRIMITIVE_TOPOLOGY)(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + ((2*faceSize) - 1)) ); // Grab all of the faces so we can search for adjacency int* pRaw = new int[d.elementCount * faceSize]; int pRawIdx = 0; for(int f = 0; f < d.elementCount; ++f) { void** raw = d.data.at(f); PlyDataArray<int>* idxs = reinterpret_cast<PlyDataArray<int>*>(raw[0]); for(unsigned int fi = 0; fi < idxs->length; ++fi) pRaw[pRawIdx++] = idxs->data[fi]; } // We can now go and add the actual indices for(int f = 0; f < (d.elementCount * faceSize); f+=3) { MeshPtr->AddIndex( pRaw[f + 0] ); MeshPtr->AddIndex( pRaw[f + 1] ); MeshPtr->AddIndex( pRaw[f + 2] ); // We now need to find an adjacency for each // edge where possible int a0 = FindAdjacentIndex( pRaw[f + 0], pRaw[f + 1], pRaw[f + 2], pRaw, d.elementCount * faceSize ); int a1 = FindAdjacentIndex( pRaw[f + 1], pRaw[f + 2], pRaw[f + 0], pRaw, d.elementCount * faceSize ); int a2 = FindAdjacentIndex( pRaw[f + 2], pRaw[f + 0], pRaw[f + 1], pRaw, d.elementCount * faceSize ); std::wstringstream out; out << "Actual indices <" << pRaw[f+0] << ", " << pRaw[f+1] << ", " << pRaw[f+2] << "> have adjacency <" << a0 << ", " << a1 << ", " << a2 << ">."; OutputDebugString( out.str().c_str() ); OutputDebugString( L"\n" ); MeshPtr->AddIndex( a0 ); MeshPtr->AddIndex( a1 ); MeshPtr->AddIndex( a2 ); } delete[] pRaw; } else { // Thirdly, can now set the appropriate topology MeshPtr->SetPrimitiveType( (D3D11_PRIMITIVE_TOPOLOGY)(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (faceSize - 1)) ); // Finally, extract this data for(int f = 0; f < d.elementCount; ++f) { void** raw = d.data.at(f); PlyDataArray<int>* idxs = reinterpret_cast<PlyDataArray<int>*>(raw[0]); for(unsigned int fi = 0; fi < idxs->length; ++fi) MeshPtr->AddIndex( idxs->data[fi] ); } } } else { throw new std::exception("Expected a 'face' element, but not found"); } // Push into renderable resource MeshPtr->LoadToBuffers( ); // Release all intermediary memory for( std::vector< PlyElementDesc >::iterator it = elements.begin(); it != elements.end(); ++it) { PlyElementDesc d = *it; for(int e = 0; e < d.elementCount; ++e) { void** raw = d.data.at(e); if(d.dataFormat.at(0).isList) { PlyDataArray<void*>* rawArray = reinterpret_cast<PlyDataArray<void*>*>(raw[0]); SAFE_DELETE_ARRAY( rawArray->data ); SAFE_DELETE(raw[0]); } else { SAFE_DELETE(raw[0]); } } } // Return to caller return MeshPtr; }
//-------------------------------------------------------------------------------- void App::Initialize() { // Create the light parameters for use with this effect Vector4f LightParams = Vector4f( 0.2f, 0.7f, 0.2f, 0.7f ); m_pLightColor = m_pRenderer11->m_pParamMgr->GetVectorParameterRef( std::wstring( L"LightColor" ) ); m_pLightColor->InitializeParameterData( &LightParams ); Vector4f LightPosition = Vector4f( -1000.0f, 200.0f, 0.0f, 0.0f ); m_pLightPosition = m_pRenderer11->m_pParamMgr->GetVectorParameterRef( std::wstring( L"LightPositionWS" ) ); m_pLightPosition->InitializeParameterData( &LightPosition ); // Create the camera, and the render view that will produce an image of the // from the camera's point of view of the scene. m_pCamera->Spatial().SetRotation( Vector3f( 0.7f, 0.0f, 0.0f ) ); m_pCamera->Spatial().SetTranslation( Vector3f( 0.0f, 50.0f, -20.0f ) ); m_pRenderView->SetBackColor( Vector4f( 0.1f, 0.1f, 0.3f, 0.0f ) ); // Create the displaced skinned actor m_pDisplacedActor = new SkinnedActor(); GeometryPtr pGeometry = GeometryPtr( new GeometryDX11() ); GeometryGeneratorDX11::GenerateWeightedSkinnedCone( pGeometry, 16, 20, 2.0f, 40.0f, 6, m_pDisplacedActor ); pGeometry->SetPrimitiveType( D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST ); m_pDisplacedActor->GetBody()->Visual.SetMaterial( MaterialGeneratorDX11::GenerateSkinnedSolid( *m_pRenderer11 ) ); RotationController<Node3D>* pRotController1 = new RotationController<Node3D>(); m_pDisplacedActor->GetNode()->Controllers.Attach( pRotController1 ); // Create the skinned actor without displacement m_pSkinnedActor = new SkinnedActor(); GeometryPtr pSkinnedGeometry = GeometryPtr( new GeometryDX11() ); GeometryGeneratorDX11::GenerateWeightedSkinnedCone( pSkinnedGeometry, 16, 20, 2.0f, 40.0f, 6, m_pSkinnedActor ); pSkinnedGeometry->SetPrimitiveType( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); m_pSkinnedActor->GetBody()->Visual.SetMaterial( MaterialGeneratorDX11::GenerateSkinnedTextured( *m_pRenderer11 ) ); RotationController<Node3D>* pRotController2 = new RotationController<Node3D>(); m_pSkinnedActor->GetNode()->Controllers.Attach( pRotController2 ); // Generate the static mesh, and attach a texture to its entity m_pStaticActor = new Actor(); GeometryPtr pStaticGeometry = GeometryLoaderDX11::loadMS3DFile2( std::wstring( L"box.ms3d" ) ); pStaticGeometry->LoadToBuffers(); MaterialPtr pStaticMaterial = MaterialGeneratorDX11::GenerateStaticTextured( *m_pRenderer11 ); m_pStaticActor->GetBody()->Visual.SetGeometry( pStaticGeometry ); m_pStaticActor->GetBody()->Visual.SetMaterial( pStaticMaterial ); RotationController<Entity3D>* pRotController3 = new RotationController<Entity3D>(); m_pStaticActor->GetBody()->Controllers.Attach( pRotController3); ResourcePtr ColorTexture = RendererDX11::Get()->LoadTexture( L"Tiles.png" ); ShaderResourceParameterWriterDX11* pTextureParameter = new ShaderResourceParameterWriterDX11(); m_pStaticActor->GetBody()->Parameters.SetShaderResourceParameter( L"ColorTexture", ColorTexture ); // Attach the actors to the scene, so that they will be rendered all together. m_pScene->AddActor( m_pDisplacedActor ); m_pScene->AddActor( m_pSkinnedActor ); m_pScene->AddActor( m_pStaticActor ); // Setup the skinned actors' bind poses and start their animations. m_pDisplacedActor->SetBindPose(); m_pDisplacedActor->SetSkinningMatrices( *m_pRenderer11 ); m_pDisplacedActor->PlayAllAnimations(); m_pSkinnedActor->SetBindPose(); m_pSkinnedActor->SetSkinningMatrices( *m_pRenderer11 ); m_pSkinnedActor->PlayAllAnimations(); m_pStaticActor->GetBody()->Transform.Position() = Vector3f( -20.0f, 10.0f, 15.0f ); m_pSkinnedActor->GetNode()->Transform.Position() = Vector3f( 0.0f, 0.0f, 20.0f ); m_pDisplacedActor->GetNode()->Transform.Position() = Vector3f( 20.0f, 0.0f, 20.0f ); }