// K3DCamera.cpp: implementation of the K3DCamera class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "K3DCamera.h" #include "KViewport.h" #include //#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 ); }*/