Skip to content

Commit

Permalink
Add mesh vertex normals
Browse files Browse the repository at this point in the history
  • Loading branch information
1r3n33 committed Jul 22, 2020
1 parent c44868e commit 0423234
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 52 deletions.
46 changes: 35 additions & 11 deletions blend2niff/exporter/niff2_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
from .niff2_tri import (niff2_tri_list_header_builder, niff2_tri_list_header_writer,
niff2_tri_group_node_builder, niff2_tri_group_node_writer)
from .niff2_vector import (niff2_vector_list_header_builder, niff2_vector_list_header_writer,
niff2_tri_nv_group_node_builder, niff2_tri_nv_group_node_writer,
niff2_vtx_nv_group_node_builder, niff2_vtx_nv_group_node_writer)
niff2_tri_nv_group_builder, niff2_tri_nv_group_writer,
niff2_vtx_nv_group_builder, niff2_vtx_nv_group_writer)
from .niff2_vtx import (niff2_vtx_list_header_builder, niff2_vtx_list_header_writer,
niff2_vtx_group_node_builder, niff2_vtx_group_node_writer)
from .niff2_misc import (niff2_chain_root_list_header_builder, niff2_chain_root_list_header_writer,
Expand Down Expand Up @@ -102,15 +102,14 @@ def write_niff2(data, filepath):
vtx_color_groups.append(default_vtx_color_group)

# Niff2 ColorGroup: Create mesh vertex color group.
# (!) Make sure to have the same number of tri_color_groups & vtx_color_group.
# (!) Make sure to have the same number of tri_color_groups & vtx_color_groups.
# This prevents nifftools/checknb2.exe from crashing.
# (!) Do not support smooth groups: 1 color per vertex!
# Indices are all aligned both for vertex coords and vertex colors.
# Indices are all aligned on both vertex coords and vertex colors.
for vtx_color_group_index, mesh in zip(range(len(data.meshes)), data.meshes):
mesh.calc_loop_triangles()
vtx_colors = [float]*len(mesh.vertices)*4

mesh.calc_loop_triangles()
for tri in mesh.loop_triangles:
for i in range(3):
vtx_index = tri.vertices[i]
Expand All @@ -133,13 +132,38 @@ def write_niff2(data, filepath):
tri_nv_groups = []
vtx_nv_groups = []
default_nv = [0.0, 1.0, 0.0] # up
default_tri_nv_group = niff2_tri_nv_group_node_builder(
0, default_nv)
default_vtx_nv_group = niff2_vtx_nv_group_node_builder(
0, default_nv)
default_tri_nv_group = niff2_tri_nv_group_builder(0, default_nv)
default_vtx_nv_group = niff2_vtx_nv_group_builder(0, default_nv)
tri_nv_groups.append(default_tri_nv_group)
vtx_nv_groups.append(default_vtx_nv_group)

# Niff2 VectorGroup: Create mesh vertex normals group.
# (!) Make sure to have the same number of tri_nv_groups & vtx_nv_groups.
# This prevents nifftools/checknb2.exe from crashing.
# (!) Do not support smooth groups: 1 normal per vertex!
# Indices are all aligned on both vertex coords and vertex normals.
for mesh in data.meshes:
mesh.calc_loop_triangles()
mesh.calc_normals_split()
vtx_normals = [float]*len(mesh.vertices)*3

for tri in mesh.loop_triangles:
for i in range(3):
vtx_index = tri.vertices[i]
loop_index = tri.loops[i]
normal = mesh.loops[loop_index].normal
vtx_normals[(vtx_index*3)+0] = normal[0]
vtx_normals[(vtx_index*3)+1] = normal[1]
vtx_normals[(vtx_index*3)+2] = normal[2]

tri_nv_group = niff2_tri_nv_group_builder(
len(tri_nv_groups), default_nv)
tri_nv_groups.append(tri_nv_group)

vtx_nv_group = niff2_vtx_nv_group_builder(
len(vtx_nv_groups), vtx_normals)
vtx_nv_groups.append(vtx_nv_group)

# Niff2 StGroup: Create a single default texture coordinates
st_groups = []
default_st = [0.5, 0.5] # center
Expand Down Expand Up @@ -412,9 +436,9 @@ def write_niff2(data, filepath):
niff2_vector_list_header_writer(
vector_list_header, tri_nv_groups, vtx_nv_groups, buf)
for tri_nv_group in tri_nv_groups:
niff2_tri_nv_group_node_writer(tri_nv_group, buf)
niff2_tri_nv_group_writer(tri_nv_group, buf)
for vtx_nv_group in vtx_nv_groups:
niff2_vtx_nv_group_node_writer(vtx_nv_group, buf)
niff2_vtx_nv_group_writer(vtx_nv_group, buf)

niff2_st_list_header_writer(st_list_header, st_groups, buf)
for st_group in st_groups:
Expand Down
36 changes: 18 additions & 18 deletions blend2niff/exporter/niff2_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def niff2_vector_list_header_writer(vlh, tri_nv_groups, vtx_nv_groups, buf):


#
# TriNvGroup Node
# TriNv Group
#
class Niff2TriNvGroup:
def __init__(self, index, nv_floats):
Expand All @@ -78,25 +78,25 @@ def __init__(self, index, nv_floats):
self.nv_floats = nv_floats


def niff2_tri_nv_group_node_builder(index, nv_floats):
def niff2_tri_nv_group_builder(index, nv_floats):
return Niff2TriNvGroup(index, nv_floats)


def niff2_tri_nv_group_node_writer(tri_nv_group_node, buf):
buf += tri_nv_group_node.tri_nv_group_tag.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group_node.this_tri_nv_group_index.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group_node.tri_nv_group_header_size.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group_node.tri_nv_group_size.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group_node.tri_nv_num.to_bytes(4, BYTE_ORDER)
def niff2_tri_nv_group_writer(tri_nv_group, buf):
buf += tri_nv_group.tri_nv_group_tag.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group.this_tri_nv_group_index.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group.tri_nv_group_header_size.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group.tri_nv_group_size.to_bytes(4, BYTE_ORDER)
buf += tri_nv_group.tri_nv_num.to_bytes(4, BYTE_ORDER)

for value in tri_nv_group_node.nv_floats:
for value in tri_nv_group.nv_floats:
buf += bytearray(struct.pack(">f", value))

return buf


#
# VtxNvGroup Node
# VtxNv Group
#
class Niff2VtxNvGroup:
def __init__(self, index, nv_floats):
Expand All @@ -108,18 +108,18 @@ def __init__(self, index, nv_floats):
self.nv_floats = nv_floats


def niff2_vtx_nv_group_node_builder(index, nv_floats):
def niff2_vtx_nv_group_builder(index, nv_floats):
return Niff2VtxNvGroup(index, nv_floats)


def niff2_vtx_nv_group_node_writer(vtx_nv_group_node, buf):
buf += vtx_nv_group_node.vtx_nv_group_tag.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group_node.this_vtx_nv_group_index.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group_node.vtx_nv_group_header_size.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group_node.vtx_nv_group_size.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group_node.vtx_nv_num.to_bytes(4, BYTE_ORDER)
def niff2_vtx_nv_group_writer(vtx_nv_group, buf):
buf += vtx_nv_group.vtx_nv_group_tag.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group.this_vtx_nv_group_index.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group.vtx_nv_group_header_size.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group.vtx_nv_group_size.to_bytes(4, BYTE_ORDER)
buf += vtx_nv_group.vtx_nv_num.to_bytes(4, BYTE_ORDER)

for value in vtx_nv_group_node.nv_floats:
for value in vtx_nv_group.nv_floats:
buf += bytearray(struct.pack(">f", value))

return buf
94 changes: 71 additions & 23 deletions tests/test_niff2_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

import unittest
from blend2niff.exporter.niff2_vector import (
niff2_vector_list_header_builder, niff2_tri_nv_group_node_builder, niff2_vtx_nv_group_node_builder)
niff2_vector_list_header_builder, niff2_vector_list_header_writer,
niff2_tri_nv_group_builder, niff2_tri_nv_group_writer,
niff2_vtx_nv_group_builder, niff2_vtx_nv_group_writer)


