Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Linux test

on:
push:
branches: [ "*" ]
pull_request:
branches: [ "*" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt install blender
- name: Build
run: |
blender -b --python test\test_cube_export.py
blender -b --python test\test_cube_import.py
5 changes: 5 additions & 0 deletions cube/header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extern Lights1 cube_f3dlite_material_lights;
extern Vtx cube_Cube_mesh_vtx_0[24];
extern Gfx cube_Cube_mesh_tri_0[];
extern Gfx mat_cube_f3dlite_material[];
extern Gfx cube_Cube_mesh[];
68 changes: 68 additions & 0 deletions cube/model.inc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Lights1 cube_f3dlite_material_lights = gdSPDefLights1(
0x7F, 0x7F, 0x7F,
0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49);

Vtx cube_Cube_mesh_vtx_0[24] = {
{{ {-50, -50, 50}, 0, {368, 1008}, {129, 0, 0, 255} }},
{{ {-50, 50, 50}, 0, {624, 1008}, {129, 0, 0, 255} }},
{{ {-50, 50, -50}, 0, {624, 752}, {129, 0, 0, 255} }},
{{ {-50, -50, -50}, 0, {368, 752}, {129, 0, 0, 255} }},
{{ {-50, -50, -50}, 0, {368, 752}, {0, 0, 129, 255} }},
{{ {-50, 50, -50}, 0, {624, 752}, {0, 0, 129, 255} }},
{{ {50, 50, -50}, 0, {624, 496}, {0, 0, 129, 255} }},
{{ {50, -50, -50}, 0, {368, 496}, {0, 0, 129, 255} }},
{{ {50, -50, -50}, 0, {368, 496}, {127, 0, 0, 255} }},
{{ {50, 50, -50}, 0, {624, 496}, {127, 0, 0, 255} }},
{{ {50, 50, 50}, 0, {624, 240}, {127, 0, 0, 255} }},
{{ {50, -50, 50}, 0, {368, 240}, {127, 0, 0, 255} }},
{{ {50, -50, 50}, 0, {368, 240}, {0, 0, 127, 255} }},
{{ {50, 50, 50}, 0, {624, 240}, {0, 0, 127, 255} }},
{{ {-50, 50, 50}, 0, {624, -16}, {0, 0, 127, 255} }},
{{ {-50, -50, 50}, 0, {368, -16}, {0, 0, 127, 255} }},
{{ {-50, -50, -50}, 0, {112, 496}, {0, 129, 0, 255} }},
{{ {50, -50, -50}, 0, {368, 496}, {0, 129, 0, 255} }},
{{ {50, -50, 50}, 0, {368, 240}, {0, 129, 0, 255} }},
{{ {-50, -50, 50}, 0, {112, 240}, {0, 129, 0, 255} }},
{{ {50, 50, -50}, 0, {624, 496}, {0, 127, 0, 255} }},
{{ {-50, 50, -50}, 0, {880, 496}, {0, 127, 0, 255} }},
{{ {-50, 50, 50}, 0, {880, 240}, {0, 127, 0, 255} }},
{{ {50, 50, 50}, 0, {624, 240}, {0, 127, 0, 255} }},
};

Gfx cube_Cube_mesh_tri_0[] = {
gsSPVertex(cube_Cube_mesh_vtx_0 + 0, 16, 0),
gsSP1Triangle(0, 1, 2, 0),
gsSP1Triangle(0, 2, 3, 0),
gsSP1Triangle(4, 5, 6, 0),
gsSP1Triangle(4, 6, 7, 0),
gsSP1Triangle(8, 9, 10, 0),
gsSP1Triangle(8, 10, 11, 0),
gsSP1Triangle(12, 13, 14, 0),
gsSP1Triangle(12, 14, 15, 0),
gsSPVertex(cube_Cube_mesh_vtx_0 + 16, 8, 0),
gsSP1Triangle(0, 1, 2, 0),
gsSP1Triangle(0, 2, 3, 0),
gsSP1Triangle(4, 5, 6, 0),
gsSP1Triangle(4, 6, 7, 0),
gsSPEndDisplayList(),
};

Gfx mat_cube_f3dlite_material[] = {
gsDPPipeSync(),
gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT),
gsSPTexture(65535, 65535, 0, 0, 1),
gsSPSetLights1(cube_f3dlite_material_lights),
gsSPEndDisplayList(),
};

Gfx cube_Cube_mesh[] = {
gsSPDisplayList(mat_cube_f3dlite_material),
gsSPDisplayList(cube_Cube_mesh_tri_0),
gsDPPipeSync(),
gsSPSetGeometryMode(G_LIGHTING),
gsSPClearGeometryMode(G_TEXTURE_GEN),
gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT),
gsSPTexture(65535, 65535, 0, 0, 0),
gsSPEndDisplayList(),
};

103 changes: 103 additions & 0 deletions test/test_cube_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import math
import bpy
from os.path import dirname, abspath
import sys
import mathutils

sys.path.append(dirname(dirname(dirname(abspath(__file__)))))
from fast64 import register

