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; }
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; }
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(); } }
//================================================================================================= 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; }
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; }
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; }
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; }
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; }
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); }
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; }
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); } } } }
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; }
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; }
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); } } }
//----------------------------------------------------------------------------- // 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; }
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; }
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]; }