// Note that we only need one of these. We don't need to re-create it for every model. //----------------------------------------------------------------------------- void CPUTModelDX11::CreateBoundingBoxMesh() { CPUTResult result = CPUT_SUCCESS; float3 pVertices[8] = { float3( 1.0f, 1.0f, 1.0f ), // 0 float3( 1.0f, 1.0f, -1.0f ), // 1 float3( -1.0f, 1.0f, 1.0f ), // 2 float3( -1.0f, 1.0f, -1.0f ), // 3 float3( 1.0f, -1.0f, 1.0f ), // 4 float3( 1.0f, -1.0f, -1.0f ), // 5 float3( -1.0f, -1.0f, 1.0f ), // 6 float3( -1.0f, -1.0f, -1.0f ) // 7 }; USHORT pIndices[24] = { 0,1, 1,3, 3,2, 2,0, // Top 4,5, 5,7, 7,6, 6,4, // Bottom 0,4, 1,5, 2,6, 3,7 // Verticals }; CPUTVertexElementDesc pVertexElements[] = { { CPUT_VERTEX_ELEMENT_POSITON, tFLOAT, 12, 0 }, }; CPUTMesh *pMesh = mpBoundingBoxMesh = new CPUTMeshDX11(); pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_LINE_LIST); CPUTBufferInfo vertexElementInfo; vertexElementInfo.mpSemanticName = "POSITION"; vertexElementInfo.mSemanticIndex = 0; vertexElementInfo.mElementType = CPUT_F32; vertexElementInfo.mElementComponentCount = 3; vertexElementInfo.mElementSizeInBytes = 12; vertexElementInfo.mElementCount = 8; vertexElementInfo.mOffset = 0; CPUTBufferInfo indexDataInfo; indexDataInfo.mElementType = CPUT_U16; indexDataInfo.mElementComponentCount = 1; indexDataInfo.mElementSizeInBytes = sizeof(UINT16); indexDataInfo.mElementCount = 24; // 12 lines, 2 verts each indexDataInfo.mOffset = 0; indexDataInfo.mSemanticIndex = 0; indexDataInfo.mpSemanticName = NULL; result = pMesh->CreateNativeResources( this, -1, 1, // vertexFormatDesc.mFormatDescriptorCount, &vertexElementInfo, pVertices, // (void*)vertexFormatDesc.mpVertices, &indexDataInfo, pIndices // &vertexFormatDesc.mpIndices[0] ); ASSERT( CPUTSUCCESS(result), _L("Failed building bounding box mesh") ); cString modelSuffix = ptoc(this); UINT index = mpSubMaterialCount[0] + CPUT_MATERIAL_INDEX_BOUNDING_BOX; CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[0][index]); ((CPUTMeshDX11*)pMesh)->BindVertexShaderLayout( pMaterial, &mpInputLayout[0][index] ); }
//----------------------------------------------------------------------------- CPUTResult CPUTModel::LoadModelPayload(const cString &File) { CPUTResult result = CPUT_SUCCESS; std::ifstream file(File.c_str(), std::ios::in | std::ios::binary); ASSERT( !file.fail(), _L("CPUTModelDX11::LoadModelPayload() - Could not find binary model file: ") + File ); // set up for mesh creation loop UINT meshIndex = 0; while(file.good() && !file.eof()) { // TODO: rearrange while() to avoid if(eof). Should perform only one branch per loop iteration, not two CPUTRawMeshData vertexFormatDesc; vertexFormatDesc.Read(file); if(file.eof()) { // TODO: Wtf? Why would we get here? We check eof at the top of loop. If it isn't eof there, why is it eof here? break; } ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count")); // create the mesh. CPUTMesh *pMesh = mpMesh[meshIndex]; // always a triangle list (at this point) pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST); // get number of data blocks in the vertex element (pos,norm,uv,etc) // YUCK! TODO: Use fixed-size array of elements CPUTBufferInfo *pVertexElementInfo = new CPUTBufferInfo[vertexFormatDesc.mFormatDescriptorCount]; // pMesh->SetBounds(vertexFormatDesc.mBboxCenter, vertexFormatDesc.mBboxHalf); // running count of each type of element int positionStreamCount=0; int normalStreamCount=0; int texCoordStreamCount=0; int tangentStreamCount=0; int binormalStreamCount=0; int colorStreamCount=0; int RunningOffset = 0; for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++) { // lookup the CPUT data type equivalent pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[vertexFormatDesc.mpElements[ii].mVertexElementType]; ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error. This model file has an unknown data type in it's model data.")); // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32) pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType]; // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes) pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes; // store the number of elements (i.e. 3xF32, 3 elements) pVertexElementInfo[ii].mElementCount = vertexFormatDesc.mVertexCount; // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here pVertexElementInfo[ii].mOffset = RunningOffset; RunningOffset = RunningOffset + pVertexElementInfo[ii].mElementSizeInBytes; // extract the name of stream pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii]; switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic) { case CPUT_VERTEX_ELEMENT_POSITON: pVertexElementInfo[ii].mpSemanticName = "POSITION"; pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++; break; case CPUT_VERTEX_ELEMENT_NORMAL: pVertexElementInfo[ii].mpSemanticName = "NORMAL"; pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++; break; case CPUT_VERTEX_ELEMENT_TEXTURECOORD: pVertexElementInfo[ii].mpSemanticName = "TEXCOORD"; pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++; break; case CPUT_VERTEX_ELEMENT_TANGENT: pVertexElementInfo[ii].mpSemanticName = "TANGENT"; pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++; break; case CPUT_VERTEX_ELEMENT_BINORMAL: pVertexElementInfo[ii].mpSemanticName = "BINORMAL"; pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++; break; case CPUT_VERTEX_ELEMENT_VERTEXCOLOR: pVertexElementInfo[ii].mpSemanticName = "COLOR"; pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++; break; default: cString errorString = _L("Invalid vertex semantic in: '")+File+_L("'\n"); TRACE(errorString.c_str()); ASSERT(0, errorString); } } // Index buffer CPUTBufferInfo indexDataInfo; indexDataInfo.mElementType = (vertexFormatDesc.mIndexType == tUINT32) ? CPUT_U32 : CPUT_U16; indexDataInfo.mElementComponentCount = 1; indexDataInfo.mElementSizeInBytes = (vertexFormatDesc.mIndexType == tUINT32) ? sizeof(UINT32) : sizeof(UINT16); indexDataInfo.mElementCount = vertexFormatDesc.mIndexCount; indexDataInfo.mOffset = 0; indexDataInfo.mSemanticIndex = 0; indexDataInfo.mpSemanticName = NULL; if( pVertexElementInfo->mElementCount && indexDataInfo.mElementCount ) { result = pMesh->CreateNativeResources( this, meshIndex, vertexFormatDesc.mFormatDescriptorCount, pVertexElementInfo, (void*)vertexFormatDesc.mpVertices, &indexDataInfo, &vertexFormatDesc.mpIndices[0] ); if(CPUTFAILED(result)) { return result; } // CC added result = pMesh->ExtractVerticesandIndices(); if(CPUTFAILED(result)) { return result; } // CC added ends } delete [] pVertexElementInfo; pVertexElementInfo = NULL; ++meshIndex; } ASSERT( file.eof(), _L("") ); // close file file.close(); return result; }
//----------------------------------------------------------------------------- CPUTResult CPUTModel::LoadModelPayload(const cString &FileName) { CPUTResult result = CPUT_SUCCESS; CPUTFileSystem::CPUTOSifstream file(FileName, std::ios::in | std::ios::binary); ASSERT( !file.fail(), _L("CPUTModel::LoadModelPayload() - Could not find binary model file: ") + FileName ); // set up for mesh creation loop UINT meshIndex = 0; while(file.good() && !file.eof()) { // TODO: rearrange while() to avoid if(eof). Should perform only one branch per loop iteration, not two CPUTRawMeshData vertexFormatDesc; vertexFormatDesc.Read(file); if(file.eof()) { // TODO: Wtf? Why would we get here? We check eof at the top of loop. If it isn't eof there, why is it eof here? break; } ASSERT( meshIndex < mMeshCount, _L("Actual mesh count doesn't match stated mesh count")); // create the mesh. CPUTMesh *pMesh = mpMesh[meshIndex]; // always a triangle list (at this point) pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST); // get number of data blocks in the vertex element (pos,norm,uv,etc) CPUTBufferElementInfo *pVertexElementInfo = new CPUTBufferElementInfo[vertexFormatDesc.mFormatDescriptorCount]; // running count of each type of element int positionStreamCount=0; int normalStreamCount=0; int texCoordStreamCount=0; int tangentStreamCount=0; int binormalStreamCount=0; int colorStreamCount=0; int blendWeightStreamCount = 0; int blendIndexStreamCount = 0; int runningOffset = 0; for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++) { // lookup the CPUT data type equivalent pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT(vertexFormatDesc.mpElements[ii].mVertexElementType); ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(".MDL file load error. This model file has an unknown data type in it's model data.")); // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32) pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType]; // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes) pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes; // store the number of elements (i.e. 3xF32, 3 elements) // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here pVertexElementInfo[ii].mOffset = runningOffset; runningOffset = runningOffset + pVertexElementInfo[ii].mElementSizeInBytes; // extract the name of stream pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii]; //TODO: Calculate Opengl semantic index elsewhere switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic) { //FIXME - this isn't right, and needs to change for DX and OpenGL //Probably just need to move semantic bind point into OpenGL, or something. //Currently, TEXCOORD is the only semantic with multiples in common use. Adding //semantic index works provided addtional attributes (e.g. vertex color) are not //present case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_POSITON: pVertexElementInfo[ii].mpSemanticName = "POSITION"; pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::POSITION; break; case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_NORMAL: pVertexElementInfo[ii].mpSemanticName = "NORMAL"; pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::NORMAL; break; case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TEXTURECOORD: pVertexElementInfo[ii].mpSemanticName = "TEXCOORD"; pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TEXCOORD + pVertexElementInfo[ii].mSemanticIndex; break; case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_TANGENT: pVertexElementInfo[ii].mpSemanticName = "TANGENT"; pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::TANGENT; break; case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_BINORMAL: pVertexElementInfo[ii].mpSemanticName = "BINORMAL"; pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::BINORMAL; break; case eCPUT_VERTEX_ELEMENT_SEMANTIC::CPUT_VERTEX_ELEMENT_VERTEXCOLOR: pVertexElementInfo[ii].mpSemanticName = "COLOR"; pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++; pVertexElementInfo[ii].mBindPoint = CPUTSemanticBindPoint::COLOR; break; default: cString errorString = _L("Invalid vertex semantic in: '")+FileName+_L("'\n"); TRACE(errorString.c_str()); ASSERT(0, errorString); } } // Index buffer CPUTBufferElementInfo indexDataInfo; indexDataInfo.mElementType = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? CPUT_U32 : CPUT_U16; indexDataInfo.mElementComponentCount = 1; indexDataInfo.mElementSizeInBytes = (vertexFormatDesc.mIndexType == eCPUT_VERTEX_ELEMENT_TYPE::tUINT32) ? sizeof(uint32_t) : sizeof(uint16_t); indexDataInfo.mOffset = 0; indexDataInfo.mSemanticIndex = 0; indexDataInfo.mpSemanticName = NULL; if( vertexFormatDesc.mVertexCount && vertexFormatDesc.mIndexCount ) { result = pMesh->CreateNativeResources( this, meshIndex, vertexFormatDesc.mFormatDescriptorCount, pVertexElementInfo, vertexFormatDesc.mVertexCount, (void*)vertexFormatDesc.mpVertices, &indexDataInfo, vertexFormatDesc.mIndexCount, vertexFormatDesc.mpIndices ); if(CPUTFAILED(result)) { return result; } } delete [] pVertexElementInfo; pVertexElementInfo = NULL; ++meshIndex; } ASSERT( file.eof(), _L("") ); // close file file.close(); return result; }