class TestNiff2Vector(unittest.TestCase):
def test_niff2_vector_list_header_builder(self):
nv_floats = [1.0, 2.0, 3.0]
tri_nv_group_node = niff2_tri_nv_group_node_builder(
123, nv_floats)
vtx_nv_group_node = niff2_vtx_nv_group_node_builder(
123, nv_floats)
tri_nv_group = niff2_tri_nv_group_builder(123, nv_floats)
vtx_nv_group = niff2_vtx_nv_group_builder(123, nv_floats)
vector_list_header = niff2_vector_list_header_builder(
[tri_nv_group_node], [vtx_nv_group_node])
[tri_nv_group], [vtx_nv_group])
self.assertEqual(vector_list_header.vector_list_tag, 0x00060000)
self.assertEqual(vector_list_header.vector_list_header_size, 36)
self.assertEqual(vector_list_header.vector_list_size, 100)
Expand All @@ -22,22 +22,70 @@ def test_niff2_vector_list_header_builder(self):
self.assertEqual(vector_list_header.nintendo_extension_block_size, 0)
self.assertEqual(vector_list_header.user_extension_block_size, 0)

def test_niff2_tri_nv_group_node_builder(self):
def test_niff2_vector_list_header_writer(self):
nv_floats = [1.0, 2.0, 3.0]
tri_nv_group_node = niff2_tri_nv_group_node_builder(
123, nv_floats)
self.assertEqual(tri_nv_group_node.tri_nv_group_tag, 0x0060100)
self.assertEqual(tri_nv_group_node.this_tri_nv_group_index, 123)
self.assertEqual(tri_nv_group_node.tri_nv_group_header_size, 20)
self.assertEqual(tri_nv_group_node.tri_nv_group_size, 32)
self.assertEqual(tri_nv_group_node.tri_nv_num, 1)

