mirror of https://github.com/AxioDL/metaforce.git
Began migration to MLVL blend representation
This commit is contained in:
parent
07392938d8
commit
b207db8c27
|
@ -35,6 +35,7 @@ add_subdirectory(NODLib)
|
||||||
set(NODLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/NODLib/include)
|
set(NODLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/NODLib/include)
|
||||||
add_subdirectory(MathLib)
|
add_subdirectory(MathLib)
|
||||||
set(MATHLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MathLib/include)
|
set(MATHLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MathLib/include)
|
||||||
|
add_definitions(-DZE_ATHENA_TYPES=1)
|
||||||
include_directories(${ATHENA_INCLUDE_DIR} ${LOG_VISOR_INCLUDE_DIR} ${HECL_INCLUDE_DIR}
|
include_directories(${ATHENA_INCLUDE_DIR} ${LOG_VISOR_INCLUDE_DIR} ${HECL_INCLUDE_DIR}
|
||||||
${NODLIB_INCLUDE_DIR} ${MATHLIB_INCLUDE_DIR}
|
${NODLIB_INCLUDE_DIR} ${MATHLIB_INCLUDE_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
|
@ -125,7 +125,8 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
if (cmdlE)
|
if (cmdlE)
|
||||||
{
|
{
|
||||||
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
|
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
|
||||||
os.linkBlend(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE), true);
|
os.linkBlend(cmdlPath.getAbsolutePathUTF8().c_str(),
|
||||||
|
pakRouter.getBestEntryName(*cmdlE).c_str(), true);
|
||||||
|
|
||||||
/* Attach CMDL to CINF */
|
/* Attach CMDL to CINF */
|
||||||
os << "if obj.name not in bpy.context.scene.objects:\n"
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
|
@ -146,7 +147,8 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
if (cmdlE)
|
if (cmdlE)
|
||||||
{
|
{
|
||||||
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
|
HECL::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
|
||||||
os.linkBlend(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE), true);
|
os.linkBlend(cmdlPath.getAbsolutePathUTF8().c_str(),
|
||||||
|
pakRouter.getBestEntryName(*cmdlE).c_str(), true);
|
||||||
|
|
||||||
/* Attach CMDL to CINF */
|
/* Attach CMDL to CINF */
|
||||||
os << "if obj.name not in bpy.context.scene.objects:\n"
|
os << "if obj.name not in bpy.context.scene.objects:\n"
|
||||||
|
|
|
@ -5,7 +5,9 @@ add_library(DNACommon
|
||||||
${liblist}
|
${liblist}
|
||||||
PAK.hpp
|
PAK.hpp
|
||||||
GX.hpp
|
GX.hpp
|
||||||
|
MLVL.hpp
|
||||||
CMDL.cpp
|
CMDL.cpp
|
||||||
|
MAPA.hpp
|
||||||
STRG.hpp STRG.cpp
|
STRG.hpp STRG.cpp
|
||||||
TXTR.hpp TXTR.cpp
|
TXTR.hpp TXTR.cpp
|
||||||
ANCS.hpp
|
ANCS.hpp
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#ifndef __DNACOMMON_MAPA_HPP__
|
||||||
|
#define __DNACOMMON_MAPA_HPP__
|
||||||
|
|
||||||
|
#endif // __DNACOMMON_MAPA_HPP__
|
|
@ -0,0 +1,111 @@
|
||||||
|
#ifndef __DNACOMMON_MLVL_HPP__
|
||||||
|
#define __DNACOMMON_MLVL_HPP__
|
||||||
|
|
||||||
|
#include "DNACommon.hpp"
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
#include "CVector3f.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMLVL
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class PAKRouter, typename MLVL>
|
||||||
|
bool ReadMLVLToBlender(HECL::BlenderConnection& conn,
|
||||||
|
const MLVL& mlvl,
|
||||||
|
const HECL::ProjectPath& outPath,
|
||||||
|
PAKRouter& pakRouter,
|
||||||
|
const typename PAKRouter::EntryType& entry,
|
||||||
|
bool force,
|
||||||
|
std::function<void(const HECL::SystemChar*)> fileChanged)
|
||||||
|
{
|
||||||
|
/* Rename MLVL for consistency */
|
||||||
|
HECL::ProjectPath mlvlPath(outPath.getParentPath(), _S("!world.blend"));
|
||||||
|
if (!force && mlvlPath.getPathType() == HECL::ProjectPath::PT_FILE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Link Skybox CMDL */
|
||||||
|
const typename PAKRouter::EntryType* skyboxEntry = pakRouter.lookupEntry(mlvl.worldSkyboxId);
|
||||||
|
if (skyboxEntry)
|
||||||
|
{
|
||||||
|
HECL::ProjectPath skyboxPath = pakRouter.getWorking(skyboxEntry);
|
||||||
|
HECL::ProjectPath(outPath.getParentPath(), _S("!skybox.blend")).makeLinkTo(skyboxPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create World Blend */
|
||||||
|
if (!conn.createBlend(mlvlPath, HECL::BlenderConnection::TypeWorld))
|
||||||
|
return false;
|
||||||
|
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||||
|
os.format("import bpy\n"
|
||||||
|
"import bmesh\n"
|
||||||
|
"\n"
|
||||||
|
"bpy.context.scene.name = 'World'\n"
|
||||||
|
"\n"
|
||||||
|
"# Clear Scene\n"
|
||||||
|
"for ob in bpy.data.objects:\n"
|
||||||
|
" bpy.context.scene.objects.unlink(ob)\n"
|
||||||
|
" bpy.data.objects.remove(ob)\n");
|
||||||
|
|
||||||
|
/* Insert area empties */
|
||||||
|
int areaIdx = 0;
|
||||||
|
for (const auto& area : mlvl.areas)
|
||||||
|
{
|
||||||
|
const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId);
|
||||||
|
HECL::SystemUTF8View areaDirName(*mreaEntry->unique.m_areaName);
|
||||||
|
|
||||||
|
os.AABBToBMesh(area.aabb[0], area.aabb[1]);
|
||||||
|
os.format("box_mesh = bpy.data.meshes.new('%s')\n"
|
||||||
|
"bm.to_mesh(box_mesh)\n"
|
||||||
|
"bm.free()\n"
|
||||||
|
"box = bpy.data.objects.new(box_mesh.name, box_mesh)\n"
|
||||||
|
"bpy.context.scene.objects.link(box)\n"
|
||||||
|
"box.location = (%f,%f,%f)\n"
|
||||||
|
"box.scale = (%f,%f,%f)\n",
|
||||||
|
areaDirName.str().c_str(),
|
||||||
|
area.transformMtx[0].vec[3], area.transformMtx[1].vec[3], area.transformMtx[2].vec[3],
|
||||||
|
area.transformMtx[0].vec[0], area.transformMtx[1].vec[1], area.transformMtx[2].vec[2]);
|
||||||
|
|
||||||
|
/* Insert dock planes */
|
||||||
|
int dockIdx = 0;
|
||||||
|
for (const auto& dock : area.docks)
|
||||||
|
{
|
||||||
|
os << "bm = bmesh.new()\n";
|
||||||
|
Zeus::CVector3f pvAvg;
|
||||||
|
for (const atVec3f& pv : dock.planeVerts)
|
||||||
|
pvAvg += pv;
|
||||||
|
pvAvg /= dock.planeVerts.size();
|
||||||
|
int idx = 0;
|
||||||
|
for (const atVec3f& pv : dock.planeVerts)
|
||||||
|
{
|
||||||
|
Zeus::CVector3f pvRel = Zeus::CVector3f(pv) - pvAvg;
|
||||||
|
os.format("bm.verts.new((%f,%f,%f))\n"
|
||||||
|
"bm.verts.ensure_lookup_table()\n",
|
||||||
|
pvRel[0], pvRel[1], pvRel[2]);
|
||||||
|
if (idx)
|
||||||
|
os << "bm.edges.new((bm.verts[-2], bm.verts[-1]))\n";
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n";
|
||||||
|
os.format("dockMesh = bpy.data.meshes.new('DOCK_%02d_%02d')\n", areaIdx, dockIdx);
|
||||||
|
os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n"
|
||||||
|
"bpy.context.scene.objects.link(dockObj)\n"
|
||||||
|
"bm.to_mesh(dockMesh)\n"
|
||||||
|
"bm.free()\n"
|
||||||
|
"dockObj.parent = box\n";
|
||||||
|
os.format("dockObj.location = (%f,%f,%f)\n",
|
||||||
|
pvAvg[0], pvAvg[1], pvAvg[2]);
|
||||||
|
++dockIdx;
|
||||||
|
}
|
||||||
|
++areaIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
os.centerView();
|
||||||
|
os.close();
|
||||||
|
conn.saveBlend();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __DNACOMMON_MLVL_HPP__
|
|
@ -9,6 +9,7 @@
|
||||||
#include "CINF.hpp"
|
#include "CINF.hpp"
|
||||||
#include "CSKR.hpp"
|
#include "CSKR.hpp"
|
||||||
#include "ANIM.hpp"
|
#include "ANIM.hpp"
|
||||||
|
#include "Athena/FileReader.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -418,6 +419,20 @@ struct ANCS : BigYAML
|
||||||
const HECL::ProjectPath& inPath,
|
const HECL::ProjectPath& inPath,
|
||||||
const DNAANCS::Actor& actor)
|
const DNAANCS::Actor& actor)
|
||||||
{
|
{
|
||||||
|
/* Search for yaml */
|
||||||
|
HECL::ProjectPath yamlPath = inPath.getWithExtension(_S(".yaml"), true);
|
||||||
|
if (yamlPath.getPathType() != HECL::ProjectPath::PT_FILE)
|
||||||
|
Log.report(LogVisor::FatalError, _S("'%s' not found as file"),
|
||||||
|
yamlPath.getRelativePath().c_str());
|
||||||
|
|
||||||
|
Athena::io::FileReader yamlReader(yamlPath.getAbsolutePath());
|
||||||
|
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader))
|
||||||
|
Log.report(LogVisor::FatalError, _S("'%s' is not Retro::DNAMP1::ANCS type"),
|
||||||
|
yamlPath.getRelativePath().c_str());
|
||||||
|
ANCS ancs;
|
||||||
|
ancs.read(yamlReader);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -194,10 +194,10 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const PAK::Entry& entry)
|
||||||
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
return {nullptr, CMDL::Extract, {_S(".blend")}, 1};
|
||||||
case SBIG('ANCS'):
|
case SBIG('ANCS'):
|
||||||
return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 2};
|
return {nullptr, ANCS::Extract, {_S(".yaml"), _S(".blend")}, 2};
|
||||||
case SBIG('MREA'):
|
|
||||||
return {nullptr, MREA::Extract, {_S(".blend")}, 3};
|
|
||||||
case SBIG('MLVL'):
|
case SBIG('MLVL'):
|
||||||
return {MLVL::Extract, nullptr, {_S(".yaml")}};
|
return {nullptr, MLVL::Extract, {_S(".blend")}, 3};
|
||||||
|
case SBIG('MREA'):
|
||||||
|
return {nullptr, MREA::Extract, {_S(".blend")}, 4};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define __DNAMP1_MLVL_HPP__
|
#define __DNAMP1_MLVL_HPP__
|
||||||
|
|
||||||
#include "../DNACommon/PAK.hpp"
|
#include "../DNACommon/PAK.hpp"
|
||||||
|
#include "../DNACommon/MLVL.hpp"
|
||||||
|
#include "DNAMP1.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
{
|
{
|
||||||
|
@ -104,14 +106,19 @@ struct MLVL : BigYAML
|
||||||
Value<atUint32> layerNameOffsetCount;
|
Value<atUint32> layerNameOffsetCount;
|
||||||
Vector<atUint32, DNA_COUNT(layerNameOffsetCount)> layerNameOffsets;
|
Vector<atUint32, DNA_COUNT(layerNameOffsetCount)> layerNameOffsets;
|
||||||
|
|
||||||
static bool Extract(PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
static bool Extract(const SpecBase& dataSpec,
|
||||||
|
PAKEntryReadStream& rs,
|
||||||
|
const HECL::ProjectPath& outPath,
|
||||||
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const PAK::Entry& entry,
|
||||||
|
bool force,
|
||||||
|
std::function<void(const HECL::SystemChar*)> fileChanged)
|
||||||
{
|
{
|
||||||
MLVL mlvl;
|
MLVL mlvl;
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("wb"));
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
mlvl.toYAMLFile(fp);
|
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter,
|
||||||
fclose(fp);
|
entry, force, fileChanged);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -146,18 +146,10 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.scene.layers[1] = False\n";
|
||||||
|
|
||||||
/* Center view */
|
/* Link MLVL scene as background */
|
||||||
os << "bpy.context.user_preferences.view.smooth_view = 0\n"
|
os.linkBackground("//../!world.blend", "World");
|
||||||
"for window in bpy.context.window_manager.windows:\n"
|
|
||||||
" screen = window.screen\n"
|
|
||||||
" for area in screen.areas:\n"
|
|
||||||
" if area.type == 'VIEW_3D':\n"
|
|
||||||
" for region in area.regions:\n"
|
|
||||||
" if region.type == 'WINDOW':\n"
|
|
||||||
" override = {'scene': bpy.context.scene, 'window': window, 'screen': screen, 'area': area, 'region': region}\n"
|
|
||||||
" bpy.ops.view3d.view_all(override)\n"
|
|
||||||
" break\n";
|
|
||||||
|
|
||||||
|
os.centerView();
|
||||||
os.close();
|
os.close();
|
||||||
return conn.saveBlend();
|
return conn.saveBlend();
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,18 +290,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.scene.layers[1] = False\n";
|
||||||
|
|
||||||
/* Center view */
|
os.centerView();
|
||||||
os << "bpy.context.user_preferences.view.smooth_view = 0\n"
|
|
||||||
"for window in bpy.context.window_manager.windows:\n"
|
|
||||||
" screen = window.screen\n"
|
|
||||||
" for area in screen.areas:\n"
|
|
||||||
" if area.type == 'VIEW_3D':\n"
|
|
||||||
" for region in area.regions:\n"
|
|
||||||
" if region.type == 'WINDOW':\n"
|
|
||||||
" override = {'scene': bpy.context.scene, 'window': window, 'screen': screen, 'area': area, 'region': region}\n"
|
|
||||||
" bpy.ops.view3d.view_all(override)\n"
|
|
||||||
" break\n";
|
|
||||||
|
|
||||||
os.close();
|
os.close();
|
||||||
return conn.saveBlend();
|
return conn.saveBlend();
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,18 +235,7 @@ bool MREA::Extract(const SpecBase& dataSpec,
|
||||||
"bpy.ops.object.select_all(action='DESELECT')\n"
|
"bpy.ops.object.select_all(action='DESELECT')\n"
|
||||||
"bpy.context.scene.layers[1] = False\n";
|
"bpy.context.scene.layers[1] = False\n";
|
||||||
|
|
||||||
/* Center view */
|
os.centerView();
|
||||||
os << "bpy.context.user_preferences.view.smooth_view = 0\n"
|
|
||||||
"for window in bpy.context.window_manager.windows:\n"
|
|
||||||
" screen = window.screen\n"
|
|
||||||
" for area in screen.areas:\n"
|
|
||||||
" if area.type == 'VIEW_3D':\n"
|
|
||||||
" for region in area.regions:\n"
|
|
||||||
" if region.type == 'WINDOW':\n"
|
|
||||||
" override = {'scene': bpy.context.scene, 'window': window, 'screen': screen, 'area': area, 'region': region}\n"
|
|
||||||
" bpy.ops.view3d.view_all(override)\n"
|
|
||||||
" break\n";
|
|
||||||
|
|
||||||
os.close();
|
os.close();
|
||||||
return conn.saveBlend();
|
return conn.saveBlend();
|
||||||
}
|
}
|
||||||
|
|
2
MathLib
2
MathLib
|
@ -1 +1 @@
|
||||||
Subproject commit cd3d2ee1336fde95e576df163488d82390df2162
|
Subproject commit 2efe395f5003ab4afbecf965ed2d28a51ed53593
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 94fedaa3065cb8a75b204eae13cc6f0213aa426a
|
Subproject commit f2870c135dc8f7d3b5c582b94474fcc4c5268049
|
Loading…
Reference in New Issue