add some CK3dEntity code
This commit is contained in:
parent
2d190ea30b
commit
69f702a6d2
|
@ -1,8 +1,24 @@
|
||||||
#include "CK3dEntity.hpp"
|
#include "CK3dEntity.hpp"
|
||||||
#include "../CKStateChunk.hpp"
|
#include "../CKStateChunk.hpp"
|
||||||
|
#include "../CKContext.hpp"
|
||||||
|
#include "CKMesh.hpp"
|
||||||
|
|
||||||
namespace LibCmo::CK2::ObjImpls {
|
namespace LibCmo::CK2::ObjImpls {
|
||||||
|
|
||||||
|
CK3dEntity::CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name) :
|
||||||
|
CKRenderObject(ctx, ckid, name),
|
||||||
|
m_PotentialMeshes(), m_CurrentMesh(nullptr),
|
||||||
|
m_WorldMatrix(), m_ZOrder(0),
|
||||||
|
m_MoveableFlags(EnumsHelper::Merge({
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_PICKABLE,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_VISIBLE,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERCHANNELS,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INVERSEWORLDMATVALID
|
||||||
|
})),
|
||||||
|
m_3dEntityFlags(static_cast<CK_3DENTITY_FLAGS>(0)) {}
|
||||||
|
|
||||||
|
CK3dEntity::~CK3dEntity() {}
|
||||||
|
|
||||||
bool CK3dEntity::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
|
bool CK3dEntity::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) {
|
||||||
bool suc = CKRenderObject::Save(chunk, file, flags);
|
bool suc = CKRenderObject::Save(chunk, file, flags);
|
||||||
if (!suc) return false;
|
if (!suc) return false;
|
||||||
|
@ -14,6 +30,117 @@ namespace LibCmo::CK2::ObjImpls {
|
||||||
bool suc = CKRenderObject::Load(chunk, file);
|
bool suc = CKRenderObject::Load(chunk, file);
|
||||||
if (!suc) return false;
|
if (!suc) return false;
|
||||||
|
|
||||||
|
// backup moveable flags
|
||||||
|
bool hasWorldAligned = EnumsHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED);
|
||||||
|
|
||||||
|
// MARK: object animation is skipped
|
||||||
|
|
||||||
|
// read associated meshs data
|
||||||
|
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_3DENTITY::CK_STATESAVE_MESHS)) {
|
||||||
|
// MARK: I don't know why origianl code do not clear potential mesh list
|
||||||
|
// so I clear it in there.
|
||||||
|
m_PotentialMeshes.clear();
|
||||||
|
|
||||||
|
// read current mesh
|
||||||
|
CK_ID currentMeshId;
|
||||||
|
chunk->ReadObjectID(currentMeshId);
|
||||||
|
CKObject* findobj = m_Context->GetObject(currentMeshId);
|
||||||
|
if (findobj != nullptr && findobj->GetClassID() == CK_CLASSID::CKCID_MESH) {
|
||||||
|
m_CurrentMesh = static_cast<CKMesh*>(findobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read other meshs
|
||||||
|
XContainer::XObjectPointerArray potentials;
|
||||||
|
chunk->ReadXObjectPointerArray(potentials);
|
||||||
|
for (const auto& ptr : potentials) {
|
||||||
|
XContainer::NSXObjectPointerArray::AddIfNotHere(m_PotentialMeshes, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// read core entity data
|
||||||
|
if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_3DENTITY::CK_STATESAVE_3DENTITYNDATA)) {
|
||||||
|
// read 2 flags
|
||||||
|
chunk->ReadStruct(m_3dEntityFlags);
|
||||||
|
chunk->ReadStruct(m_MoveableFlags);
|
||||||
|
// remove some properties
|
||||||
|
EnumsHelper::Rm(m_3dEntityFlags, EnumsHelper::Merge({
|
||||||
|
CK_3DENTITY_FLAGS::CK_3DENTITY_UPDATELASTFRAME,
|
||||||
|
CK_3DENTITY_FLAGS::CK_3DENTITY_RESERVED0
|
||||||
|
}));
|
||||||
|
EnumsHelper::Rm(m_MoveableFlags, EnumsHelper::Merge({
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RESERVED2,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_STENCILONLY,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_DONTUPDATEFROMPARENT,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INVERSEWORLDMATVALID,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HASMOVED,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_BOXVALID,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_USERBOX,
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_UPTODATE
|
||||||
|
}));
|
||||||
|
if (hasWorldAligned) {
|
||||||
|
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_WORLDALIGNED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if order render first
|
||||||
|
if (EnumsHelper::Has(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_RENDERFIRST)) {
|
||||||
|
m_ZOrder = 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read matrix
|
||||||
|
// force read as vector3
|
||||||
|
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[0]));
|
||||||
|
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[1]));
|
||||||
|
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[2]));
|
||||||
|
chunk->ReadStruct(reinterpret_cast<VxMath::VxVector3*>(&m_WorldMatrix[3]));
|
||||||
|
// MARK: check right-hand?
|
||||||
|
// I don't know how it checked, just reinterpter IDA code.
|
||||||
|
VxMath::VxVector3 col2(*reinterpret_cast<const VxMath::VxVector3*>(&m_WorldMatrix[2])),
|
||||||
|
col1(*reinterpret_cast<const VxMath::VxVector3*>(&m_WorldMatrix[1])),
|
||||||
|
col0(*reinterpret_cast<const VxMath::VxVector3*>(&m_WorldMatrix[0]));
|
||||||
|
VxMath::VxVector3 crossProduct = VxMath::NSVxVector::CrossProduct(col0, col1);
|
||||||
|
CKFLOAT dotProduct = VxMath::NSVxVector::DotProduct(crossProduct, col2);
|
||||||
|
if (dotProduct >= 0.0f) {
|
||||||
|
EnumsHelper::Rm(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX);
|
||||||
|
} else {
|
||||||
|
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_INDIRECTMATRIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy visible data
|
||||||
|
// process direct visible
|
||||||
|
// todo add if visible
|
||||||
|
// and set or unset VX_MOVEABLE_VISIBLE
|
||||||
|
|
||||||
|
// process indirect visible
|
||||||
|
if (EnumsHelper::Has(m_ObjectFlags, CK_OBJECT_FLAGS::CKBEHAVIORLINK_ACTIVATEDLASTFRAME)) {
|
||||||
|
EnumsHelper::Add(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
|
||||||
|
} else {
|
||||||
|
EnumsHelper::Rm(m_MoveableFlags, VxMath::VX_MOVEABLE_FLAGS::VX_MOVEABLE_HIERARCHICALHIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read associated CKPlace
|
||||||
|
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PLACEVALID)) {
|
||||||
|
// MARK: we drop the support of CKPlace.
|
||||||
|
// so we just read it and skip it.
|
||||||
|
CK_ID placeid;
|
||||||
|
chunk->ReadObjectID(placeid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read parent
|
||||||
|
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_PARENTVALID)) {
|
||||||
|
// MAKR: we drop the support of parent and the whole 3dentity hierarchy system
|
||||||
|
// we ignore this field.
|
||||||
|
CK_ID parentid;
|
||||||
|
chunk->ReadObjectID(parentid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read priority (non-zero zorder)
|
||||||
|
if (EnumsHelper::Has(m_3dEntityFlags, CK_3DENTITY_FLAGS::CK_3DENTITY_ZORDERVALID)) {
|
||||||
|
chunk->ReadStruct(m_ZOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,8 @@ namespace LibCmo::CK2::ObjImpls {
|
||||||
|
|
||||||
class CK3dEntity : public CKRenderObject {
|
class CK3dEntity : public CKRenderObject {
|
||||||
public:
|
public:
|
||||||
CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name) :
|
CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name);
|
||||||
CKRenderObject(ctx, ckid, name),
|
virtual ~CK3dEntity();
|
||||||
m_Meshes(), m_CurrentMesh(nullptr), m_WorldMatrix()
|
|
||||||
{}
|
|
||||||
virtual ~CK3dEntity() {}
|
|
||||||
LIBCMO_DISABLE_COPY_MOVE(CK3dEntity);
|
LIBCMO_DISABLE_COPY_MOVE(CK3dEntity);
|
||||||
|
|
||||||
virtual CK_CLASSID GetClassID(void) override {
|
virtual CK_CLASSID GetClassID(void) override {
|
||||||
|
@ -23,10 +20,14 @@ namespace LibCmo::CK2::ObjImpls {
|
||||||
//virtual void PostLoad() override;
|
//virtual void PostLoad() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
XContainer::XObjectPointerArray m_Meshes;
|
XContainer::XObjectPointerArray m_PotentialMeshes;
|
||||||
CKMesh* m_CurrentMesh;
|
CKMesh* m_CurrentMesh;
|
||||||
VxMath::VxMatrix m_WorldMatrix;
|
VxMath::VxMatrix m_WorldMatrix;
|
||||||
|
CKDWORD m_ZOrder; // replace the whole heavy CKSceneGraphNode
|
||||||
|
|
||||||
|
VxMath::VX_MOVEABLE_FLAGS m_MoveableFlags;
|
||||||
|
CK_3DENTITY_FLAGS m_3dEntityFlags;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,16 +371,22 @@ namespace LibCmo::VxMath {
|
||||||
CKFLOAT m_Data[4][4];
|
CKFLOAT m_Data[4][4];
|
||||||
|
|
||||||
VxMatrix() : m_Data() {
|
VxMatrix() : m_Data() {
|
||||||
std::memset(m_Data, 0, sizeof(m_Data));
|
ResetToIdentity();
|
||||||
m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f;
|
|
||||||
}
|
}
|
||||||
VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); }
|
VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); }
|
||||||
LIBCMO_DEFAULT_COPY_MOVE(VxMatrix);
|
LIBCMO_DEFAULT_COPY_MOVE(VxMatrix);
|
||||||
|
void ResetToIdentity() {
|
||||||
|
std::memset(m_Data, 0, sizeof(m_Data));
|
||||||
|
m_Data[0][0] = m_Data[1][1] = m_Data[2][2] = m_Data[3][3] = 1.0f;
|
||||||
|
}
|
||||||
VxVector4& operator[](size_t i) {
|
VxVector4& operator[](size_t i) {
|
||||||
if (i >= 4) i = 0;
|
if (i >= 4) i = 0;
|
||||||
return *(reinterpret_cast<VxVector4*>(m_Data) + i);
|
return *(reinterpret_cast<VxVector4*>(m_Data) + i);
|
||||||
}
|
}
|
||||||
|
const VxVector4& operator[](size_t i) const {
|
||||||
|
if (i >= 4) i = 0;
|
||||||
|
return *(reinterpret_cast<const VxVector4*>(m_Data) + i);
|
||||||
|
}
|
||||||
bool operator==(const VxMatrix& rhs) const {
|
bool operator==(const VxMatrix& rhs) const {
|
||||||
return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0;
|
return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "../CK2/MgrImpls/CKObjectManager.hpp"
|
#include "../CK2/MgrImpls/CKObjectManager.hpp"
|
||||||
#include "../CK2/ObjImpls/CKObject.hpp"
|
#include "../CK2/ObjImpls/CKObject.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace LibCmo::XContainer {
|
namespace LibCmo::XContainer {
|
||||||
|
|
||||||
|
@ -143,6 +144,13 @@ namespace LibCmo::XContainer {
|
||||||
}
|
}
|
||||||
namespace NSXObjectPointerArray {
|
namespace NSXObjectPointerArray {
|
||||||
|
|
||||||
|
void AddIfNotHere(XObjectPointerArray& objarray, CK2::ObjImpls::CKObject* const obj) {
|
||||||
|
auto finder = std::find(objarray.begin(), objarray.end(), obj);
|
||||||
|
if (finder == objarray.end()) {
|
||||||
|
objarray.emplace_back(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PreDeletedCheck(XObjectPointerArray& objarray, CK2::CKContext* ctx) {
|
void PreDeletedCheck(XObjectPointerArray& objarray, CK2::CKContext* ctx) {
|
||||||
if (ctx == nullptr) return;
|
if (ctx == nullptr) return;
|
||||||
std::erase_if(objarray, [ctx](CK2::ObjImpls::CKObject* const& item) -> bool {
|
std::erase_if(objarray, [ctx](CK2::ObjImpls::CKObject* const& item) -> bool {
|
||||||
|
|
|
@ -180,6 +180,13 @@ namespace LibCmo::XContainer {
|
||||||
|
|
||||||
namespace NSXObjectPointerArray {
|
namespace NSXObjectPointerArray {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add object pointer if it is not list.
|
||||||
|
* @param objarray
|
||||||
|
* @param obj
|
||||||
|
*/
|
||||||
|
void AddIfNotHere(XObjectPointerArray& objarray, CK2::ObjImpls::CKObject* const obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check Object pointer validation and remove invalid pointers before deletion.
|
* @brief Check Object pointer validation and remove invalid pointers before deletion.
|
||||||
* @param objarray
|
* @param objarray
|
||||||
|
|
|
@ -118,37 +118,37 @@ namespace Unvirt::StructFormatter {
|
||||||
PrintCKBeObjectDetail(obj);
|
PrintCKBeObjectDetail(obj);
|
||||||
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKMesh\n")), stdout);
|
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKMesh\n")), stdout);
|
||||||
|
|
||||||
fputs("Vertex:\n", stdout);
|
|
||||||
fprintf(stdout, "Vertex Count: %" PRIuCKDWORD "\n", obj->GetVertexCount());
|
fprintf(stdout, "Vertex Count: %" PRIuCKDWORD "\n", obj->GetVertexCount());
|
||||||
|
fputs("Type\tAddress\tSize\n", stdout);
|
||||||
|
|
||||||
fputs("VertexPositions: ", stdout);
|
fputs("Positions\t", stdout);
|
||||||
PrintPointer(obj->GetVertexPositions());
|
PrintPointer(obj->GetVertexPositions());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||||
fputs("VertexNormals: ", stdout);
|
fputs("Normals\t", stdout);
|
||||||
PrintPointer(obj->GetVertexNormals());
|
PrintPointer(obj->GetVertexNormals());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||||
fputs("VertexUVs: ", stdout);
|
fputs("UVs\t", stdout);
|
||||||
PrintPointer(obj->GetVertexUVs());
|
PrintPointer(obj->GetVertexUVs());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector2));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector2));
|
||||||
fputs("VertexColors: ", stdout);
|
fputs("Colors\t", stdout);
|
||||||
PrintPointer(obj->GetVertexColors());
|
PrintPointer(obj->GetVertexColors());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||||
fputs("VertexSpecularColors: ", stdout);
|
fputs("SpecularColors\t", stdout);
|
||||||
PrintPointer(obj->GetVertexSpecularColors());
|
PrintPointer(obj->GetVertexSpecularColors());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||||
fputs("VertexWeights: ", stdout);
|
fputs("Weights\t", stdout);
|
||||||
PrintPointer(obj->GetVertexWeights());
|
PrintPointer(obj->GetVertexWeights());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKFLOAT));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKFLOAT));
|
||||||
|
|
||||||
fputs("Face:\n", stdout);
|
|
||||||
fprintf(stdout, "Face Count: %" PRIuCKDWORD "\n", obj->GetFaceCount());
|
fprintf(stdout, "Face Count: %" PRIuCKDWORD "\n", obj->GetFaceCount());
|
||||||
|
fputs("Type\tAddress\tSize\n", stdout);
|
||||||
|
|
||||||
fputs("FaceIndices: ", stdout);
|
fputs("Indices\t", stdout);
|
||||||
PrintPointer(obj->GetFaceIndices());
|
PrintPointer(obj->GetFaceIndices());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetFaceCount() * 3 * CKSizeof(LibCmo::CKWORD));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetFaceCount() * 3 * CKSizeof(LibCmo::CKWORD));
|
||||||
fputs("FaceMaterialSlotIndexs: ", stdout);
|
fputs("MaterialSlotIndexs\t", stdout);
|
||||||
PrintPointer(obj->GetFaceMaterialSlotIndexs());
|
PrintPointer(obj->GetFaceMaterialSlotIndexs());
|
||||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetFaceCount() * CKSizeof(LibCmo::CKWORD));
|
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetFaceCount() * CKSizeof(LibCmo::CKWORD));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user