2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 17:44:56 +00:00

Add VISIGen utility

This commit is contained in:
Jack Andersen
2017-02-23 22:28:44 -10:00
parent 50fe6d34ab
commit ccbd19b9ea
21 changed files with 1578 additions and 15 deletions

View File

@@ -5,6 +5,9 @@
#include "zeus/Math.hpp"
#include "zeus/CAABox.hpp"
#include "DataSpec/DNACommon/AROTBuilder.hpp"
#include "ScriptObjects/ScriptTypes.hpp"
extern const hecl::SystemString ExeDir;
namespace DataSpec
{
@@ -162,6 +165,26 @@ bool MREA::Extract(const SpecBase& dataSpec,
ReadBabeDeadToBlender_1_2(os, rs);
rs.seek(secStart + head.secSizes[curSec++], athena::Begin);
/* Dump VISI entities */
if (head.secSizes[curSec] && rs.readUint32Big() == 'VISI')
{
athena::io::YAMLDocWriter visiWriter("VISI");
if (auto __vec = visiWriter.enterSubVector("entities"))
{
rs.seek(18, athena::Current);
uint32_t entityCount = rs.readUint32Big();
rs.seek(8, athena::Current);
for (int i=0 ; i<entityCount ; ++i)
{
uint32_t entityId = rs.readUint32Big();
visiWriter.writeUint16(nullptr, entityId & 0xffff);
}
}
hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), _S("!visi.yaml"));
athena::io::FileWriter visiMetadata(visiMetadataPath.getAbsolutePath());
visiWriter.finish(&visiMetadata);
}
/* Origins to center of mass */
os << "bpy.context.scene.layers[1] = True\n"
"bpy.ops.object.select_by_type(type='MESH')\n"
@@ -251,7 +274,8 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const std::vector<DNACMDL::Mesh>& meshes,
const ColMesh& cMesh,
const std::vector<Light>& lights)
const std::vector<Light>& lights,
hecl::BlenderToken& btok)
{
/* Discover area layers */
hecl::ProjectPath areaDirPath = inPath.getParentPath();
@@ -322,13 +346,13 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
/* AROT */
{
AROTBuilder builder;
builder.build(secs, fullAabb, meshAabbs, meshes);
AROTBuilder arotBuilder;
arotBuilder.build(secs, fullAabb, meshAabbs, meshes);
}
/* SCLY */
DNAMP1::SCLY sclyData = {};
{
DNAMP1::SCLY sclyData = {};
sclyData.fourCC = 'SCLY';
sclyData.version = 1;
for (const hecl::ProjectPath& layer : layerScriptPaths)
@@ -373,13 +397,13 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
}
/* Lights */
std::vector<atVec3f> lightsVisi;
{
int actualCount = 0;
for (const Light& l : lights)
{
if (l.layer == 0 || l.layer == 1)
++actualCount;
}
lightsVisi.reserve(actualCount);
secs.emplace_back(12 + 65 * actualCount, 0);
athena::io::MemoryWriter w(secs.back().data(), secs.back().size());
@@ -401,15 +425,100 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
BabeDeadLight light = {};
WriteBabeDeadLightFromBlender(light, l);
light.write(w);
lightsVisi.push_back(light.position);
}
}
}
}
/* VISI */
hecl::ProjectPath visiMetadataPath(areaDirPath, _S("!visi.yaml"));
if (visiMetadataPath.isFile())
{
/* Empty (for now) */
secs.emplace_back(0, 0);
bool good = false;
athena::io::FileReader visiReader(visiMetadataPath.getAbsolutePath());
athena::io::YAMLDocReader r;
if (r.parse(&visiReader))
{
size_t entityCount;
std::vector<std::pair<uint16_t, zeus::CAABox>> entities;
if (auto __vec = r.enterSubVector("entities", entityCount))
{
entities.reserve(entityCount);
uint16_t entityId = r.readUint16(nullptr);
for (const SCLY::ScriptLayer& layer : sclyData.layers)
{
for (const std::unique_ptr<IScriptObject>& obj : layer.objects)
{
if ((obj->id & 0xffff) == entityId)
{
zeus::CAABox entAABB = obj->getVISIAABB(btok);
if (entAABB.min.x < entAABB.max.x)
entities.emplace_back(entityId, entAABB);
}
}
}
}
hecl::ProjectPath visiIntOut = outPath.getWithExtension(_S(".visiint"));
hecl::ProjectPath visiIn = outPath.getWithExtension(_S(".visi"));
athena::io::FileWriter w(visiIntOut.getAbsolutePath());
w.writeUint32Big(meshes.size());
for (const DNACMDL::Mesh& mesh : meshes)
{
w.writeUint32Big(uint32_t(mesh.topology));
w.writeUint32Big(mesh.pos.size());
for (const auto& v : mesh.pos)
{
atVec3f xfPos = hecl::BlenderConnection::DataStream::MtxVecMul4RM(mesh.sceneXf, v);
w.writeVec3fBig(xfPos);
}
w.writeUint32Big(mesh.surfaces.size());
for (const DNACMDL::Mesh::Surface& surf : mesh.surfaces)
{
w.writeUint32Big(surf.verts.size());
for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts)
w.writeUint32Big(vert.iPos);
const DNACMDL::Mesh::Material& mat = mesh.materialSets[0][surf.materialIdx];
w.writeBool(mat.transparent);
}
}
w.writeUint32Big(entities.size());
for (const auto& ent : entities)
{
w.writeUint32Big(ent.first);
w.writeVec3fBig(ent.second.min);
w.writeVec3fBig(ent.second.max);
}
w.writeUint32Big(lightsVisi.size());
for (const auto& light : lightsVisi)
w.writeVec3fBig(light);
w.close();
hecl::SystemString VisiGenPath = ExeDir + _S("/visigen");
#if _WIN32
VisiGenPath += _S(".exe");
#endif
const hecl::SystemChar* args[] = {VisiGenPath.c_str(),
visiIntOut.getAbsolutePath().c_str(),
visiIn.getAbsolutePath().c_str(),
nullptr};
if (0 == hecl::RunProcess(VisiGenPath.c_str(), args))
{
athena::io::FileReader r(visiIn.getAbsolutePath());
size_t length = r.length();
secs.emplace_back(length, 0);
r.readBytesToBuf(secs.back().data(), length);
good = true;
}
}
if (!good)
secs.emplace_back(0, 0);
}
/* PATH */

