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::loadMS3DFile2( std::wstring filename ) { // 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; 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 (int 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 (int 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 (int 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 (int 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])); } // 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* 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 = (Vector3f*)((*pPositions)[0]); Vector3f* pNrm = (Vector3f*)((*pNormals)[0]); Vector2f* pTex = (Vector2f*)((*pTexcoords)[0]); GeometryPtr MeshPtr = GeometryPtr( new GeometryDX11() ); //for ( int i = 0; i < usVertexCount; i++ ) //{ // pPos[i].x() = pMS3DVertices[i].vertex[0]; // pPos[i].y() = pMS3DVertices[i].vertex[1]; // pPos[i].z() = -pMS3DVertices[i].vertex[2]; // pNrm[i].MakeZero(); //} 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]; 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( pTexcoords ); MeshPtr->AddElement( pNormals ); // Delete temporary materials if (pMS3DMaterials != NULL) { delete[] pMS3DMaterials; pMS3DMaterials = NULL; } // Delete temporary groups and their indices if (pMS3DGroups != NULL) { for (int 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 ); }
//-------------------------------------------------------------------------------- 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 ); }