diff --git a/makefile b/makefile index dce9e7b..22bacdc 100644 --- a/makefile +++ b/makefile @@ -2,13 +2,14 @@ BELLA_SDK_NAME = bella_scene_sdk EXECUTABLE_NAME = vmax2bella PLATFORM = $(shell uname) +BUILD_TYPE ?= release# Default to release build if not specified # Common paths BELLA_SDK_PATH = ../bella_scene_sdk LZFSE_PATH = ../lzfse LIBPLIST_PATH = ../libplist -OBJ_DIR = obj/$(PLATFORM) -BIN_DIR = bin/$(PLATFORM) +OBJ_DIR = obj/$(PLATFORM)/$(BUILD_TYPE) +BIN_DIR = bin/$(PLATFORM)/$(BUILD_TYPE) OUTPUT_FILE = $(BIN_DIR)/$(EXECUTABLE_NAME) # Platform-specific configuration @@ -68,20 +69,25 @@ PLIST_LIB_DIR = $(LIBPLIST_PATH)/src/.libs LIB_PATHS = -L$(SDK_LIB_PATH) -L$(LZFSE_BUILD_DIR) -L$(PLIST_LIB_DIR) LIBRARIES = -l$(BELLA_SDK_NAME) -lm -ldl -llzfse $(PLIST_LIB) -# Common compiler flags -COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -O3 $(INCLUDE_PATHS) +# Build type specific flags +ifeq ($(BUILD_TYPE), debug) + CPP_DEFINES = -D_DEBUG -DDL_USE_SHARED + COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -g -O0 $(INCLUDE_PATHS) +else + CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED + COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -O3 $(INCLUDE_PATHS) +endif # Language-specific flags C_FLAGS = $(COMMON_FLAGS) -std=c17 CXX_FLAGS = $(COMMON_FLAGS) -std=c++17 -Wno-deprecated-declarations -CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED # Objects OBJECTS = vmax2bella.o OBJECT_FILES = $(patsubst %,$(OBJ_DIR)/%,$(OBJECTS)) # Build rules -$(OBJ_DIR)/%.o: %.cpp +$(OBJ_DIR)/vmax2bella.o: vmax2bella.cpp @mkdir -p $(@D) $(CXX) -c -o $@ $< $(CXX_FLAGS) $(CPP_DEFINES) @@ -94,9 +100,32 @@ $(OUTPUT_FILE): $(OBJECT_FILES) @cp $(PLIST_LIB_DIR)/$(PLIST_LIB_NAME) $(BIN_DIR)/ @echo "Build complete: $(OUTPUT_FILE)" -.PHONY: clean +# Add default target +all: $(OUTPUT_FILE) + +.PHONY: clean cleanall all clean: - rm -f $(OBJ_DIR)/*.o + rm -f $(OBJ_DIR)/vmax2bella.o rm -f $(OUTPUT_FILE) rm -f $(BIN_DIR)/$(SDK_LIB_FILE) rm -f $(BIN_DIR)/*.dylib + rmdir $(OBJ_DIR) 2>/dev/null || true + rmdir $(BIN_DIR) 2>/dev/null || true + +cleanall: + rm -f obj/*/release/*.o + rm -f obj/*/debug/*.o + rm -f bin/*/release/$(EXECUTABLE_NAME) + rm -f bin/*/debug/$(EXECUTABLE_NAME) + rm -f bin/*/release/$(SDK_LIB_FILE) + rm -f bin/*/debug/$(SDK_LIB_FILE) + rm -f bin/*/release/*.dylib + rm -f bin/*/debug/*.dylib + rmdir obj/*/release 2>/dev/null || true + rmdir obj/*/debug 2>/dev/null || true + rmdir bin/*/release 2>/dev/null || true + rmdir bin/*/debug 2>/dev/null || true + rmdir obj/* 2>/dev/null || true + rmdir bin/* 2>/dev/null || true + rmdir obj 2>/dev/null || true + rmdir bin 2>/dev/null || true diff --git a/oomer_voxel_vmax.h b/oomer_voxel_vmax.h index 7e0a88e..72f3098 100644 --- a/oomer_voxel_vmax.h +++ b/oomer_voxel_vmax.h @@ -1,5 +1,9 @@ #pragma once +// This is a set of common oomer utilities for Vmax models +// Will avoid using bella_sdk + + // Standard C++ library includes - these provide essential functionality #include // For key-value pair data structures (maps) #include // For set data structure @@ -20,6 +24,10 @@ using json = nlohmann::json; #define STB_IMAGE_IMPLEMENTATION #include "thirdparty/stb_image.h" // STB Image library + + + + // Structure to represent a 4x4 matrix for 3D transformations // The matrix is stored as a 2D array where m[i][j] represents row i, column j struct VmaxMatrix4x4 { @@ -115,6 +123,31 @@ VmaxMatrix4x4 axisAngleToMatrix4x4(double ax, double ay, double az, double angle return result; } +// Combine a rotation, translation, and scale into a single 4x4 matrix +// Parameters: +// rotx, roty, rotz: The axis vector to rotate around (doesn't need to be normalized) +// rota: The angle to rotate by (in radians) +// posx, posy, posz: The position to translate to +// scalex, scaley, scalez: The scale to apply to the object +// Returns: A 4x4 matrix that represents the combined transformation +VmaxMatrix4x4 combineVmaxTransforms(double rotx, double roty, double rotz, double rota, double posx, double posy, double posz, double scalex, double scaley, double scalez) { + VmaxMatrix4x4 rotMat4 = axisAngleToMatrix4x4(rotx, + roty, + rotz, + rota); + VmaxMatrix4x4 transMat4 = VmaxMatrix4x4(); + transMat4 = transMat4.createTranslation(posx, + posy, + posz); + VmaxMatrix4x4 scaleMat4 = VmaxMatrix4x4(); + scaleMat4 = scaleMat4.createScale(scalex, + scaley, + scalez); + VmaxMatrix4x4 resultMat4 = scaleMat4 * rotMat4 * transMat4; + return resultMat4; +} + + struct VmaxRGBA { uint8_t r, g, b, a; }; diff --git a/vmax2bella.cpp b/vmax2bella.cpp index 31d0a5a..505545a 100644 --- a/vmax2bella.cpp +++ b/vmax2bella.cpp @@ -220,11 +220,22 @@ int DL_main(dl::Args& args) { belScene.loadDefs(); auto belWorld = belScene.world(true); - // Parse the scene.json file to get the models + // scene.json is the toplevel file that hierarchically defines the scene + // it contains nestable groups (containers) and objects (instances) that point to resources that define the object + // objects properties + // - transformation matrix + // objects resources + /// - reference a contentsN.vmaxb (lzfse compressed plist file) that contains a 256x256x256 voxel "model" + // - reference to a paletteN.png that defines the 256 24bit colors used in the 256x256x256 model + // - reference to a paletteN.settings.vmaxpsb (plist file) that defines the 8 materials used in the "model" + // In scenegraph parlance a group is a xform, a object is a transform with a child geometry + // multiple objects can point to the same model creating what is known as an instance JsonVmaxSceneParser vmaxSceneParser; vmaxSceneParser.parseScene((vmaxDirName+"/scene.json").buf()); - //auto models = vmaxSceneParser.getModels(); - vmaxSceneParser.printSummary(); + + #ifdef _DEBUG + vmaxSceneParser.printSummary(); + #endif std::map jsonGroups = vmaxSceneParser.getGroups(); std::map belGroupNodes; // Map of UUID to bella node std::map belCanonicalNodes; // Map of UUID to bella node @@ -236,24 +247,17 @@ int DL_main(dl::Args& args) { belGroupUUID = "_" + belGroupUUID; // Make sure the group name is valid for a Bella node name belGroupNodes[belGroupUUID] = belScene.createNode("xform", belGroupUUID, belGroupUUID); // Create a Bella node for the group - // Rotate the object - VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( groupInfo.rotation[0], - groupInfo.rotation[1], - groupInfo.rotation[2], - groupInfo.rotation[3]); - // Translate the object - VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4(); - objectTransMat4 = objectTransMat4.createTranslation(groupInfo.position[0], - groupInfo.position[1], - groupInfo.position[2]); - - // Scale the object - VmaxMatrix4x4 objectScaleMat4 = VmaxMatrix4x4(); - objectScaleMat4 = objectScaleMat4.createScale(groupInfo.scale[0], - groupInfo.scale[1], - groupInfo.scale[2]); - objectMat4 = objectScaleMat4 * objectMat4 * objectTransMat4; + VmaxMatrix4x4 objectMat4 = combineVmaxTransforms(groupInfo.rotation[0], + groupInfo.rotation[1], + groupInfo.rotation[2], + groupInfo.rotation[3], + groupInfo.position[0], + groupInfo.position[1], + groupInfo.position[2], + groupInfo.scale[0], + groupInfo.scale[1], + groupInfo.scale[2]); belGroupNodes[belGroupUUID]["steps"][0]["xform"] = dl::Mat4({ objectMat4.m[0][0], objectMat4.m[0][1], objectMat4.m[0][2], objectMat4.m[0][3], @@ -307,19 +311,18 @@ int DL_main(dl::Args& args) { std::vector scale = jsonModelInfo.scale; std::vector extentCenter = jsonModelInfo.extentCenter; - // Rotate the object - VmaxMatrix4x4 modelMatrix = axisAngleToMatrix4x4(rotation[0], rotation[1], rotation[2], rotation[3]); - // Translate the object - VmaxMatrix4x4 transMatrix = VmaxMatrix4x4(); - transMatrix = transMatrix.createTranslation(position[0], - position[1], - position[2]); - VmaxMatrix4x4 scaleMatrix = VmaxMatrix4x4(); - scaleMatrix = scaleMatrix.createScale(scale[0], - scale[1], - scale[2]); - modelMatrix = scaleMatrix * modelMatrix * transMatrix; + /*VmaxMatrix4x4 modelMat4 = combineVmaxTransforms(rotation[0], + rotation[1], + rotation[2], + rotation[3], + position[0], + position[1], + position[2], + scale[0], + scale[1], + scale[2]);*/ + //modelMatrix = scaleMatrix * modelMatrix * transMatrix; // Get file names dl::String materialName = vmaxDirName + "/" + jsonModelInfo.paletteFile.c_str(); @@ -412,21 +415,17 @@ int DL_main(dl::Args& args) { auto belCanonicalNode = belCanonicalNodes[canonicalName.buf()]; auto foofoo = belScene.findNode(canonicalName); - VmaxMatrix4x4 objectMat4 = axisAngleToMatrix4x4( rotation[0], - rotation[1], - rotation[2], - rotation[3]); - VmaxMatrix4x4 objectTransMat4 = VmaxMatrix4x4(); - objectTransMat4 = objectTransMat4.createTranslation(position[0], - position[1], - position[2]); - VmaxMatrix4x4 objectScaleMat4 = VmaxMatrix4x4(); - objectScaleMat4 = objectScaleMat4.createScale(scale[0], - scale[1], - scale[2]); - - objectMat4 = objectScaleMat4 * objectMat4 * objectTransMat4; + VmaxMatrix4x4 objectMat4 = combineVmaxTransforms(rotation[0], + rotation[1], + rotation[2], + rotation[3], + position[0], + position[1], + position[2], + scale[0], + scale[1], + scale[2]); auto belNodeObjectInstance = belScene.createNode("xform", belObjectId, belObjectId); belNodeObjectInstance["steps"][0]["xform"] = dl::Mat4({