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

534 lines
14 KiB
C++

// K3DCamera.cpp: implementation of the K3DCamera class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "K3DCamera.h"
#include "KViewport.h"
#include <toolkit/XStringUtil.h>
//#include "KRenderDeviceDX.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
K3DCamera::K3DCamera()
{
Reset();
}
K3DCamera::~K3DCamera()
{
}
void K3DCamera::Reset()
{
m_bIsRightHandCoordinate = true;
m_bIsPerspective = true;
// set FOV for 24mm Lens view
// m_fFOV = 24.f / 180.f * 3.141592f;
m_fFOV = 40.f / 180.f * 3.141592f;
m_fDistance = 150.0f;
m_fElavation = 1.57f / 2.0f;
m_fXPos = 0.0f;
m_fYPos = -m_fDistance * sinf(m_fElavation);
m_fZPos = m_fDistance * cosf(m_fElavation);
m_fOrgXPos = m_fXPos;
m_fOrgYPos = m_fYPos;
m_fOrgZPos = m_fZPos;
m_fTXPos = 0.0f; m_fTYPos = 0.0f; m_fTZPos = 0.0f;
m_fZoomDelta = 15.0f;
m_dxvtUp = K3DVector(0.0f,0.0f, 1.0f);
m_fMinDistance = 0.f;
m_bUseMinDistance = false;
m_fValue = 0.f;
}
K3DMatrix * K3DCamera::GetViewMatrix()
{
K3DVector vtCam = K3DVector(m_fXPos, m_fYPos, m_fZPos);
K3DVector vtTar = K3DVector(m_fTXPos, m_fTYPos, m_fTZPos);
if(m_bIsRightHandCoordinate)
K3DMatrixLookAtRH(m_MatView, vtCam, vtTar, m_dxvtUp);
else
K3DMatrixLookAtLH(m_MatView, vtCam, vtTar, m_dxvtUp);
return &m_MatView;
}
//K3DMatrix *K3DCamera::GetProjMatrix()
//{
// return &m_matProjection;
//}
void K3DCamera::Point(float fXPos, float fYPos, float fZPos, float fTXPos, float fTYPos, float fTZPos)
{
m_fXPos = fXPos; m_fYPos = fYPos; m_fZPos = fZPos;
m_fOrgXPos = m_fXPos; m_fOrgYPos = m_fYPos; m_fOrgZPos = m_fZPos;
m_fTXPos = fTXPos; m_fTYPos = fTYPos; m_fTZPos = fTZPos;
}
void K3DCamera::Elevation(float fAngle)
{
//K3DVector vtView = GetViewVector();
K3DVector vtView = GetOrgViewVector();
Normalize(vtView);
//무한 검사
K3DVector zVec(0,0,1);
K3DVALUE value1 = DotProduct( zVec, vtView );
// _oprint( "angle : %f, value : %f\n", fAngle, value1 );
if( value1 < -0.98f )
{
if( fAngle < 0.0f ) return;
}
if( value1 > 0.98f )
{
if( fAngle > 0.0f ) return;
}
if( ( value1 < 0.0f && fAngle < 0.0f ) || ( value1 > 0.0f && fAngle > 0.0f ) )
{
float fOrgAngle = acosf( value1 );
if( fOrgAngle > K3D_PI * 0.5f ) fOrgAngle = K3D_PI - fOrgAngle;
float fAbsAngle = fabsf( fAngle );
if( fOrgAngle - fAbsAngle < acosf( 0.98f ) ) fAbsAngle = fOrgAngle - acosf( 0.98f );
if( fAngle > 0.0f) fAngle = fAbsAngle;
else fAngle = -fAbsAngle;
}
//if( value1 < -0.95f ) //한계치 근사 인가?
//{
// if( fAngle < 0.f ) return;
//}
//if( value1 > 0.95f )
//{
// if( fAngle > 0.f ) return;
//}
//// 시간 없어서 임시로.. 나중에 고치자 by blackfish
//vtView = GetOrgViewVector();
//Normalize(vtView);
////무한 검사
//value1 = DotProduct( zVec, vtView );
//// _oprint( "angle : %f, value : %f\n", fAngle, value1 );
//if( value1 < -0.95f ) //한계치 근사 인가?
//{
// if( fAngle < 0.f ) return;
//}
//if( value1 > 0.95f )
//{
// if( fAngle > 0.f ) return;
//}
m_fValue = value1;
vtView.z = 0.0f;
Normalize(vtView);
K3DVector vtUp = GetUpVector();
Normalize(vtUp);
K3DVector vtRes;
vtUp = K3DVector(0,0,1);
vtRes = CrossProduct( vtView, vtUp );
K3DMatrix mat( vtRes, vtUp, vtView );
K3DMatrix invMat;
K3DMatrixInverse(invMat, mat);
K3DMatrix rotmat;
K3DMatrixRotationYawPitchRoll( rotmat, 0, -fAngle, 0 );
K3DMatrixMultiply( invMat, invMat, rotmat );
//RotateMatrix(invMat,0, -fAngle,0);
K3DMatrix resMat;
K3DMatrixMultiply( resMat, invMat, mat);
//K3DVector v;
//m_fXPos -= m_fTXPos; m_fYPos -= m_fTYPos; m_fZPos -= m_fTZPos;
//v = K3DVector(m_fXPos, m_fYPos, m_fZPos);
//K3DVectorTransform(v,v , resMat );
//m_fXPos = v.x + m_fTXPos; m_fYPos = v.y + m_fTYPos; m_fZPos = v.z + m_fTZPos;
//
//m_fOrgXPos -= m_fTXPos; m_fOrgYPos -= m_fTYPos; m_fOrgZPos -= m_fTZPos;
//v = K3DVector(m_fOrgXPos, m_fOrgYPos, m_fOrgZPos);
//K3DVectorTransform(v,v , resMat );
//m_fOrgXPos = v.x + m_fTXPos; m_fOrgYPos = v.y + m_fTYPos; m_fOrgZPos = v.z + m_fTZPos;
K3DVector v;
m_fOrgXPos -= m_fTXPos; m_fOrgYPos -= m_fTYPos; m_fOrgZPos -= m_fTZPos;
v = K3DVector(m_fOrgXPos, m_fOrgYPos, m_fOrgZPos);
K3DVectorTransform(v,v , resMat );
m_fOrgXPos = v.x + m_fTXPos; m_fOrgYPos = v.y + m_fTYPos; m_fOrgZPos = v.z + m_fTZPos;
m_fXPos = m_fOrgXPos;
m_fYPos = m_fOrgYPos;
m_fZPos = m_fOrgZPos;
}
void K3DCamera::Turn(float fAngle)
{
//K3DVector vtView = GetViewVector();
K3DVector vtView = GetOrgViewVector();
////무한 검사
//K3DVector zVec(0,0,1);
//K3DVALUE value1 = DotProduct( zVec, vtView );
//if( value1 < -0.95f ) return;
//if( value1 > 0.95f ) return;
//vtView = GetOrgViewVector();
//// 시간 없어서 임시로.. 나중에 고치자 by blackfish
////무한 검사
//value1 = DotProduct( zVec, vtView );
//if( value1 < -0.95f ) return;
//if( value1 > 0.95f ) return;
vtView.z = 0.0f;
Normalize(vtView);
K3DVector vtUp = GetUpVector();
Normalize(vtUp);
K3DVector vtRes;
vtRes = CrossProduct( vtView, vtUp );
K3DMatrix mat( vtRes, vtUp, vtView );
K3DMatrix invMat;
K3DMatrixInverse(invMat,mat);
K3DMatrix rotmat;
K3DMatrixRotationYawPitchRoll( rotmat, -fAngle, 0, 0 );
K3DMatrixMultiply( invMat, invMat, rotmat );
K3DMatrix resMat;
K3DMatrixMultiply( resMat, invMat, mat);
//K3DVector v;
//m_fXPos -= m_fTXPos; m_fYPos -= m_fTYPos; m_fZPos -= m_fTZPos;
//v = K3DVector(m_fXPos, m_fYPos, m_fZPos);
//K3DVectorTransform(v,v , resMat );
//m_fXPos = v.x + m_fTXPos; m_fYPos = v.y + m_fTYPos; m_fZPos = v.z + m_fTZPos;
//
//m_fOrgXPos -= m_fTXPos; m_fOrgYPos -= m_fTYPos; m_fOrgZPos -= m_fTZPos;
//v = K3DVector(m_fOrgXPos, m_fOrgYPos, m_fOrgZPos);
//K3DVectorTransform(v,v , resMat );
//m_fOrgXPos = v.x + m_fTXPos; m_fOrgYPos = v.y + m_fTYPos; m_fOrgZPos = v.z + m_fTZPos;
K3DVector v;
m_fOrgXPos -= m_fTXPos; m_fOrgYPos -= m_fTYPos; m_fOrgZPos -= m_fTZPos;
v = K3DVector(m_fOrgXPos, m_fOrgYPos, m_fOrgZPos);
K3DVectorTransform(v,v , resMat );
m_fOrgXPos = v.x + m_fTXPos; m_fOrgYPos = v.y + m_fTYPos; m_fOrgZPos = v.z + m_fTZPos;
m_fXPos = m_fOrgXPos;
m_fYPos = m_fOrgYPos;
m_fZPos = m_fOrgZPos;
}
void K3DCamera::Pan(float dx, float dy, float dz)
{
//m_fXPos += dx;
//m_fYPos += dy;
//m_fZPos += dz;
m_fOrgXPos += dx;
m_fOrgYPos += dy;
m_fOrgZPos += dz;
m_fXPos = m_fOrgXPos;
m_fYPos = m_fOrgYPos;
m_fZPos = m_fOrgZPos;
m_fTXPos += dx;
m_fTYPos += dy;
m_fTZPos += dz;
}
/// 2010.11.11 - prodongi
void K3DCamera::PanWithCamDir(float dx, float dy, float dz)
{
K3DVector vtView = GetViewVector();
K3DVector vtUp = GetUpVector();
K3DVector vtRes = CrossProduct(vtView, vtUp);
Normalize(vtRes);
vtUp = CrossProduct(vtRes, vtView);
Normalize(vtUp);
float x, y, z;
x = (dx*vtRes.x + dy*vtUp.x + dz*vtView.x) * .1f;
y = (dx*vtRes.y + dy*vtUp.y + dz*vtView.y) * .1f;
z = (dx*vtRes.z + dy*vtUp.z + dz*vtView.z) * .1f;
Pan(x,y,z);
}
void K3DCamera::Zoom(float dist)
{
if( m_bUseMinDistance )
{
//최소 근접거리보다 작으면, Zoom In 하지 않는다.
if( dist<0 )
{
if( (GetDistance() + dist) < m_fMinDistance )
return;
}
}
K3DVector vtView = GetViewVector();
Normalize(vtView);
m_fDistance -= dist;
//m_fXPos -= vtView.x*dist;
//m_fYPos -= vtView.y*dist;
//m_fZPos -= vtView.z*dist;
m_fOrgXPos -= vtView.x*dist;
m_fOrgYPos -= vtView.y*dist;
m_fOrgZPos -= vtView.z*dist;
m_fXPos = m_fOrgXPos;
m_fYPos = m_fOrgYPos;
m_fZPos = m_fOrgZPos;
GetDistance();
}
void K3DCamera::FileTextOut( FILE* pF )
{
if( pF )
{
fprintf( pF, "FOV|%f|" , this->m_fFOV );
fprintf( pF, "XPOS|%f|" , this->m_fXPos );
fprintf( pF, "YPOS|%f|" , this->m_fYPos );
fprintf( pF, "ZPos|%f|" , this->m_fZPos );
fprintf( pF, "ORGXPOS|%f|" , this->m_fOrgXPos );
fprintf( pF, "ORGYPOS|%f|" , this->m_fOrgYPos );
fprintf( pF, "ORGZPOS|%f|" , this->m_fOrgZPos );
fprintf( pF, "TXPOS|%f|" , this->m_fTXPos );
fprintf( pF, "TYPOS|%f|" , this->m_fTYPos );
fprintf( pF, "TZPOS|%f|" , this->m_fTZPos );
fprintf( pF, "ZOOMDELTA|%f|", this->m_fZoomDelta );
fprintf( pF, "ELAVATION|%f|" , this->m_fElavation );
fprintf( pF, "DISTANCE|%f|" , this->m_fDistance );
fprintf( pF, "USEMINDISTANCE|%d|", (this->m_bUseMinDistance == true) ? 1 : 0 );
fprintf( pF, "MINDISTANCE|%f|" , this->m_fMinDistance );
fprintf( pF, "VALUE|%f|" , this->m_fValue );
}
}
void K3DCamera::FileTextIn( char *pBuf )
{
if( pBuf )
{
std::vector< std::string > vString;
XStringUtil::Split( pBuf, vString, "|\r\n" );
int nLoop = (int)vString.size();
if( nLoop >= 32 )
for( int i(0); 1>i; i++ )
{
vString[i++].c_str(); //FOV
m_fFOV = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //XPOS
m_fXPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //YPOS
m_fYPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ZPos
m_fZPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ORGXPOS
m_fOrgXPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ORGYPOS
m_fOrgYPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ORGZPOS
m_fOrgZPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //TXPOS
m_fTXPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //TYPOS
m_fTYPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //TZPOS
m_fTZPos = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ZOOMDELTA
m_fZoomDelta = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //ELAVATION
m_fElavation = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //DISTANCE
m_fDistance = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //USEMINDISTANCE
m_bUseMinDistance = (atoi( vString[i++].c_str() ) == 1 ) ? true : false;
vString[i++].c_str(); //MINDISTANCE
m_fMinDistance = (float)atof( vString[i++].c_str() );
vString[i++].c_str(); //VALUE
m_fValue = (float)atof( vString[i++].c_str() );
}
}
}
/*void K3DCamera::Render( KViewportObject *viewport, bool bOffSet )
{
//K3DMatrixMultiply(m_MatView, m_MatTrans, m_MatRotate);
K3DVector vtCam = K3DVector(m_fXPos, m_fYPos, m_fZPos);
K3DVector vtTar = K3DVector(m_fTXPos, m_fTYPos, m_fTZPos);
K3DMatrixLookAtRH(m_MatView, vtCam, vtTar,m_dxvtUp);
K3DMatrixPerspectiveFovRH( &m_matProjection, m_fFOV, viewport->GetVertexAspect(), viewport->GetNearClip(), viewport->GetFarClip() );
viewport->SetViewTransform( vtCam, vtTar, m_MatView, m_matProjection );
//Speed Tree
K3DMatrixIdentity( m_matBlendShader );
K3DMatrixMultiply(&m_matBlendShader, &m_MatView, &m_matProjection);
}*/
/*void K3DCamera::GetLineFromScreen( KViewportObject *pViewport, int scrx, int scry, K3DVector *vNear, K3DVector *vFar ) const
{
pViewport->GetCameraSegmentView(scrx, scry, *vNear, *vFar);
}
void K3DCamera::GetScreenPosition(KViewportObject *pViewport, const K3DVector & vWorldPos, int *pPosX, int *pPosY)
{
pViewport->PickScreenPoint(vWorldPos, *pPosX, *pPosY);
}
void K3DCamera::GetFrustumCube( KViewportObject* pViewport, const KViewportStruct& rViewPort, int nMarginX, int nMarginY, K3DVertex* pFrustumCube ) const
{
int nLeft = (int)rViewPort.X - nMarginX;
int nTop = (int)rViewPort.Y - nMarginY;
int nRight = (int)rViewPort.X + nMarginX + (int)rViewPort.Width - 1;
int nBottom = (int)rViewPort.Y + nMarginY + (int)rViewPort.Height - 1;
pViewport->GetCameraFrustum(nLeft, nTop, nRight, nBottom, pFrustumCube);
}
K3DVector* K3DCamera::GetFrustum(KViewportObject* pViewport)
{
return pViewport->GetFrustum();
}*/
/*void K3DCamera::_MakeFrustum(KViewportObject* pViewport)
{
K3DVector vtCam = K3DVector(m_fXPos, m_fYPos, m_fZPos);
K3DVector vtTar = K3DVector(m_fTXPos, m_fTYPos, m_fTZPos);
if(IsCoordinateRightHand()) {
K3DMatrixLookAtRH(m_MatView, vtCam, vtTar,m_dxvtUp);
K3DMatrixPerspectiveFovRH( &m_matProjection, m_fFOV, pViewport->GetVertexAspect(), pViewport->GetNearClip(), pViewport->GetFarClip() );
}
else {
K3DMatrixLookAtLH(m_MatView, vtCam, vtTar,m_dxvtUp);
K3DMatrixPerspectiveFovLH( &m_matProjection, m_fFOV, pViewport->GetVertexAspect(), pViewport->GetNearClip(), pViewport->GetFarClip() );
}
K3DMatrix mat = m_MatView * m_matProjection;
for(int i = 0; i < K3DFrustum::PLANE_MAX; ++i)
{
K3DPlane & plane = m_Frustum.GetPlane(i);
switch(i)
{
case K3DFrustum::PLANE_LEFT:
plane.a = mat._14 + mat._11;
plane.b = mat._24 + mat._21;
plane.c = mat._34 + mat._31;
plane.d = mat._44 + mat._41;
break;
case K3DFrustum::PLaNE_RIGHT:
plane.a = mat._14 - mat._11;
plane.b = mat._24 - mat._21;
plane.c = mat._34 - mat._31;
plane.d = mat._44 - mat._41;
break;
case K3DFrustum::PLANE_TOP:
plane.a = mat._14 - mat._12;
plane.b = mat._24 - mat._22;
plane.c = mat._34 - mat._32;
plane.d = mat._44 - mat._42;
break;
case K3DFrustum::PLANE_BOTTOM:
plane.a = mat._14 + mat._12;
plane.b = mat._24 + mat._22;
plane.c = mat._34 + mat._32;
plane.d = mat._44 + mat._42;
break;
case K3DFrustum::PLANE_NEAR:
plane.a = mat._14 + mat._13;
plane.b = mat._24 + mat._23;
plane.c = mat._34 + mat._33;
plane.d = mat._44 + mat._43;
break;
case K3DFrustum::PLANE_FAR:
plane.a = mat._14 - mat._13;
plane.b = mat._24 - mat._23;
plane.c = mat._34 - mat._33;
plane.d = mat._44 - mat._43;
break;
}
K3DPlaneNormalize(&plane, &plane);
}
}*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*K3DOrthoCamera::K3DOrthoCamera()
{
Reset();
}
K3DOrthoCamera::~K3DOrthoCamera()
{
}
void K3DOrthoCamera::Reset()
{
m_fNearClip = 100;
m_fFarClip = 50000;
m_fOriginX = m_fOriginY = .0f;
K3DMatrixIdentity( m_MatView );
}
K3DMatrix * K3DOrthoCamera::GetViewMatrix()
{
m_MatView._41 = m_fOriginX;
m_MatView._42 = m_fOriginY;
return &m_MatView;
}
*/
/*void K3DOrthoCamera::Render( KViewportObject *viewport )
{
m_MatView._41 = m_fOriginX;
m_MatView._42 = m_fOriginY;
K3DMatrixOrthoRH( m_matProjection, m_fViewWidth, m_fViewHeigth, m_fNearClip, m_fFarClip );
viewport->SetViewTransform( K3DVector(0,0,0), K3DVector(0,0,0), m_MatView, m_matProjection );
}*/