#include "StdAfx.h" #include "../eterBase/Utils.h" #include "AttributeInstance.h" #include "GrpMath.h" CDynamicPool CAttributeInstance::ms_kPool; const float c_fStepSize = 50.0f; bool CAttributeInstance::Picking(const D3DXVECTOR3 & v, const D3DXVECTOR3 & dir, float & out_x, float & out_y) { if (IsEmpty()) return FALSE; //fy *= -1.0f; bool bPicked = false; float nx = 0; float ny = 0; for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i) for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3) { const D3DXVECTOR3 & cv0 = m_v3HeightDataVector[i][j]; const D3DXVECTOR3 & cv2 = m_v3HeightDataVector[i][j+1]; const D3DXVECTOR3 & cv1 = m_v3HeightDataVector[i][j+2]; D3DXVECTOR3 n; D3DXVec3Cross(&n,&(cv1-cv0),&(cv2-cv0)); D3DXVECTOR3 x; float t; t = - D3DXVec3Dot(&(v-cv0),&n)/D3DXVec3Dot(&dir,&n); x = v+t*dir; D3DXVECTOR3 temp; D3DXVec3Cross(&temp,&(cv1-cv0),&(x-cv0)); if (D3DXVec3Dot(&temp,&n)<0) continue; D3DXVec3Cross(&temp,&(cv2-cv1),&(x-cv1)); if (D3DXVec3Dot(&temp,&n)<0) continue; D3DXVec3Cross(&temp,&(cv0-cv2),&(x-cv2)); if (D3DXVec3Dot(&temp,&n)<0) continue; if (bPicked) { if ((v.x-x.x)*(v.x-x.x)+(v.y-x.y)*(v.y-x.y)<(v.x-nx)*(v.x-nx)+(v.y-ny)*(v.y-ny)) { nx=x.x; ny=x.y; } } else { nx = x.x; ny = x.y; } bPicked = true; } if (bPicked) { out_x = nx; out_y = ny; } return bPicked; } BOOL CAttributeInstance::GetHeight(float fx, float fy, float * pfHeight) { if(IsEmpty()) return FALSE; fy *= -1.0f; if (!IsInHeight(fx, fy)) return FALSE; BOOL bFlag = FALSE; for (DWORD i = 0; i < m_v3HeightDataVector.size(); ++i) for (DWORD j = 0; j < m_v3HeightDataVector[i].size(); j+=3) { const D3DXVECTOR3 & c_rv3Vertex0 = m_v3HeightDataVector[i][j]; const D3DXVECTOR3 & c_rv3Vertex1 = m_v3HeightDataVector[i][j+1]; const D3DXVECTOR3 & c_rv3Vertex2 = m_v3HeightDataVector[i][j+2]; if ( fxc_rv3Vertex0.x && fx>c_rv3Vertex1.x && fx>c_rv3Vertex2.x || fyc_rv3Vertex0.y && fy>c_rv3Vertex1.y && fy>c_rv3Vertex2.y ) continue; if (IsInTriangle2D(c_rv3Vertex0.x, c_rv3Vertex0.y, c_rv3Vertex1.x, c_rv3Vertex1.y, c_rv3Vertex2.x, c_rv3Vertex2.y, fx, fy)) { D3DXVECTOR3 v3Line1 = c_rv3Vertex1 - c_rv3Vertex0; D3DXVECTOR3 v3Line2 = c_rv3Vertex2 - c_rv3Vertex0; D3DXVECTOR3 v3Cross; D3DXVec3Cross(&v3Cross, &v3Line1, &v3Line2); D3DXVec3Normalize(&v3Cross, &v3Cross); if (0.0f != v3Cross.z) { float fd = (v3Cross.x*c_rv3Vertex0.x + v3Cross.y*c_rv3Vertex0.y + v3Cross.z*c_rv3Vertex0.z); float fm = (v3Cross.x*fx + v3Cross.y*fy); *pfHeight = fMAX((fd - fm) / v3Cross.z, *pfHeight); bFlag = TRUE; } } } return bFlag; } CAttributeData * CAttributeInstance::GetObjectPointer() const { return m_roAttributeData.GetPointer(); } BOOL CAttributeInstance::IsInHeight(float fx, float fy) { float fdx = m_matGlobal._41 - fx; float fdy = m_matGlobal._42 - fy; if (sqrtf(fdx*fdx + fdy*fdy) > m_fHeightRadius) return FALSE; return TRUE; } void CAttributeInstance::SetObjectPointer(CAttributeData * pAttributeData) { Clear(); m_roAttributeData.SetPointer(pAttributeData); } void CAttributeInstance::RefreshObject(const D3DXMATRIX & c_rmatGlobal) { assert(!m_roAttributeData.IsNull()); m_matGlobal = c_rmatGlobal; // Height m_fHeightRadius = m_roAttributeData->GetMaximizeRadius(); DWORD dwHeightDataCount = m_roAttributeData->GetHeightDataCount(); m_v3HeightDataVector.clear(); m_v3HeightDataVector.resize(dwHeightDataCount); for (DWORD i = 0; i < dwHeightDataCount; ++i) { const THeightData * c_pHeightData; if (!m_roAttributeData->GetHeightDataPointer(i, &c_pHeightData)) continue; DWORD dwVertexCount = c_pHeightData->v3VertexVector.size(); m_v3HeightDataVector[i].clear(); m_v3HeightDataVector[i].resize(dwVertexCount); for (DWORD j = 0; j < dwVertexCount; ++j) { D3DXVec3TransformCoord(&m_v3HeightDataVector[i][j], &c_pHeightData->v3VertexVector[j], &m_matGlobal); } } } const char * CAttributeInstance::GetDataFileName() const { return m_roAttributeData->GetFileName(); } void CAttributeInstance::CreateSystem(UINT uCapacity) { ms_kPool.Create(uCapacity); } void CAttributeInstance::DestroySystem() { ms_kPool.Destroy(); } CAttributeInstance* CAttributeInstance::New() { return ms_kPool.Alloc(); } void CAttributeInstance::Delete(CAttributeInstance* pkInst) { ms_kPool.Free(pkInst); } BOOL CAttributeInstance::IsEmpty() const { if (!m_v3HeightDataVector.empty()) return FALSE; return TRUE; } void CAttributeInstance::Clear() { m_fHeightRadius = 0.0f; m_fCollisionRadius = 0.0f; D3DXMatrixIdentity(&m_matGlobal); m_v3HeightDataVector.clear(); m_roAttributeData.SetPointer(NULL); } CAttributeInstance::CAttributeInstance() { } CAttributeInstance::~CAttributeInstance() { }