finish ballance element
This commit is contained in:
parent
c1f92c7244
commit
1eaaedfcbd
@ -1,6 +1,6 @@
|
||||
import bpy
|
||||
import os, typing, enum
|
||||
from . import UTIL_functions, UTIL_blender_mesh
|
||||
import os, typing, enum, array
|
||||
from . import UTIL_functions, UTIL_file_io, UTIL_blender_mesh, UTIL_virtools_types
|
||||
|
||||
#region Raw Elements Operations
|
||||
|
||||
@ -86,11 +86,97 @@ def get_ballance_elements() -> bpy.types.CollectionProperty:
|
||||
|
||||
#endregion
|
||||
|
||||
#region
|
||||
#region Element Loader
|
||||
|
||||
def load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
def _save_element(mesh: bpy.types.Mesh, filename: str) -> None:
|
||||
# todo: if we need add element placeholder save operator,
|
||||
# write this function and call this function in operator.
|
||||
pass
|
||||
|
||||
def _load_element(mesh: bpy.types.Mesh, element_id: int) -> None:
|
||||
# resolve mesh path
|
||||
element_name: str | None = get_ballance_element_name(element_id)
|
||||
if element_name is None:
|
||||
raise UTIL_functions.BBPException('invalid element id in _load_element()')
|
||||
|
||||
element_filename: str = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"meshes",
|
||||
element_name + '.bin'
|
||||
)
|
||||
|
||||
# open file and read
|
||||
with open(element_filename, 'rb') as fmesh:
|
||||
# prepare container
|
||||
vpos: array.array = array.array('f')
|
||||
vnml: array.array = array.array('f')
|
||||
face: array.array = array.array('L')
|
||||
|
||||
# read data
|
||||
# position is vector3
|
||||
vpos_count = UTIL_file_io.read_uint32(fmesh)
|
||||
vpos.extend(UTIL_file_io.read_float_array(fmesh, vpos_count * 3))
|
||||
# normal is vector3
|
||||
vnml_count = UTIL_file_io.read_uint32(fmesh)
|
||||
vnml.extend(UTIL_file_io.read_float_array(fmesh, vnml_count * 3))
|
||||
# each face use 6 uint32 to describe,
|
||||
# they are: pos1, nml1, pos2, nml2, pos3, nml3.
|
||||
# each item is a 0 based index refering to corresponding list
|
||||
face_count = UTIL_file_io.read_uint32(fmesh)
|
||||
face.extend(UTIL_file_io.read_uint32_array(fmesh, face_count * 6))
|
||||
|
||||
# open mesh writer and write data
|
||||
with UTIL_blender_mesh.MeshWriter(mesh) as writer:
|
||||
# prepare writer essential function
|
||||
mesh_part: UTIL_blender_mesh.MeshWriter.MeshWriterPartData = UTIL_blender_mesh.MeshWriter.MeshWriterPartData()
|
||||
def vpos_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
v: UTIL_virtools_types.VxVector3 = UTIL_virtools_types.VxVector3()
|
||||
for i in range(vpos_count):
|
||||
idx: int = i * 3
|
||||
v.x = vpos[idx]
|
||||
v.y = vpos[idx + 1]
|
||||
v.z = vpos[idx + 2]
|
||||
yield v
|
||||
mesh_part.mVertexPosition = vpos_iterator()
|
||||
def vnml_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector3]:
|
||||
v: UTIL_virtools_types.VxVector3 = UTIL_virtools_types.VxVector3()
|
||||
for i in range(vnml_count):
|
||||
idx: int = i * 3
|
||||
v.x = vnml[idx]
|
||||
v.y = vnml[idx + 1]
|
||||
v.z = vnml[idx + 2]
|
||||
yield v
|
||||
mesh_part.mVertexNormal = vnml_iterator()
|
||||
def vuv_iterator() -> typing.Iterator[UTIL_virtools_types.VxVector2]:
|
||||
v: UTIL_virtools_types.VxVector2 = UTIL_virtools_types.VxVector2()
|
||||
yield v
|
||||
mesh_part.mVertexUV = vuv_iterator()
|
||||
def mtl_iterator() -> typing.Iterator[bpy.types.Material]:
|
||||
pass
|
||||
mesh_part.mMaterial = mtl_iterator()
|
||||
def face_iterator() -> typing.Iterator[UTIL_blender_mesh.FaceData]:
|
||||
# create face data with 3 placeholder
|
||||
f: UTIL_blender_mesh.FaceData = UTIL_blender_mesh.FaceData([UTIL_blender_mesh.FaceVertexData() for i in range(3)])
|
||||
for i in range(face_count):
|
||||
idx: int = i * 6
|
||||
f.mIndices[0].mPosIdx = face[idx]
|
||||
f.mIndices[0].mNmlIdx = face[idx + 1]
|
||||
f.mIndices[1].mPosIdx = face[idx + 2]
|
||||
f.mIndices[1].mNmlIdx = face[idx + 3]
|
||||
f.mIndices[2].mPosIdx = face[idx + 4]
|
||||
f.mIndices[2].mNmlIdx = face[idx + 5]
|
||||
yield f
|
||||
mesh_part.mFace = face_iterator()
|
||||
|
||||
writer.add_part(mesh_part)
|
||||
|
||||
# end of with writer
|
||||
# write mesh data
|
||||
|
||||
# end of with fmesh
|
||||
# close file
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ballance Elements Operation Help Class & Functions
|
||||
@ -154,7 +240,7 @@ class BallanceElementsHelper():
|
||||
raise UTIL_functions.BBPException('invalid element id')
|
||||
new_mesh: bpy.types.Mesh = bpy.data.meshes.new(get_ballance_element_name(element_id))
|
||||
|
||||
load_element(new_mesh, element_id)
|
||||
_load_element(new_mesh, element_id)
|
||||
self.__mElementMap[element_id] = new_mesh
|
||||
return new_mesh
|
||||
|
||||
@ -199,7 +285,7 @@ def reset_ballance_elements() -> None:
|
||||
if eleid is None or item.mesh_ptr is None:
|
||||
invalid_idx.append(index)
|
||||
else:
|
||||
load_element(item.mesh_ptr, eleid)
|
||||
_load_element(item.mesh_ptr, eleid)
|
||||
|
||||
# inc counter
|
||||
index += 1
|
||||
|
87
bbp_ng/UTIL_file_io.py
Normal file
87
bbp_ng/UTIL_file_io.py
Normal file
@ -0,0 +1,87 @@
|
||||
import bpy, mathutils
|
||||
import struct, os, io, typing
|
||||
from . import UTIL_virtools_types
|
||||
|
||||
_FileWriter_t = io.BufferedWriter
|
||||
_FileReader_t = io.BufferedReader
|
||||
|
||||
#region Writer Functions
|
||||
|
||||
def write_string(fs: _FileWriter_t, strl: str) -> None:
|
||||
count = len(strl)
|
||||
write_uint32(fs, count)
|
||||
fs.write(strl.encode("utf_32_le"))
|
||||
|
||||
def write_uint8(fs: _FileWriter_t, num: int) -> None:
|
||||
fs.write(struct.pack("<B", num))
|
||||
|
||||
def write_uint32(fs: _FileWriter_t, num: int) -> None:
|
||||
fs.write(struct.pack("<I", num))
|
||||
|
||||
def write_uint64(fs: _FileWriter_t, num: int) -> None:
|
||||
fs.write(struct.pack("<Q", num))
|
||||
|
||||
def write_bool(fs: _FileWriter_t, boolean: bool) -> None:
|
||||
if boolean:
|
||||
write_uint8(fs, 1)
|
||||
else:
|
||||
write_uint8(fs, 0)
|
||||
|
||||
def write_float(fs: _FileWriter_t, fl: float) -> None:
|
||||
fs.write(struct.pack("<f", fl))
|
||||
|
||||
def write_world_matrix(fs: _FileWriter_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
||||
fs.write(struct.pack("<16f", *mat.to_tuple()))
|
||||
|
||||
def write_color(fs: _FileWriter_t, colors: UTIL_virtools_types.VxColor) -> None:
|
||||
fs.write(struct.pack("<fff", *colors.to_tuple_rgb()))
|
||||
|
||||
def write_uint32_array(fs: _FileWriter_t, vals: typing.Iterable[int], count: int) -> None:
|
||||
fs.write(struct.pack('<' + str(count) + 'I', *vals))
|
||||
|
||||
def write_float_array(fs: _FileWriter_t, vals: typing.Iterable[float], count: int) -> None:
|
||||
fs.write(struct.pack('<' + str(count) + 'f', *vals))
|
||||
|
||||
#endregion
|
||||
|
||||
#region Reader Functions
|
||||
|
||||
def peek_stream(fs: _FileReader_t) -> bytes:
|
||||
res = fs.read(1)
|
||||
fs.seek(-1, os.SEEK_CUR)
|
||||
return res
|
||||
|
||||
def read_float(fs: _FileReader_t) -> float:
|
||||
return struct.unpack("f", fs.read(4))[0]
|
||||
|
||||
def read_uint8(fs: _FileReader_t) -> int:
|
||||
return struct.unpack("B", fs.read(1))[0]
|
||||
|
||||
def read_uint32(fs: _FileReader_t) -> int:
|
||||
return struct.unpack("I", fs.read(4))[0]
|
||||
|
||||
def read_uint64(fs: _FileReader_t) -> int:
|
||||
return struct.unpack("Q", fs.read(8))[0]
|
||||
|
||||
def read_string(fs: _FileReader_t) -> str:
|
||||
count = read_uint32(fs)
|
||||
return fs.read(count * 4).decode("utf_32_le")
|
||||
|
||||
def read_bool(fs: _FileReader_t) -> None:
|
||||
return read_uint8(fs) != 0
|
||||
|
||||
def read_world_materix(fs: _FileReader_t, mat: UTIL_virtools_types.VxMatrix) -> None:
|
||||
mat.from_tuple(struct.unpack("<16f", fs.read(16 * 4)))
|
||||
|
||||
def read_color(fs: _FileReader_t, target: UTIL_virtools_types.VxColor) -> None:
|
||||
target.from_tuple_rgb(struct.unpack("fff", fs.read(3 * 4)))
|
||||
|
||||
def read_uint32_array(fs: _FileReader_t, count: int) -> tuple[int, ...]:
|
||||
fmt: struct.Struct = struct.Struct('<' + str(count) + 'I')
|
||||
return fmt.unpack(fs.read(fmt.size))
|
||||
|
||||
def read_float_array(fs: _FileReader_t, count: int) -> tuple[float, ...]:
|
||||
fmt: struct.Struct = struct.Struct('<' + str(count) + 'f')
|
||||
return fmt.unpack(fs.read(fmt.size))
|
||||
|
||||
#endregion
|
@ -1,3 +1,4 @@
|
||||
import mathutils
|
||||
import typing, enum
|
||||
from . import UTIL_functions
|
||||
|
||||
@ -100,6 +101,85 @@ class VxColor():
|
||||
self.g = UTIL_functions.clamp_float(self.g, 0.0, 1.0)
|
||||
self.b = UTIL_functions.clamp_float(self.b, 0.0, 1.0)
|
||||
|
||||
class VxMatrix():
|
||||
"""
|
||||
The Matrix representation.
|
||||
The bracket statement exactly equal with Virtools.
|
||||
"""
|
||||
__mData: list[list[float]]
|
||||
|
||||
def __init__(self):
|
||||
# init array
|
||||
self.__mData = [[0] * 4 for i in range(4)]
|
||||
# set to identy
|
||||
self.reset()
|
||||
|
||||
def from_tuple(self, data: tuple[float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float]) -> None:
|
||||
(
|
||||
self.__mData[0][0], self.__mData[0][1], self.__mData[0][2], self.__mData[0][3],
|
||||
self.__mData[1][0], self.__mData[1][1], self.__mData[1][2], self.__mData[1][3],
|
||||
self.__mData[2][0], self.__mData[2][1], self.__mData[2][2], self.__mData[2][3],
|
||||
self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3]
|
||||
) = data
|
||||
|
||||
def from_blender(self, data_: mathutils.Matrix) -> None:
|
||||
# transposed first
|
||||
data: mathutils.Matrix = data_.transposed()
|
||||
(
|
||||
self.__mData[0][0], self.__mData[0][1], self.__mData[0][2], self.__mData[0][3],
|
||||
self.__mData[1][0], self.__mData[1][1], self.__mData[1][2], self.__mData[1][3],
|
||||
self.__mData[2][0], self.__mData[2][1], self.__mData[2][2], self.__mData[2][3],
|
||||
self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3]
|
||||
) = (
|
||||
data[0][0], data[0][1], data[0][2], data[0][3],
|
||||
data[1][0], data[1][1], data[1][2], data[1][3],
|
||||
data[2][0], data[2][1], data[2][2], data[2][3],
|
||||
data[3][0], data[3][1], data[3][2], data[3][3]
|
||||
)
|
||||
|
||||
def to_tuple(self) -> tuple[float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float]:
|
||||
return (
|
||||
self.__mData[0][0], self.__mData[0][1], self.__mData[0][2], self.__mData[0][3],
|
||||
self.__mData[1][0], self.__mData[1][1], self.__mData[1][2], self.__mData[1][3],
|
||||
self.__mData[2][0], self.__mData[2][1], self.__mData[2][2], self.__mData[2][3],
|
||||
self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3]
|
||||
)
|
||||
|
||||
def to_tuple(self) -> mathutils.Matrix:
|
||||
data: mathutils.Matrix = mathutils.Matrix(
|
||||
(self.__mData[0][0], self.__mData[0][1], self.__mData[0][2], self.__mData[0][3]),
|
||||
(self.__mData[1][0], self.__mData[1][1], self.__mData[1][2], self.__mData[1][3]),
|
||||
(self.__mData[2][0], self.__mData[2][1], self.__mData[2][2], self.__mData[2][3]),
|
||||
(self.__mData[3][0], self.__mData[3][1], self.__mData[3][2], self.__mData[3][3]),
|
||||
)
|
||||
# transpose self
|
||||
data.transpose()
|
||||
return data
|
||||
|
||||
def reset(self) -> None:
|
||||
# reset to identy
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
self.__mData[i][j] = 0.0
|
||||
|
||||
self.__mData[0][0] = 1.0
|
||||
self.__mData[1][1] = 1.0
|
||||
self.__mData[2][2] = 1.0
|
||||
self.__mData[3][3] = 1.0
|
||||
|
||||
def __swap_row_column(self) -> None:
|
||||
# swap column 1 and 2
|
||||
for i in range(4):
|
||||
self.__mData[i][1], self.__mData[i][2] = self.__mData[i][2], self.__mData[i][1]
|
||||
# swap row 1 and 2
|
||||
for i in range(4):
|
||||
self.__mData[1][i], self.__mData[2][i] = self.__mData[2][i], self.__mData[1][i]
|
||||
|
||||
def to_virtools_matrix(self) -> None:
|
||||
self.__swap_row_column()
|
||||
|
||||
def to_blender_matrix(self) -> None:
|
||||
self.__swap_row_column()
|
||||
|
||||
class VXTEXTURE_BLENDMODE(enum.IntEnum):
|
||||
"""!
|
||||
|
Loading…
Reference in New Issue
Block a user