예제 #1
0
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;
}
예제 #2
0
		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();
		}
예제 #3
0
		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();
		}
예제 #4
0
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;
}
예제 #6
0
////////////////////////////////////////////////////////////////////////
///
/// 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;
}