661 lines
18 KiB
C++
661 lines
18 KiB
C++
#include "stdafx.h"
|
|
#include "SGameCameraAnimator.h"
|
|
#include "SGameWorld.h"
|
|
#include "TerrainMapEngine.h"
|
|
#include "SGameLowQualityWater.h"
|
|
#include "KViewport.h"
|
|
|
|
//=======================================================================================
|
|
//
|
|
// SGameCameraTerrainHeightAnimator
|
|
//
|
|
|
|
SGameCameraTerrainHeightAnimator::SGameCameraTerrainHeightAnimator
|
|
( CTerrainMapEngine& terrain
|
|
, SGameLowQualityWater& water )
|
|
: m_terrain ( terrain )
|
|
, m_water ( water )
|
|
{
|
|
}
|
|
|
|
SGameCameraTerrainHeightAnimator::~SGameCameraTerrainHeightAnimator()
|
|
{
|
|
}
|
|
|
|
void SGameCameraTerrainHeightAnimator::Animate( DWORD time, SGameCamera& camera )
|
|
{
|
|
if( camera.GetCameraMode() != SGameCamera::CAMERA_GAME_MODE ) return;
|
|
|
|
// collide with terrain & water
|
|
|
|
K3DVector vCameraPosition = camera.GetCameraPosition();
|
|
K3DVector vProjXYCameraPosition( vCameraPosition.x, vCameraPosition.y, 0.f );
|
|
|
|
// 땅/물 높이 가져오기
|
|
float fTerrainHeight;
|
|
float fWaterHeight = -3.0000000e+038f;
|
|
|
|
//아래 부분을 없애면, 물 속으로 카메라 들어 가짐.
|
|
if( m_water.GetWaterHeight( vProjXYCameraPosition, fWaterHeight ) )
|
|
fWaterHeight += 5.0f;
|
|
|
|
float fHeight = 0.0f;
|
|
bool bOnProp = false;
|
|
WORD wTile = 0;
|
|
m_terrain.GetTerrainHeight(
|
|
vProjXYCameraPosition.x, vProjXYCameraPosition.y, fTerrainHeight, wTile, &bOnProp );
|
|
if ( fTerrainHeight < fWaterHeight )
|
|
{
|
|
bOnProp = true;
|
|
fHeight = fWaterHeight;
|
|
}
|
|
else
|
|
{
|
|
bOnProp = false;
|
|
fHeight = fTerrainHeight;
|
|
}
|
|
if ( !bOnProp )
|
|
m_terrain.GetTerrainHeight( vProjXYCameraPosition.x, vProjXYCameraPosition.y, fHeight, wTile );
|
|
else
|
|
fHeight = fWaterHeight;
|
|
|
|
K3DVector vRelativePos = camera.GetRelativePosition();
|
|
K3DVector vProjXYRelativePos( vRelativePos.x, vRelativePos.y, 0.f );
|
|
float fProjXYLength = K3DVectorLength( vProjXYRelativePos );
|
|
|
|
float fBaseHeight = fHeight + ( SGameCamera::CAMERA_ELEVATION_BASE * fProjXYLength );
|
|
if( vCameraPosition.z < fBaseHeight )
|
|
{
|
|
if( camera.IsDistanceChanged() )
|
|
camera.Elevate( camera.GetDistanceDelta() * SGameCamera::CAMERA_ROTATION_CONSTANT );
|
|
vRelativePos.z += fBaseHeight - vCameraPosition.z;
|
|
camera.SetRelativePosition( vRelativePos );
|
|
}
|
|
}
|
|
|
|
//=======================================================================================
|
|
//
|
|
// SGameCameraTerrainCollisionAnimator
|
|
//
|
|
|
|
SGameCameraTerrainCollisionAnimator::SGameCameraTerrainCollisionAnimator
|
|
( CTerrainMapEngine& terrain
|
|
, SGameLowQualityWater& water )
|
|
: m_terrain ( terrain )
|
|
, m_water ( water )
|
|
, m_vPrevCameraPosition ( 0, 0, 0 )
|
|
, m_vPrevTargetPosition ( 0, 0, 0 )
|
|
{
|
|
}
|
|
|
|
SGameCameraTerrainCollisionAnimator::~SGameCameraTerrainCollisionAnimator()
|
|
{
|
|
}
|
|
|
|
void SGameCameraTerrainCollisionAnimator::Animate( DWORD time, SGameCamera& camera )
|
|
{
|
|
if( camera.GetCameraMode() != SGameCamera::CAMERA_GAME_MODE ) return;
|
|
|
|
// collide with terrain & water
|
|
|
|
CollisionArgument colarg;
|
|
|
|
if( _HasMoved( camera ) )
|
|
{
|
|
colarg.rayPosition = camera.GetCameraTargetPosition();
|
|
colarg.rayDirection = camera.GetCameraPosition() - camera.GetCameraTargetPosition();
|
|
colarg.collidePoint = colarg.rayPosition + colarg.rayDirection;
|
|
colarg.collideDirection = colarg.rayDirection;
|
|
|
|
_ExecuteCollisionResponseWithTerrain( colarg );
|
|
|
|
// backup collision argument for next step
|
|
m_backupCollisionArgument = colarg;
|
|
}
|
|
else
|
|
{
|
|
colarg = m_backupCollisionArgument;
|
|
}
|
|
|
|
K3DVector vFound = colarg.collidePoint;
|
|
K3DVector vRelFound = colarg.collidePoint - colarg.rayPosition;
|
|
|
|
K3DVector vProjXYRelPos( vRelFound.x, vRelFound.y, 0.f );
|
|
float fProjXYLength = K3DVectorLength( vProjXYRelPos );
|
|
|
|
if( colarg.found )
|
|
{
|
|
vFound.z += SGameCamera::CAMERA_ELEVATION_BASE * fProjXYLength;
|
|
}
|
|
else
|
|
{
|
|
float fBaseHeight
|
|
= _GetTerrainHeight( vFound )
|
|
+ ( SGameCamera::CAMERA_ELEVATION_BASE * fProjXYLength );
|
|
|
|
if( vFound.z < fBaseHeight )
|
|
{
|
|
if( camera.IsDistanceChanged() )
|
|
camera.Elevate( camera.GetDistanceDelta() * SGameCamera::CAMERA_ROTATION_CONSTANT );
|
|
|
|
vFound.z = fBaseHeight;
|
|
}
|
|
}
|
|
|
|
camera.SetRelativePosition( vFound - colarg.rayPosition );
|
|
}
|
|
|
|
bool SGameCameraTerrainCollisionAnimator::_HasMoved( const SGameCamera& camera )
|
|
{
|
|
K3DVector vCameraPosition = camera.GetCameraPosition();
|
|
K3DVector vTargetPosition = camera.GetCameraTargetPosition();
|
|
|
|
bool bHasMoved = ( m_vPrevCameraPosition != vCameraPosition ||
|
|
m_vPrevTargetPosition != vTargetPosition ) ? true : false;
|
|
|
|
// backup for next process
|
|
m_vPrevCameraPosition = vCameraPosition;
|
|
m_vPrevTargetPosition = vTargetPosition;
|
|
|
|
return bHasMoved;
|
|
}
|
|
|
|
float SGameCameraTerrainCollisionAnimator::_GetTerrainHeight( const K3DVector& position )
|
|
{
|
|
K3DVector vProjXYCameraPosition( position.x, position.y, 0.f );
|
|
|
|
// 땅/물 높이 가져오기
|
|
float fTerrainHeight;
|
|
float fWaterHeight = -3.0000000e+038f;
|
|
|
|
//아래 부분을 없애면, 물 속으로 카메라 들어 가짐.
|
|
if( m_water.GetWaterHeight( vProjXYCameraPosition, fWaterHeight ) )
|
|
fWaterHeight += 5.0f;
|
|
|
|
float fHeight = 0.0f;
|
|
bool bOnProp = false;
|
|
WORD wTile = 0;
|
|
m_terrain.GetTerrainHeight(
|
|
vProjXYCameraPosition.x, vProjXYCameraPosition.y, fTerrainHeight, wTile, &bOnProp );
|
|
if ( fTerrainHeight < fWaterHeight )
|
|
{
|
|
bOnProp = true;
|
|
fHeight = fWaterHeight;
|
|
}
|
|
else
|
|
{
|
|
bOnProp = false;
|
|
fHeight = fTerrainHeight;
|
|
}
|
|
if ( !bOnProp )
|
|
m_terrain.GetTerrainHeight( vProjXYCameraPosition.x, vProjXYCameraPosition.y, fHeight, wTile );
|
|
else
|
|
fHeight = fWaterHeight;
|
|
|
|
return fHeight;
|
|
}
|
|
|
|
void SGameCameraTerrainCollisionAnimator::
|
|
_ExecuteCollisionResponseWithTerrain( CollisionArgument& argument )
|
|
{
|
|
K3DVector targetPos = argument.rayPosition + argument.rayDirection;
|
|
K3DCamera camera;
|
|
camera.SetTargetPos( targetPos.x, targetPos.y, targetPos.z );
|
|
TERRAIN_PICK_RESULT result = m_terrain.GetLineCrossedPoint(
|
|
&camera, argument.rayPosition, targetPos, argument.collidePoint );
|
|
if( result == TERRAIN_PICK_RESULT::TERRAIN_PICK_SUCCECED ||
|
|
result == TERRAIN_PICK_RESULT::TERRAIN_STOOL_PICK_SUCCECED )
|
|
{
|
|
argument.found = true;
|
|
}
|
|
else
|
|
{
|
|
argument.found = false;
|
|
}
|
|
}
|
|
|
|
//=======================================================================================
|
|
//
|
|
// SGameCameraPropCollisionAnimator
|
|
//
|
|
|
|
SGameCameraPropCollisionAnimator::SGameCameraPropCollisionAnimator
|
|
( CTerrainMapEngine& terrain
|
|
, const K3DVector& vCollisionRadius
|
|
, DWORD dwInterpolationTime )
|
|
: m_terrain ( terrain )
|
|
, m_vCollidableSphereRadius ( vCollisionRadius )
|
|
, m_vPrevCameraPosition ( 0, 0, 0 )
|
|
, m_vPrevTargetPosition ( 0, 0, 0 )
|
|
, m_dwTime ( 0 )
|
|
, m_dwInterpolationTime ( dwInterpolationTime )
|
|
, m_bInterpolated ( false )
|
|
, m_fCurrRadius ( 0 )
|
|
, m_fGoalRadius ( 0 )
|
|
#ifdef _DEBUG
|
|
, m_bDebugRender ( true )
|
|
#endif
|
|
{
|
|
}
|
|
|
|
SGameCameraPropCollisionAnimator::~SGameCameraPropCollisionAnimator()
|
|
{
|
|
}
|
|
|
|
void SGameCameraPropCollisionAnimator::Animate( DWORD time, SGameCamera& camera )
|
|
{
|
|
if( camera.GetCameraMode() != SGameCamera::CAMERA_GAME_MODE ) return;
|
|
|
|
m_dwTimeDiff = time - m_dwTime;
|
|
m_dwTime = time;
|
|
|
|
CollisionArgument arg;
|
|
|
|
if( _HasMoved( camera ) )
|
|
{
|
|
// prepare argument for responding by collision detection
|
|
arg.radius = m_vCollidableSphereRadius;
|
|
arg.rayPosition = camera.GetCameraTargetPosition();
|
|
arg.rayDirection = camera.GetRelativePosition();
|
|
|
|
// excute collision response
|
|
_ExecuteCollisionResponseWithProp( arg );
|
|
_BackupCollisionArgument( arg );
|
|
}
|
|
else
|
|
{
|
|
arg = m_backupCollidionArgument;
|
|
}
|
|
|
|
// soften collision response
|
|
_SoftenResponse( arg );
|
|
|
|
// locate camera on responsed position
|
|
camera.SetRelativePosition( arg.collidePoint - arg.rayPosition );
|
|
}
|
|
|
|
void SGameCameraPropCollisionAnimator::Render( KViewportObject* pViewport )
|
|
{
|
|
#ifdef _DEBUG
|
|
pViewport->RegisterWire( &m_primitiveWire );
|
|
#endif
|
|
}
|
|
|
|
bool SGameCameraPropCollisionAnimator::_HasMoved( SGameCamera& camera )
|
|
{
|
|
K3DVector vCameraPosition = camera.GetCameraPosition();
|
|
K3DVector vTargetPosition = camera.GetCameraTargetPosition();
|
|
|
|
bool bHasMoved = ( m_vPrevCameraPosition != vCameraPosition ||
|
|
m_vPrevTargetPosition != vTargetPosition ) ? true : false;
|
|
|
|
// backup for next process
|
|
m_vPrevCameraPosition = vCameraPosition;
|
|
m_vPrevTargetPosition = vTargetPosition;
|
|
|
|
return bHasMoved;
|
|
}
|
|
|
|
void SGameCameraPropCollisionAnimator::_ExecuteCollisionResponseWithProp(
|
|
CollisionArgument& argument )
|
|
{
|
|
// debug rendering
|
|
#ifdef _DEBUG
|
|
if( m_bDebugRender )
|
|
{
|
|
m_primitiveWire.Clear();
|
|
m_primitiveWire.AddLine(
|
|
argument.rayPosition,
|
|
argument.rayPosition + argument.rayDirection * 0.9f,
|
|
KColor( 0xffff0000 ) );
|
|
m_primitiveWire.AddLine(
|
|
argument.rayPosition + argument.rayDirection * 0.9f,
|
|
argument.rayPosition + argument.rayDirection,
|
|
KColor( 0xffffffff ) );
|
|
}
|
|
#endif
|
|
|
|
// detect collision point
|
|
if( m_terrain.GetPropLineCrossedPointTwoSidesWithCollisionMesh
|
|
( argument.rayPosition
|
|
, argument.rayPosition + argument.rayDirection
|
|
, argument.nearestT
|
|
, argument.collidePoint
|
|
#ifdef _DEBUG
|
|
, argument.foundPolygon
|
|
#endif
|
|
) )
|
|
{
|
|
argument.found = true;
|
|
argument.collideDirection = argument.nearestT * argument.rayDirection;
|
|
#ifdef _DEBUG
|
|
if( m_bDebugRender )
|
|
{
|
|
m_primitiveWire.AddLine(
|
|
argument.foundPolygon[ 0 ], argument.foundPolygon[ 1 ], KColor( 0xffffffff ) );
|
|
m_primitiveWire.AddLine(
|
|
argument.foundPolygon[ 1 ], argument.foundPolygon[ 2 ], KColor( 0xffffffff ) );
|
|
m_primitiveWire.AddLine(
|
|
argument.foundPolygon[ 2 ], argument.foundPolygon[ 0 ], KColor( 0xffffffff ) );
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
argument.found = false;
|
|
argument.collidePoint = argument.rayPosition + argument.rayDirection;
|
|
argument.collideDirection = argument.rayDirection;
|
|
}
|
|
}
|
|
|
|
void SGameCameraPropCollisionAnimator::_SoftenResponse( CollisionArgument& argument )
|
|
{
|
|
m_fGoalRadius = K3DVectorLength( argument.rayDirection );
|
|
m_fCurrRadius = _GetInterpolatedRadius();
|
|
|
|
if( argument.found )
|
|
{
|
|
float fCollidedRadius = K3DVectorLength( argument.collideDirection );
|
|
if( m_fCurrRadius > fCollidedRadius )
|
|
m_fCurrRadius = fCollidedRadius;
|
|
m_bInterpolated = true;
|
|
}
|
|
else
|
|
{
|
|
if( m_fCurrRadius > m_fGoalRadius )
|
|
{
|
|
m_fCurrRadius = m_fGoalRadius;
|
|
m_bInterpolated = false;
|
|
}
|
|
}
|
|
|
|
K3DVector vInterpolatedPosition = argument.rayDirection;
|
|
vInterpolatedPosition.Normalize() *= m_fCurrRadius;
|
|
argument.collidePoint = argument.rayPosition + vInterpolatedPosition;
|
|
}
|
|
|
|
float SGameCameraPropCollisionAnimator::_GetInterpolatedRadius()
|
|
{
|
|
return _HasInterpolated()
|
|
? m_fCurrRadius + m_fGoalRadius * ( (float)m_dwTimeDiff / m_dwInterpolationTime )
|
|
: m_fGoalRadius;
|
|
}
|
|
|
|
//=======================================================================================
|
|
//
|
|
// SGameCameraTerrainAndPropCollisionAnimator
|
|
//
|
|
|
|
SGameCameraTerrainAndPropCollisionAnimator::SGameCameraTerrainAndPropCollisionAnimator
|
|
( CTerrainMapEngine& terrain
|
|
, SGameLowQualityWater& water
|
|
, const K3DVector& vCollisionRadius
|
|
, DWORD dwInterpolationTime )
|
|
: m_terrain ( terrain )
|
|
, m_water ( water )
|
|
, m_vCollidableSphereRadius ( vCollisionRadius )
|
|
, m_vPrevCameraPosition ( 0, 0, 0 )
|
|
, m_vPrevTargetPosition ( 0, 0, 0 )
|
|
, m_dwTime ( 0 )
|
|
, m_dwInterpolationTime ( dwInterpolationTime )
|
|
, m_bInterpolated ( false )
|
|
, m_fCurrRadius ( 0 )
|
|
, m_fGoalRadius ( 0 )
|
|
#ifdef _DEBUG
|
|
, m_bDebugRender ( true )
|
|
#endif
|
|
{
|
|
}
|
|
|
|
SGameCameraTerrainAndPropCollisionAnimator::~SGameCameraTerrainAndPropCollisionAnimator()
|
|
{
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::Animate( DWORD time, SGameCamera& camera )
|
|
{
|
|
if( camera.GetCameraMode() != SGameCamera::CAMERA_GAME_MODE ) return;
|
|
|
|
m_dwTimeDiff = time - m_dwTime;
|
|
m_dwTime = time;
|
|
|
|
CollisionArgument arg;
|
|
|
|
if( _HasMoved( camera ) )
|
|
{
|
|
// prepare argument for responding by collision detection
|
|
arg.radius = m_vCollidableSphereRadius;
|
|
arg.rayPosition = camera.GetCameraTargetPosition();
|
|
arg.rayDirection = camera.GetRelativePosition();
|
|
|
|
_ExecuteCollisionResponseWithWater( arg, camera );
|
|
|
|
// excute collision response
|
|
_ExecuteCollisionResponseWithTerrain( arg );
|
|
|
|
// adjust ray direction
|
|
arg.rayDirection = arg.collideDirection;
|
|
arg.nearestT = 1.0f; // { [sonador][7.1.7]충돌 처리 개선(Swept Shpere Collision Detection)
|
|
|
|
_ExecuteCollisionResponseWithProp( arg );
|
|
|
|
// backup collision result
|
|
m_backupCollidionArgument = arg;
|
|
}
|
|
else
|
|
{
|
|
arg = m_backupCollidionArgument;
|
|
}
|
|
|
|
m_fGoalRadius = K3DVectorLength( camera.GetRelativePosition() );
|
|
m_fCurrRadius = _GetInterpolatedRadius();
|
|
|
|
// soften collision response
|
|
_SoftenResponse( arg );
|
|
|
|
// locate camera on responsed position
|
|
camera.SetRelativePosition( arg.collidePoint - arg.rayPosition );
|
|
|
|
// { [sonador][7.1.7]충돌 처리 개선(Swept Shpere Collision Detection)
|
|
#ifdef _DEBUG
|
|
if( m_bDebugRender )
|
|
{
|
|
m_primitiveWire.Clear();
|
|
m_primitiveWire.AddLine( arg.rayPosition, arg.rayPosition + arg.rayDirection * 0.9f, KColor( 0xffff0000 ) );
|
|
m_primitiveWire.AddLine( arg.rayPosition + arg.rayDirection * 0.9f, arg.rayPosition + arg.rayDirection, KColor( 0xffffffff ) );
|
|
m_primitiveWire.AddSphere( arg.collidePoint, arg.radius.x, KColor( 0xffffffff ), 32 );
|
|
|
|
if( arg.found )
|
|
{
|
|
m_primitiveWire.AddLine( arg.foundPolygon[ 0 ], arg.foundPolygon[ 1 ], KColor( 0xffffffff ) );
|
|
m_primitiveWire.AddLine( arg.foundPolygon[ 1 ], arg.foundPolygon[ 2 ], KColor( 0xffffffff ) );
|
|
m_primitiveWire.AddLine( arg.foundPolygon[ 2 ], arg.foundPolygon[ 0 ], KColor( 0xffffffff ) );
|
|
}
|
|
|
|
if( !arg.debugLines.empty( ) )
|
|
{
|
|
CollisionArgument::DEBUG_LINE_CONTAINER::iterator it = arg.debugLines.begin( ), itend = arg.debugLines.end( );
|
|
for( ; it != itend; )
|
|
{
|
|
CollisionArgument::DEBUG_LINE_CONTAINER::reference lineBegin = *it++;
|
|
CollisionArgument::DEBUG_LINE_CONTAINER::reference lineEnd = *it++;
|
|
m_primitiveWire.AddLine( lineBegin.first, lineEnd.first, lineBegin.second );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
// }
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::Render( KViewportObject* pViewport )
|
|
{
|
|
#ifdef _DEBUG
|
|
pViewport->RegisterWire( &m_primitiveWire );
|
|
#endif
|
|
}
|
|
|
|
// { sonador 7.1.9 성능 개선
|
|
void SGameCameraTerrainAndPropCollisionAnimator::SetRadius( const K3DVector& vRadius )
|
|
{
|
|
m_vCollidableSphereRadius.Set( vRadius.x, vRadius.y, vRadius.z );
|
|
}
|
|
// }
|
|
|
|
bool SGameCameraTerrainAndPropCollisionAnimator::_HasMoved( SGameCamera& camera )
|
|
{
|
|
K3DVector vCameraPosition = camera.GetCameraPosition();
|
|
K3DVector vTargetPosition = camera.GetCameraTargetPosition();
|
|
|
|
bool bHasMoved = ( m_vPrevCameraPosition != vCameraPosition ||
|
|
m_vPrevTargetPosition != vTargetPosition ) ? true : false;
|
|
|
|
// backup for next process
|
|
m_vPrevCameraPosition = vCameraPosition;
|
|
m_vPrevTargetPosition = vTargetPosition;
|
|
|
|
return bHasMoved;
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::_ExecuteCollisionResponseWithWater( CollisionArgument& argument, SGameCamera& camera )
|
|
{
|
|
// pick water
|
|
/*if( m_water.GetEllipsoidCrossedPoint(
|
|
argument.rayPosition
|
|
, argument.rayDirection
|
|
, argument.radius
|
|
, argument.nearestT
|
|
, vWaterCandidate
|
|
#ifdef _DEBUG
|
|
, argument.foundPolygon
|
|
#endif
|
|
) )
|
|
{
|
|
if( argument.nearestT > 0.0f )
|
|
argument.found = true;
|
|
else
|
|
argument.nearestT = 1.0f;
|
|
}*/
|
|
|
|
float fWaterHeight = -3.0000000e+038f;
|
|
K3DVector vCamera = argument.rayPosition + argument.rayDirection;
|
|
K3DVector vProjXYCamera( vCamera.x, vCamera.y, 0.0f );
|
|
//아래 부분을 없애면, 물 속으로 카메라 들어 가짐.
|
|
if( m_water.GetWaterHeight( vProjXYCamera, fWaterHeight ) )
|
|
fWaterHeight += argument.radius.z;
|
|
|
|
// 카메라가 물 위에 있다.
|
|
if( fWaterHeight > vCamera.z )
|
|
{
|
|
argument.found = true;
|
|
vCamera.z = fWaterHeight;
|
|
// record collision results
|
|
argument.collidePoint = vCamera;
|
|
argument.collideDirection = vCamera - argument.rayPosition;
|
|
// reset collision argument
|
|
argument.rayDirection = argument.collideDirection;
|
|
argument.nearestT = 1.0f;
|
|
|
|
// reset camera && deactive interpolation
|
|
camera.SetRelativePosition( argument.collideDirection );
|
|
m_bInterpolated = false;
|
|
}
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::_ExecuteCollisionResponseWithTerrain( CollisionArgument& argument )
|
|
{
|
|
// { [sonador][7.1.7]충돌 처리 개선(Swept Shpere Collision Detection)
|
|
K3DVector vTerrainCandidate( 0, 0, 0 );
|
|
|
|
// pick terrain
|
|
if( m_terrain.GetTerrainEllipsoidCrossedPoint(
|
|
argument.rayPosition
|
|
, argument.rayDirection
|
|
, argument.radius
|
|
, argument.nearestT
|
|
, vTerrainCandidate
|
|
#ifdef _DEBUG
|
|
, argument.foundPolygon
|
|
, argument.debugLines
|
|
#endif
|
|
) )
|
|
{
|
|
argument.found = true;
|
|
if( argument.nearestT > 0.001f )
|
|
{
|
|
argument.collideDirection = argument.rayDirection * argument.nearestT;
|
|
}
|
|
else
|
|
{
|
|
argument.collideDirection = argument.rayDirection * 0.001f;
|
|
}
|
|
argument.collidePoint = argument.rayPosition + argument.collideDirection;
|
|
}
|
|
else
|
|
{
|
|
argument.collideDirection = argument.rayDirection;
|
|
argument.collidePoint = argument.rayPosition + argument.rayDirection;
|
|
}
|
|
// }
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::_ExecuteCollisionResponseWithProp( CollisionArgument& argument )
|
|
{
|
|
// { [sonador][7.1.7]충돌 처리 개선(Swept Shpere Collision Detection)
|
|
// detect collision point
|
|
K3DVector vCollidePoint;
|
|
if( m_terrain.GetPropEllipsoidCrossedPointTwoSides
|
|
( argument.rayPosition
|
|
, argument.rayPosition + argument.rayDirection
|
|
, argument.radius
|
|
, argument.nearestT
|
|
, vCollidePoint
|
|
#ifdef _DEBUG
|
|
, argument.foundPolygon
|
|
#endif
|
|
) )
|
|
{
|
|
argument.found = true;
|
|
if( argument.nearestT > 0.001f )
|
|
{
|
|
argument.collideDirection = argument.rayDirection * argument.nearestT;
|
|
}
|
|
else
|
|
{
|
|
argument.collideDirection = argument.rayDirection * 0.001f;
|
|
}
|
|
argument.collidePoint = argument.rayPosition + argument.collideDirection;
|
|
}
|
|
// }
|
|
}
|
|
|
|
void SGameCameraTerrainAndPropCollisionAnimator::_SoftenResponse( CollisionArgument& argument )
|
|
{
|
|
if( argument.found )
|
|
{
|
|
float fCollidedRadius = K3DVectorLength( argument.collideDirection );
|
|
if( m_fCurrRadius > fCollidedRadius )
|
|
m_fCurrRadius = fCollidedRadius;
|
|
m_bInterpolated = true;
|
|
}
|
|
else
|
|
{
|
|
if( m_fCurrRadius > m_fGoalRadius )
|
|
{
|
|
m_fCurrRadius = m_fGoalRadius;
|
|
m_bInterpolated = false;
|
|
}
|
|
}
|
|
|
|
K3DVector vInterpolatedPosition = argument.collideDirection;
|
|
if( !vInterpolatedPosition.IsZero( ) )
|
|
{
|
|
vInterpolatedPosition.Normalize() *= m_fCurrRadius;
|
|
}
|
|
argument.collidePoint = argument.rayPosition + vInterpolatedPosition;
|
|
}
|
|
|
|
float SGameCameraTerrainAndPropCollisionAnimator::_GetInterpolatedRadius()
|
|
{
|
|
return _HasInterpolated()
|
|
? m_fCurrRadius + m_fGoalRadius * ( (float)m_dwTimeDiff / m_dwInterpolationTime )
|
|
: m_fGoalRadius;
|
|
} |