View File

@@ -135,7 +135,8 @@ struct MREA
const hecl::ProjectPath& inPath,
const std::vector<DNACMDL::Mesh>& meshes,
const ColMesh& cMesh,
const std::vector<Light>& lights);
const std::vector<Light>& lights,
hecl::BlenderToken& btok);
};
}

View File

@@ -16,7 +16,7 @@ struct Actor : IScriptObject
Value<atVec3f> orientation;
Value<atVec3f> scale;
Value<atVec3f> collisionExtent;
Value<atVec3f> centroid;
Value<atVec3f> collisionOffset;
Value<float> unknown2;
Value<float> unknown3;
HealthInfo healthInfo;
@@ -64,6 +64,36 @@ struct Actor : IScriptObject
{
actorParameters.scanIDs(scansOut);
}
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
zeus::CAABox aabbOut;
if (model)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model);
conn.openBlend(path);
hecl::BlenderConnection::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);
}
else if (animationParameters.animationCharacterSet)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(
animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_S(".blend"), true));
hecl::BlenderConnection::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);
}
if (aabbOut.min.x > aabbOut.max.x)
return {};
zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location);
return aabbOut.getTransformedAABox(xf);
}
};
}
}

View File

@@ -50,6 +50,13 @@ struct DamageableTrigger : IScriptObject
g_curSpec->flattenDependencies(texture2, pathsOut);
g_curSpec->flattenDependencies(texture3, pathsOut);
}
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f;
zeus::CVector3f loc(location);
return zeus::CAABox(loc - halfExtent, loc + halfExtent);
}
};
}
}

