#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 ) { // Çѱâ 2009.7.22 // ÇÁ·ÎÁ§Å¸ÀÏ ±ËÀû °ü·Ã.. (#4851) // Catmullrom º¸°£À» »ç¿ëÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó Á߷°¡¼Óµµ·Î Àû¿ëµÇµµ·Ï ¹Ù²Þ. // 2Â÷ °î¼±À¸·Î ó¸®.. if( m_bFirstProcess ) { // Note: distance ´Â Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ÇÁ·ÎÁ§Å¸ÀÏ »ý¼ºµÇ´Â ½ÃÁ¡ÀÇ °ªÀ̰í directionÀº ¼­¹ö¿¡¼­ °è»êµÇ´Â ȸÀü°ªÀ̶ó¸é // ¾à°£ÀÇ ½Ã°£Â÷ ¶§¹®¿¡ ¹æÇâÀÌ ´Þ¶óÁú ¼ö ÀÖÀ¸¹Ç·Î ÇÁ·ÎÁ§Å¸ÀÏ »ý¼ºµÇ´Â ½ÃÁ¡ÀÇ direction À» »ç¿ëÅä·Ï ÇÑ´Ù. // ¼­¹öÀÇ ÇÁ·ÎÁ§Å¸ÀÏÀº Ŭ¶óÇÑÅ× ¹Þ¾Æ¼­ »ý¼ºÇϹǷΠ¼­¹ö¿¡¼­µµ ÀÌ·¸°Ô ÇØ¾ß Ŭ¶ó¿¡¼­ Á¤ÇØÁØ ¹æÇâ´ë·Î »ý¼ºÇÏ°Ô µÇ¾î Ʋ¾îÁöÁö ¾Ê´Â´Ù. // #37334 ¾àÇÏ°Ô ½÷Áú°æ¿ì Æ÷¹°¼±ÀÇ ÃÖ´ë ³ôÀ̰ªº¸´Ù ¸ñÇ¥ÁöÁ¡ÀÇ ³ôÀÌ °ªÀÌ ´õ ³ô¾ÆÁ® ¹ö¸®´Â ¹®Á¦°¡ »ý±æ ¼öµµ ÀÖ´Ù. // ±×·¯¸é °á°ú °ªÀÌ À߸ø ³ª¿À¹Ç·Î º¸Á¤°ª Á¦°Å.. //if( m_vTargetPosition.y - m_vStartPos.y <= 0.0f ) // m_vTargetPosition.y += 50.0f; // ij¸¯ÅÍ ³ôÀÌ °¨¾ÈÇØ¼­ Á» ´õ ¿Ã·ÁÁÜ. EtVector3 vDistance = m_vTargetPosition - m_vStartPos; // ¹æÇâ°ú DirectionÀÇ xz ºÎÈ£°¡ ÀÏÄ¡ÇØ¾ß¸¸ ÇÔ... 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; // °ÅÀÇ ¿øÁ¡¿¡ °¡±î¿î direction ÀÌ ³ª¿Ã ¶§ ¹Ì¹¦ÇÏ°Ô ºÎÈ£°¡ ´Þ¶óÁö´Â °æ¿ì°¡ ÀÖÀ¸¹Ç·Î direction À» µû¶ó°¡µµ·Ï ó¸®. 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; } // ¹æÇâ º¤ÅÍÀÇ ±â¿ï±â¸¸Å­ µÞÇ×À» ´ëü½Ã۰í 0.5*Gt^2 + c Çü½ÄÀÇ ±ÙÀÇ °ø½ÄÀ¸·Î ½Ã°£°ªÀ» ±¸ÇÔ float fSlope = 0.0f; float fC = -vDistance.y; // ij¸¯ÅÍÀÇ ¹æÇâÀÌ ¿µº¤ÅÍÀÎ °æ¿ì°¡ ÀÖ³ª 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; // À½¼ö°¡ µÇ´Â °æ¿ì´Â ¾î¶² °æ¿ìÀÎÁö È®ÀÎÇØº¸ÀÚ. -_- if( fD < 0.0f ) fD *= -1.0f; //_ASSERT( fD >= 0.0f ); float fEstimateElapseTime = sqrtf( fD ) / (2.0f * fA); // ½Ã°£Àº ¹«Á¶°Ç ¾ç¼ö 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; } // ÇöÀç ¹æÇâÀº ÇöÀç ¼Óµµ º¤Å͸¦ Á¤±ÔÈ­ ½ÃŲ °Í°ú °°À½. EtVector3 vNowDir = m_vInitialSpeed + m_fElapsedTime*CDnGravityOrbitCalculator::GRAVITY; EtVector3 vDelta = 0.5f*CDnGravityOrbitCalculator::GRAVITY*(m_fElapsedTime*m_fElapsedTime) + m_vInitialSpeed*m_fElapsedTime; // ±ËÀû ÀÚü°¡ ȸÀüµÇ´Â ¿É¼ÇÀÌ Ãß°¡µÊ. (#15056) // ¸¸¾à¿¡ ¸ñÀûÁö¸¦ DestPosition À¸·Î ÇØ³õ°í ·£´ýÀ¸·Î ¶³¾îÁö°Ô ÇØ³ù´Ù¸é ±ËÀû ȸÀü °ªÀÌ Àû¿ëµÇÁö ¾Ê°í x, z ±×´ë·Î Àû¿ëµÊ. // ¿¹¸¦ µé¾î, 90µµ·Î ´¯Çô³öµµ ±ËÀûÀÌ 90µµ ±âÁØÀ¸·Î Èð¾îÁö´Â °ÍÀÌ ¾Æ´Ô. ¸ñÀûÁö°¡ x, z ±âÁØ ±×´ë·Î À̹ǷÎ... 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; // °è»ê ºÎÇϸ¦ ¾Æ³¢±â À§ÇØ ³«ÇÏÇÒ ¶§ ºÎÅÍ °è»êÇÑ´Ù. // ¼Óµµ°¡ 0ÀÌ µÇ´Â ½ÃÁ¡ÀÓ. EtVector3 vFallingStartPos( 0.0f, 0.0f, 0.0f ); // y ÃàÀ¸·Î ¼Óµµ°¡ 0ÀÌ µÇ´Â ½ÃÁ¡ÀÇ ½Ã°£À» ±¸ÇÔ. float fFallingStartTime = (-fInitialSpeed*vInitialDir.y) / GRAVITY.y; // ³«ÇÏ ÁöÁ¡À¸·Î ¹ß»çü À§Ä¡ ÁöÁ¤.. vFallingStartPos = (fInitialSpeed*vInitialDir*fFallingStartTime + ((GRAVITY*fFallingStartTime*fFallingStartTime) / 2.0f)); Cross.m_vPosition = vShootPos; // vShootPos ´Â ¿ùµåÁÂÇ¥ ±âÁØ. Cross.MoveLocalYAxis( vFallingStartPos.y ); // vFallingStartPos ´Â ·ÎÄÃÁÂÇ¥ ±âÁØ. µû¶ó¼­ ÃàÀ̵¿À¸·Î À§Ä¡ ÁöÁ¤. Cross.MoveLocalZAxis( vFallingStartPos.z ); Cross.MoveLocalXAxis( vFallingStartPos.x ); EtVector3 vPrevPos = Cross.m_vPosition; // ÇØ´ç ÁöÁ¡ºÎÅÍ ³«ÇÏÇÒ ¶§ ±îÁö ÁöÇü°ú ºÎµúÈ÷³ª È®ÀÎ.. 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; } } // ÀÏÁ¤ ½Ã°£ÀÌ ³Ñ¾î°¡¸é ³«ÇÏÁöÁ¡ ¾ø´Â °ÍÀ¸·Î °£ÁÖÇÏ°í ·çÇÁ Á¾·á. if( 5.0f < fElapsedTime ) { // ÁöÇü¿¡ Ãæµ¹µÇ´Â ÁöÁ¡ÀÌ ¾ø´Â °æ¿ì ¿ø·¡ ½ð À§Ä¡ÀÇ y °ª¿¡ µµ´ÞÇÏ´Â À§Ä¡·Î ¼ÂÆÃÇØÁØ´Ù. 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