From a70e32a3060c7bab7f085448da3f46965a3124f6 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Fri, 1 Dec 2023 23:31:09 +0800 Subject: [PATCH] fix issues - revert nullptr check for BMap::MeshTrans pointer getter. - fix pointer return error of BMap::MeshTrans - fix type hint error and variable name error in PyBMap - fix CKMesh flag init value error - improve empty material slots saving. add a nullptr entry if no slots to make sure virtools can load it. --- BMap/BMExports.cpp | 16 ++++++------- BMap/BMap.cpp | 10 ++++---- BMapBindings/PyBMap/.gitignore | 1 + BMapBindings/PyBMap/PyBMap/bmap_wrapper.py | 24 +++++++++++-------- LibCmo/CK2/ObjImpls/CKMesh.cpp | 27 +++++++++++++++------- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/BMap/BMExports.cpp b/BMap/BMExports.cpp index ba31a4c..979c175 100644 --- a/BMap/BMExports.cpp +++ b/BMap/BMExports.cpp @@ -256,7 +256,7 @@ bool BMMeshTrans_PrepareVertexCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(Li bool BMMeshTrans_PrepareVertex(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareVertex()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareNormalCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count)) { if (!CheckBMMeshTrans(trans)) return false; @@ -265,7 +265,7 @@ bool BMMeshTrans_PrepareNormalCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(Li bool BMMeshTrans_PrepareNormal(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareNormal()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareUVCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count)) { if (!CheckBMMeshTrans(trans)) return false; @@ -274,7 +274,7 @@ bool BMMeshTrans_PrepareUVCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo bool BMMeshTrans_PrepareUV(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector2*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareUV()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareMtlSlotCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count)) { if (!CheckBMMeshTrans(trans)) return false; @@ -283,7 +283,7 @@ bool BMMeshTrans_PrepareMtlSlotCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(L bool BMMeshTrans_PrepareMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CK2::CK_ID*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareMtlSlot()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareFaceCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count)) { if (!CheckBMMeshTrans(trans)) return false; @@ -292,22 +292,22 @@ bool BMMeshTrans_PrepareFaceCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibC bool BMMeshTrans_PrepareFaceVertexIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareFaceVertexIndices()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareFaceNormalIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareFaceNormalIndices()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareFaceUVIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareFaceUVIndices()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_PrepareFaceMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem)) { if (!CheckBMMeshTrans(trans)) return false; BMPARAM_OUT_ASSIGN(out_mem, trans->PrepareFaceMtlSlot()); - return BMPARAM_OUT_VAL(out_mem) != nullptr; + return true; } bool BMMeshTrans_Parse(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(BMap::BMFile*, bmfile), BMPARAM_IN(LibCmo::CK2::CK_ID, objid)) { if (!CheckBMMeshTrans(trans)) return false; diff --git a/BMap/BMap.cpp b/BMap/BMap.cpp index 45e67cc..e506174 100644 --- a/BMap/BMap.cpp +++ b/BMap/BMap.cpp @@ -94,17 +94,17 @@ namespace BMap { LibCmo::CKDWORD* BMMeshTransition::PrepareFaceNormalIndices() { if (m_IsParsed || !m_IsFaceOK) return nullptr; - return m_FaceVertexs.data(); + return m_FaceNormals.data(); } LibCmo::CKDWORD* BMMeshTransition::PrepareFaceUVIndices() { if (m_IsParsed || !m_IsFaceOK) return nullptr; - return m_FaceVertexs.data(); + return m_FaceUVs.data(); } LibCmo::CKDWORD* BMMeshTransition::PrepareFaceMtlSlot() { if (m_IsParsed || !m_IsFaceOK) return nullptr; - return m_FaceVertexs.data(); + return m_FaceMtlSlotIdxs.data(); } bool BMMeshTransition::Parse(BMFile* bmfile, LibCmo::CK2::CK_ID mesh_id) { @@ -148,8 +148,8 @@ namespace BMap { // create one first TransitionVertex tvec( m_Vertexs[m_FaceVertexs[faceid * 3 + j]], - m_Normals[m_FaceVertexs[faceid * 3 + j]], - m_UVs[m_FaceVertexs[faceid * 3 + j]] + m_Normals[m_FaceNormals[faceid * 3 + j]], + m_UVs[m_FaceUVs[faceid * 3 + j]] ); // try insert it diff --git a/BMapBindings/PyBMap/.gitignore b/BMapBindings/PyBMap/.gitignore index d6db128..61d8727 100644 --- a/BMapBindings/PyBMap/.gitignore +++ b/BMapBindings/PyBMap/.gitignore @@ -1,4 +1,5 @@ # my ban +.vscode/ *.dll *.pdb *.so diff --git a/BMapBindings/PyBMap/PyBMap/bmap_wrapper.py b/BMapBindings/PyBMap/PyBMap/bmap_wrapper.py index 8ac79d9..9a3168e 100644 --- a/BMapBindings/PyBMap/PyBMap/bmap_wrapper.py +++ b/BMapBindings/PyBMap/PyBMap/bmap_wrapper.py @@ -115,7 +115,11 @@ def _vxvector2_iterator(pvector: bmap.bm_VxVector2_p, count: int) -> typing.Iter idx += 2 yield ret -def _ckfaceindices_assigner(pindices: bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None: +# bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p is just a type hint +# wo do not need distinguish them in code. +# because the type of pindices is decided by runtime. + +def _ckfaceindices_assigner(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int, itor: typing.Iterator[virtools_types.CKFaceIndices]) -> None: idx: int = 0 for _ in range(count): userindices: virtools_types.CKFaceIndices = next(itor) @@ -124,7 +128,7 @@ def _ckfaceindices_assigner(pindices: bmap.bm_CKDWORD_p, count: int, itor: typin pindices[idx + 2] = userindices.i3 idx += 3 -def _ckfaceindices_iterator(pindices: bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]: +def _ckfaceindices_iterator(pindices: bmap.bm_CKWORD_p | bmap.bm_CKDWORD_p, count: int) -> typing.Iterator[virtools_types.CKFaceIndices]: ret: virtools_types.CKFaceIndices = virtools_types.CKFaceIndices() idx: int = 0 for _ in range(count): @@ -175,12 +179,12 @@ class BMObject(_AbstractCKObject): else: return name.value.decode(g_BMapEncoding) - def set_name(self, name: str | None) -> None: + def set_name(self, name_: str | None) -> None: name: bmap.bm_CKSTRING - if name is None: + if name_ is None: name = bmap.bm_CKSTRING(0) else: - name = bmap.bm_CKSTRING(name.encode(g_BMapEncoding)) + name = bmap.bm_CKSTRING(name_.encode(g_BMapEncoding)) bmap.BMObject_SetName(self._get_pointer(), self._get_ckid(), name) class BMTexture(BMObject): @@ -415,8 +419,8 @@ class BMMesh(BMObject): bmap.BMMesh_GetLitMode(self._get_pointer(), self._get_ckid(), ctypes.byref(mode)) return virtools_types.VXMESH_LITMODE(mode.value) - def set_lit_mode(self, mode: virtools_types.VXMESH_LITMODE) -> None: - mode: bmap.bm_enum = bmap.bm_enum(mode.value) + def set_lit_mode(self, mode_: virtools_types.VXMESH_LITMODE) -> None: + mode: bmap.bm_enum = bmap.bm_enum(mode_.value) bmap.BMMesh_SetLitMode(self._get_pointer(), self._get_ckid(), mode) def get_vertex_count(self) -> int: @@ -535,9 +539,9 @@ class BM3dObject(BMObject): ret.from_const(tuple(flat[i] for i in range(16))) return ret - def set_world_matrix(self, mat: virtools_types.VxMatrix) -> None: + def set_world_matrix(self, mat_: virtools_types.VxMatrix) -> None: # star syntax expand the tuple as the argument. - mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat.to_const())) + mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat_.to_const())) bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat) def get_current_mesh(self) -> BMMesh | None: @@ -819,7 +823,7 @@ class BMMeshTrans(_AbstractPointer): idx: int = 0 for _ in range(count): - usermtl: BMMaterial = next(itor) + usermtl: BMMaterial | None = next(itor) if usermtl is None: raw_ckid[idx] = g_InvalidCKID else: diff --git a/LibCmo/CK2/ObjImpls/CKMesh.cpp b/LibCmo/CK2/ObjImpls/CKMesh.cpp index 0022d16..b4c3901 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.cpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.cpp @@ -22,8 +22,8 @@ namespace LibCmo::CK2::ObjImpls { m_LineIndices(), // init flags m_Flags(EnumsHelper::Merge({ - VxMath::VXMESH_FLAGS::VXMESH_FORCETRANSPARENCY, - VxMath::VXMESH_FLAGS::VXMESH_HASTRANSPARENCY + VxMath::VXMESH_FLAGS::VXMESH_VISIBLE, + VxMath::VXMESH_FLAGS::VXMESH_RENDERCHANNELS })) { // set visible in default EnumsHelper::Add(m_ObjectFlags, CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE); @@ -53,14 +53,25 @@ namespace LibCmo::CK2::ObjImpls { } // write material slots - if (GetMaterialSlotCount() != 0) { + // MARK: due to virtools shit implement, we must make sure there is at least one material channel existed. + // so if the material slot is empty, we write a mullptr slot for it. + { chunk->WriteIdentifier(CK_STATESAVEFLAGS_MESH::CK_STATESAVE_MESHMATERIALS); - chunk->WriteStruct(GetMaterialSlotCount()); - for (auto& mtlSlot : m_MaterialSlot) { - // write object id - chunk->WriteObjectPointer(mtlSlot); - // MARK: write a zero? idk what the fuck it is. + if (GetMaterialSlotCount() != 0) { + // write real slots + chunk->WriteStruct(GetMaterialSlotCount()); + for (auto& mtlSlot : m_MaterialSlot) { + // write object id + chunk->WriteObjectPointer(mtlSlot); + // MARK: write a zero? idk what the fuck it is. + chunk->WriteStruct(static_cast(0)); + } + } else { + // write fake one like real one + chunk->WriteStruct(static_cast(1)); + // write id and blank + chunk->WriteObjectPointer(nullptr); chunk->WriteStruct(static_cast(0)); } }