void C3d::Open(const TriFile &tfile) { Cleanup(); rotation = true; if( FAILED( g_pd3dDevice->CreateVertexBuffer(tfile.header.numVertices*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL))) return; CUSTOMVERTEX* pVertices; if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) ) return; vcount = tfile.header.numVertices; if(tfile.hasTangentsBinormals) { for( DWORD i=0; i<tfile.header.numVertices; i++ ) { pVertices[i].position = tfile.verticestb(i)->vertexPosition; pVertices[i].normal = tfile.verticestb(i)->vertexNormal; pVertices[i].uv = tfile.verticestb(i)->vertexUV; } }else{ for( DWORD i=0; i<tfile.header.numVertices; i++ ) { pVertices[i].position = tfile.verticesc(i)->vertexPosition; pVertices[i].normal = tfile.verticesc(i)->vertexNormal; pVertices[i].uv = tfile.verticesc(i)->vertexUV; } } ComputeBoundingSphere(pVertices, vcount, &vCenter, &vRadius); g_pVB->Unlock(); D3DVIEWPORT9 vp; g_pd3dDevice->GetViewport(&vp); vp.MinZ = -((int)vRadius/300)*55.0f; g_pd3dDevice->SetViewport(&vp); D3DXMatrixIdentity( &matWorld ); MatrixTranslation( &matWorld, vCenter.x, -vCenter.y, -vCenter.z ); DWORD *indices=NULL; ClearIndexes(); ClearTextures(); g_pTexture.resize(tfile.header.numSurfaces); for(unsigned int i = 0; i < tfile.header.numSurfaces; i++) g_pTexture[i] = NULL; g_pIB.resize(tfile.header.numSurfaces); fcount.resize(tfile.header.numSurfaces); for(dword i = 0; i < tfile.header.numSurfaces; i++) { g_pd3dDevice->CreateIndexBuffer(tfile.surfaces[i].numTriangles*3*4,D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &g_pIB[i], NULL); g_pIB[i]->Lock( 0, 0, (void**)&indices, 0 ); for(dword c = 0; c < tfile.surfaces[i].numTriangles; c++) { indices[3*c] = tfile.triangles[i][c][0]; indices[3*c+1] = tfile.triangles[i][c][1]; indices[3*c+2] = tfile.triangles[i][c][2]; } g_pIB[i]->Unlock(); fcount[i] = tfile.surfaces[i].numTriangles; } loaded = true; }
MeshElement::MeshElement(const VertexElementDescriptor &vertexFormat, const oakvr::core::MemoryBuffer &vb , uint8_t indexStride, const oakvr::core::MemoryBuffer ib , sp<Material> &pMaterial) : m_vertexData{ vb }, m_indexStride{ indexStride }, m_indexData{ ib }, m_pMaterial{pMaterial} { m_vertexFormat.push_back(vertexFormat); m_vertexStride = vertexFormat.size; m_indexCount = static_cast<uint32_t>(m_indexData.Size() / m_indexStride); m_vertexCount = static_cast<uint32_t>(m_vertexData.Size() / m_vertexStride); ComputeBoundingSphere(); }
MeshElement::MeshElement(const std::vector<VertexElementDescriptor> &vertexFormat, const oakvr::core::MemoryBuffer &vb , uint8_t indexStride, const oakvr::core::MemoryBuffer ib , sp<Material> &pMaterial, const std::vector<StringId> &vecTextures) : m_vertexFormat( vertexFormat ), m_vertexData{ vb }, m_indexStride{ indexStride }, m_indexData{ ib }, m_pMaterial{ pMaterial }, m_vecTextures(vecTextures) { m_vertexStride = 0; for (auto &e : m_vertexFormat) { m_vertexStride += e.size; } m_indexCount = static_cast<uint32_t>(m_indexData.Size() / m_indexStride); m_vertexCount = static_cast<uint32_t>(m_vertexData.Size() / m_vertexStride); ComputeBoundingSphere(); }
void CChain::SetChain(const Vector& P0, const Vector& P1, int iNumParticles, int iRigidity, float fParticleRadius, float fParticleMass) { Free(); Allocate(iNumParticles, iNumParticles-1); if (iNumParticles < 2) return; if (iRigidity <= 0) iRigidity = 1; SetRigidity(iRigidity); //----------------------------------------------------------- // copy particles //----------------------------------------------------------- Vector P = P0; Vector D = (P0 - P1) / ((float) iNumParticles); for(int i = 0; i < iNumParticles; i ++) { AddParticle(CParticle(P, fParticleRadius, (i != 0)? fParticleMass : 0.0f)); P += D; } //------------------------------------------------------------------ // link particles together //------------------------------------------------------------------ for(int i = 0; i < iNumParticles-1; i ++) { AddConstraint(CLinConstraint(&GetParticle(i), &GetParticle(i+1))); P += D; } ComputeBoundingSphere(); m_iSelfCollisionStep = 2; }
// // Framework functions // bool Setup() { HRESULT hr = 0; // // Load the XFile data. // ID3DXBuffer* adjBuffer = 0; ID3DXBuffer* mtrlBuffer = 0; DWORD numMtrls = 0; hr = D3DXLoadMeshFromX( "../media/object/bigship1.x", D3DXMESH_MANAGED, Device, &adjBuffer, &mtrlBuffer, 0, &numMtrls, &Mesh); if(FAILED(hr)) { ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0); return false; } // // Extract the materials, load textures. // if( mtrlBuffer != 0 && numMtrls != 0 ) { D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer(); for(int i = 0; i < numMtrls; i++) { // the MatD3D property doesn't have an ambient value set // when its loaded, so set it now: mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse; // save the ith material Mtrls.push_back( mtrls[i].MatD3D ); // check if the ith material has an associative texture if( mtrls[i].pTextureFilename != 0 ) { // yes, load the texture for the ith subset IDirect3DTexture9* tex = 0; D3DXCreateTextureFromFile( Device, mtrls[i].pTextureFilename, &tex); // save the loaded texture Textures.push_back( tex ); } else { // no texture for the ith subset Textures.push_back( 0 ); } } } byhj::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer // // Optimize the mesh. // hr = Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0); byhj::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer if(FAILED(hr)) { ::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0); return false; } // // Compute Bounding Sphere and Bounding Box. // byhj::BoundingSphere boundingSphere; byhj::BoundingBox boundingBox; ComputeBoundingSphere(Mesh, &boundingSphere); ComputeBoundingBox(Mesh, &boundingBox); D3DXCreateSphere( Device, boundingSphere._radius, 20, 20, &SphereMesh, 0); D3DXCreateBox( Device, boundingBox._max.x - boundingBox._min.x, boundingBox._max.y - boundingBox._min.y, boundingBox._max.z - boundingBox._min.z, &BoxMesh, 0); // // Set texture filters. // Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); // // Set Lights. // D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f); D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f); D3DLIGHT9 light = byhj::InitDirectionalLight(&dir, &col); Device->SetLight(0, &light); Device->LightEnable(0, true); Device->SetRenderState(D3DRS_NORMALIZENORMALS, true); Device->SetRenderState(D3DRS_SPECULARENABLE, true); // // Set camera. // D3DXVECTOR3 pos(4.0f, 12.0f, -20.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH( &V, &pos, &target, &up); Device->SetTransform(D3DTS_VIEW, &V); // // Set projection matrix. // D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, // 90 - degree (float)Width / (float)Height, 1.0f, 1000.0f); Device->SetTransform(D3DTS_PROJECTION, &proj); return true; }
//////////////////////////////////////////////////////////////////////// /// /// Loads DirectX mesh file. /// /// @param filename Filename to load. /// /// @return success or failure. /// //////////////////////////////////////////////////////////////////////// const VCNBool VCNDXMesh::LoadFromFile( const VCNString& filename ) { VCND3D9* renderer = static_cast<VCND3D9*>( VCNRenderCore::GetInstance() ); LPDIRECT3DDEVICE9 d3dDevice = renderer->GetD3DDevice(); CComPtr<ID3DXMesh> systemMesh; CComPtr<ID3DXBuffer> materialBuffer; // Load the mesh from the specified file // DWORD numMaterials = 0; HRESULT hr = D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, d3dDevice, NULL, &materialBuffer,NULL, &numMaterials, &systemMesh ); if ( FAILED(hr) ) return false; // Load materials // D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)materialBuffer->GetBufferPointer(); for (DWORD i = 0; i < numMaterials; ++i) { VCN_ASSERT_MSG( i == 0 || mMaterialID == kInvalidResID, VCNTXT("We do not support multiple material per meshes") ); // Create the texture if it exists - it may not if (d3dxMaterials[i].pTextureFilename) { VCNString texturePath = VCNTXT("Textures/"); texturePath += VCN_A2W(d3dxMaterials[i].pTextureFilename); // Check if the texture is already loaded VCNResID texID = kInvalidResID; VCND3D9Texture* resTexture = VCNResourceCore::GetInstance()->GetResource<VCND3D9Texture>(texturePath); if (!resTexture) { LPDIRECT3DTEXTURE9 d3dTexture = NULL; hr = D3DXCreateTextureFromFile(d3dDevice, texturePath.c_str(), &d3dTexture); VCN_ASSERT_MSG( SUCCEEDED(hr), _T("Can't load texture [%s]"), texturePath.c_str() ); resTexture = new VCND3D9Texture( d3dTexture ); resTexture->SetName( texturePath ); texID = VCNResourceCore::GetInstance()->AddResource( texturePath, resTexture ); } else { texID = resTexture->GetResourceID(); } VCNMaterial* material = new VCNMaterial(); material->SetName( VCNString(VCNTXT("material_dx_mesh_")) + filename ); material->SetAmbientColor( VCNColor((const VCNFloat*)&d3dxMaterials[i].MatD3D.Ambient) ); material->SetDiffuseColor( VCNColor((const VCNFloat*)&d3dxMaterials[i].MatD3D.Diffuse) ); material->SetSpecularColor( VCNColor((const VCNFloat*)&d3dxMaterials[i].MatD3D.Specular) ); material->SetSpecularPower( d3dxMaterials[i].MatD3D.Power ); VCNEffectParamSet& params = material->GetEffectParamSet(); params.SetEffectID( eidLitTextured ); params.AddResource( VCNTXT("DiffuseTexture"), texID ); // Add material as a resource. mMaterialID = VCNResourceCore::GetInstance()->AddResource( material->GetName(), material ); } } // Optimize the mesh if possible // const VCNUInt faceCount = systemMesh->GetNumFaces(); DWORD* adjac = new DWORD[faceCount*3]; hr = systemMesh->GenerateAdjacency(0.5f, adjac); hr = systemMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, adjac, NULL, NULL, NULL); // Calculate Tangent and Binormal hr = D3DXComputeTangentFrameEx(systemMesh, D3DDECLUSAGE_TEXCOORD, 0, D3DDECLUSAGE_TANGENT, 0, D3DDECLUSAGE_BINORMAL, 0, D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_DONT_ORTHOGONALIZE | D3DXTANGENT_WEIGHT_BY_AREA, adjac, -1.01f, -0.01f, -1.01f, &systemMesh, NULL); delete [] adjac; // Load caches // const VCNUInt vertexCount = systemMesh->GetNumVertices(); const DWORD meshFVF = systemMesh->GetFVF(); const DWORD stride = D3DXGetFVFVertexSize( meshFVF ); const DWORD positionStride = D3DXGetFVFVertexSize( D3DFVF_XYZ ); const DWORD normalStride = D3DXGetFVFVertexSize( D3DFVF_NORMAL ); const DWORD diffuseStride = D3DXGetFVFVertexSize( D3DFVF_DIFFUSE ); const DWORD textureStride = D3DXGetFVFVertexSize( D3DFVF_TEX1 ); VCNFloat* vtPositionBufStart = new VCNFloat[vertexCount * kCacheStrides[VT_POSITION]]; VCNFloat* vtNormalBufStart = new VCNFloat[vertexCount * kCacheStrides[VT_LIGHTING]]; VCNFloat* vtTextureBufStart = new VCNFloat[vertexCount * kCacheStrides[VT_DIFFUSE_TEX_COORDS]]; VCNFloat* vtPositionBuf = vtPositionBufStart; VCNFloat* vtNormalBuf = vtNormalBufStart; VCNFloat* vtTextureBuf = vtTextureBufStart; BYTE* vbptr = NULL; systemMesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&vbptr); for(VCNUInt i = 0; i < vertexCount; ++i) { if ( meshFVF == (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1) ) { // Read position D3DXVECTOR3* pos = (D3DXVECTOR3*)vbptr; *vtPositionBuf = pos->x; vtPositionBuf++; *vtPositionBuf = pos->y; vtPositionBuf++; *vtPositionBuf = pos->z; vtPositionBuf++; // Read normal D3DXVECTOR3* normal = (D3DXVECTOR3*)(vbptr + positionStride); *vtNormalBuf = normal->x; vtNormalBuf++; *vtNormalBuf = normal->y; vtNormalBuf++; *vtNormalBuf = normal->z; vtNormalBuf++; // Set default diffuse color std::fill(vtNormalBuf, vtNormalBuf+3, 1.0f); vtNormalBuf += 3; float* texCoords = (float*)(vbptr + positionStride + normalStride); *vtTextureBuf = texCoords[0]; vtTextureBuf++; *vtTextureBuf = texCoords[1]; vtTextureBuf++; vbptr += stride; } else { VCN_ASSERT_FAIL( VCNTXT("Mesh FVF not supported [FVF(%d) stride = %d]"), meshFVF, stride ); } } systemMesh->UnlockVertexBuffer(); VCNResID positionCache = renderer->CreateCache(VT_POSITION, vtPositionBufStart, vertexCount * kCacheStrides[VT_POSITION]); VCNResID lightingCache = renderer->CreateCache(VT_LIGHTING, vtNormalBufStart, vertexCount * kCacheStrides[VT_LIGHTING]); VCNResID textureCache = renderer->CreateCache(VT_DIFFUSE_TEX_COORDS, vtTextureBufStart, vertexCount * kCacheStrides[VT_DIFFUSE_TEX_COORDS]); SetCacheID(VT_POSITION, positionCache); SetCacheID(VT_LIGHTING, lightingCache); SetCacheID(VT_DIFFUSE_TEX_COORDS, textureCache); delete [] vtPositionBufStart; delete [] vtNormalBufStart; delete [] vtTextureBufStart; VCNUShort* ibptr = NULL; VCNUShort* indices = new VCNUShort[faceCount * 3]; systemMesh->LockIndexBuffer(D3DLOCK_READONLY, (LPVOID*)&ibptr); for(VCNUInt i = 0; i < systemMesh->GetNumFaces(); i++) { indices[(i * 3) + 0] = *(ibptr++); indices[(i * 3) + 1] = *(ibptr++); indices[(i * 3) + 2] = *(ibptr++); } systemMesh->UnlockIndexBuffer(); VCNResID indexCacheID = renderer->CreateCache(VT_INDEX, indices, faceCount * 3 * kCacheStrides[VT_INDEX]); SetFaceCache(indexCacheID); SetFaceCount(faceCount); SetPrimitiveType(PT_TRIANGLELIST); delete [] indices; // Compute bounding sphere if ( !ComputeBoundingSphere(systemMesh) ) return false; return true; }