finish MeshTransition & BMTexture bindings in pybmap

This commit is contained in:
yyc12345 2023-11-06 10:47:49 +08:00
parent a8bd6888cb
commit cd2d408618
2 changed files with 220 additions and 11 deletions

View File

@ -107,7 +107,39 @@ class BMObject(_AbstractCKObject):
bmap.BMObject_SetName(self._get_pointer(), self._get_ckid(), name) bmap.BMObject_SetName(self._get_pointer(), self._get_ckid(), name)
class BMTexture(BMObject): class BMTexture(BMObject):
pass def get_file_name(self) -> str | None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING()
bmap.BMTexture_GetFileName(self._get_pointer(), self._get_ckid(), ctypes.byref(filename))
if filename.value is None:
return None
else:
return filename.value.decode(g_BMapEncoding)
def load_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_LoadImage(self._get_pointer(), self._get_ckid(), filename)
def save_image(self, filepath: str) -> None:
filename: bmap.bm_CKSTRING = bmap.bm_CKSTRING(filepath.encode(g_BMapEncoding))
bmap.BMTexture_SaveImage(self._get_pointer(), self._get_ckid(), filename)
def get_save_options(self) -> virtools_types.CK_TEXTURE_SAVEOPTIONS:
opt: bmap.bm_enum = bmap.bm_enum()
bmap.BMTexture_GetSaveOptions(self._get_pointer(), self._get_ckid(), ctypes.byref(opt))
return virtools_types.CK_TEXTURE_SAVEOPTIONS(opt.value)
def set_save_options(self, opt_: virtools_types.CK_TEXTURE_SAVEOPTIONS) -> None:
opt: bmap.bm_enum = bmap.bm_enum(opt_.value)
bmap.BMTexture_SetSaveOptions(self._get_pointer(), self._get_ckid(), opt)
def get_video_format(self) -> virtools_types.VX_PIXELFORMAT:
fmt: bmap.bm_enum = bmap.bm_enum()
bmap.BMTexture_GetVideoFormat(self._get_pointer(), self._get_ckid(), ctypes.byref(fmt))
return virtools_types.VX_PIXELFORMAT(fmt.value)
def set_video_format(self, fmt_: virtools_types.VX_PIXELFORMAT) -> None:
fmt: bmap.bm_enum = bmap.bm_enum(fmt_.value)
bmap.BMTexture_SetVideoFormat(self._get_pointer(), self._get_ckid(), fmt)
class BMMaterial(BMObject): class BMMaterial(BMObject):
pass pass
@ -116,16 +148,18 @@ class BMMesh(BMObject):
pass pass
class BM3dObject(BMObject): class BM3dObject(BMObject):
def get_world_matrix(self) -> virtools_types.ConstVxMatrix: def get_world_matrix(self) -> virtools_types.VxMatrix:
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix() mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix()
bmap.BM3dObject_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat)) bmap.BM3dObject_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
# use cast & pointer to get matrix data conveniently # use cast & pointer to get matrix data conveniently
flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p) flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p)
return tuple(flat[i] for i in range(16)) ret: virtools_types.VxMatrix = virtools_types.VxMatrix()
ret.from_const(tuple(flat[i] for i in range(16)))
return ret
def set_world_matrix(self, mat: virtools_types.ConstVxMatrix) -> None: def set_world_matrix(self, mat: virtools_types.VxMatrix) -> None:
# star syntax expand the tuple as the argument. # star syntax expand the tuple as the argument.
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*mat) mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat.to_const()))
bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat) bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
def get_current_mesh(self) -> BMMesh | None: def get_current_mesh(self) -> BMMesh | None:
@ -157,15 +191,18 @@ class BMGroup(BMObject):
def add_object(self, member: BM3dObject) -> None: def add_object(self, member: BM3dObject) -> None:
bmap.BMGroup_AddObject(self._get_pointer(), self._get_ckid(), member._get_ckid()) bmap.BMGroup_AddObject(self._get_pointer(), self._get_ckid(), member._get_ckid())
def iterate_objects(self) -> typing.Iterator[BM3dObject]: def get_object_count(self) -> int:
# get count
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD() csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
bmap.BMGroup_GetObjectCount(self._get_pointer(), self._get_ckid(), ctypes.byref(csize)) bmap.BMGroup_GetObjectCount(self._get_pointer(), self._get_ckid(), ctypes.byref(csize))
return csize.value
def iterate_objects(self) -> typing.Iterator[BM3dObject]:
csize: int = self.get_object_count()
# iterate list # iterate list
cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD() cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
retid: bmap.bm_CKID = bmap.bm_CKID() retid: bmap.bm_CKID = bmap.bm_CKID()
for i in range(csize.value): for i in range(csize):
cidx.value = i cidx.value = i
bmap.BMGroup_GetObject(self._get_pointer(), self._get_ckid(), cidx, ctypes.byref(retid)) bmap.BMGroup_GetObject(self._get_pointer(), self._get_ckid(), cidx, ctypes.byref(retid))
# return visitor # return visitor
@ -203,23 +240,31 @@ class BMFileReader(_AbstractPointer):
bmap.BMFile_Free(self._get_pointer()) bmap.BMFile_Free(self._get_pointer())
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def __get_ckobject_count(self,
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool]) -> int:
# get size
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
count_getter(self._get_pointer(), ctypes.byref(csize))
return csize.value
def __iterate_ckobjects(self, def __iterate_ckobjects(self,
class_type: type[TCKObj], class_type: type[TCKObj],
count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool], count_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD_p], bool],
obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bool]) -> typing.Iterator[TCKObj]: obj_getter: typing.Callable[[bmap.bm_void_p, bmap.bm_CKDWORD, bmap.bm_CKID_p], bool]) -> typing.Iterator[TCKObj]:
# get size first # get size first
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD() csize: int = self.__get_ckobject_count(count_getter)
count_getter(self._get_pointer(), ctypes.byref(csize))
# iterate list # iterate list
cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD() cidx: bmap.bm_CKDWORD = bmap.bm_CKDWORD()
retid: bmap.bm_CKID = bmap.bm_CKID() retid: bmap.bm_CKID = bmap.bm_CKID()
for i in range(csize.value): for i in range(csize):
cidx.value = i cidx.value = i
obj_getter(self._get_pointer(), cidx, ctypes.byref(retid)) obj_getter(self._get_pointer(), cidx, ctypes.byref(retid))
# yield return constructed obj visitor # yield return constructed obj visitor
yield class_type(self._get_pointer(), retid) yield class_type(self._get_pointer(), retid)
def get_texture_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetTextureCount)
def iterate_textures(self) -> typing.Iterator[BMTexture]: def iterate_textures(self) -> typing.Iterator[BMTexture]:
return self.__iterate_ckobjects( return self.__iterate_ckobjects(
BMTexture, BMTexture,
@ -227,6 +272,8 @@ class BMFileReader(_AbstractPointer):
bmap.BMFile_GetTexture bmap.BMFile_GetTexture
) )
def get_material_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMaterialCount)
def iterate_materials(self) -> typing.Iterator[BMMaterial]: def iterate_materials(self) -> typing.Iterator[BMMaterial]:
return self.__iterate_ckobjects( return self.__iterate_ckobjects(
BMMaterial, BMMaterial,
@ -234,6 +281,8 @@ class BMFileReader(_AbstractPointer):
bmap.BMFile_GetMaterial bmap.BMFile_GetMaterial
) )
def get_mesh_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetMeshCount)
def iterate_meshs(self) -> typing.Iterator[BMMesh]: def iterate_meshs(self) -> typing.Iterator[BMMesh]:
return self.__iterate_ckobjects( return self.__iterate_ckobjects(
BMMesh, BMMesh,
@ -241,6 +290,8 @@ class BMFileReader(_AbstractPointer):
bmap.BMFile_GetMesh bmap.BMFile_GetMesh
) )
def get_3dobject_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_Get3dObjectCount)
def iterate_3dobjects(self) -> typing.Iterator[BM3dObject]: def iterate_3dobjects(self) -> typing.Iterator[BM3dObject]:
return self.__iterate_ckobjects( return self.__iterate_ckobjects(
BM3dObject, BM3dObject,
@ -248,6 +299,8 @@ class BMFileReader(_AbstractPointer):
bmap.BMFile_Get3dObject bmap.BMFile_Get3dObject
) )
def get_group_count(self) -> int:
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
def iterate_groups(self) -> typing.Iterator[BMGroup]: def iterate_groups(self) -> typing.Iterator[BMGroup]:
return self.__iterate_ckobjects( return self.__iterate_ckobjects(
BMGroup, BMGroup,
@ -350,4 +403,113 @@ class BMMeshTrans(_AbstractPointer):
bmap.BMMeshTrans_Delete(self._get_pointer()) bmap.BMMeshTrans_Delete(self._get_pointer())
self._set_pointer(g_InvalidPtr) self._set_pointer(g_InvalidPtr)
def parse(self, bmfile: BMFileWriter, objmesh: BMMesh) -> None:
bmap.BMMeshTrans_Parse(self._get_pointer(), bmfile._get_pointer(), objmesh._get_ckid())
def prepare_vertex(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
# prepare count first
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
bmap.BMMeshTrans_PrepareVertexCount(self._get_pointer(), csize)
# get raw pointer and conv to float ptr for convenient visit
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareVertex(self._get_pointer(), ctypes.byref(raw_vector))
raw_float: bmap.bm_CKFLOAT_p = ctypes.cast(raw_vector, bmap.bm_CKFLOAT_p)
# iterate iterator and set
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector3 = next(itor)
raw_float[idx] = uservector.x
raw_float[idx + 1] = uservector.y
raw_float[idx + 2] = uservector.z
idx += 3
def prepare_normal(self, count: int, itor: typing.Iterator[virtools_types.VxVector3]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
bmap.BMMeshTrans_PrepareNormalCount(self._get_pointer(), csize)
raw_vector: bmap.bm_VxVector3_p = bmap.bm_VxVector3_p()
bmap.BMMeshTrans_PrepareNormal(self._get_pointer(), ctypes.byref(raw_vector))
raw_float: bmap.bm_CKFLOAT_p = ctypes.cast(raw_vector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector3 = next(itor)
raw_float[idx] = uservector.x
raw_float[idx + 1] = uservector.y
raw_float[idx + 2] = uservector.z
idx += 3
def prepare_uv(self, count: int, itor: typing.Iterator[virtools_types.VxVector2]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
bmap.BMMeshTrans_PrepareUVCount(self._get_pointer(), csize)
raw_vector: bmap.bm_VxVector2_p = bmap.bm_VxVector2_p()
bmap.BMMeshTrans_PrepareUV(self._get_pointer(), ctypes.byref(raw_vector))
raw_float: bmap.bm_CKFLOAT_p = ctypes.cast(raw_vector, bmap.bm_CKFLOAT_p)
idx: int = 0
for _ in range(count):
uservector: virtools_types.VxVector2 = next(itor)
raw_float[idx] = uservector.x
raw_float[idx + 1] = uservector.y
idx += 2
def prepare_mtl_slot(self, count: int, itor: typing.Iterator[BMMaterial | None]) -> None:
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
bmap.BMMeshTrans_PrepareMtlSlotCount(self._get_pointer(), csize)
raw_ckid: bmap.bm_CKID_p = bmap.bm_CKID_p()
bmap.BMMeshTrans_PrepareMtlSlot(self._get_pointer(), ctypes.byref(raw_ckid))
idx: int = 0
for _ in range(count):
usermtl: BMMaterial = next(itor)
if usermtl is None:
raw_ckid[idx] = g_InvalidCKID
else:
raw_ckid[idx] = usermtl._get_ckid().value
idx += 1
def prepare_face(self,
count: int,
vec_idx: typing.Iterator[int],
nml_idx: typing.Iterator[int],
uv_idx: typing.Iterator[int],
mtl_idx: typing.Iterator[int]) -> None:
"""
The count of `vec_idx`, `nml_idx`, `uv_idx` must equal with `3 * count`.
And `mtl_idx`'s length must equal with `count`.
"""
# prepare face size
csize: bmap.bm_CKDWORD = bmap.bm_CKDWORD(count)
bmap.BMMeshTrans_PrepareFaceCount(self._get_pointer(), csize)
# get 4 raw pointer for following assign
raw_vec_idx: bmap.bm_CKDWORD_p = bmap.bm_CKDWORD_p()
raw_nml_idx: bmap.bm_CKDWORD_p = bmap.bm_CKDWORD_p()
raw_uv_idx: bmap.bm_CKDWORD_p = bmap.bm_CKDWORD_p()
raw_mtl_idx: bmap.bm_CKDWORD_p = bmap.bm_CKDWORD_p()
bmap.BMMeshTrans_PrepareFaceVertexIndices(self._get_pointer(), ctypes.byref(raw_vec_idx))
bmap.BMMeshTrans_PrepareFaceNormalIndices(self._get_pointer(), ctypes.byref(raw_nml_idx))
bmap.BMMeshTrans_PrepareFaceUVIndices(self._get_pointer(), ctypes.byref(raw_uv_idx))
bmap.BMMeshTrans_PrepareFaceMtlSlot(self._get_pointer(), ctypes.byref(raw_mtl_idx))
# iterate and assign
idx3: int = 0
idx1: int = 0
for _ in range(count):
raw_vec_idx[idx3] = next(vec_idx)
raw_vec_idx[idx3 + 1] = next(vec_idx)
raw_vec_idx[idx3 + 2] = next(vec_idx)
raw_nml_idx[idx3] = next(nml_idx)
raw_nml_idx[idx3 + 1] = next(nml_idx)
raw_nml_idx[idx3 + 2] = next(nml_idx)
raw_uv_idx[idx3] = next(uv_idx)
raw_uv_idx[idx3 + 1] = next(uv_idx)
raw_uv_idx[idx3 + 2] = next(uv_idx)
idx3 += 3
raw_mtl_idx[idx1] = next(mtl_idx)
idx1 += 1
#endregion #endregion

View File

@ -132,6 +132,53 @@ class VxMatrix():
self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3] self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3]
) )
class CK_TEXTURE_SAVEOPTIONS(enum.IntEnum):
"""!
Specify the way textures or sprites will be saved
"""
CKTEXTURE_RAWDATA = 0 ##< Save raw data inside file. The bitmap is saved in a raw 32 bit per pixel format.
CKTEXTURE_EXTERNAL = 1 ##< Store only the file name for the texture. The bitmap file must be present in the bitmap paths when loading the composition.
CKTEXTURE_IMAGEFORMAT = 2 ##< Save using format specified. The bitmap data will be converted to the specified format by the correspondant bitmap plugin and saved inside file.
CKTEXTURE_USEGLOBAL = 3 ##< Use Global settings, that is the settings given with CKContext::SetGlobalImagesSaveOptions. (Not valid when using CKContext::SetImagesSaveOptions).
CKTEXTURE_INCLUDEORIGINALFILE = 4 ##< Insert original image file inside CMO file. The bitmap file that was used originally for the texture or sprite will be append to the composition file and extracted when the file is loaded.
class VX_PIXELFORMAT(enum.IntEnum):
"""!
Pixel format types.
"""
UNKNOWN_PF = 0 ##< Unknown pixel format
_32_ARGB8888 = 1 ##< 32-bit ARGB pixel format with alpha
_32_RGB888 = 2 ##< 32-bit RGB pixel format without alpha
_24_RGB888 = 3 ##< 24-bit RGB pixel format
_16_RGB565 = 4 ##< 16-bit RGB pixel format
_16_RGB555 = 5 ##< 16-bit RGB pixel format (5 bits per color)
_16_ARGB1555 = 6 ##< 16-bit ARGB pixel format (5 bits per color + 1 bit for alpha)
_16_ARGB4444 = 7 ##< 16-bit ARGB pixel format (4 bits per color)
_8_RGB332 = 8 ##< 8-bit RGB pixel format
_8_ARGB2222 = 9 ##< 8-bit ARGB pixel format
_32_ABGR8888 = 10 ##< 32-bit ABGR pixel format
_32_RGBA8888 = 11 ##< 32-bit RGBA pixel format
_32_BGRA8888 = 12 ##< 32-bit BGRA pixel format
_32_BGR888 = 13 ##< 32-bit BGR pixel format
_24_BGR888 = 14 ##< 24-bit BGR pixel format
_16_BGR565 = 15 ##< 16-bit BGR pixel format
_16_BGR555 = 16 ##< 16-bit BGR pixel format (5 bits per color)
_16_ABGR1555 = 17 ##< 16-bit ABGR pixel format (5 bits per color + 1 bit for alpha)
_16_ABGR4444 = 18 ##< 16-bit ABGR pixel format (4 bits per color)
_DXT1 = 19 ##< S3/DirectX Texture Compression 1
_DXT2 = 20 ##< S3/DirectX Texture Compression 2
_DXT3 = 21 ##< S3/DirectX Texture Compression 3
_DXT4 = 22 ##< S3/DirectX Texture Compression 4
_DXT5 = 23 ##< S3/DirectX Texture Compression 5
_16_V8U8 = 24 ##< 16-bit Bump Map format format (8 bits per color)
_32_V16U16 = 25 ##< 32-bit Bump Map format format (16 bits per color)
_16_L6V5U5 = 26 ##< 16-bit Bump Map format format with luminance
_32_X8L8V8U8 = 27 ##< 32-bit Bump Map format format with luminance
_8_ABGR8888_CLUT = 28 ##< 8 bits indexed CLUT (ABGR)
_8_ARGB8888_CLUT = 29 ##< 8 bits indexed CLUT (ARGB)
_4_ABGR8888_CLUT = 30 ##< 4 bits indexed CLUT (ABGR)
_4_ARGB8888_CLUT = 31 ##< 4 bits indexed CLUT (ARGB)
class VXTEXTURE_BLENDMODE(enum.IntEnum): class VXTEXTURE_BLENDMODE(enum.IntEnum):
"""! """!
Blend Mode Flags Blend Mode Flags