DragonNest/GameCommon/DnGravityOrbit.cpp

221 lines
7.8 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
#include "StdAfx.h"
#include "DnGravityOrbit.h"
#include "DnProjectile.h"
#include "DnWorld.h"
const EtVector3 CDnGravityOrbitCalculator::GRAVITY( 0.0f, -980.0f, 0.0f );
CDnGravityOrbit::CDnGravityOrbit( const S_PROJECTILE_PROPERTY* pProjectileInfo ) : m_vStartPos( 0.0f, 0.0f, 0.0f ),
m_vDirectionWhenCreate( 0.0f, 0.0f, 0.0f ),
m_vInitialSpeed( 0.0f, 0.0f, 0.0f ),
m_vTargetPosition( 0.0f, 0.0f, 0.0f ),
m_fProjectileOrbitRotateZDegree( 0.0f ),
m_bFirstProcess( true ),
m_fElapsedTime( 0.0f )
{
m_fProjectileOrbitRotateZDegree = pProjectileInfo->fProjectileOrbitRotateZ;
}
CDnGravityOrbit::~CDnGravityOrbit( void )
{
}
void CDnGravityOrbit::Initialize( const MatrixEx& Cross, const MatrixEx& OffsetCross )
{
m_vStartPos = Cross.m_vPosition;
m_vDirectionWhenCreate = Cross.m_vZAxis;
EtVec3Normalize( &m_vDirectionWhenCreate, &Cross.m_vZAxis );
}
void CDnGravityOrbit::ProcessOrbit( /*IN OUT*/ MatrixEx& Cross, EtVector3& vPrevPos, LOCAL_TIME LocalTime, float fDelta )
{
// <20>ѱ<EFBFBD> 2009.7.22
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.. (#4851)
// Catmullrom <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ϶<C6B4> <20>߷°<DFB7><C2B0>ӵ<EFBFBD><D3B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD> <20>ٲ<EFBFBD>.
// 2<><32> <20><EFBFBD><EEBCB1><EFBFBD><EFBFBD> ó<><C3B3>..
if( m_bFirstProcess )
{
// Note: distance <20><> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̰<EFBFBD> direction<6F><6E> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> ȸ<><C8B8><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>
// <20><EFBFBD><E0B0A3> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޶<EFBFBD><DEB6><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> direction <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޾Ƽ<DEBE> <20><><EFBFBD><EFBFBD><EFBFBD>ϹǷ<CFB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̷<EFBFBD><CCB7><EFBFBD> <20>ؾ<EFBFBD> Ŭ<>󿡼<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>Ǿ<EFBFBD> Ʋ<><C6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
// #37334 <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
// <20>׷<EFBFBD><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
//if( m_vTargetPosition.y - m_vStartPos.y <= 0.0f )
// m_vTargetPosition.y += 50.0f; // ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><> <20><> <20>÷<EFBFBD><C3B7><EFBFBD>.
EtVector3 vDistance = m_vTargetPosition - m_vStartPos;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Direction<6F><6E> xz <20><>ȣ<EFBFBD><C8A3> <20><>ġ<EFBFBD>ؾ߸<D8BE> <20><>...
bool bXValid = (vDistance.x < 0.0f && m_vDirectionWhenCreate.x < 0.0f || vDistance.x >= 0.0f && m_vDirectionWhenCreate.x >= 0.0f);
bool bZValid = (vDistance.z < 0.0f && m_vDirectionWhenCreate.z < 0.0f || vDistance.z >= 0.0f && m_vDirectionWhenCreate.z >= 0.0f);
bool bValidDirection = bXValid && bZValid;
if( 0.0f == m_vDirectionWhenCreate.y )
m_vDirectionWhenCreate.y = 0.1f;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> direction <20><> <20><><EFBFBD><EFBFBD> <20><> <20>̹<EFBFBD><CCB9>ϰ<EFBFBD> <20><>ȣ<EFBFBD><C8A3> <20>޶<EFBFBD><DEB6><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> direction <20><> <20><><EFBFBD>󰡵<EFBFBD><F3B0A1B5><EFBFBD> ó<><C3B3>.
if( false == bXValid )
{
if( m_vDirectionWhenCreate.x < 0.0f && vDistance.x >= 0.0f ||
m_vDirectionWhenCreate.x >= 0.0f && vDistance.x < 0.0f )
vDistance.x *= -1.0f;
}
else
if( false == bZValid )
{
if( m_vDirectionWhenCreate.z < 0.0f && vDistance.z >= 0.0f ||
m_vDirectionWhenCreate.z >= 0.0f && vDistance.z < 0.0f )
vDistance.z *= -1.0f;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>⸸ŭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC>Ű<EFBFBD><C5B0> 0.5*Gt^2 + c <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
float fSlope = 0.0f;
float fC = -vDistance.y;
// ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20>ֳ<EFBFBD> OTL
_ASSERT( m_vDirectionWhenCreate.x != 0.0f || m_vDirectionWhenCreate.z != 0.0f );
if( m_vDirectionWhenCreate.x == 0.0f && m_vDirectionWhenCreate.z == 0.0f )
m_vDirectionWhenCreate.x = m_vDirectionWhenCreate.z = 0.1f;
bool bUseX = true;
if( 0.0f != m_vDirectionWhenCreate.x )
{
fSlope = m_vDirectionWhenCreate.y / m_vDirectionWhenCreate.x;
fC += vDistance.x * fSlope;
}
else
{
fSlope = m_vDirectionWhenCreate.y / m_vDirectionWhenCreate.z;
fC += vDistance.z * fSlope;
bUseX = false;
}
float fA = 0.5f * CDnGravityOrbitCalculator::GRAVITY.y;
float fD = -4.0f * fA * fC;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD>غ<EFBFBD><D8BA><EFBFBD>. -_-
if( fD < 0.0f )
fD *= -1.0f;
//_ASSERT( fD >= 0.0f );
float fEstimateElapseTime = sqrtf( fD ) / (2.0f * fA);
// <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if( fEstimateElapseTime < 0.0f )
fEstimateElapseTime *= -1.0f;
float fPower = 0.0f;
if( bUseX )
fPower = vDistance.x / (m_vDirectionWhenCreate.x*fEstimateElapseTime);
else
fPower = vDistance.z / (m_vDirectionWhenCreate.z*fEstimateElapseTime);
m_vInitialSpeed = m_vDirectionWhenCreate * fPower;
m_bFirstProcess = false;
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӵ<EFBFBD> <20><><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20><>Ų <20>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD>.
EtVector3 vNowDir = m_vInitialSpeed + m_fElapsedTime*CDnGravityOrbitCalculator::GRAVITY;
EtVector3 vDelta = 0.5f*CDnGravityOrbitCalculator::GRAVITY*(m_fElapsedTime*m_fElapsedTime) + m_vInitialSpeed*m_fElapsedTime;
// <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> ȸ<><C8B8><EFBFBD>Ǵ<EFBFBD> <20>ɼ<EFBFBD><C9BC><EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD>. (#15056)
// <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DestPosition <20><><EFBFBD><EFBFBD> <20>س<EFBFBD><D8B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>س<EFBFBD><D8B3>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> ȸ<><C8B8> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> x, z <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, 90<39><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 90<39><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x, z <20><><EFBFBD><EFBFBD> <20>״<EFBFBD><D7B4><EFBFBD> <20>̹Ƿ<CCB9>...
if( 0.0f != m_fProjectileOrbitRotateZDegree )
{
EtMatrix matRotZ;
EtVector3 vCharViewXZ( m_vDirectionWhenCreate.x, 0.0f, m_vDirectionWhenCreate.z );
EtVec3Normalize( &vCharViewXZ, &vCharViewXZ );
EtMatrixRotationAxis( &matRotZ, &vCharViewXZ, D3DXToRadian(m_fProjectileOrbitRotateZDegree) );
EtVec3TransformNormal( &vDelta, &vDelta, &matRotZ );
EtVec3TransformNormal( &vNowDir, &vNowDir, &matRotZ );
}
//
EtVector3 vNowPos = m_vStartPos + vDelta;
EtVec3Normalize( &vNowDir, &vNowDir );
if( EtVec3LengthSq( &vNowDir ) != 0.0f )
Cross.m_vZAxis = vNowDir;
Cross.m_vPosition = vNowPos;
Cross.MakeUpCartesianByZAxis();
m_fElapsedTime += fDelta;
}
#ifndef _GAMESERVER
//////////////////////////////////////////////////////////////////////////
bool CDnGravityOrbitCalculator::CalcHitGroundPos( MatrixEx Cross, const EtVector3& vShootPos, const float fInitialSpeed,
const EtVector3& vInitialDir, EtVector3& vGroundHitPosition )
{
bool bResult = false;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϸ<EFBFBD> <20>Ƴ<EFBFBD><C6B3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// <20>ӵ<EFBFBD><D3B5><EFBFBD> 0<><30> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
EtVector3 vFallingStartPos( 0.0f, 0.0f, 0.0f );
// y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ӵ<EFBFBD><D3B5><EFBFBD> 0<><30> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD>.
float fFallingStartTime = (-fInitialSpeed*vInitialDir.y) / GRAVITY.y;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߻<EFBFBD>ü <20><>ġ <20><><EFBFBD><EFBFBD>..
vFallingStartPos = (fInitialSpeed*vInitialDir*fFallingStartTime + ((GRAVITY*fFallingStartTime*fFallingStartTime) / 2.0f));
Cross.m_vPosition = vShootPos; // vShootPos <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ <20><><EFBFBD><EFBFBD>.
Cross.MoveLocalYAxis( vFallingStartPos.y ); // vFallingStartPos <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD>.
Cross.MoveLocalZAxis( vFallingStartPos.z );
Cross.MoveLocalXAxis( vFallingStartPos.x );
EtVector3 vPrevPos = Cross.m_vPosition;
// <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>..
float fTimeDelta = 1.0f / 20.0f;
float fElapsedTime = fFallingStartTime;
while( true )
{
fElapsedTime += fTimeDelta;
EtVector3 vNowPos = (fInitialSpeed*vInitialDir*fElapsedTime + ((GRAVITY*fElapsedTime*fElapsedTime) / 2.0f));
Cross.m_vPosition = vShootPos;
Cross.MoveLocalYAxis( vNowPos.y );
Cross.MoveLocalZAxis( vNowPos.z );
Cross.MoveLocalXAxis( vNowPos.x );
EtVector3 vDir = Cross.m_vPosition - vPrevPos;
EtVec3Normalize( &vDir, &vDir );
EtVector3 vPickPos;
float fHeight = CDnWorld::GetInstance().GetHeight( Cross.m_vPosition );
if( Cross.m_vPosition.y <= fHeight )
{
if( CDnWorld::GetInstance().Pick( vPrevPos, vDir, vPickPos ) == true )
{
vGroundHitPosition = vPickPos;
bResult = true;
break;
}
}
// <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20>Ѿ<D1BE><EEB0A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
if( 5.0f < fElapsedTime )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><>ġ<EFBFBD><C4A1> y <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
float fYPosZeroTime = -2.0f*(fInitialSpeed*vInitialDir.y) / GRAVITY.y;
EtVector3 vYPosZero = (fInitialSpeed*vInitialDir*fYPosZeroTime + ((GRAVITY*fYPosZeroTime*fYPosZeroTime) / 2.0f));
Cross.m_vPosition = vShootPos;
Cross.MoveLocalYAxis( vYPosZero.y );
Cross.MoveLocalZAxis( vYPosZero.z );
Cross.MoveLocalXAxis( vYPosZero.x );
vGroundHitPosition = Cross.m_vPosition;
break;
}
vPrevPos = Cross.m_vPosition;
}
return bResult;
}
#endif