add some CK3dEntity code
This commit is contained in:
parent
2d190ea30b
commit
69f702a6d2
|
@ -1,8 +1,24 @@
|
|||
#include "CK3dEntity.hpp"
|
||||
#include "../CKStateChunk.hpp"
|
||||
#include "../CKContext.hpp"
|
||||
#include "CKMesh.hpp"
|
||||
|
||||
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 suc = CKRenderObject::Save(chunk, file, flags);
|
||||
if (!suc) return false;
|
||||
|
@ -14,6 +30,117 @@ namespace LibCmo::CK2::ObjImpls {
|
|||
bool suc = CKRenderObject::Load(chunk, file);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,8 @@ namespace LibCmo::CK2::ObjImpls {
|
|||
|
||||
class CK3dEntity : public CKRenderObject {
|
||||
public:
|
||||
CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name) :
|
||||
CKRenderObject(ctx, ckid, name),
|
||||
m_Meshes(), m_CurrentMesh(nullptr), m_WorldMatrix()
|
||||
{}
|
||||
virtual ~CK3dEntity() {}
|
||||
CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name);
|
||||
virtual ~CK3dEntity();
|
||||
LIBCMO_DISABLE_COPY_MOVE(CK3dEntity);
|
||||
|
||||
virtual CK_CLASSID GetClassID(void) override {
|
||||
|
@ -23,9 +20,13 @@ namespace LibCmo::CK2::ObjImpls {
|
|||
//virtual void PostLoad() override;
|
||||
|
||||
protected:
|
||||
XContainer::XObjectPointerArray m_Meshes;
|
||||
XContainer::XObjectPointerArray m_PotentialMeshes;
|
||||
CKMesh* m_CurrentMesh;
|
||||
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];
|
||||
|
||||
VxMatrix() : m_Data() {
|
||||
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;
|
||||
ResetToIdentity();
|
||||
}
|
||||
VxMatrix(CKFLOAT m[4][4]) : m_Data() { std::memcpy(m_Data, m, sizeof(m_Data)); }
|
||||
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) {
|
||||
if (i >= 4) i = 0;
|
||||
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 {
|
||||
return std::memcmp(m_Data, rhs.m_Data, sizeof(m_Data)) == 0;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "../CK2/MgrImpls/CKObjectManager.hpp"
|
||||
#include "../CK2/ObjImpls/CKObject.hpp"
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace LibCmo::XContainer {
|
||||
|
||||
|
@ -143,6 +144,13 @@ namespace LibCmo::XContainer {
|
|||
}
|
||||
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) {
|
||||
if (ctx == nullptr) return;
|
||||
std::erase_if(objarray, [ctx](CK2::ObjImpls::CKObject* const& item) -> bool {
|
||||
|
|
|
@ -180,6 +180,13 @@ namespace LibCmo::XContainer {
|
|||
|
||||
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.
|
||||
* @param objarray
|
||||
|
|
|
@ -118,37 +118,37 @@ namespace Unvirt::StructFormatter {
|
|||
PrintCKBeObjectDetail(obj);
|
||||
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKMesh\n")), stdout);
|
||||
|
||||
fputs("Vertex:\n", stdout);
|
||||
fprintf(stdout, "Vertex Count: %" PRIuCKDWORD "\n", obj->GetVertexCount());
|
||||
fputs("Type\tAddress\tSize\n", stdout);
|
||||
|
||||
fputs("VertexPositions: ", stdout);
|
||||
fputs("Positions\t", stdout);
|
||||
PrintPointer(obj->GetVertexPositions());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||
fputs("VertexNormals: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||
fputs("Normals\t", stdout);
|
||||
PrintPointer(obj->GetVertexNormals());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||
fputs("VertexUVs: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector3));
|
||||
fputs("UVs\t", stdout);
|
||||
PrintPointer(obj->GetVertexUVs());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector2));
|
||||
fputs("VertexColors: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::VxMath::VxVector2));
|
||||
fputs("Colors\t", stdout);
|
||||
PrintPointer(obj->GetVertexColors());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||
fputs("VertexSpecularColors: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||
fputs("SpecularColors\t", stdout);
|
||||
PrintPointer(obj->GetVertexSpecularColors());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||
fputs("VertexWeights: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
|
||||
fputs("Weights\t", stdout);
|
||||
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());
|
||||
fputs("Type\tAddress\tSize\n", stdout);
|
||||
|
||||
fputs("FaceIndices: ", stdout);
|
||||
fputs("Indices\t", stdout);
|
||||
PrintPointer(obj->GetFaceIndices());
|
||||
fprintf(stdout, " (0x%" PRIxCKDWORD " bytes)\n", obj->GetFaceCount() * 3 * CKSizeof(LibCmo::CKWORD));
|
||||
fputs("FaceMaterialSlotIndexs: ", stdout);
|
||||
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\n", obj->GetFaceCount() * 3 * CKSizeof(LibCmo::CKWORD));
|
||||
fputs("MaterialSlotIndexs\t", stdout);
|
||||
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