client/UserInterface/CameraProcedure.cpp

352 lines
10 KiB
C++

#include "StdAfx.h"
#include "PythonBackground.h"
#include "../eterlib/Camera.h"
//////////////////////////////////////////////////////////////////////////
// ¸ŢźźÁö
extern void SetHeightLog(bool isLog);
float CCamera::CAMERA_MIN_DISTANCE = 200.0f;
float CCamera::CAMERA_MAX_DISTANCE = 2500.0f;
void CCamera::ProcessTerrainCollision()
{
CPythonBackground & rPythonBackground = CPythonBackground::Instance();
D3DXVECTOR3 v3CollisionPoint;
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kTargetToCameraBottomRay, &v3CollisionPoint))
{
SetCameraState(CAMERA_STATE_CANTGODOWN);
D3DXVECTOR3 v3CheckVector = m_v3Eye - 2.0f * m_fTerrainCollisionRadius * m_v3Up;
v3CheckVector.z = rPythonBackground.GetHeight(floorf(v3CheckVector.x), floorf(v3CheckVector.y));
D3DXVECTOR3 v3NewEye = v3CheckVector + 2.0f * m_fTerrainCollisionRadius * m_v3Up;
if (v3NewEye.z > m_v3Eye.z)
{
//printf("ToCameraBottom(%f, %f, %f) TCR %f, UP(%f, %f, %f), new %f > old %f",
// v3CheckVector.x, v3CheckVector.y, v3CheckVector.z,
// m_fTerrainCollisionRadius,
// m_v3Up.x, m_v3Up.y, m_v3Up.z,
// v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
/*
SetCameraState(CAMERA_STATE_NORMAL);
D3DXVECTOR3 v3NewEye = v3CollisionPoint;
SetEye(v3NewEye);
*/
}
else
SetCameraState(CAMERA_STATE_NORMAL);
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraBottomToTerrainRay, &v3CollisionPoint))
{
SetCameraState(CAMERA_STATE_CANTGODOWN);
if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 2.0f * m_fTerrainCollisionRadius)
{
D3DXVECTOR3 v3NewEye = v3CollisionPoint + 2.0f * m_fTerrainCollisionRadius * m_v3Up;
//printf("CameraBottomToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
}
else
SetCameraState(CAMERA_STATE_NORMAL);
/*
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraFrontToTerrainRay, &v3CollisionPoint))
{
if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 4.0f * m_fTerrainCollisionRadius)
{
D3DXVECTOR3 v3NewEye = v3CollisionPoint - 4.0f * m_fTerrainCollisionRadius * m_v3View;
//printf("CameraFrontToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
}
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraBackToTerrainRay, &v3CollisionPoint))
{
if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < m_fTerrainCollisionRadius)
{
D3DXVECTOR3 v3NewEye = v3CollisionPoint + m_fTerrainCollisionRadius * m_v3View;
//printf("CameraBackToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
}
// Left
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraLeftToTerrainRay, &v3CollisionPoint))
{
SetCameraState(CAMERA_STATE_CANTGOLEFT);
if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius)
{
D3DXVECTOR3 v3NewEye = v3CollisionPoint + 3.0f * m_fTerrainCollisionRadius * m_v3Cross;
//printf("CameraLeftToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
}
else
SetCameraState(CAMERA_STATE_NORMAL);
// Right
if (rPythonBackground.GetPickingPointWithRayOnlyTerrain(m_kCameraRightToTerrainRay, &v3CollisionPoint))
{
SetCameraState(CAMERA_STATE_CANTGORIGHT);
if (D3DXVec3Length(&(m_v3Eye - v3CollisionPoint)) < 3.0f * m_fTerrainCollisionRadius)
{
D3DXVECTOR3 v3NewEye = v3CollisionPoint - 3.0f * m_fTerrainCollisionRadius * m_v3Cross;
//printf("CameraRightToTerrain new %f > old %f", v3NewEye.z, m_v3Eye.z);
SetEye(v3NewEye);
}
}
else
SetCameraState(CAMERA_STATE_NORMAL);
*/
}
struct CameraCollisionChecker
{
bool m_isBlocked;
std::vector<D3DXVECTOR3>* m_pkVct_v3Position;
CDynamicSphereInstance * m_pdsi;
CameraCollisionChecker(CDynamicSphereInstance * pdsi, std::vector<D3DXVECTOR3>* pkVct_v3Position) : m_pdsi(pdsi), m_pkVct_v3Position(pkVct_v3Position), m_isBlocked(false)
{
}
void operator () (CGraphicObjectInstance* pOpponent)
{
if (pOpponent->CollisionDynamicSphere(*m_pdsi))
{
m_pkVct_v3Position->push_back(pOpponent->GetPosition());
m_isBlocked = true;
}
}
};
void CCamera::ProcessBuildingCollision()
{
float fMoveAmountSmall = 2.0f;
float fMoveAmountLarge = 4.0f;
D3DXVECTOR3 v3CheckVector;
CDynamicSphereInstance s;
s.fRadius = m_fObjectCollisionRadius;
s.v3LastPosition = m_v3Eye;
Vector3d aVector3d;
aVector3d.Set(m_v3Eye.x, m_v3Eye.y, m_v3Eye.z);
// ľÚ
CCullingManager & rkCullingMgr = CCullingManager::Instance();
{
v3CheckVector = m_v3Eye - m_fObjectCollisionRadius * m_v3View;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
if (m_v3AngularVelocity.y > 0.0f)
{
m_v3AngularVelocity.y = 0.0f;
m_v3AngularVelocity.z += fMoveAmountLarge;
}
// m_v3AngularVelocity.y = fMAX(fMoveAmountSmall, m_v3AngularVelocity.y);
//// m_v3AngularVelocity.y += fMoveAmountSmall;
if (kVct_kPosition.size() > 1)
{
// m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z);
m_v3AngularVelocity.z += fMoveAmountSmall;
}
else
{
D3DXVec3Cross(&v3CheckVector, &(kVct_kPosition[0] - m_v3Eye), &m_v3View);
float fDot = D3DXVec3Dot(&v3CheckVector, &m_v3Up);
if (fDot < 0)
{
// m_v3AngularVelocity.x = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.x);
m_v3AngularVelocity.x -= fMoveAmountSmall;
}
else if(fDot > 0)
{
// m_v3AngularVelocity.x = fMAX(fMoveAmountSmall, m_v3AngularVelocity.x);
m_v3AngularVelocity.x += fMoveAmountSmall;
}
else
{
// m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z);
m_v3AngularVelocity.z += fMoveAmountSmall;
}
}
}
}
// Ŕ§
{
v3CheckVector = m_v3Eye + 2.0f * m_fObjectCollisionRadius * m_v3Up;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
m_v3AngularVelocity.z = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.y);
// m_v3AngularVelocity.z -= 1.0f;
}
}
// ÁÂ
{
v3CheckVector = m_v3Eye + 3.0f * m_fObjectCollisionRadius * m_v3Cross;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
if (m_v3AngularVelocity.x > 0.0f)
{
m_v3AngularVelocity.x = 0.0f;
m_v3AngularVelocity.y += fMoveAmountLarge;
}
}
}
// żě
{
v3CheckVector = m_v3Eye - 3.0f * m_fObjectCollisionRadius * m_v3Cross;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
if (m_v3AngularVelocity.x < 0.0f)
{
m_v3AngularVelocity.x = 0.0f;
m_v3AngularVelocity.y += fMoveAmountLarge;
}
}
}
// žĆˇĄ
{
v3CheckVector = m_v3Eye - 2.0f * m_fTerrainCollisionRadius * m_v3Up;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
if (m_v3AngularVelocity.z < 0.0f)
{
m_v3AngularVelocity.z = 0.0f;
m_v3AngularVelocity.y += fMoveAmountLarge;
}
}
}
// žŐ
{
v3CheckVector = m_v3Eye + 4.0f * m_fObjectCollisionRadius * m_v3View;
s.v3Position = v3CheckVector;
std::vector<D3DXVECTOR3> kVct_kPosition;
CameraCollisionChecker kCameraCollisionChecker(&s, &kVct_kPosition);
rkCullingMgr.ForInRange(aVector3d, m_fObjectCollisionRadius, &kCameraCollisionChecker);
bool bCollide = kCameraCollisionChecker.m_isBlocked;
if (bCollide)
{
if (m_v3AngularVelocity.y < 0.0f)
{
m_v3AngularVelocity.y = 0.0f;
m_v3AngularVelocity.z += fMoveAmountLarge;
}
if (kVct_kPosition.size() > 1)
{
// m_v3AngularVelocity.z = fMAX(fMoveAmountLarge, m_v3AngularVelocity.z);
m_v3AngularVelocity.z += fMoveAmountLarge;
}
else
{
D3DXVec3Cross(&v3CheckVector, &(kVct_kPosition[0] - m_v3Eye), &m_v3View);
float fDot = D3DXVec3Dot(&v3CheckVector, &m_v3Up);
if (fDot < 0)
{
// m_v3AngularVelocity.x = fMIN(-fMoveAmountSmall, m_v3AngularVelocity.x);
m_v3AngularVelocity.x -= fMoveAmountSmall;
}
else if(fDot > 0)
{
// m_v3AngularVelocity.x = fMAX(fMoveAmountSmall, m_v3AngularVelocity.x);
m_v3AngularVelocity.x += fMoveAmountSmall;
}
else
{
// m_v3AngularVelocity.z = fMAX(fMoveAmountSmall, m_v3AngularVelocity.z);
m_v3AngularVelocity.z += fMoveAmountSmall;
}
}
}
}
}
void CCamera::Update()
{
// ProcessBuildingCollision();
RotateEyeAroundTarget(m_v3AngularVelocity.z, m_v3AngularVelocity.x);
float fNewDistance=fMAX(CAMERA_MIN_DISTANCE, fMIN( CAMERA_MAX_DISTANCE, GetDistance() - m_v3AngularVelocity.y ) );
SetDistance(fNewDistance);
if (m_bProcessTerrainCollision)
ProcessTerrainCollision();
m_v3AngularVelocity *= 0.5f;
if (fabs(m_v3AngularVelocity.x) < 1.0f)
m_v3AngularVelocity.x = 0.0f;
if (fabs(m_v3AngularVelocity.y) < 1.0f)
m_v3AngularVelocity.y = 0.0f;
if (fabs(m_v3AngularVelocity.z) < 1.0f)
m_v3AngularVelocity.z = 0.0f;
const float CAMERA_MOVABLE_DISTANCE = CAMERA_MAX_DISTANCE - CAMERA_MIN_DISTANCE;
const float CAMERA_TARGET_DELTA = CAMERA_TARGET_FACE - CAMERA_TARGET_STANDARD;
float fCameraCurMovableDistance=CAMERA_MAX_DISTANCE - GetDistance();
float fNewTargetHeight = CAMERA_TARGET_STANDARD + CAMERA_TARGET_DELTA * fCameraCurMovableDistance / CAMERA_MOVABLE_DISTANCE;
SetTargetHeight(fNewTargetHeight);
// Cinematic
#ifdef __20040725_CAMERA_WORK__
m_MovementPosition += m_MovementSpeed;
if (0.0f != m_MovementPosition.m_fViewDir)
MoveFront(m_MovementPosition.m_fViewDir);
if (0.0f != m_MovementPosition.m_fCrossDir)
MoveAlongCross(m_MovementPosition.m_fCrossDir);
if (0.0f != m_MovementPosition.m_fUpDir)
MoveVertical(m_MovementPosition.m_fUpDir);
#endif
}