178 lines
4.3 KiB
C++
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()
|
|
{
|
|
}
|