// // Populate a D3DGeometry object from a Maya mesh // bool D3DGeometry::Populate( const MDagPath& dagPath, ID3D11Device* D3D) { HRESULT hr; Release(); MFnMesh mesh( dagPath.node()); // Figure out texturing // MString pn = dagPath.fullPathName(); //printf("Convert shape %s\n", pn.asChar()); bool haveTexture = false; int numUVsets = mesh.numUVSets(); MString uvSetName; MObjectArray textures; if (numUVsets > 0) { mesh.getCurrentUVSetName( uvSetName ); // Always send down uvs for now, since we don't dirty the populate // based on material texture connection. // //MStatus status = mesh.getAssociatedUVSetTextures(uvSetName, textures); //if (status == MS::kSuccess && textures.length()) int numCoords = mesh.numUVs( uvSetName ); if (numCoords > 0) { haveTexture = true; } } bool haveColors = false; int numColors = mesh.numColorSets(); MString colorSetName; if (numColors > 0) { haveColors = true; mesh.getCurrentColorSetName(colorSetName); } bool useNormals = true; // Setup our requirements needs. MGeometryRequirements requirements; requirements.addPosition(); if (useNormals) requirements.addNormal(); if (haveTexture) requirements.addTexCoord( uvSetName ); if (haveColors) requirements.addColor( colorSetName ); // Test for tangents and binormals bool testBinormal = false; if (testBinormal) requirements.addBinormal( uvSetName ); bool testTangent= false; if (testTangent) requirements.addTangent( uvSetName ); MGeometry geom = MGeometryManager::getGeometry( dagPath, requirements, NULL ); unsigned int numPrims = geom.primitiveArrayCount(); if( numPrims) { const MGeometryPrimitive prim = geom.primitiveArray(0); NumIndices = prim.elementCount(); if( NumIndices) { //MGeometryData::ElementType primType = prim.dataType(); unsigned int *idx = (unsigned int *) prim.data(); // Get the position data const MGeometryData pos = geom.position(); float * posPtr = (float * )pos.data(); if( !idx || !posPtr) return false; NumVertices = pos.elementCount(); // Start building our vertex format. We always have position, so // start with that and add in all the elements we find along the way Stride = sizeof( float) * 3; // Get the normals data float * normPtr = NULL; if( useNormals) { const MGeometryData norm = geom.normal(); normPtr = (float * )norm.data(); Stride += sizeof( float) * 3; } // Get the texture coordinate data float *uvPtr = NULL; if( haveTexture) { const MGeometryData uvs = geom.texCoord( uvSetName ); uvPtr = (float *)uvs.data(); Stride += sizeof( float) * 2; } // Always using FixedFunctionVertex for now Stride = sizeof(FixedFunctionVertex); useNormals = true; haveTexture = true; // Copy our vertex data into the buffer // int FloatsPerVertex = Stride / sizeof( float); float* vertBuffer = new float[ NumVertices * FloatsPerVertex ]; float* VertexData = vertBuffer; int StrideOffset = FloatsPerVertex - 3; //MGlobal::displayInfo( MString( "Allocating buffers for ") + NumVertices + MString( " verts and ") + NumIndices + MString( " indices\n")); for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *posPtr++; *VertexData++ = *posPtr++; *VertexData++ = *posPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 3; if( normPtr) { for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *normPtr++; *VertexData++ = *normPtr++; *VertexData++ = *normPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 3; } if( uvPtr) { StrideOffset = FloatsPerVertex - 2; for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *uvPtr++; *VertexData++ = 1.0f - *uvPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 2; } // Allocate our vertex buffer // D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = Stride * NumVertices; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = vertBuffer; hr = D3D->CreateBuffer( &bd, &InitData, &VertexBuffer ); if ( FAILED( hr ) ) { MGlobal::displayWarning( "DX11 renderer : Unable to allocate vertex buffer\n"); return false; } delete [] vertBuffer; // Allocate our index buffer // bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = NumIndices * sizeof( DWORD); bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; InitData.pSysMem = idx; hr = D3D->CreateBuffer( &bd, &InitData, &IndexBuffer ); if ( FAILED( hr ) ) { MGlobal::displayWarning( "DX11 renderer : Unable to allocate index buffer\n"); return false; } } } return IndexBuffer && VertexBuffer; }
// // Populate a D3DGeometry object from a Maya mesh // bool D3DGeometry::Populate( const MDagPath& dagPath, LPDIRECT3DDEVICE9 D3D) { Release(); MFnMesh mesh( dagPath.node()); // Figure out texturing // bool haveTexture = false; int numUVsets = mesh.numUVSets(); MString uvSetName; MObjectArray textures; if (numUVsets > 0) { mesh.getCurrentUVSetName( uvSetName ); // Always send down uvs for now, since we don't dirty the populate // based on material texture connection. // //MStatus status = mesh.getAssociatedUVSetTextures(uvSetName, textures); //if (status == MS::kSuccess && textures.length()) { haveTexture = true; } } bool haveColors = false; int numColors = mesh.numColorSets(); MString colorSetName; if (numColors > 0) { haveColors = true; mesh.getCurrentColorSetName(colorSetName); } bool useNormals = true; // Setup our requirements needs. MGeometryRequirements requirements; requirements.addPosition(); if (useNormals) requirements.addNormal(); if (haveTexture) requirements.addTexCoord( uvSetName ); if (haveColors) requirements.addColor( colorSetName ); // Test for tangents and binormals bool testBinormal = false; if (testBinormal) requirements.addBinormal( uvSetName ); bool testTangent= false; if (testTangent) requirements.addTangent( uvSetName ); MGeometry geom = MGeometryManager::getGeometry( dagPath, requirements, NULL ); unsigned int numPrims = geom.primitiveArrayCount(); if( numPrims) { const MGeometryPrimitive prim = geom.primitiveArray(0); NumIndices = prim.elementCount(); if( NumIndices) { //MGeometryData::ElementType primType = prim.dataType(); unsigned int *idx = (unsigned int *) prim.data(); // Get the position data const MGeometryData pos = geom.position(); float * posPtr = (float * )pos.data(); if( !idx || !posPtr) return false; NumVertices = pos.elementCount(); // Start building our vertex format. We always have position, so // start with that and add in all the elements we find along the way FVF = D3DFVF_XYZ; Stride = sizeof( float) * 3; // Get the normals data float * normPtr = NULL; if( useNormals) { const MGeometryData norm = geom.normal(); normPtr = (float * )norm.data(); Stride += sizeof( float) * 3; FVF |= D3DFVF_NORMAL; } // Get the texture coordinate data float *uvPtr = NULL; if( haveTexture) { const MGeometryData uvs = geom.texCoord( uvSetName ); uvPtr = (float *)uvs.data(); Stride += sizeof( float) * 2; FVF |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0); } unsigned int numColorComponents = 4; float *clrPtr = NULL; if (haveColors) { const MGeometryData clrs = geom.color( colorSetName ); clrPtr = (float *)clrs.data(); } else if (testBinormal) { const MGeometryData binorm = geom.binormal( uvSetName ); clrPtr = (float *)binorm.data(); numColorComponents = 3; } else if (testTangent) { const MGeometryData tang = geom.tangent( uvSetName ); clrPtr = (float *)tang.data(); numColorComponents = 3; } // Allocate our vertex buffer // if( D3D->CreateVertexBuffer( Stride * NumVertices, D3DUSAGE_WRITEONLY, FVF, D3DPOOL_DEFAULT, &VertexBuffer, NULL) != D3D_OK) { MGlobal::displayWarning( "Direct3D renderer : Unable to allocate vertex buffer\n"); return false; } // Copy our vertex data into the buffer // float* VertexData = NULL; int FloatsPerVertex = Stride / sizeof( float); int StrideOffset = FloatsPerVertex - 3; //MGlobal::displayInfo( MString( "Allocating buffers for ") + NumVertices + MString( " verts and ") + NumIndices + MString( " indices\n")); VertexBuffer->Lock( 0, 0, (void**)&VertexData, D3DLOCK_DISCARD); for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *posPtr++; *VertexData++ = *posPtr++; *VertexData++ = *posPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 3; if( normPtr) { for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *normPtr++; *VertexData++ = *normPtr++; *VertexData++ = *normPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 3; } if( uvPtr) { StrideOffset = FloatsPerVertex - 2; for( unsigned int i = 0; i < NumVertices; i++) { *VertexData++ = *uvPtr++; *VertexData++ = 1.0f - *uvPtr++; VertexData += StrideOffset; } VertexData -= NumVertices * FloatsPerVertex - 2; } VertexBuffer->Unlock(); // Allocate our index buffer // if( D3D->CreateIndexBuffer( NumIndices * sizeof( DWORD), 0, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &IndexBuffer, NULL) != D3D_OK) { MGlobal::displayWarning( "Direct3D renderer : Unable to allocate index buffer\n"); return false; } // Copy our index data into the buffer // unsigned int* IndexData = NULL; IndexBuffer->Lock( 0, 0, (void**)&IndexData, D3DLOCK_DISCARD); memcpy( IndexData, idx, NumIndices * sizeof(DWORD)); IndexBuffer->Unlock(); } } return IndexBuffer && VertexBuffer; }