client/GameLib/PhysicsObject.cpp

178 lines
4.3 KiB
C++

#include "StdAfx.h"
#include "PhysicsObject.h"
const float c_fFrameTime = 0.02f;
const float EPSILON = 0.001f;
IPhysicsWorld* IPhysicsWorld::ms_pWorld = NULL;
IObjectManager* IObjectManager::ms_ObjManager = NULL;
void CPhysicsObject::Update(float fElapsedTime)
{
if (m_xPushingPosition.isPlaying())
m_xPushingPosition.Interpolate(fElapsedTime);
if (m_yPushingPosition.isPlaying())
m_yPushingPosition.Interpolate(fElapsedTime);
}
void CPhysicsObject::Accumulate(D3DXVECTOR3 * pv3Position)
{
// If object is moving, give minor power to object.
float fForce = 0.0f;
if (fabs(m_v3Velocity.x) < EPSILON ||
fabs(m_v3Velocity.y) < EPSILON ||
fabs(m_v3Velocity.z) < EPSILON )
{
fForce -= (m_fMass * m_fFriction);
}
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
m_v3Velocity += m_v3Acceleration;
if (m_v3Velocity.x * m_v3Direction.x < EPSILON)
{
m_v3Velocity.x = 0.0f;
m_v3Direction.x = 0.0f;
}
if (m_v3Velocity.y * m_v3Direction.y < EPSILON)
{
m_v3Velocity.y = 0.0f;
m_v3Direction.y = 0.0f;
}
if (m_v3Velocity.z * m_v3Direction.z < EPSILON)
{
m_v3Velocity.z = 0.0f;
m_v3Direction.z = 0.0f;
}
pv3Position->x += m_v3Velocity.x;
pv3Position->y += m_v3Velocity.y;
pv3Position->z += m_v3Velocity.z;
}
void CPhysicsObject::IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce)
{
// Accumulate Acceleration by External Force
m_v3Acceleration = m_v3Direction * (fForce / m_fMass);
m_v3Velocity = m_v3Acceleration;
/*
Tracenf("force %f, mass %f, accel (%f, %f, %f)", fForce, m_fMass,
m_v3Acceleration.x,
m_v3Acceleration.y,
m_v3Acceleration.z);
*/
// NOTE : 최종 위치를 구해둔다. 근데 100보다 크다면? ;
const int LoopValue = 100;
D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
for(int i = 0; i < LoopValue; ++i)
{
Accumulate(&v3Movement);
// VICTIM_COLLISION_TEST
IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
if (pWorld)
{
if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement))
{
Initialize();
return;
//for (float fRatio = 0.0f; fRatio < 1.0f; fRatio += 0.1f)
//{
// // 좀더 정밀하게 체크한다
// if (pWorld->isPhysicalCollision(c_rvBasePosition + v3Movement * fRatio))
// {
// v3Movement = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// break;
// }
//}
//break;
}
}
// VICTIM_COLLISION_TEST_END
if (fabs(m_v3Velocity.x) < EPSILON &&
fabs(m_v3Velocity.y) < EPSILON &&
fabs(m_v3Velocity.z) < EPSILON )
break;
}
SetLastPosition(v3Movement, float(LoopValue) * c_fFrameTime);
if( m_pActorInstance )
{
IObjectManager* pObjectManager = IObjectManager::GetObjectManager();
pObjectManager->AdjustCollisionWithOtherObjects( m_pActorInstance );
}
}
void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
{
m_v3LastPosition.x = float(c_rPosition.x);
m_v3LastPosition.y = float(c_rPosition.y);
m_v3LastPosition.z = float(c_rPosition.z);
m_xPushingPosition.Setup(0.0f, c_rPosition.x, fBlendingTime);
m_yPushingPosition.Setup(0.0f, c_rPosition.y, fBlendingTime);
}
void CPhysicsObject::GetLastPosition(TPixelPosition * pPosition)
{
pPosition->x = (m_v3LastPosition.x);
pPosition->y = (m_v3LastPosition.y);
pPosition->z = (m_v3LastPosition.z);
}
void CPhysicsObject::SetDirection(const D3DXVECTOR3 & c_rv3Direction)
{
m_v3Direction.x = c_rv3Direction.x;
m_v3Direction.y = c_rv3Direction.y;
m_v3Direction.z = c_rv3Direction.z;
}
float CPhysicsObject::GetXMovement()
{
return m_xPushingPosition.GetChangingValue();
}
float CPhysicsObject::GetYMovement()
{
return m_yPushingPosition.GetChangingValue();
}
bool CPhysicsObject::isBlending()
{
// NOTE : IncreaseExternalForce() 에 의해 밀리는 처리중인가?
if (0.0f != D3DXVec3Length(&m_v3Velocity))
return true;
// NOTE : SetLastPosition() 에 의해 밀리는 처리중인가?
if (m_xPushingPosition.isPlaying() ||
m_yPushingPosition.isPlaying())
return true;
return false;
}
void CPhysicsObject::Initialize()
{
m_fMass = 1.0f;
m_fFriction = 0.3f;
m_v3Direction = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3Acceleration = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3Velocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_v3LastPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_xPushingPosition.Initialize();
m_yPushingPosition.Initialize();
}
CPhysicsObject::CPhysicsObject()
{
m_pActorInstance = NULL;
}
CPhysicsObject::~CPhysicsObject()
{
}