void SDFShadowDemo::BuildQuad() { // create a screen quad m_pQuad = GeometryPtr(new GeometryDX11()); const i32 NumVertexOfQuad = 4; // create the vertex element streams VertexElementDX11* pPositions = new VertexElementDX11(3, NumVertexOfQuad); 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; VertexElementDX11* pColors = new VertexElementDX11(4, NumVertexOfQuad); pColors->m_SemanticName = VertexElementDX11::ColorSemantic; pColors->m_uiSemanticIndex = 0; pColors->m_Format = DXGI_FORMAT_R32G32B32A32_FLOAT; pColors->m_uiInputSlot = 0; pColors->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pColors->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pColors->m_uiInstanceDataStepRate = 0; m_pQuad->AddElement(pPositions); m_pQuad->AddElement(pColors); *pPositions->Get3f(0) = Vector3f(-1.0f, +1.0f, 0.0f); *pPositions->Get3f(1) = Vector3f(+1.0f, +1.0f, 0.0f); *pPositions->Get3f(2) = Vector3f(-1.0f, -1.0f, 0.0f); *pPositions->Get3f(3) = Vector3f(+1.0f, -1.0f, 0.0f); *pColors->Get4f(0) = Colors::White; *pColors->Get4f(1) = Colors::White; *pColors->Get4f(2) = Colors::White; *pColors->Get4f(3) = Colors::White; m_pQuad->AddFace(TriangleIndices(0, 1, 2)); m_pQuad->AddFace(TriangleIndices(1, 3, 2)); m_pQuad->LoadToBuffers(); }
//-------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------- GeometryPtr GeometryLoaderDX11::loadMS3DFileWithAnimation( std::wstring filename, SkinnedActor* pActor ) { // Get the file path to the models FileSystem fs; filename = fs.GetModelsFolder() + filename; // Temporary Milkshape structures unsigned short usVertexCount = 0; unsigned short usTriangleCount = 0; unsigned short usGroupCount = 0; unsigned short usMaterialCount = 0; MS3DVertex* pMS3DVertices = NULL; MS3DTriangle* pMS3DTriangles = NULL; MS3DGroup* pMS3DGroups = NULL; MS3DMaterial* pMS3DMaterials = NULL; int i; std::ifstream fin; MS3DHeader header; // Open the file and read the MS3D header data fin.open( filename.c_str(),std::ios::binary ); fin.read((char*)(&(header.id)), sizeof(header.id)); fin.read((char*)(&(header.version)), sizeof(header.version)); if (header.version!=3 && header.version!=4) return NULL; // Load all the vertices fin.read((char*)(&usVertexCount), sizeof(unsigned short)); pMS3DVertices = new MS3DVertex[usVertexCount]; for (i=0; i < usVertexCount; i++) { fin.read((char*)&(pMS3DVertices[i].flags), sizeof(unsigned char)); fin.read((char*)&(pMS3DVertices[i].vertex[0]), sizeof(float)); fin.read((char*)&(pMS3DVertices[i].vertex[1]), sizeof(float)); fin.read((char*)&(pMS3DVertices[i].vertex[2]), sizeof(float)); fin.read((char*)&(pMS3DVertices[i].boneId), sizeof(char)); fin.read((char*)&(pMS3DVertices[i].referenceCount), sizeof(unsigned char)); } // Load all the triangle indices fin.read((char*)(&usTriangleCount), sizeof(unsigned short)); pMS3DTriangles = new MS3DTriangle[usTriangleCount]; for (i=0; i < usTriangleCount; i++) { fin.read((char*)&(pMS3DTriangles[i].flags),sizeof(unsigned short)); fin.read((char*)&(pMS3DTriangles[i].vertexIndices[0]), sizeof(unsigned short)); //3*sizeof(unsigned short)); fin.read((char*)&(pMS3DTriangles[i].vertexIndices[1]), sizeof(unsigned short)); //3*sizeof(unsigned short)); fin.read((char*)&(pMS3DTriangles[i].vertexIndices[2]), sizeof(unsigned short)); //3*sizeof(unsigned short)); fin.read((char*)&(pMS3DTriangles[i].vertexNormals[0]), 3*sizeof(float)); fin.read((char*)&(pMS3DTriangles[i].vertexNormals[1]), 3*sizeof(float)); fin.read((char*)&(pMS3DTriangles[i].vertexNormals[2]), 3*sizeof(float)); fin.read((char*)&(pMS3DTriangles[i].s), 3*sizeof(float)); fin.read((char*)&(pMS3DTriangles[i].t), 3*sizeof(float)); fin.read((char*)&(pMS3DTriangles[i].smoothingGroup), sizeof(unsigned char)); fin.read((char*)&(pMS3DTriangles[i].groupIndex), sizeof(unsigned char)); } // Load all the group information fin.read((char*)(&usGroupCount), sizeof(unsigned short)); pMS3DGroups = new MS3DGroup[usGroupCount]; for (i=0; i < usGroupCount; i++) { fin.read((char*)&(pMS3DGroups[i].flags), sizeof(unsigned char)); fin.read((char*)&(pMS3DGroups[i].name), sizeof(char[32])); fin.read((char*)&(pMS3DGroups[i].numtriangles), sizeof(unsigned short)); unsigned short triCount = pMS3DGroups[i].numtriangles; pMS3DGroups[i].triangleIndices = new unsigned short[triCount]; fin.read((char*)(pMS3DGroups[i].triangleIndices), sizeof(unsigned short) * triCount); fin.read((char*)&(pMS3DGroups[i].materialIndex), sizeof(char)); } // Load all the material information fin.read((char*)(&usMaterialCount),sizeof(unsigned short)); pMS3DMaterials = new MS3DMaterial[usMaterialCount]; for (i=0; i < usMaterialCount; i++) { fin.read((char*)&(pMS3DMaterials[i].name), sizeof(char[32])); fin.read((char*)&(pMS3DMaterials[i].ambient), 4 * sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].diffuse), 4 * sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].specular), 4 * sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].emissive), 4 * sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].shininess), sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].transparency), sizeof(float)); fin.read((char*)&(pMS3DMaterials[i].mode), sizeof(char)); fin.read((char*)&(pMS3DMaterials[i].texture), sizeof(char[128])); fin.read((char*)&(pMS3DMaterials[i].alphamap), sizeof(char[128])); } float fAnimationFPS; // 4 bytes float fCurrentTime; // 4 bytes int iTotalFrames; // 4 bytes unsigned short nNumJoints; // 2 bytes fin.read((char*)&(fAnimationFPS), sizeof(float)); fin.read((char*)&(fCurrentTime), sizeof(float)); fin.read((char*)&(iTotalFrames), sizeof(int)); fin.read((char*)&(nNumJoints), sizeof(unsigned short)); MS3DKeyframeJoint* pMS3DJoints = 0; if ( nNumJoints > 0 ) pMS3DJoints = new MS3DKeyframeJoint[nNumJoints]; for ( i = 0; i < nNumJoints; i++ ) { fin.read((char*)&(pMS3DJoints[i].flags), sizeof(unsigned char)); fin.read((char*)&(pMS3DJoints[i].name), sizeof(char[32])); fin.read((char*)&(pMS3DJoints[i].parentName), sizeof(char[32])); fin.read((char*)&(pMS3DJoints[i].rotation[0]), 3 * sizeof(float)); fin.read((char*)&(pMS3DJoints[i].position[0]), 3 * sizeof(float)); fin.read((char*)&(pMS3DJoints[i].numKeyFramesRot), sizeof(unsigned short)); fin.read((char*)&(pMS3DJoints[i].numKeyFramesTrans), sizeof(unsigned short)); pMS3DJoints[i].keyFramesRot = new MS3DKeyframeRotation[pMS3DJoints[i].numKeyFramesRot]; pMS3DJoints[i].keyFramesTrans = new MS3DKeyframePosition[pMS3DJoints[i].numKeyFramesTrans]; for ( int j = 0; j < pMS3DJoints[i].numKeyFramesRot; j++ ) { fin.read((char*)&(pMS3DJoints[i].keyFramesRot[j].time), 1 * sizeof(float)); fin.read((char*)&(pMS3DJoints[i].keyFramesRot[j].rotation), 3 * sizeof(float)); } for ( int j = 0; j < pMS3DJoints[i].numKeyFramesTrans; j++ ) { fin.read((char*)&(pMS3DJoints[i].keyFramesTrans[j].time), 1 * sizeof(float)); fin.read((char*)&(pMS3DJoints[i].keyFramesTrans[j].position), 3 * sizeof(float)); } //std::wstringstream s; //s << GlyphString::ToUnicode( std::string( pMS3DJoints[i].name ) ) << std::endl; //for ( int z = 0; z < pMS3DJoints[i].numKeyFramesRot; z++ ) // s << L"rotation: " << pMS3DJoints[i].keyFramesRot[z].time << L" " <<pMS3DJoints[i].keyFramesRot[z].rotation[0] << L" " << pMS3DJoints[i].keyFramesRot[z].rotation[1] << L" " << pMS3DJoints[i].keyFramesRot[z].rotation[2] << std::endl; //for ( int z = 0; z < pMS3DJoints[i].numKeyFramesTrans; z++ ) // s << L"position: " << pMS3DJoints[i].keyFramesTrans[z].time << L" " <<pMS3DJoints[i].keyFramesTrans[z].position[0] << L" " << pMS3DJoints[i].keyFramesTrans[z].position[1] << L" " << pMS3DJoints[i].keyFramesTrans[z].position[2] << std::endl; //Log::Get().Write( s.str() ); } // Close the file (remaining file data unused) fin.close(); // create the vertex element streams VertexElementDX11* pPositions = new VertexElementDX11( 3, usTriangleCount*3 ); 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; VertexElementDX11* pBoneIDs = new VertexElementDX11( 1, usTriangleCount*3 ); pBoneIDs->m_SemanticName = VertexElementDX11::BoneIDSemantic; pBoneIDs->m_uiSemanticIndex = 0; pBoneIDs->m_Format = DXGI_FORMAT_R32_SINT; pBoneIDs->m_uiInputSlot = 0; pBoneIDs->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pBoneIDs->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pBoneIDs->m_uiInstanceDataStepRate = 0; VertexElementDX11* pTexcoords = new VertexElementDX11( 2, usTriangleCount*3 ); pTexcoords->m_SemanticName = VertexElementDX11::TexCoordSemantic; pTexcoords->m_uiSemanticIndex = 0; pTexcoords->m_Format = DXGI_FORMAT_R32G32_FLOAT; pTexcoords->m_uiInputSlot = 0; pTexcoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pTexcoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pTexcoords->m_uiInstanceDataStepRate = 0; VertexElementDX11* pNormals = new VertexElementDX11( 3, usTriangleCount*3 ); 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* pPos = pPositions->Get3f( 0 ); int* pIds = pBoneIDs->Get1i( 0 ); Vector3f* pNrm = pNormals->Get3f( 0 ); Vector2f* pTex = pTexcoords->Get2f( 0 ); // Create the geometry object, and fill it with the data read from the file. GeometryPtr MeshPtr = GeometryPtr( new GeometryDX11() ); TriangleIndices face; for ( int i = 0; i < usTriangleCount; i++ ) { face.P1() = 3*i+0; face.P2() = 3*i+2; face.P3() = 3*i+1; pPos[3*i+0].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[0]; pPos[3*i+0].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[1]; pPos[3*i+0].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[2]; pPos[3*i+1].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[0]; pPos[3*i+1].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[1]; pPos[3*i+1].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[2]; pPos[3*i+2].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[0]; pPos[3*i+2].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[1]; pPos[3*i+2].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[2]; pIds[3*i+0] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].boneId; pIds[3*i+1] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].boneId; pIds[3*i+2] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].boneId; pNrm[3*i+0].x = pMS3DTriangles[i].vertexNormals[0][0]; pNrm[3*i+0].y = pMS3DTriangles[i].vertexNormals[0][1]; pNrm[3*i+0].z = -pMS3DTriangles[i].vertexNormals[0][2]; pNrm[3*i+1].x = pMS3DTriangles[i].vertexNormals[1][0]; pNrm[3*i+1].y = pMS3DTriangles[i].vertexNormals[1][1]; pNrm[3*i+1].z = -pMS3DTriangles[i].vertexNormals[1][2]; pNrm[3*i+2].x = pMS3DTriangles[i].vertexNormals[2][0]; pNrm[3*i+2].y = pMS3DTriangles[i].vertexNormals[2][1]; pNrm[3*i+2].z = -pMS3DTriangles[i].vertexNormals[2][2]; pTex[3*i+0].x = pMS3DTriangles[i].s[0]; pTex[3*i+0].y = pMS3DTriangles[i].t[0]; pTex[3*i+1].x = pMS3DTriangles[i].s[1]; pTex[3*i+1].y = pMS3DTriangles[i].t[1]; pTex[3*i+2].x = pMS3DTriangles[i].s[2]; pTex[3*i+2].y = pMS3DTriangles[i].t[2]; MeshPtr->AddFace( face ); } for ( int i = 0; i < usVertexCount; i++ ) { pNrm[i].Normalize(); } MeshPtr->AddElement( pPositions ); MeshPtr->AddElement( pBoneIDs ); MeshPtr->AddElement( pTexcoords ); MeshPtr->AddElement( pNormals ); // Now set the geometry in the SkinnedActor, and create the bones // and add them to the SkinnedActor. if ( pActor ) { // Set the geometry in the body of the actor pActor->GetBody()->Visual.SetGeometry( MeshPtr ); // Create an array of nodes, one for each joint. std::map<std::string,Node3D*> JointNodes; for ( int i = 0; i < nNumJoints; i++ ) { Node3D* pBone = new Node3D(); Vector3f BindPosition = Vector3f( pMS3DJoints[i].position[0], pMS3DJoints[i].position[1], pMS3DJoints[i].position[2] ); AnimationStream<Vector3f>* pPosFrames = new AnimationStream<Vector3f>(); for ( int j = 0; j < pMS3DJoints[i].numKeyFramesTrans; j++ ) { Vector3f p = Vector3f( pMS3DJoints[i].keyFramesTrans[j].position[0], pMS3DJoints[i].keyFramesTrans[j].position[1], pMS3DJoints[i].keyFramesTrans[j].position[2] ); pPosFrames->AddState( AnimationState<Vector3f>( pMS3DJoints[i].keyFramesTrans[j].time, p ) ); } AnimationStream<Vector3f>* pRotFrames = new AnimationStream<Vector3f>(); Vector3f BindRotation = Vector3f( pMS3DJoints[i].rotation[0] + 6.28f, pMS3DJoints[i].rotation[1] + 6.28f, pMS3DJoints[i].rotation[2] + 6.28f ); for ( int j = 0; j < pMS3DJoints[i].numKeyFramesRot; j++ ) { Vector3f p = Vector3f( pMS3DJoints[i].keyFramesRot[j].rotation[0] + 6.28f, pMS3DJoints[i].keyFramesRot[j].rotation[1] + 6.28f, pMS3DJoints[i].keyFramesRot[j].rotation[2] + 6.28f ); pRotFrames->AddState( AnimationState<Vector3f>( pMS3DJoints[i].keyFramesRot[j].time, p ) ); } pActor->AddBoneNode( pBone, BindPosition, BindRotation, pPosFrames, pRotFrames ); JointNodes[std::string(pMS3DJoints[i].name)] = pBone; } // Connect up the bones to form the skeleton. for ( int i = 0; i < nNumJoints; i++ ) { Node3D* pParent = JointNodes[std::string(pMS3DJoints[i].parentName)]; Node3D* pChild = JointNodes[std::string(pMS3DJoints[i].name)]; // If the node has a parent, link them if ( pParent && pChild ) pParent->AttachChild( pChild ); // If the node has no parent, link it to the root of the skinned actor (for connection // to the scene graph). if ( !pParent && pChild ) pActor->GetNode()->AttachChild( pChild ); } } // Delete temporary joint information if ( pMS3DJoints ) { for ( int i = 0; i < nNumJoints; i++ ) { delete[] pMS3DJoints[i].keyFramesRot; delete[] pMS3DJoints[i].keyFramesTrans; } delete[] pMS3DJoints; } // Delete temporary materials if (pMS3DMaterials != NULL) { delete[] pMS3DMaterials; pMS3DMaterials = NULL; } // Delete temporary groups and their indices if (pMS3DGroups != NULL) { for (i = 0; i < usGroupCount; i++) { if (pMS3DGroups[i].triangleIndices != NULL) { delete[] pMS3DGroups[i].triangleIndices; pMS3DGroups[i].triangleIndices = NULL; } } delete[] pMS3DGroups; pMS3DGroups = NULL; } // Delete temporary triangles if (pMS3DTriangles != NULL) { delete[] pMS3DTriangles; pMS3DTriangles = NULL; } // Delete temporary vertices if (pMS3DVertices != NULL) { delete[] pMS3DVertices; pMS3DVertices = NULL; } //MeshPtr->GenerateVertexDeclaration(); MeshPtr->LoadToBuffers(); return( MeshPtr ); }
void SDFShadowDemo::LoadGeometry() { // load mesh file Assimp::Importer imp; const aiScene* pScene = nullptr; const std::wstring meshFileNameW = L"testScene.obj"; const std::wstring meshFilePathW = FileSystem::getSingleton().GetModelsFolder(); const std::string meshFileFullPath = TextHelper::ToAscii(meshFilePathW + meshFileNameW); pScene = imp.ReadFile(meshFileFullPath, aiProcess_MakeLeftHanded | aiProcess_Triangulate | aiProcess_FlipWindingOrder); if (!pScene) { return; } auto count = pScene->mNumMeshes; if (count < 1) return; // load a scene into GeometryDX11 for (auto id = 0U; id < count; ++id) { auto pMesh = pScene->mMeshes[id]; auto pGeometry = GeometryPtr(new GeometryDX11()); const i32 NumVertexOfBox = pMesh->mNumVertices; // create the vertex element streams VertexElementDX11* pPositions = new VertexElementDX11(3, NumVertexOfBox); 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; VertexElementDX11* pColors = new VertexElementDX11(4, NumVertexOfBox); pColors->m_SemanticName = VertexElementDX11::ColorSemantic; pColors->m_uiSemanticIndex = 0; pColors->m_Format = DXGI_FORMAT_R32G32B32A32_FLOAT; pColors->m_uiInputSlot = 0; pColors->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pColors->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pColors->m_uiInstanceDataStepRate = 0; pGeometry->AddElement(pPositions); pGeometry->AddElement(pColors); for (auto i = 0; i < NumVertexOfBox; ++i) { aiVector3D pos = pMesh->mVertices[i]; *pPositions->Get3f(i) = Vector3f(pos.x, pos.y, pos.z); *pColors->Get4f(i) = Colors::Green; } for (auto i = 0U; i < pMesh->mNumFaces; ++i) { aiFace face = pMesh->mFaces[i]; assert(face.mNumIndices == 3); pGeometry->AddFace(TriangleIndices(face.mIndices[0], face.mIndices[1], face.mIndices[2])); } pGeometry->LoadToBuffers(); m_vGeoms.push_back(pGeometry); } count = pScene->mRootNode->mNumChildren; for (auto i = 0U; i < count; ++i) { Matrix4f mat(true); aiNode* node = pScene->mRootNode->mChildren[i]; for (auto j = 0; j < 4; ++j) { aiMatrix4x4 trans = node->mTransformation; auto ptr = trans[j]; mat(j, 0) = ptr[0]; mat(j, 1) = ptr[1]; mat(j, 2) = ptr[2]; mat(j, 3) = ptr[3]; } mat = mat.Transpose(); m_vMats.push_back(mat); } SetupPipeline(); }
//-------------------------------------------------------------------------------- void App::CreateTerrainGeometry() { Log::Get().Write( L"Creating terrain geometry" ); // Setup actual resource m_pTerrainGeometry = NULL; m_pTerrainGeometry = GeometryPtr( new GeometryDX11( ) ); // Create vertex data VertexElementDX11 *pPositions = new VertexElementDX11( 3, (TERRAIN_X_LEN + 1) * (TERRAIN_Z_LEN + 1) ); pPositions->m_SemanticName = "CONTROL_POINT_POSITION"; 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; VertexElementDX11 *pTexCoords = new VertexElementDX11( 2, (TERRAIN_X_LEN + 1) * (TERRAIN_Z_LEN + 1) ); pTexCoords->m_SemanticName = "CONTROL_POINT_TEXCOORD"; pTexCoords->m_uiSemanticIndex = 0; pTexCoords->m_Format = DXGI_FORMAT_R32G32_FLOAT; pTexCoords->m_uiInputSlot = 0; pTexCoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pTexCoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pTexCoords->m_uiInstanceDataStepRate = 0; Vector3f *pPosData = pPositions->Get3f( 0 ); Vector2f *pTCData = pTexCoords->Get2f( 0 ); float fWidth = static_cast< float >( TERRAIN_X_LEN ); float fHeight = static_cast< float >( TERRAIN_Z_LEN ); for( int x = 0; x < TERRAIN_X_LEN + 1; ++x ) { for( int z = 0; z < TERRAIN_Z_LEN + 1; ++z ) { float fX = static_cast<float>(x) / fWidth - 0.5f; float fZ = static_cast<float>(z) / fHeight - 0.5f; pPosData[ x + z * (TERRAIN_X_LEN + 1) ] = Vector3f( fX, 0.0f, fZ ); pTCData[ x + z * (TERRAIN_X_LEN + 1) ] = Vector2f( fX + 0.5f, fZ + 0.5f ); } } m_pTerrainGeometry->AddElement( pPositions ); m_pTerrainGeometry->AddElement( pTexCoords ); // Create index data for( int x = 0; x < TERRAIN_X_LEN; ++x ) { for( int z = 0; z < TERRAIN_Z_LEN; ++z ) { // Define 12 control points per terrain quad // 0-3 are the actual quad vertices m_pTerrainGeometry->AddIndex( (z + 0) + (x + 0) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( (z + 1) + (x + 0) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( (z + 0) + (x + 1) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( (z + 1) + (x + 1) * (TERRAIN_X_LEN + 1) ); // 4-5 are +x m_pTerrainGeometry->AddIndex( clamp(z + 0, 0, TERRAIN_Z_LEN) + clamp(x + 2, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( clamp(z + 1, 0, TERRAIN_Z_LEN) + clamp(x + 2, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); // 6-7 are +z m_pTerrainGeometry->AddIndex( clamp(z + 2, 0, TERRAIN_Z_LEN) + clamp(x + 0, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( clamp(z + 2, 0, TERRAIN_Z_LEN) + clamp(x + 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); // 8-9 are -x m_pTerrainGeometry->AddIndex( clamp(z + 0, 0, TERRAIN_Z_LEN) + clamp(x - 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( clamp(z + 1, 0, TERRAIN_Z_LEN) + clamp(x - 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); // 10-11 are -z m_pTerrainGeometry->AddIndex( clamp(z - 1, 0, TERRAIN_Z_LEN) + clamp(x + 0, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); m_pTerrainGeometry->AddIndex( clamp(z - 1, 0, TERRAIN_Z_LEN) + clamp(x + 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) ); } } // Move the in-memory geometry to be // an actual renderable resource m_pTerrainGeometry->LoadToBuffers(); m_pTerrainGeometry->SetPrimitiveType( D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST ); Log::Get().Write( L"Created terrain geometry" ); }
void GeometryLoaderDX11::loadFBXFile( std::string szFilename, std::vector<GeometryPtr>& vGeomVector, std::vector<std::string>& vNames ) { FileSystem fs; szFilename = fs.GetModelsFolderS() + szFilename; pFBXManager = FbxManager::Create(); if( !pFBXManager ) Log::Get().Write( L"CGeometryLoader11.cpp: Error creating FBX Manager!" ); FbxIOSettings* pIOS = FbxIOSettings::Create( pFBXManager, IOSROOT ); pFBXManager->SetIOSettings( pIOS ); FbxString lPath = FbxGetApplicationDirectory(); pFBXManager->LoadPluginsDirectory( lPath.Buffer() ); FbxScene* pScene = FbxScene::Create( pFBXManager, "" ); int /*nFileMajor,*/ nFileMinor, nFileRevision; int nSDKMajor, nSDKMinor, nSDKRevision; int i, /*nAnimationStack,*/ lFileFormat; // bool bStatus; // char szPassword[1024]; FbxManager::GetFileFormatVersion( nSDKMajor, nSDKMinor, nSDKRevision ); FbxImporter* pImporter = FbxImporter::Create( pFBXManager, "" ); if (!pFBXManager->GetIOPluginRegistry()->DetectReaderFileFormat(szFilename.c_str(), lFileFormat) ) { // Unrecognizable file format. Try to fall back to FbxImporter::eFBX_BINARY lFileFormat = pFBXManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );; } bool ImportStatus = pImporter->Initialize( szFilename.c_str(), lFileFormat, pFBXManager->GetIOSettings() ); pImporter->GetFileVersion( nFileMinor, nFileMinor, nFileRevision ); if( !ImportStatus ) { Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter Initialize failed!" ); return; } ImportStatus = pImporter->Import( pScene ); if( !ImportStatus ) { Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter failed to import the file to the scene!" ); return; } FbxAxisSystem SceneAxisSystem = pScene->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem AxisSystem( FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded ); if( SceneAxisSystem != AxisSystem ) { AxisSystem.ConvertScene( pScene ); } //FbxSystemUnit SceneSystemUnit = pScene->GetGlobalSettings().GetSystemUnit(); //if( SceneSystemUnit.GetScaleFactor() != 1.0f ) // FbxSystemUnit::cm.ConvertScene( pScene ); FBXTriangulateRecursive( pScene->GetRootNode() ); FbxArray<FbxMesh*> vMeshs; FBXFillMeshArray( pScene, vMeshs ); unsigned short usVertexCount = 0; unsigned short usTriangleCount = 0; unsigned short usGroupCount = 0; unsigned short usMaterialCount = 0; unsigned short usIndicesCount = 0; for( i = 0; i < vMeshs.GetCount(); i++ ) { Log::Get().Write( L"CGeometryLoader11.cpp: Loading File!" ); std::string name = vMeshs[i]->GetNode()->GetName(); vNames.push_back( name ); usVertexCount = vMeshs[i]->GetControlPointsCount(); if( usVertexCount == 0 ) continue; usTriangleCount = vMeshs[i]->GetPolygonVertexCount() / 3; usIndicesCount = vMeshs[i]->GetPolygonVertexCount(); VertexElementDX11* pPositions = new VertexElementDX11( 3, usTriangleCount * 3 ); 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; VertexElementDX11* pTexCoords = new VertexElementDX11( 2, usTriangleCount * 3 ); pTexCoords->m_SemanticName = VertexElementDX11::TexCoordSemantic; pTexCoords->m_uiSemanticIndex = 0; pTexCoords->m_Format = DXGI_FORMAT_R32G32_FLOAT; pTexCoords->m_uiInputSlot = 0; pTexCoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; pTexCoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; pTexCoords->m_uiInstanceDataStepRate = 0; VertexElementDX11* pNormals = new VertexElementDX11( 3, usTriangleCount * 3 ); 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* pPos = pPositions->Get3f(0); Vector3f* pNorm = pNormals->Get3f(0); Vector2f* pTex = pTexCoords->Get2f(0); FbxVector4* pFBXVerts = new FbxVector4[usVertexCount]; memcpy( pFBXVerts, vMeshs[i]->GetControlPoints(), usVertexCount * sizeof(FbxVector4)); TriangleIndices face; GeometryPtr pGeomPointer( new GeometryDX11() ); for( int j = 0; j < usTriangleCount; j++ ) { int nIndex = 0; FbxVector4 FBXNorm( 0, 0, 0, 0 ); FbxVector2 FBXUV( 0, 0 ); face.P1() = nIndex = vMeshs[i]->GetPolygonVertex( j, 0 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 0, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 0, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; face.P2() = nIndex = vMeshs[i]->GetPolygonVertex( j, 1 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 1, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 1, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; face.P3() = nIndex = vMeshs[i]->GetPolygonVertex( j, 2 ); pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0]; pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1]; pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2]; vMeshs[i]->GetPolygonVertexNormal( j, 2, FBXNorm ); pNorm[nIndex].x = (float)FBXNorm[0]; pNorm[nIndex].y = (float)FBXNorm[1]; pNorm[nIndex].z = (float)FBXNorm[2]; vMeshs[i]->GetPolygonVertexUV( j, 2, "map1", FBXUV ); pTex[nIndex].x = (float)FBXUV[0]; pTex[nIndex].y = (float)FBXUV[1]; pGeomPointer->AddFace( face ); } for( int j = 0; j < usVertexCount; j++ ) { pNorm[j].Normalize(); } pGeomPointer->AddElement( pPositions ); pGeomPointer->AddElement( pNormals ); pGeomPointer->AddElement( pTexCoords ); delete[] pFBXVerts; vGeomVector.push_back( pGeomPointer ); vMeshs[i]->Destroy(); vMeshs[i] = NULL; } pImporter->Destroy(); pImporter = NULL; pScene->Destroy(); pScene = NULL; pIOS->Destroy(); pIOS = NULL; pFBXManager->Destroy(); pFBXManager = NULL; }