libcmo21/LibCmo/CK2/ObjImpls/CKCamera.cpp
yyc12345 c18ff8f2e3 fix: fix various issues.
- fix convertion loss in CKCamera.
- bump up version to 0.3.0
- use CMake to generate version info header.
- fix annotation about Dassault ComputeCRC error.
- change member field initialization value in CKLight.
2024-12-31 17:48:24 +08:00

156 lines
4.1 KiB
C++

#include "CKCamera.hpp"
#include "../CKStateChunk.hpp"
namespace LibCmo::CK2::ObjImpls {
// Convenient macro to mark this object is not UPTODATE.
#define REMOVE_UPTODATE_FLAG { \
CK_OBJECT_FLAGS obj_flags = GetObjectFlags(); \
YYCC::EnumHelper::Remove(obj_flags, CK_OBJECT_FLAGS::CK_OBJECT_UPTODATE); \
SetObjectFlags(obj_flags); \
}
CKCamera::CKCamera(CKContext* ctx, CK_ID ckid, CKSTRING name) :
CK3dEntity(ctx, ckid, name),
m_ProjectType(CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION),
m_Fov(0.5f), m_OrthographicZoom(1.0f),
m_Width(4), m_Height(3),
m_FrontPlane(1.0f), m_BackPlane(4000.0f) {
REMOVE_UPTODATE_FLAG;
}
CKCamera::~CKCamera() {}
bool CKCamera::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
bool suc = CK3dEntity::Save(chunk, file, flags);
if (!suc) return false;
// Save main data
{
chunk->WriteIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_CAMERAONLY);
chunk->WriteStruct(m_ProjectType);
chunk->WriteStruct(m_Fov);
chunk->WriteStruct(m_OrthographicZoom);
// Build width and height compound.
CKDWORD widht_and_height = m_Width & 0x0000FFFFu;
widht_and_height |= (m_Height << 16) & 0xFFFF0000u;
chunk->WriteStruct(widht_and_height);
chunk->WriteStruct(m_FrontPlane);
chunk->WriteStruct(m_BackPlane);
}
chunk->SetClassId(CK_CLASSID::CKCID_CAMERA);
return true;
}
bool CKCamera::Load(CKStateChunk* chunk, CKFileVisitor* file) {
bool suc = CK3dEntity::Load(chunk, file);
if (!suc) return false;
// MARK: Drop the support for very old file format.
if (chunk->GetDataVersion() < CK_STATECHUNK_DATAVERSION::CHUNK_MAJORCHANGE_VERSION) {
return false;
}
// Read main data
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_CAMERA::CK_STATESAVE_CAMERAONLY)) {
chunk->ReadStruct(m_ProjectType);
chunk->ReadStruct(m_Fov);
chunk->ReadStruct(m_OrthographicZoom);
// Width and Height is stored in one DWORD
// Higher WORD is height and lower WORD is width.
// HIGH >>> height (2 bytes), width (2 bytes) <<< LOW
CKDWORD widht_and_height;
chunk->ReadStruct(widht_and_height);
m_Width = widht_and_height & 0x0000FFFFu;
m_Height = (widht_and_height & 0xFFFF0000u) >> 16;
chunk->ReadStruct(m_FrontPlane);
chunk->ReadStruct(m_BackPlane);
}
REMOVE_UPTODATE_FLAG;
return true;
}
#pragma region Class Operations
CK_CAMERA_PROJECTION CKCamera::GetProjectionType() const {
return m_ProjectType;
}
void CKCamera::SetProjectionType(CK_CAMERA_PROJECTION proj) {
m_ProjectType = proj;
REMOVE_UPTODATE_FLAG;
}
CKFLOAT CKCamera::GetOrthographicZoom() const {
return m_OrthographicZoom;
}
void CKCamera::SetOrthographicZoom(CKFLOAT zoom) {
m_OrthographicZoom = zoom;
REMOVE_UPTODATE_FLAG;
}
CKFLOAT CKCamera::GetFrontPlane() const {
return m_FrontPlane;
}
CKFLOAT CKCamera::GetBackPlane() const {
return m_BackPlane;
}
CKFLOAT CKCamera::GetFov() const {
return m_Fov;
}
void CKCamera::SetFrontPlane(CKFLOAT front) {
m_FrontPlane = front;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::SetBackPlane(CKFLOAT back) {
m_BackPlane = back;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::SetFov(CKFLOAT fov) {
m_Fov = fov;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::GetAspectRatio(CKDWORD& width, CKDWORD& height) const {
width = m_Width;
height = m_Height;
}
void CKCamera::SetAspectRatio(CKDWORD width, CKDWORD height) {
m_Width = width;
m_Height = height;
REMOVE_UPTODATE_FLAG;
}
void CKCamera::ComputeProjectionMatrix(VxMath::VxMatrix& mat) const {
CKFLOAT aspect = static_cast<CKFLOAT>(m_Width) / m_Height;
if (m_ProjectType == CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION) {
mat.Perspective(m_Fov, aspect, m_FrontPlane, m_BackPlane);
} else {
mat.Orthographic(m_OrthographicZoom, aspect, m_FrontPlane, m_BackPlane);
}
}
//void CKCamera::ResetRoll() {}
//void CKCamera::Roll(CKFLOAT angle) {}
CK3dEntity* CKCamera::GetTarget() const {
// Not supported, return nullptr anyway.
return nullptr;
}
void CKCamera::SetTarget(CK3dEntity* target) {
// Do nothing because no support.
}
#pragma endregion
// Undef convenient macro
#undef REMOVE_UPTODATE_FLAG
}