def test_niff2_vtx_nv_group_node_builder(self):
tri_nv_group = niff2_tri_nv_group_builder(123, nv_floats)
vtx_nv_group = niff2_vtx_nv_group_builder(123, nv_floats)
vector_list_header = niff2_vector_list_header_builder(
[tri_nv_group], [vtx_nv_group])
buf = niff2_vector_list_header_writer(
vector_list_header, [tri_nv_group], [vtx_nv_group], bytearray())
byte_list = [0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0x00, 0x64,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x20]
self.assertEqual(list(buf), byte_list)

def test_niff2_tri_nv_group_builder(self):
nv_floats = [1.0, 2.0, 3.0]
tri_nv_group = niff2_tri_nv_group_builder(123, nv_floats)
self.assertEqual(tri_nv_group.tri_nv_group_tag, 0x0060100)
self.assertEqual(tri_nv_group.this_tri_nv_group_index, 123)
self.assertEqual(tri_nv_group.tri_nv_group_header_size, 20)
self.assertEqual(tri_nv_group.tri_nv_group_size, 32)
self.assertEqual(tri_nv_group.tri_nv_num, 1)

def test_niff2_tri_nv_group_writer(self):
nv_floats = [1.0, 2.0, 3.0]
tri_nv_group = niff2_tri_nv_group_builder(123, nv_floats)
buf = niff2_tri_nv_group_writer(tri_nv_group, bytearray())
byte_list = [0x00, 0x06, 0x01, 0x00,
0x00, 0x00, 0x00, 0x7B,
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x01,
0x3F, 0x80, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x40, 0x40, 0x00, 0x00]
self.assertEqual(list(buf), byte_list)

def test_niff2_vtx_nv_group_builder(self):
nv_floats = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
vtx_nv_group = niff2_vtx_nv_group_builder(123, nv_floats)
self.assertEqual(vtx_nv_group.vtx_nv_group_tag, 0x0060200)
self.assertEqual(vtx_nv_group.this_vtx_nv_group_index, 123)
self.assertEqual(vtx_nv_group.vtx_nv_group_header_size, 20)
self.assertEqual(vtx_nv_group.vtx_nv_group_size, 44)
self.assertEqual(vtx_nv_group.vtx_nv_num, 2)

def test_niff2_vtx_nv_group_writer(self):
nv_floats = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
vtx_nv_group_node = niff2_vtx_nv_group_node_builder(
123, nv_floats)
self.assertEqual(vtx_nv_group_node.vtx_nv_group_tag, 0x0060200)
self.assertEqual(vtx_nv_group_node.this_vtx_nv_group_index, 123)
self.assertEqual(vtx_nv_group_node.vtx_nv_group_header_size, 20)
self.assertEqual(vtx_nv_group_node.vtx_nv_group_size, 44)
self.assertEqual(vtx_nv_group_node.vtx_nv_num, 2)
vtx_nv_group = niff2_vtx_nv_group_builder(123, nv_floats)
buf = niff2_vtx_nv_group_writer(vtx_nv_group, bytearray())
byte_list = [0x00, 0x06, 0x02, 0x00,
0x00, 0x00, 0x00, 0x7B,
0x00, 0x00, 0x00, 0x14,
0x00, 0x00, 0x00, 0x2C,
0x00, 0x00, 0x00, 0x02,
0x3F, 0x80, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x40, 0x40, 0x00, 0x00,
0x40, 0x80, 0x00, 0x00,
0x40, 0xA0, 0x00, 0x00,
0x40, 0xC0, 0x00, 0x00]
self.assertEqual(list(buf), byte_list)

0 comments on commit 0423234

Please sign in to comment.