sys.path.append(dirname(dirname(abspath(__file__))))
from fast64_internal.utility import PluginError, applyRotation
from fast64_internal.f3d.f3d_gbi import DLFormat
from fast64_internal.f3d.f3d_material import createF3DMat, getDefaultMaterialPreset
from fast64_internal.f3d.f3d_writer import exportF3DtoC, getWriteMethodFromEnum

register()


def purge_orphans():
if bpy.app.version >= (3, 0, 0):
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
else:
# call purge_orphans() recursively until there are no more orphan data blocks to purge
result = bpy.ops.outliner.orphans_purge()
if result.pop() != "CANCELLED":
purge_orphans()


def clean_scene():
"""
Removing all of the objects, collection, materials, particles,
textures, images, curves, meshes, actions, nodes, and worlds from the scene
"""
if bpy.context.active_object and bpy.context.active_object.mode == "EDIT":
bpy.ops.object.editmode_toggle()

for obj in bpy.data.objects:
obj.hide_set(False)
obj.hide_select = False
obj.hide_viewport = False

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()

collection_names = [col.name for col in bpy.data.collections]
for name in collection_names:
bpy.data.collections.remove(bpy.data.collections[name])

# in the case when you modify the world shader
world_names = [world.name for world in bpy.data.worlds]
for name in world_names:
bpy.data.worlds.remove(bpy.data.worlds[name])
# create a new world data block
bpy.ops.world.new()
bpy.context.scene.world = bpy.data.worlds["World"]

purge_orphans()


clean_scene()

bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0))

bpy.ops.object.select_all(action="SELECT")

if bpy.context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")

allObjs = bpy.context.selected_objects
if len(allObjs) == 0:
raise PluginError("No objects selected.")
obj = bpy.context.selected_objects[0]
if obj.type != "MESH":
raise PluginError("Object is not a mesh.")

preset = getDefaultMaterialPreset("Shaded Solid")
createF3DMat(obj, preset)

scaleValue = bpy.context.scene.blenderF3DScale
finalTransform = mathutils.Matrix.Diagonal(mathutils.Vector((scaleValue, scaleValue, scaleValue))).to_4x4()
applyRotation([obj], math.radians(90), "X")

exportPath = bpy.path.abspath(bpy.context.scene.DLExportPath)
dlFormat = DLFormat.Static if bpy.context.scene.DLExportisStatic else DLFormat.Dynamic
texDir = bpy.context.scene.DLTexDir
savePNG = bpy.context.scene.saveTextures
separateTexDef = bpy.context.scene.DLSeparateTextureDef
DLName = "cube"
matWriteMethod = getWriteMethodFromEnum(bpy.context.scene.matWriteMethod)

exportF3DtoC(
exportPath,
obj,
dlFormat,
finalTransform,
texDir,
savePNG,
separateTexDef,
DLName,
matWriteMethod,
)

applyRotation([obj], math.radians(-90), "X")
83 changes: 83 additions & 0 deletions test/test_cube_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import math
import bpy
from os.path import dirname, abspath
import sys

sys.path.append(dirname(dirname(dirname(abspath(__file__)))))
from fast64 import register

sys.path.append(dirname(dirname(abspath(__file__))))
from fast64_internal.f3d.f3d_gbi import get_F3D_GBI
from fast64_internal.f3d.f3d_material import createF3DMat
from fast64_internal.f3d.f3d_parser import F3DContext, getImportData, importMeshC

register()


def purge_orphans():
if bpy.app.version >= (3, 0, 0):
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
else:
# call purge_orphans() recursively until there are no more orphan data blocks to purge
result = bpy.ops.outliner.orphans_purge()
if result.pop() != "CANCELLED":
purge_orphans()


def clean_scene():
"""
Removing all of the objects, collection, materials, particles,
textures, images, curves, meshes, actions, nodes, and worlds from the scene
"""
if bpy.context.active_object and bpy.context.active_object.mode == "EDIT":
bpy.ops.object.editmode_toggle()

for obj in bpy.data.objects:
obj.hide_set(False)
obj.hide_select = False
obj.hide_viewport = False

bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete()

collection_names = [col.name for col in bpy.data.collections]
for name in collection_names:
bpy.data.collections.remove(bpy.data.collections[name])

# in the case when you modify the world shader
world_names = [world.name for world in bpy.data.worlds]
for name in world_names:
bpy.data.worlds.remove(bpy.data.worlds[name])
# create a new world data block
bpy.ops.world.new()
bpy.context.scene.world = bpy.data.worlds["World"]

purge_orphans()


clean_scene()

obj = None
if bpy.context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")

name = "cube_Cube_mesh"
importPath = "./cube/model.inc.c"
basePath = bpy.path.abspath(bpy.context.scene.DLImportBasePath)
scaleValue = bpy.context.scene.blenderF3DScale

removeDoubles = bpy.context.scene.DLRemoveDoubles
importNormals = bpy.context.scene.DLImportNormals
drawLayer = bpy.context.scene.DLImportDrawLayer

data = getImportData([importPath])

importMeshC(
data,
name,
scaleValue,
removeDoubles,
importNormals,
drawLayer,
F3DContext(get_F3D_GBI(), basePath, createF3DMat(None)),
)