Files
2026-06-01 12:46:52 +02:00

269 lines
7.6 KiB
C++

#pragma once
#include "SGameObject.h"
#include "K3DBound.h"
class K3DCamera;
class SGameCameraWork;
// { [sonador][COLLIDABLE_CAMERA]
class SGameCamera;
class IGameCameraAnimator
{
public:
// sonador 7.1.9 성능 개선
enum TYPE {
TERRAIN_HEIGHT_RESPONSE,
TERRAIN_COLLISION_RESPONSE,
TERRAIN_PROP_COLLISION_RESPONSE,
TERRAIN_AND_PROP_COLLISION_RESPONSE,
};
virtual ~IGameCameraAnimator() {}
virtual void Animate( DWORD time, SGameCamera& camera ) = 0;
virtual void Render( KViewportObject* pViewport ) = 0;
virtual TYPE GetType() = 0;
};
// }
class SGameCamera : public SGameObject
{
/// 기본 동작
enum
{
MODE_NONE = 0,
MODE_ZOOM,
MODE_PAN,
MODE_TURN,
MODE_ELEVATION,
};
/// 추가 이펙트 동작
enum
{
EFFECT_NONE = 0,
EFFECT_01,
EFFECT_02,
};
/// 카메라 바닥 밑으로 내릴때의 거동
enum {
MODE_APPROACH = 0 ///< 캐릭터쪽으로 접근. Lineage식
, MODE_LOOKUP ///< 위를 올려다 봄. WoW식
, MODE_LINEAGE = MODE_APPROACH
, MODE_WOW = MODE_LOOKUP
};
public:
// New Camera parameters
static const float PI;
static const float CAMERA_ELEVATION_BASE; ///< 바닥으로부터의 최소 높이
static const float CAMERA_ROTATION_CONSTANT; ///< 마우스 x값에 대한 좌우 회전변위
static const float CAMERA_ELEVATION_CONSTANT; ///< 마우스 y값에 대한 상하 이동 변위
static const float CAMERA_DOLLY_CONSTANT; ///< 마우스 wheel값에 대한 dolly변위
static const float CAMERA_DISTANCE_ZOOM_MIN; ///< Zoom(마우스 휠)으로 이동했을 때 가까워질 수 있는 최소값
static const float CAMERA_DISTANCE_ZOOM_BASE;
static const float CAMERA_DISTANCE_ZOOM_MIN_MAX;
static const float CAMERA_DISTANCE_MIN;
static const float CAMERA_DISTANCE_MAX;
static const DWORD CAMERA_ZOOM_IN_OUT_TIME;
public:
SGameCamera( K3DCamera* pCamera, class SGame * pGame ) ;
~SGameCamera();
//기능 요구 사항
/// 최소 줌으로 : radius=MINRADIUS
void SetMinZoom();
/// 북향 45' : elevationfactor=1.0, angle=1.5*PI
void SetNorth45();
/** Zoom (실제로는 dolly... K3DCamera::Zoom()도 zoom이 아니라 dolly다 -.-)
zDelta : "적당한 값". 실제로는mouse wheel입력값 */
void Zoom(short zDelta);
//
// 카메라 거동 제어용 파라미터 함수들
//
/// 회전위치값. XY평면상에서의 각도
void SetDirection(float radianDirection)
{ m_fXYAngle=radianDirection; }
/// height = ground_height + (xy-distance * elevationFactor). 즉 1.0이면 (평면지형에서) 45도
void SetElevation(float elevationFactor)
{ m_fElevationFactor=elevationFactor; }
/// Absolute XY distance (zoom!)
void SetDistance(float distance)
{ m_fRadius=distance; }
//
// Note:
// x=distance*cos(radianDirection);
// y=distance*sin(radianDirection);
// z=distance * elevationFactor;
//
/// 좌우 회전 변위값
void Rotate(float radianDelta);
/// 상하 이동 변위값
void Elevate(float elevationFactorDelta);
/// 평면거리 변위값
void Distance(float distanceDelta);
/// 마우스 x값에 따라 좌우 회전
void Turn(int turnvalue);
/// 마우스 y값에 따라 상하 이동
void Updown(int elevationValue);
/// 마우스 휠에 따라 distance조절 (Zoom()과 같은 기능)
void Dolly(int delta);
/** 카메라 타겟점 위치
카메라 이동 target. 실제로는 약간 늦게 따라감 */
void SetTargetPosition(K3DVector pos);
// 카메라 거동 모드
/// MODE_APPROACH / MODE_LOOKUP, 또는, MODE_LINEAGE / MODE_WOW
void SetMoveMode(int mode) { m_nCameraMoveMode=mode; }
int GetMoveMode() { return m_nCameraMoveMode; }
// 카메라 terrain following on/off
bool GetTerrainFollowing() { return m_bFollowTerrain; }
void SetTerrainFollowing(bool bFollowOn) { m_bFollowTerrain=bFollowOn; }
// 파라미터로부터 각종 계산. Get...부르기 전에 꼭 불러줘야 한다.
/// fBaseHeight : 카메라가 있는 지점의 Z위치. relativeCameraPosition.z의 기준값
void CalculateCamera(float fBaseHeight = 0.0f, bool bBaseHeight = false);
/// 카메라 좌표와 타겟 위치를 m_pCamera에 설정
void ApplyCameraPositions();
//
// 실제 카메라 위치 가져오는 함수
//
/// World상의 카메라 위치
K3DVector GetCameraPosition() const;
/// World상의 타겟 위치
K3DVector GetCameraTargetPosition() const;
// { [sonador][COLLIDABLE_CAMERA]
float GetCurrentRadius() const { return m_fCurRadius; }
float GetRadius() const { return m_fRadius; }
const K3DMatrix& GetRotationMatrix() const { return m_matCam; }
const K3DVector& GetRelativePosition() const { return m_relativeCameraPosition; }
void SetRelativePosition( const K3DVector& position )
{ m_relativeCameraPosition = position; }
bool IsDistanceChanged() const { return m_bDistanceDelta; }
float GetDistanceDelta() const { return m_fDistanceDelta; }
// }
bool IsVibrating() { return (m_nEffect != EFFECT_NONE); /* ? true : false;*/ }
void FileTextOut( FILE* pF, bool bDetail );
void FileTextIn( char *pBuf, bool bDetail );
void SetTargetZOffSet( float fZ );
void ResetDistanceDelta();
void SetDollyConstant( float fDollyConstant );
void DefaultDollyConstant();
float getAngleX() const { return m_fAngleX; }
float getAngleZ() const { return m_fAngleZ; } /// 2011.04.21 - prodongi
enum CAMERA_MODE
{
CAMERA_GAME_MODE = 0,
CAMERA_EVSCENE_MODE,
CAMERA_STANDING_MODE,
CAMERA_ENDING_MODE,
};
protected:
K3DVector m_relativeCameraPosition; ///< target중심 카메라 상대위치
// 카메라 파라미터
int m_nCameraMoveMode; ///< Lineage모드 or Wow모드
bool m_bFollowTerrain; ///< 바닥 따라간다/안따라간다
float m_fRadius;
float m_fPrevRadius;
float m_fCurRadius;
DWORD m_dwLerpTime;
float m_fDollyConstant;
float m_fXYAngle;
float m_fElevationFactor;
K3DVector m_cameraPosition; ///< targetPositionCurrent + calculated_relative_position()
K3DVector m_targetPositionDestination; ///< 카메라가 봐야 할 위치
K3DVector m_targetPositionCurrent; ///< 현재 카메라가 보고 있는 위치 (destination을 약간 늦게 따라감)
float m_fTargetZOffSet;
K3DMatrix m_matCam;
float m_fAngleX;
float m_fAngleZ;
float m_fDistanceDelta;
bool m_bDistanceDelta;
public:
//상하 각지면서 이동.
//위치 조절
//지면 충돌 시 높이 조절 처리~
//뷰벡터 변경 처리
virtual bool Process( DWORD time, unsigned long uProcessBitVector=0 );
virtual bool Render( unsigned long uRenderBitVector, KViewportObject** ppViewportList, int nViewportCount );
/// 바로 처리
virtual void SendGameMsg( struct SGameMessage * msg );
K3DCamera* GetCamera() { return m_pCamera; }
void SetCameraWork( SGameCameraWork* pCameraWork );
CAMERA_MODE GetCameraMode() { return m_nCameraMode; }
void SetCameraMode( CAMERA_MODE nCameraMode ) { m_nCameraMode = nCameraMode; }
void StopCameraWork();
bool IsStopCameraWork();
protected:
K3DCamera * m_pCamera;
class SGame * m_pGame;
K3DBoundRotCube m_BoundCube;
int m_nMode;
short m_nDelta;
DWORD m_dwStartTime;
DWORD m_dwTime;
DWORD m_dwPrevProcessTime;
int m_nEffect;
DWORD m_dwCameraVibrateTimeDueTime; ///< 시작 시간
DWORD m_dwCameraVibrateVar;
float m_fDeltaX;
float m_fDeltaY;
SGameCameraWork* m_pCameraWork;
CAMERA_MODE m_nCameraMode;
// { [sonador][COLLIDABLE_CAMERA]
public:
void ProcessAnimator();
protected:
typedef std::vector< IGameCameraAnimator* > t_animator_vector;
t_animator_vector m_animators;
public:
void AddAnimator( IGameCameraAnimator& animator );
void RemoveAnimator( IGameCameraAnimator& animator );
void RemoveAllAnimator();
// }
};