Esempio n. 1
0
int OrbitX::shotTest(D3DXVECTOR3 posO, D3DXVECTOR3 posN, int *index, float *pU, float* pV, float *dist) {
  D3DXMATRIX Translate;
  
  D3DXMatrixTranslation(&Translate, posO.x, posO.y, posO.z);
  Translate = Translate*WorldInverse;

  posO = D3DXVECTOR3((Translate)._41, (Translate)._42, (Translate)._43);
  
  D3DXMatrixTranslation(&Translate, posN.x, posN.y, posN.z);
  Translate = Translate*WorldInverse;

  posN = D3DXVECTOR3((Translate)._41, (Translate)._42, (Translate)._43);

  BOOL bHit = FALSE;
  DWORD dwFace;
  FLOAT fBary1, fBary2, fDist;

  D3DXIntersect(mesh, &posO, &(posN-posO), &bHit, &dwFace, &fBary1, &fBary2, &fDist,
                               NULL, NULL);

 

  if(bHit){
    if(fDist < 1.0){
      Tools::g->con.buff << fDist << " " <<Tools::Distance(posO, posN);
      Tools::g->con.Print();
      *pU = fBary1;
      *pV = fBary2;
      *dist = fDist;
      *index = dwFace;
      return 1;
    }    
  }
  return 0;
}
Esempio n. 2
0
int luaGetH(lua_State *L)
{
	float x=(float)lua_tonumber(L, 1);
	float z=(float)lua_tonumber(L, 2);
	BOOL hit;
	FLOAT dist;
	LPDIRECT3DVERTEXBUFFER8 pVB;
	LPDIRECT3DINDEXBUFFER8  pIB;
	WORD*            pIndices;
	D3DVERTEX*    pVertices;
	if(m_pLandMesh==NULL) {
		lua_pushnumber(L,-100000.0f);
		return 1;
	}
	m_pLandMesh->GetSysMemMesh()->GetVertexBuffer( &pVB );
	m_pLandMesh->GetSysMemMesh()->GetIndexBuffer( &pIB );
	pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 );
	pVB->Lock( 0, 0, (BYTE**)&pVertices, 0 );
	D3DXVECTOR3 v1,v2;
	GVector dir2=GVector(0,-1,0);
	v1.x=x;v1.y=100000.0f;v1.z=z;
	v2.x=0;v2.y=-1;v2.z=0;
	D3DXIntersect(m_pLandMesh->GetSysMemMesh(),&v1,&v2,&hit,NULL,NULL,NULL,&dist,NULL,NULL);
	if(!hit) dist=-100000.0f;
	else dist=100000.0f-dist;
	lua_pushnumber(L,dist);
	return 1;

}
Esempio n. 3
0
void D3D9Mesh::QueryHits(const Vec3f &Pos, const Vec3f &Dir, Vector<float> &Hits, DWORD &FirstHitFaceIndex, float &u, float &v) const
{
    D3DXVECTOR3 D3DPos = Pos;
    D3DXVECTOR3 D3DDir = Dir;
    BOOL Hit;
    DWORD HitCount;
    FLOAT Dist;
    LPD3DXBUFFER AllHits = NULL;

    D3DXIntersect(_Mesh, &D3DPos, &D3DDir, &Hit, &FirstHitFaceIndex, &u, &v, &Dist, &AllHits, &HitCount);

    Hits.Allocate(HitCount);
    if(HitCount)
    {
        LPD3DXINTERSECTINFO HitInfo = (LPD3DXINTERSECTINFO)AllHits->GetBufferPointer();
        for(UINT HitIndex = 0; HitIndex < HitCount; HitIndex++)
        {
            Hits[HitIndex] = HitInfo[HitIndex].Dist;
        }
        Hits.Sort();
    }

    if(AllHits != NULL)
    {
        AllHits->Release();
    }
}
Esempio n. 4
0
//=================================================================================================
float Terrain::Raytest(const Vec3& from, const Vec3& to) const
{
	Vec3 dir = to - from;
	float fout;

	if(!RayToBox(from, dir, box, &fout) || fout > 1.f)
		return -1.f;

	Matrix m = Matrix::Translation(pos).Inverse();
	Vec3 rayPos = Vec3::Transform(from, m),
		rayDir = Vec3::TransformNormal(dir, m);
	BOOL hit;
	DWORD face;
	float bar1, bar2;

	{
		//START_PROFILE("Intersect");
		V(D3DXIntersect(mesh, (D3DXVECTOR3*)&rayPos, (D3DXVECTOR3*)&rayDir, &hit, &face, &bar1, &bar2, &fout, nullptr, nullptr));
	}

	if(hit)
	{
		// tu by³ bug - fout zwraca odrazu wynik w przedziale (0..1) a nie tak jak myœla³em ¿e jest to dystans od startu do przeciêcia
		//printf("from %g,%g,%g\tto %g,%g,%g\tdist %g\thit %g\n", from.x, from.y, from.z, to.x, to.y, to.z, distance(from, to), fout);
		//fout /= distance(from, to);
		if(fout > 1.f)
			return -1.f;
		else
			return fout;
	}
	else
		return -1.f;
}
Esempio n. 5
0
bool CEntity::ComputeNormalVector(
	LPD3DXMESH _pMesh, D3DXVECTOR3& _vNormal, D3DXVECTOR3& _vCol, CEntity* target)
{
	BOOL isHit = false;
	DWORD dwFaceIndex = 0;
	float fDist = 0;
	LPD3DXBUFFER ppAllhit;
	DWORD pCountOfHits;
	
	D3DXVECTOR3 vPos = m_vPos - target->GetPos();
	D3DXVECTOR3 vtar = (-vPos);
	D3DXVec3Normalize( &vtar, &vtar);

	D3DXIntersect( _pMesh, &vPos, &vtar, &isHit, 
		&dwFaceIndex, NULL, NULL, &fDist, &ppAllhit, &pCountOfHits );

	if ( !isHit || fDist > GetSize()  )
		return false;// Ãæµ¹ÀÌ ¾È‰ç°Å³ª °Å¸®°¡ ¸Ö´Ù¸é ¸®ÅÏ;

	LPDIRECT3DVERTEXBUFFER9 pVB; 
	LPDIRECT3DINDEXBUFFER9 pIB; 

	_pMesh->GetVertexBuffer(&pVB); 
	_pMesh->GetIndexBuffer( &pIB ); 

	WORD* pIndices; 
	D3DVERTEX* pVertices; 

	pIB->Lock( 0, 0, (void**)&pIndices, 0 ); 
	pVB->Lock( 0, 0,(void**)&pVertices, 0); 

	D3DXVECTOR3 v0 = pVertices[pIndices[3*dwFaceIndex+0]].vPos; 
	D3DXVECTOR3 v1 = pVertices[pIndices[3*dwFaceIndex+1]].vPos; 
	D3DXVECTOR3 v2 = pVertices[pIndices[3*dwFaceIndex+2]].vPos; 
	
	D3DXPLANE plane;
	
	D3DXPlaneFromPoints( &plane, &v0, &v1, &v2);
	
	_vCol = (v0 + v1 + v2)/3.f;
	_vCol += target->GetPos();

	_vNormal.x = plane.a;
	_vNormal.y = plane.b;
	_vNormal.z = plane.c;
	
#ifdef _DEBUG
	//Ãæµ¹ÁöÁ¡ Ç¥½Ã
	_SINGLE(CDebug)->AddPosMark( _vCol, COLOR_BLACK);
#endif
	
	pVB->Unlock(); 
	pIB->Unlock(); 
	Safe_Release(pVB); 
	Safe_Release(pIB); 

	return true;
}
Esempio n. 6
0
float RAY::Intersect(ID3DXMesh* mesh)
{
	if(mesh == NULL)return -1.0f;

	// Collect only the closest intersection
	BOOL hit;
	DWORD dwFace;
	float hitU, hitV, dist;
	D3DXIntersect(mesh, &org, &dir, &hit, &dwFace, &hitU, &hitV, &dist, NULL, NULL);

	if(hit) return dist;
	else return -1.0f;
}
Esempio n. 7
0
float SFRay::Intersect(LPD3DXMESH mesh)
{
	if(mesh == NULL)return -1.0f;

	// Collect only the closest intersection
	BOOL hit;
	DWORD dwFace;
	float hitU, hitV, dist;
	D3DXIntersect(mesh, &mOrigin, &mDirection, &hit, &dwFace, &hitU, &hitV, &dist, NULL, NULL);

	if(hit) return dist;
	else return -1.0f;
}
Esempio n. 8
0
float RAY::Intersect(MESHINSTANCE iMesh)
{
	if(iMesh.m_pMesh == NULL || iMesh.m_pMesh->m_pMesh == NULL)return -1.0f;

	// Collect only the closest intersection
	BOOL hit;
	DWORD dwFace;
	float hitU, hitV, dist;
	D3DXIntersect(iMesh.m_pMesh->m_pMesh, &org, &dir, &hit, &dwFace, &hitU, &hitV, &dist, NULL, NULL);

	if(hit) return dist;
	else return -1.0f;
}
Esempio n. 9
0
bool D3D9Mesh::QueryInside(const Vec3f &Pos, const Vec3f &Dir)
{
    D3DXVECTOR3 D3DPos = Pos;
    D3DXVECTOR3 D3DDir = Dir;
    BOOL Hit;
    DWORD FaceIndex, HitCount;
    FLOAT U, _Vertices, Dist;
    //LPD3DXBUFFER AllHits = NULL;

    D3DXIntersect(_Mesh, &D3DPos, &D3DDir, &Hit, &FaceIndex, &U, &_Vertices, &Dist, NULL, &HitCount);
    //AllHits->Release();

    return (HitCount % 2 == 1);
}
Esempio n. 10
0
HRESULT KG3DMeshBone::UpdateSelBone(BOOL bSelectedUpdate /* = FALSE */)
{
    HRESULT hResult  = E_FAIL;
    HRESULT hRetCode = E_FAIL;
    IEKG3DSceneOutputWnd *piSceneCurOutputWnd = NULL;

    D3DXMATRIX  matWorldInv;
    D3DXVECTOR3 vOrg;
    D3DXVECTOR3 vDir;
    BOOL  bHit   = FALSE;
    DWORD dwFace = 0;

    KG_PROCESS_ERROR(m_pAttachScene);
    KG_PROCESS_ERROR(m_pAttachModel);

    hRetCode = m_pAttachScene->GetCurOutputWnd(&piSceneCurOutputWnd);
    KGLOG_COM_PROCESS_ERROR(hRetCode);
    KG_PROCESS_ERROR(piSceneCurOutputWnd);
    KG_PROCESS_ERROR(m_pSysMesh); 
    piSceneCurOutputWnd->GetPickRay(&vOrg, &vDir, NULL);

    D3DXMatrixIdentity(&matWorldInv);
    D3DXMatrixInverse(&matWorldInv, NULL, &m_pAttachModel->m_matWorld/*m_matWorld*/);
    D3DXVec3TransformCoord(&vOrg, &vOrg, &matWorldInv);
    D3DXVec3TransformNormal(&vDir, &vDir, &matWorldInv);

    D3DXIntersect(
        m_pSysMesh,
        &vOrg,
        &vDir,
        &bHit,
        &dwFace,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL
    );

    KG_PROCESS_ERROR(bHit);

    m_nSelSubIndex = static_cast<int>(dwFace) / 8;
    if (bSelectedUpdate)
        m_nSeledIndex = m_nSelSubIndex;

    hResult = S_OK;
Exit0:
    return hResult;
}
Esempio n. 11
0
void MOUSE::CalculateMappos(TERRAIN &terrain)
{
	//Get Mouse Ray
	D3DXMATRIX world;
	D3DXMatrixIdentity(&world);
	m_pDevice->SetTransform(D3DTS_WORLD, &world);
	RAY mRay = GetRay();

	float minDistance = 10000.0f;
	for(int i=0;i<(int)terrain.m_patches.size();i++)
	{
		if(mRay.Intersect(terrain.m_patches[i]->m_BBox) > 0.0f)
		{
			// Collect only the closest intersection
			BOOL hit;
			DWORD dwFace;
			float hitU, hitV, dist;
			D3DXIntersect(terrain.m_patches[i]->m_pMesh, &mRay.org, &mRay.dir, &hit, &dwFace, &hitU, &hitV, &dist, NULL, NULL);

			if(hit && dist < minDistance)
			{
				minDistance = dist;
				int tiles = dwFace / 2;		//Two faces to each map tile
				int tilesPerRow = terrain.m_patches[i]->m_mapRect.right - terrain.m_patches[i]->m_mapRect.left;
				int y = tiles / tilesPerRow, x = tiles - y * tilesPerRow;

				if(dwFace % 2 == 0)		//Hit upper left face
				{
					if(hitU > 0.5f)x++;
					else if(hitV > 0.5f)y++;
				}
				else					//Hit lower right face
				{
					if(hitU + hitV < 0.5f)y++;
					else if(hitU > 0.5f)x++;
					else {x++;y++;}
				}

				m_mappos.Set(terrain.m_patches[i]->m_mapRect.left + x, terrain.m_patches[i]->m_mapRect.top + y);
				m_ballPos = terrain.GetWorldPos(m_mappos);
			}			
		}
	}	
}
Esempio n. 12
0
bool CBoundBox::CheckIntersectByRay( D3DXVECTOR3 *pPos, D3DXVECTOR3 *pDir )
{
	static BOOL bHit = false;
	static DWORD dwFaceIndex,dwCountOfHits;
	static float u,v,dist;
	static LPD3DXBUFFER pAllHits;
	HRESULT hr = D3DXIntersect(
		m_box,
		pPos,
		pDir,
		&bHit,
		&dwFaceIndex,
		&u,
		&v,
		&dist,
		&pAllHits,
		&dwCountOfHits);
	return bHit;
}
Esempio n. 13
0
int SolidX::shotTest(D3DXVECTOR3 pos, D3DXVECTOR3 dir,
                          
  int *index, float *pU, float* pV, float *dist){

  D3DXMATRIX Translate;

  
  D3DXMatrixTranslation(&Translate, pos.x, pos.y, pos.z);
  Translate = Translate*WorldInverse;

  pos = D3DXVECTOR3((Translate)._41, (Translate)._42, (Translate)._43);


  
  D3DXMatrixTranslation(&Translate, dir.x, dir.y, dir.z);
  Translate._44 = 0;
  Translate = Translate*WorldInverse;

  dir = D3DXVECTOR3((Translate)._41, (Translate)._42, (Translate)._43);


  BOOL bHit = FALSE;
  DWORD dwFace;
  FLOAT fBary1, fBary2, fDist;

  D3DXIntersect(mesh, &pos, &dir, &bHit, &dwFace, &fBary1, &fBary2, &fDist,
                               NULL, NULL);

  if(bHit){
    *pU = fBary1;
    *pV = fBary2;
    *dist = fDist;
    *index = dwFace;
    return 1;
  }
  return 0;
}
Esempio n. 14
0
void World::editTerrain()
{
	BOOL hit = false;
	DWORD faceIndex, hitCount;
	float u, v, dist;
	LPD3DXBUFFER allHits;
	ID3DXMesh* mesh = mTerrain->getMesh()->getMesh();

	if(gInput->keyDown(VK_LBUTTON) || gInput->keyDown(VK_RBUTTON))
	{
		float strength = 300.0f;
		if(gInput->keyDown(VK_RBUTTON))
			strength *= -1;  

		D3DXVECTOR3 origin, dir;
		gInput->getWorldPickingRay(origin, dir);

		D3DXIntersect(mesh, &origin, &dir, &hit, &faceIndex, &u, &v, &dist, &allHits, &hitCount);

		if(hit)
		{
			DWORD* k = 0;

			mesh->LockIndexBuffer(0, (void**)&k);
			int pressed = k[faceIndex*3];
			mesh->UnlockIndexBuffer();

			VertexPNT* v = 0;
			mesh->LockVertexBuffer(0, (void**)&v);

			int size = 10;

			int x = pressed % mTerrain->getColums();
			int z = pressed / mTerrain->getColums();

			for(int i = z - size/2; i < z + size/2; i++)
				for(int j = x - size/2; j < x + size/2; j++) {
					if(i < 0 || j < 0 || i >= mTerrain->getRows() || j >= mTerrain->getColums())
						continue;

					float dist = sqrt((float)(z-i)*(z-i) + (float)(x-j)*(x-j));
					dist = max(dist, 3.0f);

					if(strength > 0)
						v[i*mTerrain->getColums() + j].pos.y += min(strength / dist, strength)/100;
					else
						v[i*mTerrain->getColums() + j].pos.y += max(strength / dist, strength)/100;
				}

			mesh->UnlockVertexBuffer();

			//mTerrain->smothOut(x, z, 10);
		}
	}

	if(gInput->keyPressed(VK_MBUTTON)) {
		D3DXIntersect(mesh, &gCamera->getPosition(), &gCamera->getDirection(), &hit, &faceIndex, &u, &v, &dist, &allHits, &hitCount);

		if(hit)
		{
			DWORD* k = 0;

			mesh->LockIndexBuffer(0, (void**)&k);
			int pressed = k[faceIndex*3];
			mesh->UnlockIndexBuffer();

			VertexPNT* v = 0;
			mesh->LockVertexBuffer(0, (void**)&v);

			int size = 10;

			int x = pressed % mTerrain->getColums();
			int z = pressed / mTerrain->getColums();


			mTerrain->smothOut(x, z, 5);
		}
	}
}
Esempio n. 15
0
//-----------------------------------------------------------------------------
// Returns the result of a ray intersection with the scene and all its objects.
//-----------------------------------------------------------------------------
bool SceneManager::RayIntersectScene( RayIntersectionResult *result, D3DXVECTOR3 rayPosition, D3DXVECTOR3 rayDirection, bool checkScene, SceneObject *thisObject, bool checkObjects )
{
	float hitDistance = 0.0f;

	// Check if the ray needs to check for intersection with the scene.
	if( checkScene == true )
	{
		// Go through all the faces in the scene, check for intersection.
		for( unsigned long f = 0; f < m_totalFaces; f++ )
		{
			// Skip this face if its material is set to ignore rays.
			if( m_faces[f].renderCache->GetMaterial()->GetIgnoreRay() == true )
				continue;

			// Check the ray against this face.
			if( D3DXIntersectTri( (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex0], (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex1], (D3DXVECTOR3*)&m_vertices[m_faces[f].vertex2], &rayPosition, &rayDirection, NULL, NULL, &hitDistance ) == TRUE )
			{
				if( hitDistance < result->distance || result->material == NULL )
				{
					( *result ).distance = hitDistance;
					( *result ).material = m_faces[f].renderCache->GetMaterial();
				}
			}
		}
	}

	// Check if the ray needs to check for intersection with the objects.
	if( checkObjects == true )
	{
		// Stores the ray in model space.
		D3DXVECTOR3 rp, rd;

		// Iterate all the objects in the scene, check for intersection.
		SceneObject *object = m_dynamicObjects->GetFirst();
		while( object != NULL )
		{
			// Only check this object if it is enabled, has a mesh and is not
			// the calling object.
			if( object->GetEnabled() == true && object->GetMesh() != NULL && object != thisObject )
			{
				// Transform the ray into model space.
				D3DXMATRIX inverse;
				D3DXMatrixInverse( &inverse, NULL, object->GetWorldMatrix() );
				D3DXVec3TransformCoord( &rp, &rayPosition, &inverse );
				D3DXVec3TransformNormal( &rd, &rayDirection, &inverse );

				// Go through the list of frames in the object's mesh.
				LinkedList< Frame > *frames = object->GetMesh()->GetFrameList();
				frames->Iterate( true );
				while( frames->Iterate() != NULL )
				{
					// Ignore this frame if it has no mesh.
					if( frames->GetCurrent()->pMeshContainer == NULL )
						continue;

					// Check the ray against this frame's mesh.
					BOOL hit;
					D3DXIntersect( frames->GetCurrent()->pMeshContainer->MeshData.pMesh, &rp, &rd, &hit, NULL, NULL, NULL, &hitDistance, NULL, NULL );
					if( hit == TRUE && ( hitDistance < result->distance || result->material == NULL ) )
					{
						( *result ).distance = hitDistance;
						( *result ).material = object->GetMesh()->GetStaticMesh()->materials[0];
						( *result ).hitObject = object;
					}
				}
			}

			// Go to the next object.
			object = m_dynamicObjects->GetNext( object );
		}
	}

	// Return false if no intersection occured.
	if( result->material == NULL )
		return false;

	// Calculate the point of intersection.
	( *result ).point = rayPosition + rayDirection * result->distance;

	return true;
}
Esempio n. 16
0
BOOL KG3DBaseCoordImp::IntersectMeshAndFindPoint(const RepresentData& RpData, const InputData& IpData
														 , D3DXVECTOR3& vInter, KG3DCOORD& IntersectedCoord )
{
	//把碰撞线转换到Mesh的Local空间,然后求出交点

	D3DXVECTOR3 vSrcLocal;
	D3DXVECTOR3 vDirLocal;	

	D3DXMATRIX matUse;
	{
		D3DXMATRIX vMatScaling;
		{
			FLOAT fRadius = GetSelectorRingRadius(RpData);
			FLOAT fScale = fRadius / em_mesh_range;
			D3DXMatrixScaling(&vMatScaling, fScale,fScale,fScale);
		}

		D3DXMATRIX vMatTrans;
		{
			D3DXVECTOR3 vMeshPos = RpData.vecPos;
			D3DXMatrixTranslation(&vMatTrans, vMeshPos.x, vMeshPos.y, vMeshPos.z);
		}
		matUse = vMatScaling * vMatTrans;
		D3DXMATRIX vMatInv;
		D3DXMATRIX* pRet = D3DXMatrixInverse(&vMatInv, NULL, &matUse);
		if(NULL == pRet)
			return FALSE;

		D3DXVec3TransformCoord(&vSrcLocal, &IpData.vMouseRaySrc, &vMatInv);
		D3DXVec3TransformNormal(&vDirLocal, &IpData.vMouseRayNormalizedDir, &vMatInv);
		D3DXVec3Normalize(&vDirLocal, &vDirLocal);
	}

	FLOAT distRet = 0;
	BOOL bRet = FALSE;


	for(size_t i = 0; i < _countof(RpData.MeshForPlane); ++i)//对面的碰撞是优先的
	{
		if(NULL == RpData.MeshForPlane[i])
			continue;

		HRESULT hr = D3DXIntersect(RpData.MeshForPlane[i], &vSrcLocal, &vDirLocal
			, &bRet, NULL, NULL, NULL, &distRet, NULL, NULL);
		if(FAILED(hr) || !bRet)
			continue;

		D3DXVECTOR3 vRet = vSrcLocal + vDirLocal * distRet;
		D3DXVec3TransformCoord(&vInter, &vRet, &matUse);


		//如果交点距离比中心距离大,即在后面半圆上,根据Filter来决定是否要结果
		if(RpData.bFilterInter != em_filter_none)
		{
			FLOAT distCamToInter = D3DXVec3Length(&(RpData.CamPos - vInter));
			FLOAT distCamToCenter = D3DXVec3Length(&(RpData.CamPos - RpData.vecPos));

			if (RpData.bFilterInter == em_filter_front)
			{
				if(distCamToInter < distCamToCenter)
					continue;
			}
			else 
			{
				if(distCamToInter > distCamToCenter)
					continue;
			}				
		}

		IntersectedCoord = KG3DCOORD(KG3DCOORD_FIRST_PLANE + i);

		return TRUE;
	}

	//对中间的碰撞面第二优先
	do
	{
		if(NULL == RpData.MeshForIntegration)
			break;

		HRESULT hr = D3DXIntersect(RpData.MeshForIntegration, &vSrcLocal, &vDirLocal
			, &bRet, NULL, NULL, NULL, &distRet, NULL, NULL);
		if(FAILED(hr) || !bRet)
			break;

		D3DXVECTOR3 vRet = vSrcLocal + vDirLocal * distRet;
		D3DXVec3TransformCoord(&vInter, &vRet, &matUse);

		IntersectedCoord = KG3DCOORD_INTEGRATION;

		return TRUE;

	}while(false);

	for (size_t i = 0; i < _countof(RpData.MeshForAxis); ++i)
	{
		if(NULL == RpData.MeshForAxis[i])
			break;

		HRESULT hr = D3DXIntersect(RpData.MeshForAxis[i], &vSrcLocal, &vDirLocal
			, &bRet, NULL, NULL, NULL, &distRet, NULL, NULL);
		if(FAILED(hr) || !bRet)
			continue;

		D3DXVECTOR3 vRet = vSrcLocal + vDirLocal * distRet;
		D3DXVec3TransformCoord(&vInter, &vRet, &matUse);

		IntersectedCoord = KG3DCOORD(KG3DCOORD_FIRST_AXIS + i);

		return TRUE;
	}
	return FALSE;
}
Esempio n. 17
0
bool GStillEntity::checkIntersect ( const D3DXVECTOR4& vPos, /*世界坐标系中的点 */ const D3DXVECTOR4& vDir, /*世界坐标系中的向量 */ bool bInsectInfo /*是 裥枰鲎残畔?*/ )
{
    HRESULT hr = S_FALSE;

    //将Pos和Dir转换到物体本地坐标系中
    D3DXMATRIX matWorld = getTrans()->getLocalD3D();
    D3DXMatrixInverse ( &matWorld, NULL, &matWorld );

    D3DXVec4Transform ( ( D3DXVECTOR4 * ) &vDir, ( D3DXVECTOR4 * ) &vDir, &matWorld );
    D3DXVec3Normalize ( ( D3DXVECTOR3* ) &vDir, ( D3DXVECTOR3* ) &vDir );
    D3DXVec4Transform ( ( D3DXVECTOR4 * ) &vPos, ( D3DXVECTOR4 * ) &vPos, &matWorld );

    if ( mMeshForInsect == NULL )
    {
        recreateInsectMesh();
    }

    BOOL bHit = FALSE;

    hr = D3DXIntersect (
             mMeshForInsect, ( D3DXVECTOR3* ) &vPos, ( D3DXVECTOR3* ) &vDir, &bHit,
             &m_InsectInfo.dwFaceIndex, &m_InsectInfo.u, &m_InsectInfo.v, &m_InsectInfo.fDist,
             NULL, NULL
         );

    mNodeState.setBit ( eObjState_Picked, ( bool ) bHit );
    dDebugMsgBox ( hr, "碰撞失败!" );

    if ( FAILED ( hr ) )
    {
        return false;
    }

    if ( bInsectInfo && mNodeState[eObjState_Picked] )
    {
        D3DXVECTOR3 v[3];
        DWORD dwIndex[3];

        //先要获取索引缓冲区格式
        LPDIRECT3DINDEXBUFFER9 pI = NULL;
        mMeshForInsect->GetIndexBuffer ( &pI );

        D3DINDEXBUFFER_DESC indexDesc;
        dMemoryZero ( &indexDesc, sizeof ( D3DINDEXBUFFER_DESC ) );

        if ( pI != NULL )
        {
            pI->GetDesc ( &indexDesc );
        }

        if ( indexDesc.Format== D3DFMT_INDEX16 )
        {
            WORD *pIndexData16;

            hr = mMeshForInsect->LockIndexBuffer ( D3DLOCK_READONLY, ( void** ) &pIndexData16 );

            dwIndex[0] = pIndexData16[m_InsectInfo.dwFaceIndex * 3 + 0];
            dwIndex[1] = pIndexData16[m_InsectInfo.dwFaceIndex * 3 + 1];
            dwIndex[2] = pIndexData16[m_InsectInfo.dwFaceIndex * 3 + 2];
        }
        else
        {
            DWORD *pIndexData32;

            hr = mMeshForInsect->LockIndexBuffer ( D3DLOCK_READONLY, ( void** ) &pIndexData32 );

            dwIndex[0] = pIndexData32[m_InsectInfo.dwFaceIndex * 3 + 0];
            dwIndex[1] = pIndexData32[m_InsectInfo.dwFaceIndex * 3 + 1];
            dwIndex[2] = pIndexData32[m_InsectInfo.dwFaceIndex * 3 + 2];
        }


        mMeshForInsect->UnlockIndexBuffer();

        D3DXVECTOR3 *pVertexData;

        hr = mMeshForInsect->LockVertexBuffer ( D3DLOCK_READONLY, ( void** ) &pVertexData );

        v[0] = pVertexData[dwIndex[0]];
        v[1] = pVertexData[dwIndex[1]];
        v[2] = pVertexData[dwIndex[2]];

        mMeshForInsect->UnlockVertexBuffer();

        D3DXVECTOR4 vNormal ( ZEROFLOAT, ZEROFLOAT, ZEROFLOAT, ZEROFLOAT );
        D3DXVECTOR4 vHitPos ( ZEROFLOAT, ZEROFLOAT, ZEROFLOAT, ZEROFLOAT );

        D3DXVECTOR3 vTmp1, vTmp2;
        vTmp1 = v[1] - v[0];
        vTmp2 = v[2] - v[0];

        vHitPos = ( D3DXVECTOR4 ) v[0] + m_InsectInfo.u * ( D3DXVECTOR4 ) vTmp1 + m_InsectInfo.v * ( D3DXVECTOR4 ) vTmp2;
        vHitPos.w = 1;

        updateWorld ();

        D3DXVec4Transform ( &vHitPos, &vHitPos, &getTrans()->getLocalD3D() );
        m_InsectInfo.vHitPos = D3DXVECTOR3 ( vHitPos.x, vHitPos.y, vHitPos.z );

        D3DXVec3Cross ( ( D3DXVECTOR3* ) &vNormal, &vTmp1, &vTmp2 );
        vNormal.w = 0;


        D3DXVec4Transform ( &vNormal, &vNormal, &matWorld );
        D3DXVec3Normalize ( ( D3DXVECTOR3* ) &vNormal, ( D3DXVECTOR3* ) &vNormal );

        m_InsectInfo.vNormal = D3DXVECTOR3 ( vNormal.x, vNormal.y, vNormal.z );

    }

    return mNodeState[eObjState_Picked];

}