RSE-Model/RSEModel/Model-Extractor.c

188 lines
4.8 KiB
C

/**
* \file Model-Extractor.c
* \date 25/07/2022
* \author JackCarterSmith
* \copyright GPL-v3.0
* \brief HOB model parser and export to Waveform OBJ format.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <RSPLib_errors.h>
#include <hob_struct.h>
#include <hob_parser.h>
#include "config.h"
#include "options.h"
#include "obj_exporter.h"
/*
* Internal functions declarations
*/
static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* opt_ptr);
static void createSubDir(char *dirName);
static unsigned char checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]);
static void cleanUpMemory(T_HOB* hobStruct);
static void dispHelp();
/*
* - MAIN -
*/
int main(int argc, char *argv[]) {
T_PROG_OPTIONS _opts;
unsigned char p;
// Hello world!
printf("\n*** RogueSquadron Extractor (RSE) - MODEL module - v%s ***\n", VERSION);
// Check for arguments
if (argc < 2) {
printf("\n[ERR] No input file/commands specified!\n");
dispHelp();
return ERROR_ARGS_NULL;
}
// Create options for programs according to user's arguments.
p = checkInputArgs(&_opts, argc, argv);
if ( p == ERROR_GENERIC ) return NO_ERROR;
else if ( p != NO_ERROR ) return p;
return mainProcess(argc, argv, &_opts);
}
/*
* Private functions definition
*/
static unsigned int mainProcess(int args_cnt, char* args_value[], T_PROG_OPTIONS* p_opts) {
unsigned short file_index;
T_HOB* hobStruct = NULL;
int i;
// Manage multiple inputs files
for ( file_index = p_opts->input_files_cnt; file_index < args_cnt; file_index++)
{
printf("\n=============================================\n[INFO] - Parsing file: %s ...\n", args_value[file_index]);
hobStruct = calloc(1, sizeof(T_HOB));
// Parse data from HOB file and put in T_HOB structure.
if (RSP_ModelLib_ParseHOBFile(args_value[file_index], hobStruct, p_opts) != NO_ERROR) {
printf("[ERR] Failed to parse datas from %s\n", args_value[file_index]);
free(hobStruct);
return ERROR_PROCESS;
}
if (hobStruct->obj_count > 0) {
if (p_opts->output_dir) createSubDir(args_value[file_index]);
for ( i = 0; i < hobStruct->obj_count; i++ ) {
if (exportOBJModel(&(hobStruct->objects[i]), args_value[file_index], p_opts) != NO_ERROR)
printf("[ERR] Failed to export %s object in OBJ format!\n", hobStruct->objects[i].name);
else
printf("[INFO] Successfully exported %s object in OBJ format.\n", hobStruct->objects[i].name);
}
}
}
cleanUpMemory(hobStruct);
return NO_ERROR;
}
static unsigned char checkInputArgs(T_PROG_OPTIONS* opt_ptr, int p_arg_nbr, char* p_args[]) {
char test[256];
int i;
// Set default options
opt_ptr->raw = 0;
opt_ptr->output_dir = 1;
opt_ptr->export_mtl = 1;
if (p_arg_nbr > 1) {
for ( i = 1; i < p_arg_nbr; i++) {
strcpy(test, p_args[i]);
if (p_args[i][0] != '-') break;
if (strcmp(p_args[i], "-h") == 0) {
dispHelp();
return ERROR_GENERIC;
} else if (strcmp(p_args[i], "-v") == 0) {
opt_ptr->verbose_mode = 1;
printf("[OPTN] Verbose enabled.\n");
} else if (strcmp(p_args[i], "-vv") == 0) {
opt_ptr->verbose_mode = 1;
opt_ptr->debug_mode = 1;
printf("[OPTN] Debug enabled.\n");
} else if (strcmp(p_args[i], "-vvv") == 0) {
opt_ptr->verbose_mode = 1;
opt_ptr->debug_mode = 1;
opt_ptr->god_mode = 1;
printf("[OPTN] God damn it!\n");
} else if (strcmp(p_args[i], "-no-subdir") == 0) {
opt_ptr->output_dir = 0;
printf("[OPTN] Export to current directory.\n");
} else if (strcmp(p_args[i], "-mtl") == 0) {
opt_ptr->export_mtl = 0;
printf("[OPTN] No materials datas.\n");
} else {
printf("[ERR] Unknown option: %s\n", p_args[i]);
}
}
opt_ptr->input_files_cnt = i;
return NO_ERROR;
}
return ERROR_ARGS_NULL;
}
static void createSubDir(char *dirName) {
if (dirName == NULL) return;
char _dir[260]; //TODO: Change directory management
strcpy(_dir, dirName);
strcat(_dir, "-out");
#ifdef _WIN32
CreateDirectory(_dir, NULL);
#else
mkdir(_dir, 0755);
#endif
}
static void cleanUpMemory(T_HOB* hobStruct) {
int i,j;
for ( i=0; i<hobStruct->obj_count; i++ ) {
for ( j=0; j<hobStruct->objects[i].face_group_count; j++ ) {
free(hobStruct->objects[i].object_parts[j].faces);
free(hobStruct->objects[i].object_parts[j].vertices);
}
free(hobStruct->objects[i].object_parts);
}
free(hobStruct->objects);
free(hobStruct);
}
static void dispHelp() {
printf("\n");
printf("Options:\n -h Print this message\n");
printf(" -v -vv Activate verbose console output\n");
printf(" -no-subdir Export models inside current folder\n");
printf(" -no-mtl Disable materials datas export with model\n");
printf("\n");
printf("Usage: RSE-Model_%s [options] <hob files...>\n", VERSION);
printf("\n");
}