View File

@@ -19,8 +19,8 @@ struct DoorArea : IScriptObject
AnimationParameters animationParameters;
ActorParameters actorParameters;
Value<atVec3f> unknown1;
Value<atVec3f> unknown2;
Value<atVec3f> unknown3;
Value<atVec3f> collisionExtent;
Value<atVec3f> collisionOffset;
Value<bool> unknown4;
Value<bool> unknown5;
Value<bool> unknown6;
@@ -49,6 +49,28 @@ struct DoorArea : IScriptObject
{
actorParameters.scanIDs(scansOut);
}
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
zeus::CAABox aabbOut;
if (animationParameters.animationCharacterSet)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(
animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_S(".blend"), true));
hecl::BlenderConnection::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);
}
if (aabbOut.min.x > aabbOut.max.x)
return {};
zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location);
return aabbOut.getTransformedAABox(xf);
}
};
}
}

View File

@@ -267,5 +267,16 @@ const std::vector<const struct ScriptObjectSpec*> SCRIPT_OBJECT_DB =
&priv::WorldTeleporterx62Ent,
};
zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale,
const zeus::CVector3f& orientation,
const zeus::CVector3f& position)
{
return zeus::CTransform::RotateZ(zeus::degToRad(orientation.z)) *
zeus::CTransform::RotateY(zeus::degToRad(orientation.y)) *
zeus::CTransform::RotateX(zeus::degToRad(orientation.x)) *
zeus::CTransform::Scale(scale) +
position;
}
}
}

View File

@@ -3,12 +3,18 @@
#include "../../DNACommon/DNACommon.hpp"
#include "../DNAMP1.hpp"
#include "../SAVW.hpp"
#include "zeus/CAABox.hpp"
#include <stdio.h>
namespace DataSpec
{
namespace DNAMP1
{
zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale,
const zeus::CVector3f& orientation,
const zeus::CVector3f& position);
struct IScriptObject : BigYAML
{
DECL_YAML
@@ -32,6 +38,7 @@ struct IScriptObject : BigYAML
virtual void nameIDs(PAKRouter<PAKBridge>& pakRouter) const {}
virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const {}
virtual void gatherScans(std::vector<Scan>& scansOut) const {}
virtual zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const { return {}; }
};
}
}

View File

@@ -66,6 +66,36 @@ struct Platform : IScriptObject
{
actorParameters.scanIDs(scansOut);
}
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
zeus::CAABox aabbOut;
if (model)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model);
conn.openBlend(path);
hecl::BlenderConnection::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);
}
else if (animationParameters.animationCharacterSet)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(
animationParameters.animationCharacterSet);
conn.openBlend(path.getWithExtension(_S(".blend"), true));
hecl::BlenderConnection::DataStream ds = conn.beginData();
auto aabb = ds.getMeshAABB();
aabbOut = zeus::CAABox(aabb.first, aabb.second);
}
if (aabbOut.min.x > aabbOut.max.x)
return {};
zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location);
return aabbOut.getTransformedAABox(xf);
}
};
}
}

View File

@@ -21,6 +21,13 @@ struct Trigger : IScriptObject
Value<bool> active;
Value<bool> unknown2;
Value<bool> unknown3;
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f;
zeus::CVector3f loc(location);
return zeus::CAABox(loc - halfExtent, loc + halfExtent);
}
};
}
}

View File

@@ -173,6 +173,13 @@ struct Water : IScriptObject
g_curSpec->flattenDependencies(particle4, pathsOut);
g_curSpec->flattenDependencies(particle5, pathsOut);
}
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
{
zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f;
zeus::CVector3f loc(location);
return zeus::CAABox(loc - halfExtent, loc + halfExtent);
}
};
}
}