client/EterLib/AttributeInstance.cpp

216 lines
4.9 KiB
C++

#include "StdAfx.h"
#include "../eterBase/Utils.h"
#include "AttributeInstance.h"
#include "GrpMath.h"
CDynamicPool<CAttributeInstance> 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 (
fx<c_rv3Vertex0.x && fx<c_rv3Vertex1.x && fx<c_rv3Vertex2.x ||
fx>c_rv3Vertex0.x && fx>c_rv3Vertex1.x && fx>c_rv3Vertex2.x ||
fy<c_rv3Vertex0.y && fy<c_rv3Vertex1.y && fy<c_rv3Vertex2.y ||
fy>c_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()
{
}