DragonNest/GameCommon/MAWalkMovement.cpp

2058 lines
60 KiB
C++
Raw Permalink Normal View History

#include "Stdafx.h"
#include "MAWalkMovement.h"
#include "EtMatrixEx.h"
#include "DnWorld.h"
#include "DnActionBase.h"
#include "DnActor.h"
#include "VelocityFunc.h"
#include "MAActorRenderBase.h"
#include "PerfCheck.h"
#include "EtTestCollision.h"
#include "navigationcell.h"
#include "navigationmesh.h"
#include "navigationpath.h"
#ifndef _GAMESERVER
#include "EtDecal.h"
#endif
#if defined(_DEBUG) || defined(_RDEBUG)
#define _USE_COLLISION_DEBUG 0
#else
#define _USE_COLLISION_DEBUG 0
#endif
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
MAWalkMovement::MAWalkMovement()
: m_vMovement( 0.f, 0.f )
, m_vJumpMovement( 0.f, 0.f )
, m_vJumpXVector( 0.f, 0.f, 0.f )
, m_vJumpZVector( 0.f, 0.f, 0.f )
, m_vVelocity( 0.f, 0.f, 0.f )
, m_vVelocityResist( -30.f, -30.f, -30.f )
, m_vLastVelocity( 0.f, 0.f, 0.f )
, m_vMoveVectorX( 0.f, 0.f, 0.f )
, m_vMoveVectorZ( 0.f, 0.f, 0.f )
, m_vMovePos( 0.f, 0.f, 0.f )
, m_vMagnetDir( 0.f, 0.f )
, m_vTargetLookVec( 0.f, 0.f )
, m_vLastVelocityValue( 0.f, 0.f, 0.f )
, m_fMoveYDistancePerSec( 0.0f )
, m_fLeftMoveYDistance( 0.0f )
, m_bAppliedYDistance( false )
, m_bMaintainYDistanceOnArriveDestPosition( false )
, m_bOnDrop(false)
, m_bOnFall(false)
, m_bOnStop(false)
, m_fDropVelocity(0.0f)
, m_fNaviTargetMinDistance(0.0f)
, m_nNaviType(0)
{
m_fLimitDgrees = 90.f;
m_PrevLocalTime = 0;
m_fJumpMoveSpeed = 0.f;
m_fTargetMinDistance = 0.f;
m_bRefreshZVector = false;
m_fMagnetLength = 0.f;
m_fAngleAssist = 0.f;
m_bEnableNaviMode = false;
m_bFloorForceVelocity = false;
m_bLastFloorForceVelocity = false;
m_bFloorCollision = false;
m_LastLookTargetTime = 0;
m_bDebugRenderAttr = false;
// m_fLastHeight = 0.f;
#ifndef _GAMESERVER
m_fLastMoveDelta = 0.f;
memset( m_fLastMoveLength, 0, sizeof(m_fLastMoveLength) );
m_nLastMoveCount = 0;
#endif
#ifdef PRE_MOD_NAVIGATION_PATH
m_bAutoMoving = false;
#endif // PRE_MOD_NAVIGATION_PATH
}
MAWalkMovement::~MAWalkMovement()
{
}
bool Compare_CollisionOrder( SCollisionInfo &a, SCollisionInfo &b )
{
return a.CollisionNormal.y < b.CollisionNormal.y;
}
EtVector2 g_DirVector[4] =
{
EtVector2( -0.707107f, 0.707107f ),
EtVector2( 0.707107f, 0.707107f ),
EtVector2( 0.707107f, -0.707107f ),
EtVector2( -0.707107f, -0.707107f )
};
void GetCheckDirctionVector( const int nIndex, EtVector2 & etVector )
{
if( 0 == nIndex )
{
etVector = EtVector2( -0.707107f, 0.707107f );
}
else if( 1 == nIndex )
{
etVector = EtVector2( 0.707107f, 0.707107f );
}
else if( 2 == nIndex )
{
etVector = EtVector2( 0.707107f, -0.707107f );
}
else if( 3 == nIndex )
{
etVector = EtVector2( -0.707107f, -0.707107f );
}
}
bool MAWalkMovement::CheckDiagonalBlock( float fX, float fY )
{
char cAttr = INSTANCE(CDnWorld).GetAttribute( fX, fY );
int nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( fX, fY );
if( nBlockSize == 0 ) return false;
float fWorldX, fWorldY;
INSTANCE(CDnWorld).CalcWorldBasePos( fX, fY, fWorldX, fWorldY );
int nX = int(fWorldX) / nBlockSize;
int nY = int(fWorldY) / nBlockSize;
float fTempX = fWorldX - ( nX * nBlockSize );
float fTempY = fWorldY - ( nY * nBlockSize );
if( cAttr & 0x10 )
{
if( fTempX + fTempY > nBlockSize ) return false;
}
if( cAttr & 0x20 )
{
if( fTempX > fTempY ) return false;
}
if( cAttr & 0x40 )
{
if( fTempX + fTempY < nBlockSize ) return false;
}
if( cAttr & 0x80 )
{
if( fTempX < fTempY ) return false;
}
return true;
}
bool MAWalkMovement::CheckMovableBlock( char cAttr )
{
if( cAttr == 0 ) return true;
if( ( cAttr & 0xf0 ) != 0 ) return true;
return false;
}
void MAWalkMovement::ProcessCommon( LOCAL_TIME LocalTime, float fDelta )
{
m_bOnDrop = m_bOnFall = m_bOnStop = false;
m_fDropVelocity = 0.f;
m_pActor->SetPrevPosition( m_pMatExWorld->m_vPosition );
EtVector3 vPrevPos = m_pMatExWorld->m_vPosition;
EtVector3 vPrevVel = m_vVelocity;
EtVector2 vAniDistance( 0.f, 0.f );
EtVector3 *vDist = m_pActor->GetAniDistance();
if( m_pActor->GetState() & CDnActorState::Move &&
false == (m_pActor->GetState() & CDnActorState::IgnoreBackMoveSpeed) ) {
EtVector2 vApplyMoveSpeed( 0.f, 0.f );
if( m_pActor->GetMoveSpeed() == 0 || fDelta == 0.f ) {
vApplyMoveSpeed.x = vDist->x;
vApplyMoveSpeed.y = vDist->z;
}
else {
float fMoveSpeed = m_pActor->GetMoveSpeed() * fDelta;
vApplyMoveSpeed.x = ( ( 1.f / fDelta ) * vDist->x ) / 300.f;
vApplyMoveSpeed.y = ( ( 1.f / fDelta ) * vDist->z ) / 300.f;
vApplyMoveSpeed *= fMoveSpeed;
}
vAniDistance += EtVector2( m_vMoveVectorX.x, m_vMoveVectorX.z ) * vApplyMoveSpeed.x;
vAniDistance += EtVector2( m_vMoveVectorZ.x, m_vMoveVectorZ.z ) * vApplyMoveSpeed.y;
}
else {
vAniDistance += EtVector2( m_pMatExWorld->m_vXAxis.x, m_pMatExWorld->m_vXAxis.z ) * vDist->x;
vAniDistance += EtVector2( m_pMatExWorld->m_vZAxis.x, m_pMatExWorld->m_vZAxis.z ) * vDist->z;
}
m_vMovement += vAniDistance;
// Look ó<><C3B3>
if( m_hLookTarget )
{
EtVector2 vLook;
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
EtVector3 vTargetPosition = m_hLookTarget->FindAutoTargetPos();
vLook.x = vTargetPosition.x - m_pMatExWorld->m_vPosition.x;
vLook.y = vTargetPosition.z - m_pMatExWorld->m_vPosition.z;
#else
vLook.x = m_hLookTarget->GetPosition()->x - m_pMatExWorld->m_vPosition.x;
vLook.y = m_hLookTarget->GetPosition()->z - m_pMatExWorld->m_vPosition.z;
#endif
if( EtVec2LengthSq( &vLook ) > 0.f )
{
EtVec2Normalize( &vLook, &vLook );
float fDot = EtVec2Dot( &vLook, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
float fAngle = EtToDegree( EtAcos( fDot ) );
bool bForceLook = true;
if( fAngle > m_pActor->GetRotateAngleSpeed() * fDelta ) bForceLook = false;
m_pActor->Look( vLook, bForceLook );
if( bForceLook )
OnEndLook();
m_LastLookTargetTime = LocalTime;
}
}
if ( m_bEnableNaviMode )
{
if( !m_WayPointList.empty() && m_WayPointId != m_WayPointList.end() )
{
m_vMovePos = (*m_WayPointId).Position;
}
else
{
m_bEnableNaviMode = false;
}
}
// Ÿ<><C5B8> <20>̵<EFBFBD> ó<><C3B3>
else if( m_hMoveTarget )
{
#ifdef PRE_FIX_PARTSMONSTER_AI_TARGETTING
m_vMovePos = m_hMoveTarget->FindAutoTargetPos();
#else
m_vMovePos = *m_hMoveTarget->GetPosition();
#endif
}
// Look ó<><C3B3>
if( EtVec2LengthSq( &m_vTargetLookVec ) > 0.f ) {
float fDot = D3DXVec2Dot( &m_vTargetLookVec, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
float fAngle = EtToDegree( EtAcos(fDot) );
float fAngleSpeed = m_pActor->GetRotateAngleSpeed() * fDelta;
if( fAngle > fAngleSpeed ) {
EtVector3 vCrossVec;
D3DXVec3Cross( &vCrossVec, &EtVec2toVec3( m_vTargetLookVec ), &m_pMatExWorld->m_vZAxis );
if( vCrossVec.y > 0.f )
m_pMatExWorld->RotateYaw( fAngleSpeed );
else m_pMatExWorld->RotateYaw( -fAngleSpeed );
fDot = D3DXVec2Dot( &m_vTargetLookVec, &EtVec3toVec2( m_pMatExWorld->m_vZAxis ) );
if( fDot >= 1.f ) fDot = 1.f;
fAngle = EtToDegree( EtAcos(fDot) );
if( fAngle <= fAngleSpeed ) {
m_pMatExWorld->m_vZAxis = EtVec2toVec3( m_vTargetLookVec );
m_pMatExWorld->MakeUpCartesianByZAxis();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
}
else {
m_pMatExWorld->m_vZAxis = EtVec2toVec3( m_vTargetLookVec );
m_pMatExWorld->MakeUpCartesianByZAxis();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD> ó<><C3B3>
if( EtVec3LengthSq( &m_vMovePos ) > 0.f ) {
EtVector3 vTemp = m_vMovePos - m_pMatExWorld->m_vPosition;
vTemp.y = 0.f;
float fLength = EtVec3Length( &vTemp );
if( !m_hMoveTarget ) {
if( m_pActor->GetMoveSpeed() > 0.f )
m_fTargetMinDistance = m_pActor->GetMoveSpeed() * fDelta;
else m_fTargetMinDistance = EtVec2Length( &m_vMovement );
if( m_fTargetMinDistance == 0.f ) {
m_fTargetMinDistance = EtVec3Length( m_pActor->GetAniDistance() );
}
m_fTargetMinDistance += 1.f;
}
if( fLength <= m_fTargetMinDistance || !m_pActor->IsMove() )
{
if( !m_hMoveTarget && fLength <= m_fTargetMinDistance ) {
EtVec3Normalize( &vTemp, &vTemp );
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * fLength;
}
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
#ifdef PRE_MOD_NAVIGATION_PATH
// <20>ڵ<EFBFBD><DAB5>̵<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׺<EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
if( ( m_bAutoMoving ||m_bEnableNaviMode ) && !m_WayPointList.empty() )
{
WayPointID CurrentWayPointID = m_WayPointId;
m_WayPointId++;
if ( m_WayPointId == m_WayPointList.end() )
{
m_bOnStop = true;
m_bEnableNaviMode = false;
m_bAutoMoving = false;
}
else
{
if( m_bAutoMoving )
OnAutoMoving( (EtVector3)(*m_WayPointId).Position, (EtVector3)(*CurrentWayPointID).Position );
else if( m_bEnableNaviMode )
OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
}
}
else
{
m_bOnStop = true;
m_bEnableNaviMode = false;
m_bAutoMoving = false;
}
#else // PRE_MOD_NAVIGATION_PATH
// <20>׺<EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ѱ<EFBFBD><D1B1><EFBFBD>.
if( m_bEnableNaviMode && !m_WayPointList.empty() )
{
m_WayPointId++;
if ( m_WayPointId == m_WayPointList.end() )
{
m_bOnStop = true;
m_bEnableNaviMode = false;
}
else OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
}
else
{
m_bOnStop = true;
m_bEnableNaviMode = false;
}
#endif // PRE_MOD_NAVIGATION_PATH
}
else {
EtVec3Normalize( &vTemp, &vTemp );
if( m_bRefreshZVector ) {
m_vMoveVectorZ = vTemp;
if( EtVec2LengthSq( &m_vTargetLookVec ) == 0.f ) {
m_pMatExWorld->m_vZAxis = vTemp;
}
else m_vTargetLookVec = EtVec3toVec2( vTemp );
m_pMatExWorld->MakeUpCartesianByZAxis();
}
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * ( m_pActor->GetMoveSpeed() * fDelta );
#ifndef _GAMESERVER
if( m_pActor->GetMoveSpeed() > 0 ) {
m_fLastMoveDelta += fDelta;
if( m_fLastMoveDelta >= FORCE_REVISION_DELTA ) {
m_fLastMoveDelta -= FORCE_REVISION_DELTA;
m_nLastMoveCount++;
if( m_nLastMoveCount == FORCE_REVISION_HISTORY_COUNT ) {
float fTemp = fLength;
for( int n=0; n<FORCE_REVISION_HISTORY_COUNT; n++ ) fTemp += m_fLastMoveLength[n];
fTemp /= ( FORCE_REVISION_HISTORY_COUNT + 1 );
bool bValidDiff = false;
float fOffsetSpeed = m_pActor->GetMoveSpeed() / 15.f;
if( abs( fTemp - fLength ) < fOffsetSpeed ) {
bValidDiff = true;
for( int n=0; n<FORCE_REVISION_HISTORY_COUNT; n++ )
if( abs( m_fLastMoveLength[n] - fTemp ) > fOffsetSpeed ) bValidDiff = false;
}
if( bValidDiff && !( m_pActor->IsPlayerActor() && (m_pActor->GetMySmartPtr() == CDnActor::s_hLocalActor ) ) ) {
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
m_vMovement += EtVector2( vTemp.x, vTemp.z ) * fLength;
m_pMatExWorld->m_vPosition.y = vPrevPos.y = m_vMovePos.y;
m_pActor->SetPrevPosition( vPrevPos );
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
// OnStop( m_pMatEx->m_vPosition );
m_bOnStop = true;
m_bEnableNaviMode = false;
}
else {
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
}
}
m_fLastMoveLength[m_nLastMoveCount] = fLength;
}
}
#endif
}
}
// Magnet ó<><C3B3>
if( m_fMagnetLength > 0.f ) {
float fSpeed = (float)m_pActor->GetMoveSpeed();
if( fSpeed == 0.f ) fSpeed = 300.f;
float fMagnetMove = fSpeed * fDelta;
if( m_fMagnetLength - fMagnetMove <= 0.f ) fMagnetMove = m_fMagnetLength;
m_vMovement += m_vMagnetDir * fMagnetMove;
m_fMagnetLength -= fMagnetMove;
if( m_fMagnetLength <= 0.f ) {
m_vMagnetDir = EtVector2( 0.f, 0.f );
m_fMagnetLength = 0.f;
}
}
// Velocity ó<><C3B3>
EtVector3 vVelocity = EtVector3( 0.f, 0.f, 0.f );
m_vLastVelocityValue = EtVector3( 0.f, 0.f, 0.f );
if( m_vVelocity.z ) {
float fTemp = m_vVelocity.z;
float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX;
float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f;
float fTemp2 = m_vVelocity.z;
m_vLastVelocityValue.z = CalcMovement( fTemp2, 1.f, fMax, fMin, m_vVelocityResist.z );
vVelocity += m_vVelocityZVector * CalcMovement( m_vVelocity.z, fDelta, fMax, fMin, m_vVelocityResist.z );
if( m_vVelocity.z * fTemp <= 0.f ) m_vVelocity.z = 0.f;
}
if( m_vVelocity.x ) {
float fTemp = m_vVelocity.x;
float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX;
float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f;
float fTemp2 = m_vVelocity.x;
m_vLastVelocityValue.x = CalcMovement( fTemp2, 1.f, fMax, fMin, m_vVelocityResist.x );
vVelocity += m_vVelocityXVector * CalcMovement( m_vVelocity.x, fDelta, fMax, fMin, m_vVelocityResist.x );
if( m_vVelocity.x * fTemp <= 0.f ) m_vVelocity.x = 0.f;
}
m_vMovement += EtVector2( vVelocity.x, vVelocity.z );
m_fAngleAssist = 0.f;
if( EtVec2Length( &m_vMovement ) > 0.f )
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD>
EtVector3 vTempPos = m_pMatExWorld->m_vPosition;
vTempPos.x += m_vMovement.x;
vTempPos.z += m_vMovement.y;
vTempPos.y = INSTANCE(CDnWorld).GetHeight( vTempPos );
if( ( m_pActor->GetAddHeight() == 0.f && m_pMatExWorld->m_vPosition.y == INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition ) ) || m_pMatExWorld->m_vPosition.y <= vTempPos.y )
{
EtVector3 vMoveNor, vDirNor;
EtVec3Normalize( &vMoveNor, &EtVector3( m_vMovement.x, vTempPos.y - m_pMatExWorld->m_vPosition.y, m_vMovement.y ) );
EtVec3Normalize( &vDirNor, &EtVector3( m_vMovement.x, 0.f, m_vMovement.y ) );
m_fAngleAssist = EtVec3Dot( &vMoveNor, &vDirNor );
m_vMovement *= m_fAngleAssist;
}
}
// <20>̵<EFBFBD> ó<><C3B3>
EtVector3 vTemp = m_pMatExWorld->m_vPosition;
vTemp.x += m_vMovement.x - ( vAniDistance.x * m_fAngleAssist );
vTemp.z += m_vMovement.y - ( vAniDistance.y * m_fAngleAssist );
vTemp.y += vVelocity.y;
m_pActor->SetStaticPosition( vTemp );
m_pMatExWorld->m_vPosition.x += m_vMovement.x;
m_pMatExWorld->m_vPosition.z += m_vMovement.y;
m_pMatExWorld->m_vPosition.y += vVelocity.y;
// <20><><EFBFBD><EFBFBD> ó<><C3B3>
float fCurVelocity = 0.f;
float fHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition ) + m_pActor->GetAddHeight();
if( m_vVelocity.y )
{
float fTemp2 = m_vVelocity.y;
m_vLastVelocityValue.y = CalcMovement( fTemp2, 1.f, FLT_MAX, -FLT_MAX, m_vVelocityResist.y );
m_pMatExWorld->m_vPosition.y += CalcMovement( m_vVelocity.y, fDelta, FLT_MAX, -FLT_MAX, m_vVelocityResist.y );
if( m_vVelocity.y == 0.f )
m_vVelocity.y += 0.0000001f;
if( EtVec2LengthSq( &m_vJumpMovement ) > 0.f )
{
EtVector2 vVec = m_vJumpMovement * ( m_fJumpMoveSpeed * fDelta );
m_pMatExWorld->m_vPosition += m_vJumpXVector * vVec.x;
m_pMatExWorld->m_vPosition += m_vJumpZVector * vVec.y;
}
if( m_pMatExWorld->m_vPosition.y <= fHeight )
{
fCurVelocity = m_vVelocity.y - ( ( m_pMatExWorld->m_vPosition.y - fHeight ) * fDelta );
m_vVelocity.y = 0.f;
if( m_pActor->GetAddHeight() == 0.f )
m_bFloorForceVelocity = false;
m_bOnDrop = true;
m_bLastFloorForceVelocity = m_bFloorForceVelocity;
if( m_pActor->GetAddHeight() == 0.f )
m_pMatExWorld->m_vPosition.y = fHeight;
m_bFloorForceVelocity = false;
}
else
{
m_bOnFall = true;
}
}
m_fDropVelocity = fCurVelocity;
// #48950 MoveY <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Y <20><> <20>̵<EFBFBD> ó<><C3B3>
if( m_fMoveYDistancePerSec != 0.0f )
{
float fMoveDistance = m_fMoveYDistancePerSec * fDelta;
m_pMatExWorld->m_vPosition.y += fMoveDistance;
if( 0.0f < fMoveDistance )
m_fLeftMoveYDistance -= fMoveDistance;
else
m_fLeftMoveYDistance += fMoveDistance;
// <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>Ѿ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD> <20><><EFBFBD><EFBFBD>.
if( m_fLeftMoveYDistance < 0.0f )
{
if( 0.0f < fMoveDistance )
m_pMatExWorld->m_vPosition.y -= (fMoveDistance + m_fLeftMoveYDistance);
else
m_pMatExWorld->m_vPosition.y += (fMoveDistance - m_fLeftMoveYDistance);
ResetMoveYDistance();
if( true == m_bMaintainYDistanceOnArriveDestPosition )
{
m_bAppliedYDistance = true;
m_bMaintainYDistanceOnArriveDestPosition = false;
}
}
}
#ifdef _WORK
if( !( GetAsyncKeyState( VK_CONTROL ) < 0 ) )
#endif
ProcessBlock( *m_pActor->GetPrevPosition() );
#ifdef _GAMESERVER
if( m_pActor->IsPlayerActor() ) {
EtVector2 vTemp2 = EtVector2( vPrevPos.x, vPrevPos.z ) - EtVector2( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.z );
AniDistStruct Struct;
Struct.Time = LocalTime;
Struct.fDist = EtVec2Length( &vTemp2 ) * ( 1.f / fDelta );
m_VecAniDistList.push_back( Struct );
m_fAverageAniDist = FLT_MIN;
for( DWORD i=0; i<m_VecAniDistList.size(); i++ ) {
if( LocalTime - m_VecAniDistList[i].Time > 1000 ) {
m_VecAniDistList.erase( m_VecAniDistList.begin() + i );
i--;
continue;
}
if( m_VecAniDistList[i].fDist > m_fAverageAniDist )
m_fAverageAniDist = m_VecAniDistList[i].fDist;
}
}
#endif
}
void MAWalkMovement::PostProcess( LOCAL_TIME LocalTime )
{
if( m_bOnStop ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnStop( m_pMatExWorld->m_vPosition );
#else
OnStop( m_pMatExWorld->m_vPosition );
#endif
}
if( m_bOnDrop ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnDrop( m_fDropVelocity );
#else
OnDrop( m_fDropVelocity );
#endif
}
if( m_bOnFall ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnFall( m_vVelocity.y );
#else
OnFall( m_vVelocity.y );
#endif
}
m_PrevLocalTime = LocalTime;
m_vMovement = EtVector2( 0.f, 0.f );
}
bool MAWalkMovement::IsMovableBlock( CDnWorld* pWorld, EtVector3 &vPos )
{
char cAttr = pWorld->GetAttribute( vPos.x, vPos.z );
int nBlockSize = pWorld->GetAttributeBlockSize( vPos.x, vPos.z );
float fWorldX, fWorldY;
pWorld->CalcWorldBasePos( vPos.x, vPos.z, fWorldX, fWorldY );
float fBlockX = fmodf( fWorldX, (float)nBlockSize );
float fBlockY = fmodf( fWorldY, (float)nBlockSize );
if( (( cAttr & 0x0f ) != 1 && ( cAttr & 0x0f ) != 2) ) {
return true;
}
bool bMovable = false;
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
switch( cHiAttr ) {
case 1:
bMovable = fBlockX + fBlockY < nBlockSize;
break;
case 2:
bMovable = fBlockX < fBlockY;
break;
case 4:
bMovable = fBlockX + fBlockY > nBlockSize;
break;
case 8:
bMovable = fBlockX > fBlockY;
break;
}
return bMovable;
}
void MAWalkMovement::ProcessBlock( EtVector3 vPrevPos )
{
EtVector2 vMove;
vMove.x = m_pMatExWorld->m_vPosition.x - vPrevPos.x;
vMove.y = m_pMatExWorld->m_vPosition.z - vPrevPos.z;
EtVector2 vPos(vPrevPos.x, vPrevPos.z);
EtVector2 vAttrPos = vPos;
char cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
int nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
float fWorldX, fWorldY;
INSTANCE(CDnWorld).CalcWorldBasePos( vPos.x, vPos.y, fWorldX, fWorldY );
float fBlockX = fmodf( fWorldX, (float)nBlockSize );
float fBlockY = fmodf( fWorldY, (float)nBlockSize );
#if (_USE_COLLISION_DEBUG)
std::vector< int > debugAttr;
std::vector< EtVector2 > debugPos;
std::vector< EtVector2 > debugBlock;
std::vector< EtVector2 > debugBlockNext;
std::vector< EtVector2 > debugMove;
std::vector< EtVector2 > debugAttrPos;
std::vector< int > debugCode;
#endif
int nDebugCode = -1;
int nStep = 0;
int nSlideType = 0;
if( EtVec2LengthSq(&vMove) > 2000.0f * 2000.0f ) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD> 20 <20><><EFBFBD><EFBFBD> <20>̻<EFBFBD><CCBB><EFBFBD> <20>̵<EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>.
nStep = 101;
}
bool bBreakLoop = false;
do
{
nStep++;
if( nStep > 100 ) { // <20>̷<EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵȴ<C8B5>.
OutputDebug("Unknown Collision Error. Loop count exceed.\n");
vPos = EtVector2(vPrevPos.x, vPrevPos.z);
break;
}
if( EtVec2LengthSq(&vMove) <= 0.001f ) {
break;
}
float fBlockNextX = fBlockX + vMove.x;
float fBlockNextY = fBlockY + vMove.y;
#if (_USE_COLLISION_DEBUG)
debugAttr.push_back( cAttr );
debugPos.push_back( vPos);
debugBlock.push_back( EtVector2(fBlockX, fBlockY));
debugBlockNext.push_back( EtVector2(fBlockNextX, fBlockNextY));
debugMove.push_back( vMove );
debugAttrPos.push_back( EtVector2(vAttrPos.x/50.f, vAttrPos.y/50.f));
#endif
// <20><EFBFBD><EBB0A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>˾Ƴ<CBBE><C6B3><EFBFBD>.
int DirIndices[2][2] = {{7,5},{1,3}};
int BitX = (vMove.x >= 0 ? 1 : 0);
int BitY = (vMove.y >= 0 ? 1 : 0);
float fDirX = BitX * nBlockSize - fBlockX;
float fDirY = BitY * nBlockSize - fBlockY;
int nCollideDir = DirIndices[BitX][BitY] + ((fDirX * vMove.y - fDirY * vMove.x > 0 ) ? 1 : -1);
nCollideDir = (nCollideDir>>1)&3; // 0 2 4 6 8 -> 0 1 2 3
float fDa = 0.f;
float fDb = 0.f;
int nIndex = -1;
bool bCollideBlock = (( cAttr & 0x0f ) == 1 || ( cAttr & 0x0f ) == 2); // 0x01, 0x02 <20><> <20>浹üũ
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
if( bCollideBlock ) {
switch( cHiAttr ) {
case 1:
if( nCollideDir == 1 || nCollideDir == 2 ) {
fDa = fBlockX + fBlockY - nBlockSize;
fDb = fBlockNextX + fBlockNextY - nBlockSize;
nIndex = 0;
}
break;
case 2:
if( nCollideDir == 0 || nCollideDir == 1) {
fDa = fBlockX - fBlockY;
fDb = fBlockNextX - fBlockNextY;
nIndex = 1;
}
break;
case 4:
if( nCollideDir == 0 || nCollideDir == 3 ) {
fDa = nBlockSize - fBlockX - fBlockY;
fDb = nBlockSize - fBlockNextX - fBlockNextY;
nIndex = 2;
}
break;
case 8:
if( nCollideDir == 2 || nCollideDir == 3 ) {
fDa = fBlockY - fBlockX;
fDb = fBlockNextY - fBlockNextX;
nIndex = 3;
}
break;
}
}
float fDiagEpsilon = 0.01f;
float fEpsilon = fDiagEpsilon * 1.4142f;
if( fDa <= 0.f && fDb > 0) { // <20><EFBFBD><EBB0A2> <20><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ٲ<EFBFBD> <20><><EFBFBD><EFBFBD>
nDebugCode = 1;
float fRatio = (-fDa-fDiagEpsilon) / (fDb-fDa);
vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1,(1 - fRatio));
// g_DirVector<6F><72><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ŷ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϹǷ<CFB9> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>޾Ƽ<DEBE> ó<><C3B3><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
//vMove = g_DirVector[ nIndex ] * D3DXVec2Dot( &g_DirVector[ nIndex ], &vMove );
EtVector2 vCheckDirVector;
GetCheckDirctionVector( nIndex, vCheckDirVector );
vMove = vCheckDirVector * D3DXVec2Dot( &vCheckDirVector, &vMove );
if( nSlideType == 2 ) { // <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> ó<><C3B3> <20>ѹ<EFBFBD><D1B9>̻<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>. <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20>ɸ<EFBFBD><C9B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
vMove = EtVector2(0,0);
}
nSlideType = 1;
// <20><><EFBFBD><EFBFBD> <20>Ѿ<D1BE><EEB0A1><EFBFBD><EFBFBD> üũ
if( fBlockX+vMove.x < 0.f || fBlockX+vMove.x > nBlockSize ||
fBlockY+vMove.y < 0.f || fBlockY+vMove.y > nBlockSize )
{
bool bDiagDirA = vMove.x+vMove.y > 0.f;
bool bDiagDirB = vMove.x-vMove.y > 0.f;
if( (cHiAttr == 2 && !bDiagDirB ) || (cHiAttr==1 && !bDiagDirA) ) {
vAttrPos.x -= nBlockSize;
fBlockX += nBlockSize;
}
else if( (cHiAttr ==4 && bDiagDirB ) || (cHiAttr==8 && bDiagDirA ) ) {
vAttrPos.x += nBlockSize;
fBlockX -= nBlockSize;
}
else if( (cHiAttr==1 && bDiagDirB ) || (cHiAttr==8 && !bDiagDirA) ) {
vAttrPos.y -= nBlockSize;
fBlockY += nBlockSize;
}
else if( (cHiAttr==2 && bDiagDirA ) || (cHiAttr==4 && !bDiagDirB ) ) {
vAttrPos.y += nBlockSize;
fBlockY -= nBlockSize;
}
else {
ASSERT( false );
}
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
}
else
{
bBreakLoop = true;
}
}
// <20>׸<EFBFBD> <20><><EFBFBD><EFBFBD> <20><20><> <20><><EFBFBD><EFBFBD> (<28>ۿ<EFBFBD><DBBF><EFBFBD> <20><> <20><><EFBFBD>츸) <20>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̵<EFBFBD>
else if( bCollideBlock && cHiAttr == 0 && (fBlockX < 0 || fBlockX >= nBlockSize || fBlockY < 0 || fBlockY >= nBlockSize) ) {
int OutDirIndices[2][2] = {{7,5},{1,3}};
int OutBitX = (vMove.x > 0.f) ? 0 : 1;
int OutBitY = (vMove.y > 0.f) ? 0 : 1;
float fOutDirX = OutBitX * nBlockSize - fBlockX;
float fOutDirY = OutBitY * nBlockSize - fBlockY;
int nOutCollideDir = OutDirIndices[OutBitX][OutBitY] + ((fOutDirX * vMove.y - fOutDirY * vMove.x > 0 ) ? -1 : 1);
nOutCollideDir = (nOutCollideDir>>1)&3; // 0 2 4 6 8 -> 0 1 2 3
nDebugCode = nOutCollideDir;
if( nOutCollideDir == 2 ) {
float fLocalDa = fBlockY - nBlockSize;
float fLocalDb = fBlockNextY - nBlockSize;
if( fLocalDa >= 0 && fLocalDb <= fEpsilon )
{
ASSERT( fLocalDa >= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (fLocalDa-fEpsilon) / (fLocalDa - fLocalDb);
if(fLocalDa>fEpsilon) vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
if(fLocalDa>fEpsilon) fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1, (1.f - fRatio ));
vMove.y = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextX >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX -= nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextX < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX += nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 0 ) {
float fLocalDa = fBlockY;
float fLocalDb = fBlockNextY;
if( fLocalDa <= 0 && fLocalDb >= -fEpsilon)
{
ASSERT( fLocalDa <= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (-fLocalDa-fEpsilon) / (fLocalDb - fLocalDa);
if(-fLocalDa>fEpsilon) vPos.x += vMove.x * fRatio;
vPos.y += vMove.y * fRatio;
if(-fLocalDa>fEpsilon) fBlockX += vMove.x * fRatio;
fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min(1, (1.f - fRatio ));
vMove.y = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextX >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX -= nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextX < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX += nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 3 ) {
float fLocalDa = fBlockX;
float fLocalDb = fBlockNextX;
if( (fLocalDa <= 0 && fLocalDb >= -fEpsilon) )
{
ASSERT( fLocalDa <= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (-fLocalDa-fEpsilon) / (fLocalDb - fLocalDa);
vPos.x += vMove.x * fRatio;
if(-fLocalDa>fEpsilon) vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
if(-fLocalDa>fEpsilon) fBlockY += vMove.y * fRatio;
ASSERT( (vPos.x==vPos.x&&vPos.y==vPos.y) );
vMove *= min( 1, (1.f - fRatio ));
vMove.x = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextY >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x -= nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX += nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextY < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x -= nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX += nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
else if( nOutCollideDir == 1 ) {
float fLocalDa = fBlockX - nBlockSize;
float fLocalDb = fBlockNextX - nBlockSize ;
if( fLocalDa >= 0 && fLocalDb <= fEpsilon )
{
ASSERT( fLocalDa >= fLocalDb );
nDebugCode |= 0x10;
float fRatio = (fLocalDa-fEpsilon) / (fLocalDa - fLocalDb);
vPos.x += vMove.x * fRatio;
if(fLocalDa>fEpsilon) vPos.y += vMove.y * fRatio;
fBlockX += vMove.x * fRatio;
if(fLocalDa>fEpsilon) fBlockY += vMove.y * fRatio;
ASSERT((vPos.x==vPos.x&&vPos.y==vPos.y));
vMove *= min(1, (1.f - fRatio ));
vMove.x = 0.f;
if( nSlideType == 1 ) {
vMove = EtVector2(0,0);
bBreakLoop = true;
}
nSlideType = 2;
if( fBlockNextY >= nBlockSize ) {
nDebugCode |= 0x20;
vAttrPos.x += nBlockSize;
vAttrPos.y += nBlockSize;
fBlockX -= nBlockSize;
fBlockY -= nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else if( fBlockNextY < 0 ) {
nDebugCode |= 0x40;
vAttrPos.x += nBlockSize;
vAttrPos.y -= nBlockSize;
fBlockX -= nBlockSize;
fBlockY += nBlockSize;
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
// continue to next step
}
else { // end of loop
bBreakLoop = true;
}
}
else {
vPos = EtVector2(vPrevPos.x, vPrevPos.z); // Unknown Collision Error
break;
}
}
}
else { // <20>׿<EFBFBD><D7BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ
if( fBlockNextX < 0 || fBlockNextX >= nBlockSize || fBlockNextY < 0 || fBlockNextY >= nBlockSize ) {
switch( nCollideDir )
{
case 0:
vAttrPos.y -= nBlockSize;
fBlockY += nBlockSize;
break;
case 1:
vAttrPos.x += nBlockSize;
fBlockX -= nBlockSize;
break;
case 2:
vAttrPos.y += nBlockSize;
fBlockY -= nBlockSize;
break;
case 3:
vAttrPos.x -= nBlockSize;
fBlockX += nBlockSize;
break;
}
cAttr = INSTANCE(CDnWorld).GetAttribute( vAttrPos.x, vAttrPos.y );
nBlockSize = INSTANCE(CDnWorld).GetAttributeBlockSize( vAttrPos.x, vAttrPos.y );
nDebugCode = 255;
// continue to next step
}
else {
bBreakLoop = true;
}
}
#if( _USE_COLLISION_DEBUG )
debugCode.push_back( nDebugCode );
#endif
if( bBreakLoop ) {
vPos.x += vMove.x;
vPos.y += vMove.y;
ASSERT((vPos.x==vPos.x&&vPos.y==vPos.y));
}
}while( !bBreakLoop );
m_pMatExWorld->m_vPosition.x = vPos.x;
m_pMatExWorld->m_vPosition.z = vPos.y;
bool bClash = true;
char cAttr2 = INSTANCE(CDnWorld).GetAttribute( m_pMatExWorld->m_vPosition );
if( ( cAttr2 & 0x0f ) == 1 || ( cAttr2 & 0x0f ) == 2 ) {
char cHiAttr = ( cAttr2 & 0xf0 ) >> 4;
if( cHiAttr != 0 )
{
if( !CheckDiagonalBlock( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.z ) ) bClash = false;
}
else bClash = false;
}
if( bClash == false )
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
}
else {
if( ( cAttr & 0x0f ) == 2 && EtVec3LengthSq( &( m_pMatExWorld->m_vPosition - vPrevPos ) ) > 0.f ) {
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnClash( m_pMatExWorld->m_vPosition, eCFCT_None ); // note by kalliste : <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٴ<EFBFBD><D9B4><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> None<6E><65><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> NoFloor <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>.
#else
OnClash( m_pMatExWorld->m_vPosition, eCFCT_None );
#endif
}
}
}
void MAWalkMovement::ProcessProp( EtVector3 vPrevPos )
{
m_bFloorCollision = false;
if( m_pActor->GetObjectHandle() )
{
#ifdef _GAMESERVER // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD>ʿ<EFBFBD> <20><><EFBFBD> ũ<><C5A9> <20>Ѵ<EFBFBD>.
const float fMinMove = 20.0f;
#else
const float fMinMove = 5.0f;
#endif
EtVector3 vDiffNormal;
float fLength;
vDiffNormal = m_pMatExWorld->m_vPosition - vPrevPos;
fLength = EtVec3Length( &vDiffNormal );
if( fLength <= fMinMove )
{
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vPrevPos, m_bFloorCollision );
}
else
{
EtVector3 vTemp = m_pMatExWorld->m_vPosition;
vDiffNormal /= fLength;
int nCount = 0;
EtVector3 vCurPrevPos = vPrevPos;
while( fLength > 0.0f )
{
if( fLength > fMinMove )
{
m_pMatExWorld->m_vPosition = vCurPrevPos + fMinMove * vDiffNormal;
fLength -= fMinMove;
}
else
{
m_pMatExWorld->m_vPosition = vCurPrevPos + fLength * vDiffNormal;
fLength = 0.0f;
}
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vCurPrevPos, m_bFloorCollision );
m_pActor->GetObjectHandle()->Update( *m_pMatExWorld );
vCurPrevPos = m_pMatExWorld->m_vPosition;
nCount++;
#ifdef _GAMESERVER
if( nCount == 50 )
#else
if( nCount == 200 )
#endif
{
m_pMatExWorld->m_vPosition = vCurPrevPos;
break;
}
}
}
}
if( m_bFloorCollision ) {
if( m_pActor->GetAddHeight() < 0.f ) m_bFloorCollision = false;
}
if( m_bFloorCollision == false )
{
if( m_pActor->GetAddHeight() != 0.f )
{
if( m_vVelocity.y == 0.f )
{
m_vVelocity.y = -1.f;
m_vVelocityResist.y = -20.f;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_bFloorForceVelocity = true;
}
}
m_pActor->SetAddHeight( 0.f );
}
if( m_bFloorCollision == false && m_vVelocity.y == 0.f )
{
#ifdef PRE_FIX_FALL_PROP_COLLISION
m_vVelocity.y = -1.f;
m_vVelocityResist.y = -20.f;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_bFloorForceVelocity = true;
#else
float fHeight = INSTANCE(CDnWorld).GetHeightWithProp( EtVector3( m_pMatExWorld->m_vPosition.x, m_pMatExWorld->m_vPosition.y + 100.f, m_pMatExWorld->m_vPosition.z ) );
float fCurHeight = fHeight + m_pActor->GetAddHeight();
m_pMatExWorld->m_vPosition.y = fCurHeight;
#endif
}
}
void MAWalkMovement::Process( LOCAL_TIME LocalTime, float fDelta )
{
// m_fLastHeight = m_pMatEx->m_vPosition.y;
ProcessCommon( LocalTime, fDelta );
#ifndef _GAMESERVER
DebugRenderAttr();
#endif
EtVector3 vPrevPos = *m_pActor->GetPrevPosition();
ProcessProp( vPrevPos );
PostProcess( LocalTime );
}
void MAWalkMovement::ProcessCollision( CDnActor *pActor, EtObjectHandle hObject, const EtVector3 &vPrevPos, bool &bFloorCollision )
{
#ifdef _WORK
if( GetAsyncKeyState( VK_CONTROL ) < 0 ) return;
#endif
int nLoop, i;
float fMoveDist;
EtVector3 vMoveDir;
DNVector(SCollisionResponse) &vecResult = m_vecResult;
vecResult.clear();
vMoveDir = m_pMatExWorld->m_vPosition - vPrevPos;
fMoveDist = EtVec3Length( &vMoveDir );
if( fMoveDist == 0.0f ) {
return;
}
vMoveDir /= fMoveDist;
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <20>ö<EFBFBD><C3B6><EFBFBD> <20><> <20>ֳ<EFBFBD> üũ.
bool bIsClimb = CheckClimb( hObject, vPrevPos, vecResult, bFloorCollision );
if( bIsClimb )
{
float fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
return;
}
if( fMoveDist <= 0.0f )
{
if( m_pActor->GetAddHeight() > 0.f )
bFloorCollision = true;
return;
}
for( nLoop = 0; nLoop < 5; nLoop++ )
{
SCollisionResponse CurResponse;
CurResponse.fContactTime = FLT_MAX;
for( i = 0; i < ( int )vecResult.size(); i++ )
{
EtVector3 vCurNormal = vecResult[ i ].vNormal;
// <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EBB8BB> ũ<>Ⱑ 1.0<EFBFBD><EFBFBD> <20>ȵǸ<C8B5> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> <20>ĺ<EFBFBD><C4BA><EFBFBD> <20><><EFBFBD><EFBFBD><EEB0A1> <20><><EFBFBD><EFBFBD>
/* if( EtVec3LengthSq( &vCurNormal ) <= 0.5f )
{
continue;
}*/
if( EtVec3Dot( &vCurNormal, &vMoveDir ) > 0.0f ) // <20><><EFBFBD>dz븻<C7B3><EBB8BB> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{
continue;
}
if( vecResult[ i ].fContactTime < CurResponse.fContactTime )
{
CurResponse = vecResult[ i ];
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5>Ҹ<EFBFBD><D2B8><EFBFBD> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD> <20><>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
if( CurResponse.fContactTime == FLT_MAX )
{
// m_pMatEx->m_vPosition = vPrevPos;
break;
}
bool bStopSlide = false;
bool bIsWall = true;
if( EtVec3Dot( &CurResponse.vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.707106f ) // 45<34><35> üũ
{
if( vMoveDir.y < -0.9999f ) // <20><><EFBFBD><EFBFBD><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȹ̲<C8B9><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
bStopSlide = true;
}
bIsWall = false;
bFloorCollision = true;
}
else if( EtVec3Dot( &CurResponse.vNormal, &EtVector3( 0.0f, -1.0f, 0.0f ) ) > 0.707106f ) // 45<34><35> õ<><C3B5>üũ
{
bIsWall = false;
}
if( !bStopSlide )
{
EtVector3 vSlideDir;
float fWeight;
CalcSlide( vSlideDir, fWeight, CurResponse.vNormal, vMoveDir );
if( ( bIsWall ) && ( vSlideDir.y > 0.0f ) && ( vMoveDir.y <= 0.0f ) ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.. vMoveDir.y > 0.0f Ŀ<><C4BF> <20><><EFBFBD><EFBFBD> <20>϶<EFBFBD><CFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> <20>Ͼ<CFBE><EEB3AA> <20>Ѵ<EFBFBD>.
{
EtVector3 vWallNormal;
vWallNormal = CurResponse.vNormal;
vWallNormal.y = 0.0f;
EtVec3Normalize( &vWallNormal, &vWallNormal );
CalcSlide( vSlideDir, fWeight, vWallNormal, vMoveDir );
}
else if( ( bIsWall ) && ( vSlideDir.y < 0.0f ) ) // <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ִ<EFBFBD>ä<EFBFBD><C3A4> <20><> ū <20><>ü<EFBFBD><C3BC> <20>Ʒ<EFBFBD><C6B7><EFBFBD> <20>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> <20>ȵȴ<C8B5>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ϸ<EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD> <20>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
{
if( m_pActor->GetState() & CDnActorState::Move && (m_pActor->GetState() & CDnActorState::Air) == false )
{
EtVector3 vWallNormal;
vWallNormal = CurResponse.vNormal;
vWallNormal.y = 0.0f;
EtVec3Normalize( &vWallNormal, &vWallNormal );
CalcSlide( vSlideDir, fWeight, vWallNormal, vMoveDir );
}
}
vMoveDir = vSlideDir;
fMoveDist *= fWeight;
m_pMatExWorld->m_vPosition = vPrevPos + vMoveDir * fMoveDist;
}
vecResult.clear();
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
for( i = ( int )vecResult.size() - 1; i >= 0; i-- )
{
if( EtVec3Dot( &vecResult[ i ].vNormal, &CurResponse.vNormal ) > 0.996194f ) // <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 5<><35> <20><><EFBFBD><EFBFBD> <20>ۿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȳ<EFBFBD><C8B3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><>ŵ
{
vecResult.erase( vecResult.begin() + i );
}
}
}
if( vecResult.empty() )
{
break;
}
}
if( nLoop == 5 )
{
if( bFloorCollision )
{
float fLandHeight;
fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
if( m_pMatExWorld->m_vPosition.y > fLandHeight )
{
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
}
m_pMatExWorld->m_vPosition = vPrevPos;
}
else // <20>ٴڰ<D9B4> <20><EFBFBD><E6B5B9> <20>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x,z<><7A> Previous<75><73> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>. <20>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>𼭸<EFBFBD><F0BCADB8><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> slide <20>ϸ鼭 <20>̵<EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
// <20>ٴڰ<D9B4> <20><EFBFBD><E6B5B9> <20>ȳ<EFBFBD><C8B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>浹 üũ<C3BC>غ<EFBFBD><D8BA><EFBFBD> y<><79> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD≯<EFBFBD> y<><79> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>ٲ<EFBFBD><D9B2><EFBFBD>
vecResult.clear();
if( hObject->FindCollision( *m_pMatExWorld, vecResult ) )
{
for( i = 0; i < ( int )vecResult.size(); i++ )
{
// <20><><EFBFBD><EFBFBD><EFBFBD>̿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
if( EtVec3Dot( &vecResult[ i ].vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.087155f )
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
bFloorCollision = true;
break;
}
}
}
}
}
else
{
float fLandHeight;
fLandHeight = INSTANCE(CDnWorld).GetHeight( m_pMatExWorld->m_vPosition );
if( fLandHeight > m_pMatExWorld->m_vPosition.y )
{
m_pMatExWorld->m_vPosition.y = fLandHeight;
}
else if( bFloorCollision )
{
// <20>ٴ<EFBFBD> <20><EFBFBD><E6B5B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20>Ͼ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ǽ<EFBFBD>.. y<><79><EFBFBD><EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD>.
// <20>׷<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> <20>ٴ<EFBFBD> <20><EFBFBD><E6B5B9> <20><><EFBFBD><EFBFBD> <20>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־ <20><><EFBFBD><EFBFBD> y<><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
if( m_pMatExWorld->m_vPosition.y < vPrevPos.y )
{
m_pMatExWorld->m_vPosition.y = vPrevPos.y;
}
m_pActor->SetAddHeight( m_pMatExWorld->m_vPosition.y - fLandHeight );
}
}
#ifdef _SHADOW_TEST
if( !m_pActor->IsShadowActor() ) OnClash( m_pMatExWorld->m_vPosition, bFloorCollision ? eCFCT_Floor : eCFCT_NoFloor );
#else
OnClash( m_pMatExWorld->m_vPosition, bFloorCollision ? eCFCT_Floor : eCFCT_NoFloor );
#endif
char cAttr = INSTANCE(CDnWorld).GetAttribute( m_pMatExWorld->m_vPosition );
if( ( cAttr & 0x0f ) == 1 || ( cAttr & 0x0f ) == 2 ) // 0x01, 0x02 <20><> <20>浹üũ
{
m_pMatExWorld->m_vPosition.x = vPrevPos.x;
m_pMatExWorld->m_vPosition.z = vPrevPos.z;
}
}
}
bool MAWalkMovement::CheckClimb( EtObjectHandle hObject, const EtVector3 &vPrevPos, DNVector(SCollisionResponse) &vecResult, bool &bFloorCollision )
{
int i;
float fMinContactTime;;
SCollisionResponse Response;
const float fClimbBasis = MAX_CLIMB_HEIGHT;
SCollisionPrimitive *pFloor;
pFloor = NULL;
fMinContactTime = 1.0f;
for( i = 0; i < ( int )vecResult.size(); i++ )
{
if( EtVec3Dot( &vecResult[ i ].vNormal, &EtVector3( 0.0f, 1.0f, 0.0f ) ) > 0.707106f )
{
hObject->CEtCollisionEntity::FindCollision( *vecResult[ i ].pCollisionPrimitive, EtVector3( 0.0f, -fClimbBasis, 0.0f ), Response, true );
if( ( Response.fContactTime >= 0.0f ) && ( fMinContactTime > Response.fContactTime ) )
{
fMinContactTime = Response.fContactTime;
pFloor = vecResult[ i ].pCollisionPrimitive;
}
}
}
if( fMinContactTime != 1.0f )
{
float fMoveHeight;
fMoveHeight = ( 1.0f - fMinContactTime ) * fClimbBasis;
if( fMoveHeight - ( vPrevPos.y - m_pMatExWorld->m_vPosition.y ) <= MAX_CLIMB_HEIGHT )
{
DNVector(SCollisionResponse) &vecClimbResult = m_vecResult;
vecClimbResult.clear();
bFloorCollision = true;
m_pMatExWorld->m_vPosition.y += fMoveHeight;
hObject->FindCollision( *m_pMatExWorld, vecClimbResult );
for( i = 0; i < ( int )vecClimbResult.size(); i++ )
{
if( vecClimbResult[ i ].pCollisionPrimitive != pFloor )
{
break;
}
}
if( i < ( int )vecClimbResult.size() )
{
m_pMatExWorld->m_vPosition.y -= fMoveHeight;
return false;
}
bFloorCollision = true;
return true;
}
}
return false;
}
void MAWalkMovement::CalcSlide( EtVector3 &SlideDir, float &fWeight, EtVector3 &CollisionNormal, EtVector3 &MoveDir )
{
EtVector3 WallCross;
EtVec3Cross( &WallCross, &CollisionNormal, &MoveDir );
EtVec3Normalize( &WallCross, &WallCross );
EtVec3Cross( &SlideDir, &WallCross, &CollisionNormal );
EtVec3Normalize( &SlideDir, &SlideDir );
fWeight = fabs( EtVec3Dot( &SlideDir, &MoveDir ) );
}
void MAWalkMovement::PushAndCollisionCheck( EtVector3 &vPush )
{
EtVector3 vPrevPos;
bool bFloorCollision;
vPrevPos = m_pMatExWorld->m_vPosition;
m_pMatExWorld->m_vPosition += vPush;
ProcessCollision( m_pActor, m_pActor->GetObjectHandle(), vPrevPos, bFloorCollision );
}
void MAWalkMovement::SetLimitDgrees( float fDgrees )
{
m_fLimitDgrees = fDgrees;
}
void MAWalkMovement::MoveZ( float fSpeed )
{
m_vMovement += EtVector2( m_vMoveVectorZ.x, m_vMoveVectorZ.z ) * fSpeed;
}
void MAWalkMovement::MoveX( float fSpeed )
{
m_vMovement += EtVector2( m_vMoveVectorX.x, m_vMoveVectorX.z ) * fSpeed;
}
void MAWalkMovement::SetMoveVectorX( EtVector3 &vVec )
{
m_vMoveVectorX = vVec;
}
void MAWalkMovement::SetMoveVectorZ( EtVector3 &vVec )
{
m_vMoveVectorZ = vVec;
}
void MAWalkMovement::Jump( float fPower, EtVector2 &vVec )
{
m_vLastVelocity.y = fPower;
m_vVelocity.y += fPower;
m_vJumpMovement = vVec;
m_vJumpXVector = m_vMoveVectorX;
m_vJumpZVector = m_vMoveVectorZ;
m_fJumpMoveSpeed = (float)m_pActor->GetMoveSpeed();
m_bFloorForceVelocity = false;
}
void MAWalkMovement::MoveJumpX( float fSpeed )
{
if( m_vJumpMovement.x > 0.f && fSpeed > 0.f ) return;
if( m_vJumpMovement.x < 0.f && fSpeed < 0.f ) return;
if( fSpeed > 0.f ) fSpeed = -fSpeed;
m_fJumpMoveSpeed += fSpeed;
if( m_fJumpMoveSpeed < 0.f ) m_fJumpMoveSpeed = 0.f;
}
void MAWalkMovement::MoveJumpZ( float fSpeed )
{
if( m_vJumpMovement.y > 0.f && fSpeed > 0.f ) return;
if( m_vJumpMovement.y < 0.f && fSpeed < 0.f ) return;
if( fSpeed > 0.f ) fSpeed = -fSpeed;
m_fJumpMoveSpeed += fSpeed;
if( m_fJumpMoveSpeed < 0.f ) m_fJumpMoveSpeed = 0.f;
}
void MAWalkMovement::SetVelocityByMoveVector( EtVector3 &vVec )
{
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
// <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> <20>ö<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߻<EFBFBD><DFBB><EFBFBD> <20><><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD> <20>ִ<EFBFBD>.
// <20><><EFBFBD><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD> <20>ұ<EFBFBD><D2B1>ϰ<EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> OnDrop<6F><70> OnFall, m_bFloorCollision<6F><6E> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>÷<EFBFBD> <20>ٲ<EFBFBD><D9B2><20><><EFBFBD><EFBFBD> <20>ڵ尡 <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD>.
// (<28><><EFBFBD><EFBFBD> <20><><EFBFBD>̱⿣ <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD>´<EFBFBD>.)
// <20><> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> <20>ͼ<EFBFBD> m_vVelocity<74><79> y<><79><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ<EFBFBD><C8AD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD>,
// <20>ٴڿ<D9B4> <20>ִ<EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD> <20>հ<EFBFBD> <20>Ʒ<EFBFBD><C6B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <20>׷<EFBFBD><D7B7><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>¿<EFBFBD><C2BF><EFBFBD> STE_VelocityAccel <20>ñ׳<C3B1><D7B3><EFBFBD> y<><79> 0<>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD>̿<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ°Ŷ<C2B0><C5B6><EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> m_vVelocity.y <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20>ϰڴ<CFB0>.
// <20>̰Ͱ<CCB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׻<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴°<CCB4> VelocityResist<73><74><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD>ش<EFBFBD>.
// <20>Ʒ<EFBFBD> m_vLastVelocity<74><79> <20><><EFBFBD>̴µ<CCB4><C2B5><EFBFBD> <20><><EFBFBD>°<EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> <20><><EFBFBD>ܽ<EFBFBD>Ŵ.
bool bKeepVelocityY = false;
float fKeepVelocityY = 0.0f;
if( m_bLastFloorForceVelocity && vVec.y == 0.0f )
{
bKeepVelocityY = true;
fKeepVelocityY = m_vVelocity.y;
}
#endif
m_vVelocity = vVec;
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
if( bKeepVelocityY ) m_vVelocity.y = fKeepVelocityY;
#endif
m_vVelocityXVector = m_vMoveVectorX;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vVelocityZVector = m_vMoveVectorZ;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity = vVec;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocity( EtVector3 &vVec )
{
m_vVelocity = vVec;
m_vVelocityXVector = m_pMatExWorld->m_vXAxis;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vVelocityZVector = m_pMatExWorld->m_vZAxis;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity = vVec;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocityX( float fPower )
{
m_vVelocity.x = fPower;
m_vVelocityXVector = m_pMatExWorld->m_vXAxis;
m_vLastVelocity.x = fPower;
}
void MAWalkMovement::SetVelocityY( float fPower )
{
m_vVelocity.y = fPower;
m_vVelocityYVector = m_pMatExWorld->m_vYAxis;
m_vJumpMovement = EtVector2( 0.f, 0.f );
m_vLastVelocity.y = fPower;
m_bFloorForceVelocity = false;
}
void MAWalkMovement::SetVelocityZ( float fPower )
{
m_vVelocity.z = fPower;
m_vVelocityZVector = m_pMatExWorld->m_vZAxis;
m_vLastVelocity.z = fPower;
}
void MAWalkMovement::SetResistance( EtVector3 &vVec )
{
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
bool bKeepVelocityResistY = false;
float fKeepVelocityResistY = 0.0f;
if( m_bLastFloorForceVelocity && vVec.y == 0.0f )
{
bKeepVelocityResistY = true;
fKeepVelocityResistY = m_vVelocityResist.y;
}
#endif
m_vVelocityResist = vVec;
#ifdef PRE_MOD_VELOCITYACCEL_SIGNAL
if( bKeepVelocityResistY ) m_vVelocityResist.y = fKeepVelocityResistY;
#endif
}
void MAWalkMovement::SetResistanceX( float fPower )
{
m_vVelocityResist.x = fPower;
}
void MAWalkMovement::SetResistanceY( float fPower )
{
m_vVelocityResist.y = fPower;
}
void MAWalkMovement::SetResistanceZ( float fPower )
{
m_vVelocityResist.z = fPower;
}
void MAWalkMovement::MovePos( EtVector3 &vPos, bool bRefreshZVec )
{
m_bEnableNaviMode = false;
m_vMovePos = vPos;
m_bRefreshZVector = bRefreshZVec;
if( bRefreshZVec ) {
m_vTargetLookVec.x = vPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
#ifndef _GAMESERVER
m_fLastMoveDelta = 0.f;
m_nLastMoveCount = 0;
#endif
}
void MAWalkMovement::MoveTarget( DnActorHandle &hActor, float fMinDistance )
{
m_hMoveTarget = hActor;
m_fTargetMinDistance = fMinDistance;
m_bRefreshZVector = true;
m_bEnableNaviMode = false;
}
DnActorHandle MAWalkMovement::GetMoveTarget()
{
return m_hMoveTarget;
}
void MAWalkMovement::MoveTargetNavi( DnActorHandle &hActor, float fMinDistance, const char* szActionName )
{
MoveTargetNavi( *hActor->GetPosition(), fMinDistance, szActionName );
if( m_bEnableNaviMode )
{
m_hNaviTarget = hActor;
m_nNaviType = NaviType::eTarget;
}
}
void MAWalkMovement::MoveTargetNavi( EtVector3& vTargetPos, float fMinDistance, const char* szActionName )
{
m_fNaviTargetMinDistance = fMinDistance;
m_szNaviTargetActionName = szActionName;
m_hLookTarget.Identity();
m_WayPointList.clear();
m_fTargetMinDistance = fMinDistance;
m_bEnableNaviMode = false;
m_nNaviType = NaviType::eMax;
m_bRefreshZVector = true;
EtVector3 vStartPos = this->m_pMatExWorld->m_vPosition;
EtVector3 vEndPos = vTargetPos;
if( m_bRefreshZVector )
{
m_vTargetLookVec.x = vTargetPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vTargetPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
CEtWorldGrid* pGrid = INSTANCE(CDnWorld).GetGrid();
if( pGrid == NULL )
return;
NavigationMesh* pNaviMesh = pGrid->GetNavMesh(vStartPos);
if( pNaviMesh == NULL )
return;
NavigationCell* pStartCell = pNaviMesh->FindClosestCell( vStartPos );
NavigationCell* pEndCell = pNaviMesh->FindClosestCell( vEndPos );
if ( !pStartCell || !pEndCell )
return;
NavigationPath naviPath;
pNaviMesh->BuildNavigationPath( naviPath, pStartCell, vStartPos, pEndCell, vEndPos );
WAYPOINT_LIST& fur_waypoint_list = naviPath.LineOfSightWayPointList();
if( fur_waypoint_list.empty() )
return;
m_WayPointList = fur_waypoint_list;
m_WayPointId = m_WayPointList.begin();
m_WayPointId++; // <20><>÷<EFBFBD><C3B7>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
OnMoveNavi( (EtVector3)(*m_WayPointId).Position );
m_bEnableNaviMode = true;
m_nNaviType = NaviType::ePosition;
}
#ifdef PRE_MOD_NAVIGATION_PATH
void MAWalkMovement::AutoMoving( EtVector3& vTargetPos, float fMinDistance, const char* szActionName, bool bGeneratePath )
{
m_fNaviTargetMinDistance = fMinDistance;
m_szNaviTargetActionName = szActionName;
m_hLookTarget.Identity();
m_WayPointList.clear();
m_fTargetMinDistance = fMinDistance;
m_bEnableNaviMode = false;
m_nNaviType = NaviType::eMax;
m_bRefreshZVector = true;
EtVector3 vStartPos = this->m_pMatExWorld->m_vPosition;
EtVector3 vEndPos = vTargetPos;
if( m_bRefreshZVector )
{
m_vTargetLookVec.x = vTargetPos.x - m_pMatExWorld->m_vPosition.x;
m_vTargetLookVec.y = vTargetPos.z - m_pMatExWorld->m_vPosition.z;
EtVec2Normalize( &m_vTargetLookVec, &m_vTargetLookVec );
}
CEtWorldGrid* pGrid = INSTANCE(CDnWorld).GetGrid();
if( pGrid == NULL )
return;
NavigationMesh* pNaviMesh = pGrid->GetNavMesh(vStartPos);
if( pNaviMesh == NULL )
return;
NavigationCell* pStartCell = pNaviMesh->FindClosestCell( vStartPos );
NavigationCell* pEndCell = pNaviMesh->FindClosestCell( vEndPos );
// <20>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>޽<EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD>
if ( !pStartCell || !pEndCell )
return;
if( bGeneratePath )
GenerateAutoMovingPath( pNaviMesh, pStartCell, pEndCell, vStartPos, vEndPos );
m_bEnableNaviMode = true;
m_nNaviType = NaviType::ePosition;
}
// Solve the Catmull-Rom parametric equation for a given time(t) and vector quadruple (p1,p2,p3,p4)
EtVector3 Eq(float t, const EtVector3& p1, const EtVector3& p2, const EtVector3& p3, const EtVector3& p4)
{
float t2 = t * t;
float t3 = t2 * t;
float b1 = static_cast<float>( .5 * ( -t3 + 2*t2 - t) );
float b2 = static_cast<float>( .5 * ( 3*t3 - 5*t2 + 2) );
float b3 = static_cast<float>( .5 * (-3*t3 + 4*t2 + t) );
float b4 = static_cast<float>( .5 * ( t3 - t2 ) );
return (p1*b1 + p2*b2 + p3*b3 + p4*b4);
}
EtVector3 GetInterpolatedSplinePoint(std::vector<EtVector3>& vecList, float t)
{
float delta_t = 1.0f / static_cast<float>(vecList.size() - 1);
// Find out in which interval we are on the spline
int p = (int)(t / delta_t);
// Compute local control point indices
#define BOUNDS(pp) { if (pp < 0) pp = 0; else if (pp >= static_cast<int>( vecList.size() )) pp = static_cast<int>( vecList.size() ) - 1; }
int p0 = p - 1; BOUNDS(p0);
int p1 = p; BOUNDS(p1);
int p2 = p + 1; BOUNDS(p2);
int p3 = p + 2; BOUNDS(p3);
// Relative (local) time
float lt = (t - delta_t*(float)p) / delta_t;
// Interpolate
return Eq(lt, vecList[p0], vecList[p1], vecList[p2], vecList[p3]);
}
void MAWalkMovement::GenerateAutoMovingPath( NavigationMesh* pNaviMesh, NavigationCell* pStartCell, NavigationCell* pEndCell, EtVector3& vStartPos, EtVector3& vEndPos )
{
if( pNaviMesh == NULL || pStartCell == NULL || pEndCell == NULL )
return;
NavigationPath naviPath;
pNaviMesh->BuildNavigationPath( naviPath, pStartCell, vStartPos, pEndCell, vEndPos );
WAYPOINT_LIST& fur_waypoint_list = naviPath.LineOfSightWayPointList();
m_LOSWayPointList.clear();
std::list<WAYPOINT>::iterator iter1 = fur_waypoint_list.begin();
for( ; iter1 != fur_waypoint_list.end(); iter1++ )
m_LOSWayPointList.push_back( (*iter1) );
if( fur_waypoint_list.size() < 2 ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Pass
return;
// <20><><EFBFBD>̴<EFBFBD> <20>κи<CEBA> <20>ɰ<EFBFBD><C9B0><EFBFBD> <20>ȭ
WAYPOINT_LIST waypointlist;
int nInnerNodeCount = static_cast<int>( fur_waypoint_list.size() ) - 2; // <20><><EFBFBD>۰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><>
std::list<WAYPOINT>::iterator iterCurrent = fur_waypoint_list.begin();
// <20><><EFBFBD>ŵǴ<C5B5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
waypointlist.push_back( *iterCurrent ); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
iterCurrent++; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
for( int i=0; i<nInnerNodeCount; i++, iterCurrent++ )
{
std::list<WAYPOINT>::iterator iterPrev = iterCurrent;
iterPrev--;
std::list<WAYPOINT>::iterator iterNext = iterCurrent;
iterNext++;
std::vector<EtVector3> tempvectorlist;
EtVector3 vecTarget = (*iterPrev).Position - (*iterCurrent).Position; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E2BAA4>
float fLength = EtVec3Length( &vecTarget );
float fPointLength = 0.0f;
if( fLength > 800.0f ) // 8m<38><6D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>յ<EFBFBD> 4m<34><6D> 5<><35> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ɰ<EFBFBD>
fPointLength = 400.0f;
else // 8m<38><6D> <20><><EFBFBD><EFBFBD> <20>ʴ´ٸ<C2B4> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɰ<EFBFBD>
fPointLength = fLength / 2.0f;
EtVector3 vecNormal;
EtVec3Normalize( &vecNormal, &vecTarget );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * fPointLength ) );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * ( fPointLength / 2.0f ) ) );
tempvectorlist.push_back( (*iterCurrent).Position );
vecTarget = (*iterNext).Position - (*iterCurrent).Position; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E2BAA4>
fLength = EtVec3Length( &vecTarget );
if( fLength > 800.0f ) // 8m<38><6D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>յ<EFBFBD> 4m<34><6D> 5<><35> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ɰ<EFBFBD>
fPointLength = 400.0f;
else // 8m<38><6D> <20><><EFBFBD><EFBFBD> <20>ʴ´ٸ<C2B4> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɰ<EFBFBD>
fPointLength = fLength / 2.0f;
EtVec3Normalize( &vecNormal, &vecTarget );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * ( fPointLength / 2.0f ) ) );
tempvectorlist.push_back( (*iterCurrent).Position + ( vecNormal * fPointLength ) );
if( tempvectorlist.size() == 0 )
continue;
// <20><20><><EFBFBD><EFBFBD>
WAYPOINT_LIST interpolationlist;
int nDivide = 40;
for( int j=0; j<nDivide; j++ )
{
WAYPOINT waypoint;
float fTime = static_cast<float>(j) / static_cast<float>(nDivide);
waypoint.Position = GetInterpolatedSplinePoint( tempvectorlist, fTime );
waypointlist.push_back( waypoint );
}
}
std::list<WAYPOINT>::iterator iterEnd = fur_waypoint_list.end();
iterEnd--;
waypointlist.push_back( *iterEnd ); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EEBCB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׺<EFBFBD><D7BA><EFBFBD><EFBFBD>̼<EFBFBD> <20>޽<EFBFBD><DEBD>ȿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> <20>˻<EFBFBD><CBBB>Ͽ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><EEB6BB> <20>ؾ<EFBFBD><D8BE>ұ<EFBFBD>??????
m_WayPointList = waypointlist;
m_WayPointId = m_WayPointList.begin();
}
#endif // PRE_MOD_NAVIGATION_PATH
void MAWalkMovement::MoveToWorld( EtVector2 &vVec )
{
m_vMovement += vVec;
}
void MAWalkMovement::ResetMove()
{
m_hMoveTarget.Identity();
m_vMovePos = EtVector3( 0.f, 0.f, 0.f );
m_vMagnetDir = EtVector2( 0.f, 0.f );
m_fMagnetLength = 0.f;
m_bEnableNaviMode = false;
}
void MAWalkMovement::Look( EtVector2 &vVec, bool bForceRotate )
{
if( bForceRotate ) {
if( EtVec2LengthSq( &vVec ) > 0.f ) {
m_pMatExWorld->m_vZAxis = EtVector3( vVec.x, 0.f, vVec.y );
EtVec3Normalize( &m_pMatExWorld->m_vZAxis, &m_pMatExWorld->m_vZAxis );
m_pMatExWorld->MakeUpCartesianByZAxis();
}
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
else {
m_vTargetLookVec = vVec;
}
}
EtVector3 *MAWalkMovement::GetLookDir()
{
return &m_pMatExWorld->m_vZAxis;
}
void MAWalkMovement::LookTarget( DnActorHandle &hActor )
{
m_hLookTarget = hActor;
if ( m_hLookTarget )
{
OnBeginLook();
}
else
{
OnEndLook();
}
}
void MAWalkMovement::ResetLook()
{
m_hLookTarget.Identity();
m_vTargetLookVec = EtVector2( 0.f, 0.f );
}
DnActorHandle MAWalkMovement::GetLookTarget()
{
return m_hLookTarget;
}
void MAWalkMovement::SetMagnetDir( EtVector2 &vPos )
{
m_vMagnetDir = vPos;
}
void MAWalkMovement::SetMagnetLength( float fLength )
{
m_fMagnetLength = fLength;
}
EtVector3 *MAWalkMovement::GetVelocity()
{
return &m_vVelocity;
}
EtVector3 *MAWalkMovement::GetResistance()
{
return &m_vVelocityResist;
}
EtVector3 *MAWalkMovement::GetLastVelocity()
{
return &m_vLastVelocity;
}
EtVector3 *MAWalkMovement::GetVelocityValue()
{
return &m_vLastVelocityValue;
}
void MAWalkMovement::SetMagnetPosition( EtVector3 &vPos )
{
EtVector2 vMagnet;
float fHeightDiff = vPos.y - m_pMatExWorld->m_vPosition.y;
vMagnet.x = vPos.x - m_pMatExWorld->m_vPosition.x;
vMagnet.y = vPos.z - m_pMatExWorld->m_vPosition.z;
float fAberraionLength = EtVec2Length( &vMagnet );
if( ( fAberraionLength > 1.f && fAberraionLength < 200.f ) && fHeightDiff < 200.f ) {
SetMagnetLength( fAberraionLength );
EtVec2Normalize( &vMagnet, &vMagnet );
SetMagnetDir( vMagnet );
}
else {
m_pActor->SetPosition( vPos );
}
}
void MAWalkMovement::SetMoveYDistancePerSec( float fMoveYDistancePerSec, float fWholeMoveYDistance, bool bMaintainYDistanceOnArriveDestPosition )
{
if( (0.0f < m_fMoveYDistancePerSec && 0.0f < fMoveYDistancePerSec) ||
(0.0f > m_fMoveYDistancePerSec && 0.0f > fMoveYDistancePerSec) )
return;
// <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
m_fMoveYDistancePerSec = fMoveYDistancePerSec;
// <20><> <20><><EFBFBD><EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD> <20>ǹ<EFBFBD><C7B9>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
_ASSERT( 0.0f < fWholeMoveYDistance );
m_fLeftMoveYDistance = fWholeMoveYDistance;
m_bAppliedYDistance = true;
// <20><>ǥ<EFBFBD><C7A5> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD> <20>Ÿ<EFBFBD><C5B8><EFBFBD>ŭ <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD> <20><> Y <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ߴٴ<DFB4> <20>÷<EFBFBD><C3B7><EFBFBD> m_bAppliedYDistance <20><>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD>.
// <20><> <20>÷<EFBFBD><C3B7>׷<EFBFBD> <20><><EFBFBD>߿<EFBFBD> WalkMovementNavi <20><><EFBFBD><EFBFBD> <20>ٴڰ<D9B4><DAB0><EFBFBD> <20><><EFBFBD≯<EFBFBD> <20><><EFBFBD>ߴ<EFBFBD> <20><>ƾ<EFBFBD><C6BE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MoveY <20>ñ׳<C3B1><D7B3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٷ<EFBFBD> <20>ٽ<EFBFBD> <20>ٴڿ<D9B4> <20>ٰ<EFBFBD> <20>ȴ<EFBFBD>.
m_bMaintainYDistanceOnArriveDestPosition = bMaintainYDistanceOnArriveDestPosition;
}
void MAWalkMovement::ResetMoveYDistance( void )
{
m_fMoveYDistancePerSec = 0.0f;
m_fLeftMoveYDistance = 0.0f;
m_bAppliedYDistance = false;
}
#ifndef _GAMESERVER
void MAWalkMovement::DebugRenderAttr()
{
#if defined(_DEBUG) || defined(_RDEBUG)
if( !m_bDebugRenderAttr ) {
return;
}
static EtTextureHandle hTexture, hTextureDiagonal;
if(!hTexture) {
hTexture = EternityEngine::LoadTexture(CEtResourceMng::GetInstance().GetFullName("Attr.dds").c_str() );
hTextureDiagonal = EternityEngine::LoadTexture(CEtResourceMng::GetInstance().GetFullName("AttrDiagonal.dds").c_str() );
}
for( int y = -5; y <= 5; y++)
for( int x = -5; x <= 5; x++)
{
float fX = ((int)(m_pMatExWorld->m_vPosition.x / 50.f)+x)*50.f+25.f;
float fZ = ((int)(m_pMatExWorld->m_vPosition.z / 50.f)+y)*50.f+25.f;
char cAttr = INSTANCE(CDnWorld).GetAttribute( EtVector3(fX,0,fZ) );
if( cAttr & 0x3 ) {
char cHiAttr = ( cAttr & 0xf0 ) >> 4;
EtDecalHandle hDecal = (new CEtDecal)->GetMySmartPtr();
float fAngle = 0.f;
if( cHiAttr == 0 ) {
hDecal->Initialize(hTexture, fX, fZ, 25.f, 0.f, 0.f, 0.f, EtColor(1,1,1,1) );
}
else {
if( cHiAttr == 1 ) fAngle = 0.f;
if( cHiAttr == 2 ) fAngle = 90.f;
if( cHiAttr == 4 ) fAngle = 180.f;
if( cHiAttr == 8 ) fAngle = 270.f;
hDecal->Initialize( hTextureDiagonal, fX, fZ, 25.f, 0.f, 0.f, fAngle, EtColor(1,1,1,1) );
}
}
}
#endif
}
#endif