From 01f5b513d4901590718bf5601d6f5cf4e9418dfa Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 20 Jan 2016 23:56:22 -0800 Subject: [PATCH 1/2] Preliminary FRME blender export --- DataSpec/DNAMP1/FRME.cpp | 78 ++++++++++++++++++++++++++++++++++++++++ DataSpec/DNAMP1/FRME.hpp | 7 +--- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp index cb7cbb1ac..edad4135c 100644 --- a/DataSpec/DNAMP1/FRME.cpp +++ b/DataSpec/DNAMP1/FRME.cpp @@ -262,5 +262,83 @@ size_t FRME::Widget::TXPNInfo::binarySize(size_t __isz) const return __isz + (version == 1 ? 78 : 66); } +bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const HECL::ProjectPath &outPath, PAKRouter &pakRouter, const PAK::Entry &entry, bool force, std::function fileChanged) +{ + FRME frme; + frme.read(rs); + + HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); + + if (!force && outPath.getPathType() == HECL::ProjectPath::Type::File) + return true; + + if (!conn.createBlend(outPath, HECL::BlenderConnection::BlendType::Frame)) + return false; + + HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true); + + os << "import bpy, math\n" + "from mathutils import Matrix, Quaternion\n" + "bpy.types.Object.retro_widget_type = bpy.props.StringProperty(name='Retro: FRME Widget Type')\n" + "bpy.types.Object.retro_widget_parent = bpy.props.StringProperty(name='Retro: FRME Widget Parent', description='Refers to internal frame widgets')\n" + "# Clear Scene\n" + "for ob in bpy.data.objects:\n" + " bpy.context.scene.objects.unlink(ob)\n" + " bpy.data.objects.remove(ob)\n"; + + os.format("bpy.context.scene.name = 'FRME_%s'\n", + entry.id.toString().c_str()); + + for (const FRME::Widget& w : frme.widgets) + { + os << "binding = None\n" + "angle = Quaternion((0.0, 0.0, 0.0), 0)\n"; + if (w.type == SBIG('CAMR')) + { + using CAMRInfo = FRME::Widget::CAMRInfo; + os.format("cam = bpy.data.cameras.new(name='%s')\n" + "binding = cam\n", w.header.name.c_str()); + CAMRInfo* info = dynamic_cast(w.widgetInfo.get()); + if (info) + { + if (info->projectionType == CAMRInfo::ProjectionType::Orthographic) + os << "cam.type = 'ORTHO'\n"; + else if (info->projectionType == CAMRInfo::ProjectionType::Perspective) + os << "cam.type = 'PERSP'\n"; + } + os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; + } + else if (w.type == SBIG('LITE')) + os.format("lite = bpy.data.lamps.new(name='%s', type='POINT')\n" + "binding = lite\n", + w.header.name.c_str()); + + + os.format("obj = bpy.data.objects.new(name='%s', object_data=binding)\n" + "obj.retro_widget_type = '%s'\n" + "parentName = '%s'\n" + "if parentName not in bpy.data.objects:\n" + " obj.retro_widget_parent = parentName\n" + "else:\n" + " obj.parent = bpy.data.objects[parentName]\n" + "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" + "mtxd = mtx.decompose()\n" + "obj.rotation_mode = 'QUATERNION'\n" + "obj.location = mtxd[0]\n" + "obj.rotation_quaternion = mtxd[1] * angle\n" + "obj.scale = mtxd[2]\n", + w.header.name.c_str(), w.type.toString().c_str(), w.header.parent.c_str(), + w.basis[0].vec[0], w.basis[0].vec[1], w.basis[0].vec[2],w.origin.vec[0], + w.basis[1].vec[0], w.basis[1].vec[1], w.basis[1].vec[2],w.origin.vec[1], + w.basis[2].vec[0], w.basis[2].vec[1], w.basis[2].vec[2],w.origin.vec[2]); + os << "bpy.context.scene.objects.link(obj)\n"; + } + + os.centerView(); + os.close(); + conn.saveBlend(); + return true; +} + } } diff --git a/DataSpec/DNAMP1/FRME.hpp b/DataSpec/DNAMP1/FRME.hpp index 5c93b8ba4..d07c4b492 100644 --- a/DataSpec/DNAMP1/FRME.hpp +++ b/DataSpec/DNAMP1/FRME.hpp @@ -215,12 +215,7 @@ struct FRME : BigDNA PAKRouter& pakRouter, const PAK::Entry& entry, bool force, - std::function fileChanged) - { - FRME frme; - frme.read(rs); - return true; - } + std::function fileChanged); }; } From 4428f6799818c0d98e62c2b93aa4af506b11aa4c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Fri, 22 Jan 2016 04:19:43 -0800 Subject: [PATCH 2/2] Actually fix MLVL for MP2/3 More FRME support --- DataSpec/DNACommon/PAK.hpp | 3 ++ DataSpec/DNAMP1/FRME.cpp | 89 ++++++++++++++++++++++++++++++++------ DataSpec/DNAMP2/MLVL.hpp | 2 +- DataSpec/DNAMP3/MLVL.hpp | 2 +- hecl | 2 +- 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp index 41fbcd5e4..ae3adc9e6 100644 --- a/DataSpec/DNACommon/PAK.hpp +++ b/DataSpec/DNACommon/PAK.hpp @@ -561,6 +561,9 @@ public: bool silenceWarnings=false, bool currentPAK=false) const { + if (!entry) + return nullptr; + if (!m_bridges) LogDNACommon.report(LogVisor::FatalError, "PAKRouter::build() must be called before PAKRouter::lookupEntry()"); diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp index edad4135c..a1f323efe 100644 --- a/DataSpec/DNAMP1/FRME.cpp +++ b/DataSpec/DNAMP1/FRME.cpp @@ -1,4 +1,5 @@ #include "FRME.hpp" +#include "../DNACommon/TXTR.hpp" namespace Retro { @@ -269,8 +270,10 @@ bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const HECL: HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); +#if 0 if (!force && outPath.getPathType() == HECL::ProjectPath::Type::File) return true; +#endif if (!conn.createBlend(outPath, HECL::BlenderConnection::BlendType::Frame)) return false; @@ -295,16 +298,27 @@ bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const HECL: "angle = Quaternion((0.0, 0.0, 0.0), 0)\n"; if (w.type == SBIG('CAMR')) { - using CAMRInfo = FRME::Widget::CAMRInfo; + using CAMRInfo = Widget::CAMRInfo; os.format("cam = bpy.data.cameras.new(name='%s')\n" "binding = cam\n", w.header.name.c_str()); CAMRInfo* info = dynamic_cast(w.widgetInfo.get()); if (info) { if (info->projectionType == CAMRInfo::ProjectionType::Orthographic) - os << "cam.type = 'ORTHO'\n"; + { + CAMRInfo::OrthographicProjection* proj = dynamic_cast(info->projection.get()); + os.format("cam.type = 'ORTHO'\n"); + } else if (info->projectionType == CAMRInfo::ProjectionType::Perspective) - os << "cam.type = 'PERSP'\n"; + { + CAMRInfo::PerspectiveProjection* proj = dynamic_cast(info->projection.get()); + os.format("cam.type = 'PERSP'\n" + "cam.lens_unit = 'FOV'\n" + "cam.angle = math.radians(%f)\n" + "cam.clip_start = %f\n" + "cam.clip_end = %f\n", + proj->fov, proj->znear, proj->zfar); + } } os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; } @@ -314,24 +328,71 @@ bool FRME::Extract(const SpecBase &dataSpec, PAKEntryReadStream &rs, const HECL: w.header.name.c_str()); - os.format("obj = bpy.data.objects.new(name='%s', object_data=binding)\n" - "obj.retro_widget_type = '%s'\n" + os.format("frme_obj = bpy.data.objects.new(name='%s', object_data=binding)\n" + "frme_obj.retro_widget_type = '%s'\n" "parentName = '%s'\n" "if parentName not in bpy.data.objects:\n" - " obj.retro_widget_parent = parentName\n" + " frme_obj.retro_widget_parent = parentName\n" "else:\n" - " obj.parent = bpy.data.objects[parentName]\n" - "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" + " frme_obj.parent = bpy.data.objects[parentName]\n", + w.header.name.c_str(), w.type.toString().c_str(), w.header.parent.c_str()); + + if (w.type == SBIG('MODL')) + { + using MODLInfo = FRME::Widget::MODLInfo; + MODLInfo* info = dynamic_cast(w.widgetInfo.get()); + HECL::ProjectPath modelPath = pakRouter.getWorking(info->model); + const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true); + + os.linkBlend(modelPath.getAbsolutePathUTF8().c_str(), + pakRouter.getBestEntryName(*cmdlE).c_str(), false); + + os << "print(obj.name)\n" + "if obj.name not in bpy.context.scene.objects:\n" + " bpy.context.scene.objects.link(obj)\n" + "obj.parent = frme_obj\n" + "obj.hide = False\n"; + } + else if (w.type == SBIG('IMGP')) + { + using IMGPInfo = Widget::IMGPInfo; + IMGPInfo* info = dynamic_cast(w.widgetInfo.get()); + if (info && info->texture) + { + std::string texName = pakRouter.getBestEntryName(info->texture); + const NOD::Node* node; + const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(info->texture, &node); + HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry); + if (txtrPath.getPathType() == HECL::ProjectPath::Type::None) + { + PAKEntryReadStream rs = texEntry->beginReadStream(*node); + TXTR::Extract(rs, txtrPath); + } + HECL::SystemString resPath = pakRouter.getResourceRelativePath(entry, info->texture); + HECL::SystemUTF8View resPathView(resPath); + os.format("if '%s' in bpy.data.images:\n" + " image = bpy.data.images['%s']\n" + "else:\n" + " image = bpy.data.images.load('''//%s''')\n" + " image.name = '%s'\n" + "frme_obj.empty_draw_type = 'IMAGE'\n" + "frme_obj.data = image\n" + "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n", + texName.c_str(), texName.c_str(), + resPathView.str().c_str(), texName.c_str()); + } + } + + os.format("mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1] * angle\n" - "obj.scale = mtxd[2]\n", - w.header.name.c_str(), w.type.toString().c_str(), w.header.parent.c_str(), + "frme_obj.rotation_mode = 'QUATERNION'\n" + "frme_obj.location = mtxd[0]\n" + "frme_obj.rotation_quaternion = mtxd[1] * angle\n" + "frme_obj.scale = mtxd[2]\n" + "bpy.context.scene.objects.link(frme_obj)\n", w.basis[0].vec[0], w.basis[0].vec[1], w.basis[0].vec[2],w.origin.vec[0], w.basis[1].vec[0], w.basis[1].vec[1], w.basis[1].vec[2],w.origin.vec[1], w.basis[2].vec[0], w.basis[2].vec[1], w.basis[2].vec[2],w.origin.vec[2]); - os << "bpy.context.scene.objects.link(obj)\n"; } os.centerView(); diff --git a/DataSpec/DNAMP2/MLVL.hpp b/DataSpec/DNAMP2/MLVL.hpp index 30a80cf85..ea9c21a17 100644 --- a/DataSpec/DNAMP2/MLVL.hpp +++ b/DataSpec/DNAMP2/MLVL.hpp @@ -104,7 +104,7 @@ struct MLVL : BigYAML { MLVL mlvl; mlvl.read(rs); - FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("wb")); + FILE* fp = HECL::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); mlvl.toYAMLFile(fp); fclose(fp); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); diff --git a/DataSpec/DNAMP3/MLVL.hpp b/DataSpec/DNAMP3/MLVL.hpp index 94165fb95..b0056fa73 100644 --- a/DataSpec/DNAMP3/MLVL.hpp +++ b/DataSpec/DNAMP3/MLVL.hpp @@ -88,7 +88,7 @@ struct MLVL : BigYAML { MLVL mlvl; mlvl.read(rs); - FILE* fp = HECL::Fopen(outPath.getWithExtension(_S(".yaml")).getAbsolutePath().c_str(), _S("wb")); + FILE* fp = HECL::Fopen(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath().c_str(), _S("wb")); mlvl.toYAMLFile(fp); fclose(fp); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); diff --git a/hecl b/hecl index 966ec1ab3..4d49e81a9 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 966ec1ab3323d6f4e4352eb459ba60523f8d8440 +Subproject commit 4d49e81a9523c671651ba00c426fccb946c370ae