mirror of
https://github.com/red031000/nitrog3d.git
synced 2025-06-18 13:15:35 -04:00
start on shape commands
This commit is contained in:
parent
53f8dc0034
commit
db40db6ef7
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ all: nitrog3d
|
||||
|
||||
nitrog3d:
|
||||
mkdir -p io_scene_g3d
|
||||
cp __init__.py import_nsbmd.py utils.py io_scene_g3d
|
||||
cp __init__.py import_nsbmd.py utils.py g3_commands.py io_scene_g3d
|
||||
zip -r nitrog3d.zip io_scene_g3d
|
||||
rm -rf io_scene_g3d
|
||||
|
||||
|
191
g3_commands.py
Normal file
191
g3_commands.py
Normal file
@ -0,0 +1,191 @@
|
||||
from .utils import error, read32, np_fixed_to_float, fixed_to_float, to_rgb, vec10_to_vec
|
||||
from enum import IntEnum
|
||||
import numpy as np
|
||||
|
||||
def parse_dl(data, size, report_func):
|
||||
offset = 0
|
||||
display_list = []
|
||||
while offset < size:
|
||||
commandData = read32(data, offset)
|
||||
offset += 4
|
||||
commands, offset = parse_dl_command(data, offset, commandData, report_func)
|
||||
display_list.append(commands)
|
||||
return display_list
|
||||
|
||||
def parse_dl_command(data, offset, commandData, report_func):
|
||||
commands = []
|
||||
for i in range(4):
|
||||
command = (commandData >> i * 8) & 0xFF
|
||||
|
||||
if command == 0x00:
|
||||
commands.append(DLCommandNoop())
|
||||
elif command == 0x10:
|
||||
mode = MatrixMode(read32(data, offset))
|
||||
offset += 4
|
||||
commands.append(DLCommandMtxMode(mode))
|
||||
elif command == 0x11:
|
||||
commands.append(DLCommandPushMtx())
|
||||
elif command == 0x12:
|
||||
matrixId = read32(data, offset)
|
||||
offset += 4
|
||||
commands.append(DLCommandPopMtx(matrixId))
|
||||
elif command == 0x13:
|
||||
matrixId = read32(data, offset)
|
||||
offset += 4
|
||||
commands.append(DLCommandStoreMtx(matrixId))
|
||||
elif command == 0x14:
|
||||
matrixId = read32(data, offset)
|
||||
offset += 4
|
||||
commands.append(DLCommandRestoreMtx(matrixId))
|
||||
elif command == 0x15:
|
||||
commands.append(DLCommandIdentity())
|
||||
elif command == 0x16:
|
||||
matrix = np_fixed_to_float(np.frombuffer(data[offset:offset + 64], dtype=np.dtype('uint32').newbyteorder('<')).reshape((4, 4)))
|
||||
offset += 64
|
||||
commands.append(DLCommandLoadMtx44(matrix))
|
||||
elif command == 0x17:
|
||||
matrix = np_fixed_to_float(np.frombuffer(data[offset:offset + 48], dtype=np.dtype('uint32').newbyteorder('<')).reshape((4, 3)))
|
||||
offset += 48
|
||||
commands.append(DLCommandLoadMtx43(matrix))
|
||||
elif command == 0x18:
|
||||
matrix = np_fixed_to_float(np.frombuffer(data[offset:offset + 64], dtype=np.dtype('uint32').newbyteorder('<')).reshape((4, 4)))
|
||||
offset += 64
|
||||
commands.append(DLCommandMultMtx44(matrix))
|
||||
elif command == 0x19:
|
||||
matrix = np_fixed_to_float(np.frombuffer(data[offset:offset + 48], dtype=np.dtype('uint32').newbyteorder('<')).reshape((4, 3)))
|
||||
offset += 48
|
||||
commands.append(DLCommandMultMtx43(matrix))
|
||||
elif command == 0x1A:
|
||||
matrix = np_fixed_to_float(np.frombuffer(data[offset:offset + 36], dtype=np.dtype('uint32').newbyteorder('<')).reshape((3, 3)))
|
||||
offset += 36
|
||||
commands.append(DLCommandMultMtx33(matrix))
|
||||
elif command == 0x1B:
|
||||
x = fixed_to_float(read32(data, offset))
|
||||
y = fixed_to_float(read32(data, offset + 4))
|
||||
z = fixed_to_float(read32(data, offset + 8))
|
||||
matrix = np.identity(4)
|
||||
matrix[0, 0] = x
|
||||
matrix[1, 1] = y
|
||||
matrix[2, 2] = z
|
||||
offset += 12
|
||||
commands.append(DLCommandScale(matrix))
|
||||
elif command == 0x1C:
|
||||
x = fixed_to_float(read32(data, offset))
|
||||
y = fixed_to_float(read32(data, offset + 4))
|
||||
z = fixed_to_float(read32(data, offset + 8))
|
||||
matrix = np.identity(4)
|
||||
matrix[0, 3] = x
|
||||
matrix[1, 3] = y
|
||||
matrix[2, 3] = z
|
||||
offset += 12
|
||||
commands.append(DLCommandTranslate(matrix))
|
||||
elif command == 0x20:
|
||||
color = read32(data, offset)
|
||||
rgb = to_rgb(color)
|
||||
offset += 4
|
||||
commands.append(DLCommandColor(rgb))
|
||||
elif command == 0x21:
|
||||
normal = vec10_to_vec(read32(data, offset))
|
||||
offset += 4
|
||||
commands.append(DLCommandNormal(normal))
|
||||
elif command == 0x22:
|
||||
texcoord = read32(data, offset)
|
||||
s = fixed_to_float((texcoord & 0xFFFF) << 8) # unsure if this shift is correct
|
||||
t = fixed_to_float(((texcoord >> 16) & 0xFFFF) << 8)
|
||||
offset += 4
|
||||
commands.append(DLCommandTexcoord(s, t))
|
||||
#todo more commands
|
||||
return commands, offset
|
||||
|
||||
class MatrixMode(IntEnum):
|
||||
PROJECTION = 0
|
||||
POSITION = 1
|
||||
POSITION_VECTOR = 2
|
||||
TEXTURE = 3
|
||||
|
||||
class DLCommand:
|
||||
def __init__(self, commandId):
|
||||
self.commandId = commandId
|
||||
|
||||
class DLCommandNoop(DLCommand):
|
||||
def __init__(self):
|
||||
super().__init__(0x00)
|
||||
|
||||
class DLCommandMtxMode(DLCommand):
|
||||
def __init__(self, mode):
|
||||
super().__init__(0x10)
|
||||
self.mode = mode
|
||||
|
||||
class DLCommandPushMtx(DLCommand):
|
||||
def __init__(self):
|
||||
super().__init__(0x11)
|
||||
|
||||
class DLCommandPopMtx(DLCommand):
|
||||
def __init__(self, matrixId):
|
||||
super().__init__(0x12)
|
||||
self.matrixId = matrixId
|
||||
|
||||
class DLCommandStoreMtx(DLCommand):
|
||||
def __init__(self, matrixId):
|
||||
super().__init__(0x13)
|
||||
self.matrixId = matrixId
|
||||
|
||||
class DLCommandRestoreMtx(DLCommand):
|
||||
def __init__(self, matrixId):
|
||||
super().__init__(0x14)
|
||||
self.matrixId = matrixId
|
||||
|
||||
class DLCommandIdentity(DLCommand):
|
||||
def __init__(self):
|
||||
super().__init__(0x15)
|
||||
|
||||
class DLCommandLoadMtx44(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x16)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandLoadMtx43(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x17)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandMultMtx44(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x18)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandMultMtx43(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x19)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandMultMtx33(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x1A)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandScale(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x1B)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandTranslate(DLCommand):
|
||||
def __init__(self, matrix):
|
||||
super().__init__(0x1C)
|
||||
self.matrix = matrix
|
||||
|
||||
class DLCommandColor(DLCommand):
|
||||
def __init__(self, color):
|
||||
super().__init__(0x20)
|
||||
self.color = color
|
||||
|
||||
class DLCommandNormal(DLCommand):
|
||||
def __init__(self, normal):
|
||||
super().__init__(0x21)
|
||||
self.normal = normal
|
||||
|
||||
class DLCommandTexcoord(DLCommand):
|
||||
def __init__(self, s, t):
|
||||
super().__init__(0x22)
|
||||
self.s = s
|
||||
self.t = t
|
@ -1,6 +1,7 @@
|
||||
from enum import IntEnum, IntFlag
|
||||
from os.path import isfile
|
||||
from .utils import read8, read16, read32, read_str, log, debug, parse_dictionary, fixed_to_float, to_rgb
|
||||
from .g3_commands import parse_dl
|
||||
import numpy as np
|
||||
|
||||
class ScalingRule(IntEnum):
|
||||
@ -393,6 +394,33 @@ class NSBMDMaterial():
|
||||
def add_palette_mat_data(self, palette_mat_data):
|
||||
self.paletteMatData.append(palette_mat_data)
|
||||
|
||||
class ShapeFlags(IntFlag):
|
||||
USE_NORMAL = 0x0001
|
||||
USE_COLOR = 0x0002
|
||||
USE_TEXCOORD = 0x0004
|
||||
USE_RESTOREMTX = 0x0008
|
||||
|
||||
class NSBMDShape():
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.useNormal = False
|
||||
self.useColor = False
|
||||
self.useTexCoord = False
|
||||
self.useRestoreMtx = False
|
||||
|
||||
def parse_flags(self, flags, report_func):
|
||||
self.useNormal = (flags & ShapeFlags.USE_NORMAL) != 0
|
||||
log('Use normal: %s' % self.useNormal, report_func)
|
||||
|
||||
self.useColor = (flags & ShapeFlags.USE_COLOR) != 0
|
||||
log('Use color: %s' % self.useColor, report_func)
|
||||
|
||||
self.useTexCoord = (flags & ShapeFlags.USE_TEXCOORD) != 0
|
||||
log('Use tex coord: %s' % self.useTexCoord, report_func)
|
||||
|
||||
self.useRestoreMtx = (flags & ShapeFlags.USE_RESTOREMTX) != 0
|
||||
log('Use restore mtx: %s' % self.useRestoreMtx, report_func)
|
||||
|
||||
class NSBMDModel():
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@ -541,11 +569,12 @@ class NSBMDImporter():
|
||||
if material_value < matIdxDataEnd:
|
||||
matIdxDataEnd = material_value
|
||||
|
||||
dict_size = read16(materialset_data[offsetDictPlttToMat:], 2)
|
||||
dict_size = read16(materialset_data[offsetDictPlttToMat:], 0x2)
|
||||
model.matIdxData = materialset_data[offsetDictPlttToMat + dict_size:matIdxDataEnd].tobytes() # no idea how this is used, but essential
|
||||
log('Material id data: %s' % model.matIdxData.hex(" "), self.report)
|
||||
|
||||
for material_key, material_value in materialset_dictionary.items():
|
||||
log('%s: %08X' % (material_key, material_value), self.report)
|
||||
material = NSBMDMaterial(material_key)
|
||||
material_data = materialset_data[material_value:]
|
||||
diffAmb = read32(material_data, 0x04)
|
||||
@ -646,8 +675,18 @@ class NSBMDImporter():
|
||||
material_id = read8(pltt_mat_data, i)
|
||||
pltt_mat = NSBMDPaletteMaterialData(pltt_mat_key, material_id, pltt_mat_bound)
|
||||
model.materials[material_id].add_palette_mat_data(pltt_mat)
|
||||
|
||||
|
||||
shape_data = data[shape_offset:]
|
||||
shape_dictionary = parse_dictionary(shape_data)
|
||||
for shape_key, shape_value in shape_dictionary.items():
|
||||
log('%s: %08X' % (shape_key, shape_value), self.report)
|
||||
shape = NSBMDShape(shape_key)
|
||||
shape_item_data = shape_data[shape_value:]
|
||||
shape_flags = read32(shape_item_data, 0x04)
|
||||
shape.parse_flags(shape_flags, self.report)
|
||||
shape_dl_offset = read32(shape_item_data, 0x08)
|
||||
shape_dl_size = read32(shape_item_data, 0x0C)
|
||||
shape.dlData = parse_dl(shape_data[shape_dl_offset:], shape_dl_size, self.report)
|
||||
|
||||
#todo
|
||||
return nsbmd
|
||||
|
9
utils.py
9
utils.py
@ -24,6 +24,9 @@ def read_dict_string(data, offset):
|
||||
def log(string, report_func):
|
||||
report_func(type={"INFO"}, message=string)
|
||||
|
||||
def error(string, report_func):
|
||||
report_func(type={"ERROR"}, message=string)
|
||||
|
||||
def debug(string, report_func):
|
||||
report_func(type={"DEBUG"}, message=string)
|
||||
|
||||
@ -53,3 +56,9 @@ def fixed_to_float(value):
|
||||
|
||||
def to_rgb(color):
|
||||
return (color & 0x1F, (color >> 5) & 0x1F, (color >> 10) & 0x1F)
|
||||
|
||||
def np_fixed_to_float(value):
|
||||
return (value / 4096.0).astype('float')
|
||||
|
||||
def vec10_to_vec(value):
|
||||
return (value & 0x3FF, (value >> 10) & 0x3FF, (value >> 20) & 0x3FF)
|
Loading…
Reference in New Issue
Block a user