219 lines
6.7 KiB
C++
219 lines
6.7 KiB
C++
|
|
#include <assimp/mesh.h>
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <execinfo.h>
|
|
#include <signal.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <assimp/postprocess.h>
|
|
|
|
#include "src/SceneWriter.h"
|
|
#include "src/CommandLineParser.h"
|
|
#include "src/materials/MaterialParser.h"
|
|
#include "src/SceneLoader.h"
|
|
#include "src/FileUtils.h"
|
|
|
|
#include "src/definition_generator/MeshDefinitionGenerator.h"
|
|
#include "src/definition_generator/CollisionGenerator.h"
|
|
#include "src/definition_generator/MaterialGenerator.h"
|
|
#include "src/definition_generator/StaticGenerator.h"
|
|
#include "src/definition_generator/LevelGenerator.h"
|
|
#include "src/definition_generator/TriggerGenerator.h"
|
|
#include "src/materials/MaterialState.h"
|
|
|
|
void handler(int sig) {
|
|
void *array[10];
|
|
size_t size;
|
|
|
|
// get void*'s for all entries on the stack
|
|
size = backtrace(array, 10);
|
|
|
|
// print out all the frames to stderr
|
|
fprintf(stderr, "Error: signal %d:\n", sig);
|
|
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
|
exit(1);
|
|
}
|
|
|
|
|
|
bool parseMaterials(const std::string& filename, DisplayListSettings& output) {
|
|
std::fstream file(filename, std::ios::in);
|
|
|
|
struct ParseResult parseResult(DirectoryName(filename));
|
|
parseMaterialFile(file, parseResult);
|
|
output.mMaterials.insert(parseResult.mMaterialFile.mMaterials.begin(), parseResult.mMaterialFile.mMaterials.end());
|
|
|
|
for (auto err : parseResult.mErrors) {
|
|
std::cerr << "Error parsing file " << filename << std::endl;
|
|
std::cerr << err.mMessage << std::endl;
|
|
}
|
|
|
|
return parseResult.mErrors.size() == 0;
|
|
}
|
|
|
|
bool getVectorByName(const aiScene* scene, const std::string name, aiVector3D& result) {
|
|
int axis;
|
|
if (!scene->mMetaData->Get(name, axis)) {
|
|
return false;
|
|
}
|
|
|
|
switch (axis) {
|
|
case 0: result = aiVector3D(1.0f, 0.0f, 0.0f); break;
|
|
case 1: result = aiVector3D(0.0f, 1.0f, 0.0f); break;
|
|
case 2: result = aiVector3D(0.0f, 0.0f, 1.0f); break;
|
|
default: return false;
|
|
}
|
|
|
|
int upSign;
|
|
if (scene->mMetaData->Get(name + "Sign", upSign)) {
|
|
if (upSign < 0) {
|
|
result = -result;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
float angleBetween(const aiVector3D& a, const aiVector3D& b) {
|
|
return acos(a * b / (a - b).SquareLength());
|
|
}
|
|
|
|
aiQuaternion getUpRotation(const aiVector3D& euler) {
|
|
return aiQuaternion(euler.y * M_PI / 180.0f, euler.z * M_PI / 180.0f, euler.x * M_PI / 180.0f);
|
|
}
|
|
|
|
/**
|
|
* F3DEX2 - 32 vertices in buffer
|
|
* F3D - 16 vetcies in buffer
|
|
*/
|
|
|
|
int main(int argc, char *argv[]) {
|
|
signal(SIGSEGV, handler);
|
|
CommandLineArguments args;
|
|
|
|
if (!parseCommandLineArguments(argc, argv, args)) {
|
|
return 1;
|
|
}
|
|
|
|
DisplayListSettings settings = DisplayListSettings();
|
|
|
|
settings.mFixedPointScale = args.mFixedPointScale;
|
|
settings.mModelScale = args.mModelScale;
|
|
settings.mRotateModel = getUpRotation(args.mEulerAngles);
|
|
settings.mPrefix = args.mPrefix;
|
|
settings.mExportAnimation = args.mExportAnimation;
|
|
settings.mExportGeometry = args.mExportGeometry;
|
|
settings.mBonesAsVertexGroups = args.mBonesAsVertexGroups;
|
|
|
|
bool hasError = false;
|
|
|
|
for (auto materialFile = args.mMaterialFiles.begin(); materialFile != args.mMaterialFiles.end(); ++materialFile) {
|
|
if (!parseMaterials(*materialFile, settings)) {
|
|
hasError = true;
|
|
}
|
|
}
|
|
|
|
if (hasError) {
|
|
return 1;
|
|
}
|
|
|
|
auto defaultMaterial = settings.mMaterials.find(args.mDefaultMaterial);
|
|
|
|
if (defaultMaterial != settings.mMaterials.end()) {
|
|
settings.mDefaultMaterialState = defaultMaterial->second->mState;
|
|
settings.mDefaultMaterialName = args.mDefaultMaterial;
|
|
settings.mForceMaterialName = args.mForceMaterialName;
|
|
}
|
|
|
|
const aiScene* scene = NULL;
|
|
|
|
unsigned int additionalPFlags = 0;
|
|
|
|
if (settings.NeedsTangents()) {
|
|
additionalPFlags |= aiProcess_CalcTangentSpace;
|
|
}
|
|
|
|
if (args.mInputFile.length()) {
|
|
std::cout << "Generating from mesh " << args.mInputFile << std::endl;
|
|
scene = loadScene(args.mInputFile, args.mOutputType != FileOutputType::Mesh, settings.mVertexCacheSize, additionalPFlags);
|
|
|
|
if (!scene) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
std::cout << "Saving to " << args.mOutputFile << std::endl;
|
|
CFileDefinition fileDef(settings.mPrefix, settings.mFixedPointScale, settings.mModelScale, settings.mRotateModel);
|
|
|
|
switch (args.mOutputType)
|
|
{
|
|
case FileOutputType::Mesh:
|
|
{
|
|
MeshDefinitionGenerator meshGenerator(settings);
|
|
std::cout << "Generating mesh definitions" << std::endl;
|
|
meshGenerator.TraverseScene(scene);
|
|
meshGenerator.GenerateDefinitions(scene, fileDef);
|
|
break;
|
|
}
|
|
case FileOutputType::Level:
|
|
{
|
|
NodeGroups nodesByGroup(scene);
|
|
Signals signals;
|
|
|
|
std::cout << "Grouping objects by room" << std::endl;
|
|
auto roomOutput = generateRooms(scene, fileDef, settings, signals, nodesByGroup);
|
|
|
|
std::cout << "Generating collider definitions" << std::endl;
|
|
auto collisionOutput = generateCollision(scene, fileDef, settings, roomOutput.get(), nodesByGroup);
|
|
|
|
std::cout << "Generating static definitions" << std::endl;
|
|
auto staticOutput = generateStatic(scene, fileDef, settings, *roomOutput, nodesByGroup);
|
|
|
|
auto triggerOutput = generateTriggers(scene, fileDef, settings, *roomOutput, signals, nodesByGroup);
|
|
|
|
auto signalsOutput = generateSignals(nodesByGroup);
|
|
|
|
std::cout << "Generating level definitions" << std::endl;
|
|
generateLevel(
|
|
scene,
|
|
fileDef,
|
|
settings,
|
|
*staticOutput,
|
|
*collisionOutput,
|
|
*triggerOutput,
|
|
*roomOutput,
|
|
*signalsOutput,
|
|
signals,
|
|
nodesByGroup
|
|
);
|
|
|
|
nodesByGroup.PrintUnusedTypes();
|
|
break;
|
|
}
|
|
case FileOutputType::Materials:
|
|
{
|
|
std::cout << "Saving materials to " << args.mOutputFile << std::endl;
|
|
|
|
MaterialGenerator materialGenerator(settings);
|
|
|
|
materialGenerator.TraverseScene(scene);
|
|
materialGenerator.GenerateDefinitions(scene, fileDef);
|
|
break;
|
|
}
|
|
case FileOutputType::CollisionMesh:
|
|
{
|
|
NodeGroups nodesByGroup(scene);
|
|
std::cout << "Generating collider definitions" << std::endl;
|
|
auto collisionOutput = generateCollision(scene, fileDef, settings, NULL, nodesByGroup);
|
|
generateMeshCollider(fileDef, *collisionOutput);
|
|
break;
|
|
}
|
|
}
|
|
|
|
std::cout << "Writing output" << std::endl;
|
|
fileDef.GenerateAll(args.mOutputFile);
|
|
|
|
return 0;
|
|
} |