#include "Stdafx.h" #include "SaveCamera.h" #include "DumpUtil.h" CSaveCamera::CSaveCamera(void) { m_pNode = NULL; m_pMaxInterface = NULL; } CSaveCamera::~CSaveCamera(void) { } void CSaveCamera::ProcessCamera( FILE *fp, INode *pNode, Interface *pMaxInterface, bool bExportTargetCamera ) { m_pNode = pNode; m_pMaxInterface = pMaxInterface; Matrix3 LocalMat; TimeValue StartTime; AffineParts Affine; StartTime = m_pMaxInterface->GetAnimRange().Start(); LocalMat = m_pNode->GetNodeTM( StartTime ); LocalMat.PreRotateX( -90.0f * ( 3.141592654f / 180.0f ) ); decomp_affine( LocalMat, &Affine ); memset( &m_Header, 0, sizeof( SCameraFileHeader ) ); m_Header.nType = CT_FREE_CAMERA; if( ( m_pNode->GetTarget() ) && ( bExportTargetCamera ) ) { m_Header.nType = CT_TARGET_CAMERA; } strcpy( m_Header.szHeaderString, CAMERA_FILE_STRING ); m_Header.nVersion = CAMERA_FILE_VERSION; m_Header.nFrame = m_pMaxInterface->GetAnimRange().End() / GetTicksPerFrame() - m_pMaxInterface->GetAnimRange().Start() / GetTicksPerFrame() + 1; int nStrlen; nStrlen = strlen( pNode->GetName() ); if( nStrlen >= 32 ) { memcpy( m_Header.szCameraName, pNode->GetName(), 31 ); m_Header.szCameraName[ 31 ] = 0; } else { strcpy( m_Header.szCameraName, pNode->GetName() ); } m_Header.vDefaultPosition.x = Affine.t.x; m_Header.vDefaultPosition.y = Affine.t.z; m_Header.vDefaultPosition.z = Affine.t.y; m_Header.qDefaultRotation.x = Affine.q.x; m_Header.qDefaultRotation.y = Affine.q.z; m_Header.qDefaultRotation.z = Affine.q.y; m_Header.qDefaultRotation.w = Affine.q.w; if( m_Header.nType == CT_TARGET_CAMERA ) { LocalMat = m_pNode->GetTarget()->GetNodeTM( StartTime ); LocalMat.PreRotateX( -90.0f * ( 3.141592654f / 180.0f ) ); decomp_affine( LocalMat, &Affine ); m_Header.vDefaultPosition.x = m_Header.vDefaultPosition.x - Affine.t.x; m_Header.vDefaultPosition.y = m_Header.vDefaultPosition.y - Affine.t.z; m_Header.vDefaultPosition.z = m_Header.vDefaultPosition.z - Affine.t.y; } GetAniData(); WriteCameraInfo( fp ); } void CSaveCamera::GetAniData() { DumpFOVSample(); DumpPosSample( m_pNode, m_vecPosition ); DumpRotSample(); } void CSaveCamera::DumpFOVSample() { int i, j; int nStart, nEnd; GenCamera *pObject; SCameraFOVKey FOVKey; float fFOVRatio; std::vector< SCameraFOVKey > vecFOV; pObject = ( GenCamera * )m_pNode->EvalWorldState( 0 ).obj; if( pObject->GetFOVType() == FOV_W ) { fFOVRatio = m_pMaxInterface->GetRendImageAspect(); } else { fFOVRatio = 1.0f; } nStart = m_pMaxInterface->GetAnimRange().Start() / GetTicksPerFrame(); nEnd = m_pMaxInterface->GetAnimRange().End() / GetTicksPerFrame(); nEnd++; m_Header.fDefaultFOV = pObject->GetFOV( m_pMaxInterface->GetAnimRange().Start() ) / fFOVRatio; for( i = nStart; i < nEnd; i++ ) { FOVKey.nTime = i - nStart; FOVKey.fFOV = pObject->GetFOV( i * GetTicksPerFrame() ) / fFOVRatio; vecFOV.push_back( FOVKey ); } m_vecFOV.push_back( vecFOV[ 0 ] ); for( i = 0; i < ( int )vecFOV.size() - 2; i++ ) { bool bIsInterpolate = true; for( j = i + 2; j < ( int )vecFOV.size(); j++ ) { float fCalcFOV, fWeight; fWeight = ( j - i - 1 ) / ( float )( j - i ); fCalcFOV = vecFOV[ i ].fFOV * ( 1.0f - fWeight ) + vecFOV[ j ].fFOV * fWeight; if( fabs( vecFOV[ j ].fFOV - fCalcFOV ) > 0.0001f ) { bIsInterpolate = false; break; } } if( bIsInterpolate ) { m_vecFOV.push_back( vecFOV[ vecFOV.size() - 1 ] ); break; } else { m_vecFOV.push_back( vecFOV[ j - 1 ] ); i += j - i - 2; } } /*if( m_vecFOV.size() == 2 ) { if( m_vecFOV[ 0 ].fFOV == m_vecFOV[ 1 ].fFOV ) { if( m_vecFOV[ 0 ].fFOV == m_Header.fDefaultFOV ) { m_vecFOV.clear(); } } }*/ } void CSaveCamera::DumpPosSample( INode *pNode, std::vector< SCameraPositionKey > &vecTargetPosition ) { int i, j; int nStart, nEnd; GenCamera *pObject; SCameraPositionKey PosKey; std::vector< SCameraPositionKey > vecPos; pObject = ( GenCamera * )pNode->EvalWorldState( 0 ).obj; nStart = m_pMaxInterface->GetAnimRange().Start() / GetTicksPerFrame(); nEnd = m_pMaxInterface->GetAnimRange().End() / GetTicksPerFrame(); nEnd++; for( i = nStart; i < nEnd; i++ ) { Matrix3 LocalMat; AffineParts Affine; LocalMat = pNode->GetNodeTM( i * GetTicksPerFrame() ); LocalMat.PreRotateX( -90.0f * ( 3.141592654f / 180.0f ) ); decomp_affine( LocalMat, &Affine ); PosKey.nTime = i - nStart; PosKey.Position = Affine.t; if( m_Header.nType == CT_TARGET_CAMERA ) { LocalMat = pNode->GetTarget()->GetNodeTM( i * GetTicksPerFrame() ); LocalMat.PreRotateX( -90.0f * ( 3.141592654f / 180.0f ) ); decomp_affine( LocalMat, &Affine ); PosKey.Position = PosKey.Position - Affine.t; } vecPos.push_back( PosKey ); } vecTargetPosition.push_back( vecPos[ 0 ] ); for( i = 0; i < ( int )vecPos.size() - 2; i++ ) { bool bIsInterpolate = true; for( j = i + 2; j < ( int )vecPos.size(); j++ ) { Point3 CalcPos, PosDiff; float fWeight; fWeight = ( j - i - 1 ) / ( float )( j - i ); CalcPos = vecPos[ i ].Position * ( 1.0f - fWeight ) + vecPos[ j ].Position * fWeight; PosDiff = vecPos[ j ].Position - CalcPos; if( PosDiff.Length() > 0.01f ) { bIsInterpolate = false; break; } } if( bIsInterpolate ) { vecTargetPosition.push_back( vecPos[ vecPos.size() - 1 ] ); break; } else { vecTargetPosition.push_back( vecPos[ j - 1 ] ); i += j - i - 2; } } if( vecTargetPosition.size() == 2 ) { if( vecTargetPosition[ 0 ].Position == vecTargetPosition[ 1 ].Position ) { if( vecTargetPosition[ 0 ].Position == m_Header.vDefaultPosition ) { vecTargetPosition.clear(); } } } } void CSaveCamera::DumpRotSample() { int i; int nStart, nEnd; GenCamera *pObject; SCameraRotationKey RotKey; std::vector< SCameraRotationKey > vecRot; pObject = ( GenCamera * )m_pNode->EvalWorldState( 0 ).obj; nStart = m_pMaxInterface->GetAnimRange().Start() / GetTicksPerFrame(); nEnd = m_pMaxInterface->GetAnimRange().End() / GetTicksPerFrame(); nEnd++; for( i = nStart; i < nEnd; i++ ) { Matrix3 LocalMat; AffineParts Affine; LocalMat = m_pNode->GetNodeTM( i * GetTicksPerFrame() ); LocalMat.PreRotateX( -90.0f * ( 3.141592654f / 180.0f ) ); decomp_affine( LocalMat, &Affine ); RotKey.nTime = i - nStart; RotKey.Rotation = Affine.q; m_vecRotation.push_back( RotKey ); } } void CSaveCamera::WriteCameraInfo( FILE *fp ) { int i; m_Header.nFOVKeyCount = ( int )m_vecFOV.size(); m_Header.nPositionKeyCount = ( int )m_vecPosition.size(); m_Header.nRotationKeyCount = ( int )m_vecRotation.size(); fwrite( &m_Header, sizeof( SCameraFileHeader ), 1, fp ); for( i = 0; i < m_Header.nFOVKeyCount; i++ ) { fwrite( &m_vecFOV[ i ], sizeof( SCameraFOVKey ), 1, fp ); } for( i = 0; i < m_Header.nPositionKeyCount; i++ ) { fwrite( &m_vecPosition[ i ].nTime, sizeof( int ), 1, fp ); DumpPoint3( fp, m_vecPosition[ i ].Position ); } for( i = 0; i < m_Header.nRotationKeyCount; i++ ) { fwrite( &m_vecRotation[ i ].nTime, sizeof( int ), 1, fp ); DumpQuat( fp, m_vecRotation[ i ].Rotation ); } }