示例#1
0
//-----------------------------------------------------------------------------
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;
}