void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (particle) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); ent->name = name + "_part"; } if (model) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); ent->name = name + "_model"; } animationParameters.nameANCS(pakRouter, name + "_animp"); actorParameters.nameIDs(pakRouter, name + "_actp"); }
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (song) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(song); ent->name = name + "_song"; } }
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (unknown18) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown18); ent->name = name + "_unknown18"; } if (model) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); ent->name = name + "_model"; } if (particle1) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); ent->name = name + "_part1"; } if (particle2) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); ent->name = name + "_part2"; } if (particle3) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); ent->name = name + "_part3"; } if (particle4) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); ent->name = name + "_part4"; } if (particle5) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); ent->name = name + "_part5"; } if (particle6) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); ent->name = name + "_part6"; } if (particle7) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); ent->name = name + "_part7"; } animationParameters.nameANCS(pakRouter, name + "_animp"); actorParameters.nameIDs(pakRouter, name + "_actp"); }
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (dcln) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dcln); ent->name = name + "_dcln"; } patternedInfo.nameIDs(pakRouter, name + "_patterned"); actorParameters.nameIDs(pakRouter, name + "_actp"); }
UniqueID32 AnimationParameters::getCINF(PAKRouter<PAKBridge>& pakRouter) const { if (!animationCharacterSet) return UniqueID32(); const nod::Node* node; const PAK::Entry* ancsEnt = pakRouter.lookupEntry(animationCharacterSet, &node); ANCS ancs; { PAKEntryReadStream rs = ancsEnt->beginReadStream(*node); ancs.read(rs); } return ancs.characterSet.characters.at(character).cinf; }
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (wpsc1) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); ent->name = name + "_wpsc1"; } if (wpsc2) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); ent->name = name + "_wpsc2"; } if (wpsc3) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc3); ent->name = name + "_wpsc3"; } if (particle1) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); ent->name = name + "_part1"; } if (particle2) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); ent->name = name + "_part2"; } if (particle3) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); ent->name = name + "_part3"; } if (particle4) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); ent->name = name + "_part4"; } patternedInfo.nameIDs(pakRouter, name + "_patterned"); actorParameters.nameIDs(pakRouter, name + "_actp"); }
bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, const hecl::ProjectPath& outPath, PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, std::function<void(const hecl::SystemChar*)> fileChanged, bool force) { /* Extract character CMDL/CSKR first */ std::vector<CharacterResInfo<typename PAKRouter::IDType>> chResInfo; ancs.getCharacterResInfo(chResInfo); for (const auto& info : chResInfo) { const nod::Node* node; const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false); if (cmdlE) { hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); if (force || cmdlPath.isNone()) { cmdlPath.makeDirChain(false); if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) return false; std::string bestName = pakRouter.getBestEntryName(*cmdlE); hecl::SystemStringConv bestNameView(bestName); fileChanged(bestNameView.c_str()); typename ANCSDNA::CSKRType cskr; pakRouter.lookupAndReadDNA(info.cskr, cskr); typename ANCSDNA::CINFType cinf; pakRouter.lookupAndReadDNA(info.cinf, cinf); using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>; RigPair rigPair(&cskr, &cinf); PAKEntryReadStream rs = cmdlE->beginReadStream(*node); DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>( conn, rs, pakRouter, *cmdlE, dataspec, rigPair); conn.saveBlend(); } } } /* Extract attachment CMDL/CSKRs first */ auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id); for (auto it = attRange.first; it != attRange.second; ++it) { auto cmdlid = it->second.first.second; const nod::Node* node; const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false); if (cmdlE) { hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); if (force || cmdlPath.isNone()) { cmdlPath.makeDirChain(false); if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) return false; std::string bestName = pakRouter.getBestEntryName(*cmdlE); hecl::SystemStringConv bestNameView(bestName); fileChanged(bestNameView.c_str()); const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid); typename ANCSDNA::CSKRType cskr; pakRouter.lookupAndReadDNA(rp->first, cskr); typename ANCSDNA::CINFType cinf; pakRouter.lookupAndReadDNA(rp->second, cinf); using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>; RigPair rigPair(&cskr, &cinf); PAKEntryReadStream rs = cmdlE->beginReadStream(*node); DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>( conn, rs, pakRouter, *cmdlE, dataspec, rigPair); conn.saveBlend(); } } } std::string bestName = pakRouter.getBestEntryName(entry); hecl::SystemStringConv bestNameView(bestName); fileChanged(bestNameView.c_str()); /* Establish ANCS blend */ if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor)) return false; std::string firstName; typename ANCSDNA::CINFType firstCinf; { hecl::blender::PyOutStream os = conn.beginPythonOut(true); os.format( "import bpy\n" "from mathutils import Vector\n" "bpy.context.scene.name = '%s'\n" "bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n" "\n" "# Using 'Blender Game'\n" "bpy.context.scene.render.engine = 'BLENDER_GAME'\n" "\n" "# Clear Scene\n" "for ob in bpy.data.objects:\n" " if ob.type != 'LAMP' and ob.type != 'CAMERA':\n" " bpy.context.scene.objects.unlink(ob)\n" " bpy.data.objects.remove(ob)\n" "\n" "actor_data = bpy.context.scene.hecl_sact_data\n" "arm_obj = None\n", pakRouter.getBestEntryName(entry).c_str()); std::unordered_set<typename PAKRouter::IDType> cinfsDone; for (const auto& info : chResInfo) { /* Provide data to add-on */ os.format( "actor_subtype = actor_data.subtypes.add()\n" "actor_subtype.name = '%s'\n\n", info.name.c_str()); /* Build CINF if needed */ if (cinfsDone.find(info.cinf) == cinfsDone.end()) { typename ANCSDNA::CINFType cinf; pakRouter.lookupAndReadDNA(info.cinf, cinf); cinf.sendCINFToBlender(os, info.cinf); if (cinfsDone.empty()) { firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf); firstCinf = cinf; } cinfsDone.insert(info.cinf); } else os.format("arm_obj = bpy.data.objects['CINF_%s']\n", info.cinf.toString().c_str()); os << "actor_subtype.linked_armature = arm_obj.name\n"; /* Link CMDL */ const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false); if (cmdlE) { hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); /* Attach CMDL to CINF */ os << "if obj.name not in bpy.context.scene.objects:\n" " bpy.context.scene.objects.link(obj)\n" "obj.parent = arm_obj\n" "obj.parent_type = 'ARMATURE'\n" "actor_subtype.linked_mesh = obj.name\n\n"; } /* Link overlays */ for (const auto& overlay : info.overlays) { os << "overlay = actor_subtype.overlays.add()\n"; os.format("overlay.name = '%s'\n", overlay.first.c_str()); /* Link CMDL */ const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(overlay.second.first, nullptr, true, false); if (cmdlE) { hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); /* Attach CMDL to CINF */ os << "if obj.name not in bpy.context.scene.objects:\n" " bpy.context.scene.objects.link(obj)\n" "obj.parent = arm_obj\n" "obj.parent_type = 'ARMATURE'\n" "overlay.linked_mesh = obj.name\n\n"; } } } /* Link attachments */ for (auto it = attRange.first; it != attRange.second; ++it) { os << "attachment = actor_data.attachments.add()\n"; os.format("attachment.name = '%s'\n", it->second.second.c_str()); auto cinfid = it->second.first.first; auto cmdlid = it->second.first.second; if (cinfid) { /* Build CINF if needed */ if (cinfsDone.find(cinfid) == cinfsDone.end()) { typename ANCSDNA::CINFType cinf; pakRouter.lookupAndReadDNA(cinfid, cinf); cinf.sendCINFToBlender(os, cinfid); if (cinfsDone.empty()) { firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid); firstCinf = cinf; } cinfsDone.insert(cinfid); } else os.format("arm_obj = bpy.data.objects['CINF_%s']\n", cinfid.toString().c_str()); os << "attachment.linked_armature = arm_obj.name\n"; } /* Link CMDL */ const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false); if (cmdlE) { hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); /* Attach CMDL to CINF */ os << "if obj.name not in bpy.context.scene.objects:\n" " bpy.context.scene.objects.link(obj)\n" "obj.parent = arm_obj\n" "obj.parent_type = 'ARMATURE'\n" "attachment.linked_mesh = obj.name\n\n"; } } } { hecl::blender::DataStream ds = conn.beginData(); std::unordered_map<std::string, hecl::blender::Matrix3f> matrices = ds.getBoneMatrices(firstName); ds.close(); DNAANIM::RigInverter<typename ANCSDNA::CINFType> inverter(firstCinf, matrices); hecl::blender::PyOutStream os = conn.beginPythonOut(true); os << "import bpy\n" "actor_data = bpy.context.scene.hecl_sact_data\n"; /* Get animation primitives */ std::map<atUint32, AnimationResInfo<typename PAKRouter::IDType>> animResInfo; ancs.getAnimationResInfo(&pakRouter, animResInfo); for (const auto& id : animResInfo) { typename ANCSDNA::ANIMType anim; if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) { os.format( "act = bpy.data.actions.new('%s')\n" "act.use_fake_user = True\n", id.second.name.c_str()); anim.sendANIMToBlender(os, inverter, id.second.additive); } os.format( "actor_action = actor_data.actions.add()\n" "actor_action.name = '%s'\n", id.second.name.c_str()); /* Extract EVNT if present */ anim.extractEVNT(id.second, outPath, pakRouter, force); } } conn.saveBlend(); return true; }
void Material::SectionPASS::constructNode(hecl::BlenderConnection::PyOutStream& out, const PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, const Material::ISection* prevSection, unsigned idx, unsigned& texMapIdx, unsigned& texMtxIdx, unsigned& kColorIdx) const { /* Add Texture nodes */ if (txtrId) { std::string texName = pakRouter.getBestEntryName(txtrId); const nod::Node* node; const PAK::Entry* texEntry = pakRouter.lookupEntry(txtrId, &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, txtrId); hecl::SystemUTF8View resPathView(resPath); out.format("if '%s' in bpy.data.textures:\n" " image = bpy.data.images['%s']\n" " texture = bpy.data.textures[image.name]\n" "else:\n" " image = bpy.data.images.load('''//%s''')\n" " image.name = '%s'\n" " texture = bpy.data.textures.new(image.name, 'IMAGE')\n" " texture.image = image\n" "tex_maps.append(texture)\n" "\n", texName.c_str(), texName.c_str(), resPathView.str().c_str(), texName.c_str()); if (uvAnim.size()) { const UVAnimation& uva = uvAnim[0]; DNAMP1::MaterialSet::Material::AddTexture(out, GX::TexGenSrc(uva.unk1 + (uva.unk1 < 2 ? 0 : 2)), texMtxIdx, texMapIdx++); DNAMP1::MaterialSet::Material::AddTextureAnim(out, uva.anim.mode, texMtxIdx++, uva.anim.vals); } else DNAMP1::MaterialSet::Material::AddTexture(out, GX::TexGenSrc(uvSrc + 4), -1, texMapIdx++); } /* Special case for RFLV (environment UV mask) */ if (Subtype(subtype.toUint32()) == Subtype::RFLV) { if (txtrId) out << "rflv_tex_node = texture_nodes[-1]\n"; return; } /* Add PASS node */ bool linkRAS = false; out << "prev_pnode = pnode\n" "pnode = new_nodetree.nodes.new('ShaderNodeGroup')\n"; switch (Subtype(subtype.toUint32())) { case Subtype::DIFF: { out << "pnode.node_tree = bpy.data.node_groups['RetroPassDIFF']\n"; if (txtrId) { out << "new_material.hecl_lightmap = texture.name\n" << "texture.image.use_fake_user = True\n"; } linkRAS = true; break; } case Subtype::RIML: out << "pnode.node_tree = bpy.data.node_groups['RetroPassRIML']\n"; if (idx == 0) linkRAS = true; break; case Subtype::BLOL: out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOL']\n"; if (idx == 0) linkRAS = true; break; case Subtype::BLOD: out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOD']\n"; if (idx == 0) linkRAS = true; break; case Subtype::CLR: out << "pnode.node_tree = bpy.data.node_groups['RetroPassCLR']\n"; if (idx == 0) linkRAS = true; break; case Subtype::TRAN: if (flags.TRANInvert()) out << "pnode.node_tree = bpy.data.node_groups['RetroPassTRANInv']\n"; else out << "pnode.node_tree = bpy.data.node_groups['RetroPassTRAN']\n"; break; case Subtype::INCA: out << "pnode.node_tree = bpy.data.node_groups['RetroPassINCA']\n"; break; case Subtype::RFLV: out << "pnode.node_tree = bpy.data.node_groups['RetroPassRFLV']\n"; break; case Subtype::RFLD: out << "pnode.node_tree = bpy.data.node_groups['RetroPassRFLD']\n" "if rflv_tex_node:\n" " new_nodetree.links.new(rflv_tex_node.outputs['Color'], pnode.inputs['Mask Color'])\n" " new_nodetree.links.new(rflv_tex_node.outputs['Value'], pnode.inputs['Mask Alpha'])\n"; break; case Subtype::LRLD: out << "pnode.node_tree = bpy.data.node_groups['RetroPassLRLD']\n"; break; case Subtype::LURD: out << "pnode.node_tree = bpy.data.node_groups['RetroPassLURD']\n"; break; case Subtype::BLOI: out << "pnode.node_tree = bpy.data.node_groups['RetroPassBLOI']\n"; break; case Subtype::XRAY: out << "pnode.node_tree = bpy.data.node_groups['RetroPassXRAY']\n"; break; case Subtype::TOON: out << "pnode.node_tree = bpy.data.node_groups['RetroPassTOON']\n"; break; default: break; } out << "gridder.place_node(pnode, 2)\n"; if (txtrId) { out << "new_nodetree.links.new(texture_nodes[-1].outputs['Color'], pnode.inputs['Tex Color'])\n" "new_nodetree.links.new(texture_nodes[-1].outputs['Value'], pnode.inputs['Tex Alpha'])\n"; } if (linkRAS) out << "new_nodetree.links.new(material_node.outputs['Color'], pnode.inputs['Prev Color'])\n" "new_nodetree.links.new(material_node.outputs['Alpha'], pnode.inputs['Prev Alpha'])\n"; else if (prevSection) { if (prevSection->m_type == ISection::Type::PASS && Subtype(static_cast<const SectionPASS*>(prevSection)->subtype.toUint32()) != Subtype::RFLV) out << "new_nodetree.links.new(prev_pnode.outputs['Next Color'], pnode.inputs['Prev Color'])\n" "new_nodetree.links.new(prev_pnode.outputs['Next Alpha'], pnode.inputs['Prev Alpha'])\n"; else if (prevSection->m_type == ISection::Type::CLR) out << "new_nodetree.links.new(kcolor_nodes[-1][0].outputs[0], pnode.inputs['Prev Color'])\n" "new_nodetree.links.new(kcolor_nodes[-1][1].outputs[0], pnode.inputs['Prev Alpha'])\n"; } /* Row Break in gridder */ out << "gridder.row_break(2)\n"; }
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const { if (particle1) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); ent->name = name + "_part1"; } if (particle2) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); ent->name = name + "_part2"; } if (particle3) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); ent->name = name + "_part3"; } if (particle4) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); ent->name = name + "_part4"; } if (particle5) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); ent->name = name + "_part5"; } if (particle6) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); ent->name = name + "_part6"; } if (particle7) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); ent->name = name + "_part7"; } if (elsc) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); ent->name = name + "_elsc"; } if (model1) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); ent->name = name + "_model1"; } if (model2) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model2); ent->name = name + "_model2"; } if (skin) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(skin); ent->name = name + "_skin"; } if (rig) { PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(rig); ent->name = name + "_rig"; } patternedInfo.nameIDs(pakRouter, name + "_patterned"); actorParameters1.nameIDs(pakRouter, name + "_actp1"); actorParameters2.nameIDs(pakRouter, name + "_actp2"); animationParameters.nameANCS(pakRouter, name + "_animp"); }