Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libultraship
10 changes: 10 additions & 0 deletions soh/soh/OTRGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
#include "soh/resource/type/SohResourceType.h"
#include "soh/resource/type/Animation.h"
#include "soh/resource/type/Skeleton.h"
#include "soh/resource/type/SkinAnimatedLimbData.h"
#include <ship/resource/factory/BlobFactory.h>
#include <fast/resource/factory/DisplayListFactory.h>
#include <fast/resource/factory/MatrixFactory.h>
Expand All @@ -113,6 +114,7 @@
#include "soh/resource/importer/SkeletonLimbFactory.h"
#include "soh/resource/importer/TextFactory.h"
#include "soh/resource/importer/BackgroundFactory.h"
#include "soh/resource/importer/SkinAnimatedLimbDataFactory.h"

#include "soh/config/ConfigUpdaters.h"
#include "soh/ShipInit.hpp"
Expand Down Expand Up @@ -912,6 +914,14 @@ void OTRGlobals::Initialize() {
"Sequence", static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSequence), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryBinaryBackgroundV0>(), RESOURCE_FORMAT_BINARY,
"Background", static_cast<uint32_t>(SOH::ResourceType::SOH_Background), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryXMLSkinVertV0>(), RESOURCE_FORMAT_XML,
"SkinVert", static_cast<uint32_t>(SOH::ResourceType::SOH_SkinVert), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryXMLSkinTransformV0>(), RESOURCE_FORMAT_XML,
"SkinTransform", static_cast<uint32_t>(SOH::ResourceType::SOH_SkinTransform), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryXMLSkinModifV0>(), RESOURCE_FORMAT_XML,
"SkinModif", static_cast<uint32_t>(SOH::ResourceType::SOH_SkinModif), 0);
loader->RegisterResourceFactory(std::make_shared<SOH::ResourceFactoryXMLSkinAnimDataV0>(), RESOURCE_FORMAT_XML,
"SkinAnimData", static_cast<uint32_t>(SOH::ResourceType::SOH_SkinAnimData), 0);

Lang::LoadLangs();

Expand Down
80 changes: 61 additions & 19 deletions soh/soh/resource/importer/SkeletonLimbFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "soh/resource/importer/SkeletonLimbFactory.h"
#include "soh/resource/importer/SkinAnimatedLimbDataFactory.h"
#include "soh/resource/type/SkeletonLimb.h"
#include "soh/resource/type/SkinAnimatedLimbData.h"
#include <ship/Context.h>
#include <ship/resource/ResourceManager.h>
#include <tinyxml2.h>
Expand Down Expand Up @@ -204,7 +206,12 @@ ResourceFactoryXMLSkeletonLimbV0::ReadResource(std::shared_ptr<Ship::File> file,
std::string limbType = reader->Attribute("Type");

// OTRTODO
skelLimb->limbType = LimbType::LOD;
// skelLimb->limbType = LimbType::LOD;
if (limbType == "Skin") {
skelLimb->limbType = LimbType::Skin;
} else {
skelLimb->limbType = LimbType::LOD;
}

// skelLimb->legTransX = reader->FloatAttribute("LegTransX");
// skelLimb->legTransY = reader->FloatAttribute("LegTransY");
Expand All @@ -224,33 +231,68 @@ ResourceFactoryXMLSkeletonLimbV0::ReadResource(std::shared_ptr<Ship::File> file,
skelLimb->childIndex = reader->IntAttribute("ChildIndex");
skelLimb->siblingIndex = reader->IntAttribute("SiblingIndex");

skelLimb->skinSegmentType = (ZLimbSkinType)reader->IntAttribute("SegmentType");
// skelLimb->childPtr = reader->Attribute("ChildLimb");
// skelLimb->siblingPtr = reader->Attribute("SiblingLimb");
skelLimb->dListPtr = reader->Attribute("DisplayList1");

if (std::string(reader->Attribute("DisplayList1")) == "gEmptyDL") {
skelLimb->dListPtr = "";
}

auto& limbData = skelLimb->limbData;

limbData.lodLimb.jointPos.x = skelLimb->transX;
limbData.lodLimb.jointPos.y = skelLimb->transY;
limbData.lodLimb.jointPos.z = skelLimb->transZ;
if (skelLimb->limbType == LimbType::LOD) {

if (skelLimb->dListPtr != "") {
skelLimb->dListPtr = "__OTR__" + skelLimb->dListPtr;
limbData.lodLimb.dLists[0] = (Gfx*)skelLimb->dListPtr.c_str();
} else {
limbData.lodLimb.dLists[0] = nullptr;
}
skelLimb->dListPtr = reader->Attribute("DisplayList1");

if (std::string(reader->Attribute("DisplayList1")) == "gEmptyDL") {
skelLimb->dListPtr = "";
}

limbData.lodLimb.jointPos.x = skelLimb->transX;
limbData.lodLimb.jointPos.y = skelLimb->transY;
limbData.lodLimb.jointPos.z = skelLimb->transZ;

if (skelLimb->dListPtr != "") {
skelLimb->dListPtr = "__OTR__" + skelLimb->dListPtr;
limbData.lodLimb.dLists[0] = (Gfx*)skelLimb->dListPtr.c_str();
} else {
limbData.lodLimb.dLists[0] = nullptr;
}

limbData.lodLimb.dLists[1] = nullptr;
limbData.lodLimb.dLists[1] = nullptr;

limbData.lodLimb.child = skelLimb->childIndex;
limbData.lodLimb.sibling = skelLimb->siblingIndex;
limbData.lodLimb.child = skelLimb->childIndex;
limbData.lodLimb.sibling = skelLimb->siblingIndex;

// skelLimb->dList2Ptr = reader->Attribute("DisplayList2");
limbData.lodLimb.child = skelLimb->childIndex;
limbData.lodLimb.sibling = skelLimb->siblingIndex;
} else if (skelLimb->limbType == LimbType::Skin) {

skelLimb->skinDList = std::string(reader->Attribute("Segment"));

limbData.skinLimb.jointPos.x = skelLimb->transX;
limbData.skinLimb.jointPos.y = skelLimb->transY;
limbData.skinLimb.jointPos.z = skelLimb->transZ;
limbData.skinLimb.child = skelLimb->childIndex;
limbData.skinLimb.sibling = skelLimb->siblingIndex;

skelLimb->limbData.skinLimb.segmentType = static_cast<int32_t>(skelLimb->skinSegmentType);

if (skelLimb->skinDList != "gEmptyDL") {
skelLimb->skinDList = "__OTR__" + skelLimb->skinDList;
skelLimb->limbData.skinLimb.segment = (Gfx*)skelLimb->skinDList.c_str();
} else {
skelLimb->skinDList = "";
skelLimb->limbData.skinLimb.segment = nullptr;
}

if (skelLimb->skinSegmentType == ZLimbSkinType::SkinType_4) {

auto skinAnimatedData = std::static_pointer_cast<SkinAnimData>(
Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(
skelLimb->skinDList.c_str()));

skelLimb->skinAnimLimbData = skinAnimatedData->data;
skelLimb->limbData.skinLimb.segment = &skelLimb->skinAnimLimbData;
}
}

return skelLimb;
}
Expand Down
152 changes: 152 additions & 0 deletions soh/soh/resource/importer/SkinAnimatedLimbDataFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include "soh/resource/importer/SkinAnimatedLimbDataFactory.h"
#include "soh/resource/type/SkinAnimatedLimbData.h"
#include "spdlog/spdlog.h"
#include <tinyxml2.h>
#include "libultraship/libultraship.h"

namespace SOH {
std::shared_ptr<Ship::IResource>
ResourceFactoryXMLSkinVertV0::ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) {
if (!FileHasValidFormatAndReader(file, initData)) {
return nullptr;
}

auto skinVert = std::make_shared<SkinVert>(initData);

auto child =
std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement()->FirstChildElement();

while (child != nullptr) {
std::string childName = child->Name();
if (childName == "SkinVertex") {
SkinVertex data;
data.index = child->IntAttribute("Index");
data.s = child->IntAttribute("S");
data.t = child->IntAttribute("T");
data.normX = child->IntAttribute("NormX");
data.normY = child->IntAttribute("NormY");
data.normZ = child->IntAttribute("NormZ");
data.alpha = child->IntAttribute("Alpha");

skinVert->skinVertexList.push_back(data);
}

child = child->NextSiblingElement();
}

return skinVert;
}

std::shared_ptr<Ship::IResource>
ResourceFactoryXMLSkinTransformV0::ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) {
if (!FileHasValidFormatAndReader(file, initData)) {
return nullptr;
}

auto skinTransform = std::make_shared<SkinTransform>(initData);

auto child =
std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement()->FirstChildElement();

while (child != nullptr) {
std::string childName = child->Name();
if (childName == "SkinTransformation") {
SkinTransformation data;
data.limbIndex = child->IntAttribute("LimbIndex");
data.x = child->IntAttribute("X");
data.y = child->IntAttribute("Y");
data.z = child->IntAttribute("Z");
data.scale = child->IntAttribute("Scale");

skinTransform->skinTransformationList.push_back(data);

}

child = child->NextSiblingElement();
}

return skinTransform;
}

std::shared_ptr<Ship::IResource>
ResourceFactoryXMLSkinModifV0::ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) {
if (!FileHasValidFormatAndReader(file, initData)) {
return nullptr;
}

auto skinModif = std::make_shared<SkinModif>(initData);

auto child =
std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement()->FirstChildElement();

while (child != nullptr) {
std::string childName = child->Name();
if (childName == "SkinLimbModif") {
SkinLimbModif data;
data.vtxCount = child->IntAttribute("VtxCount");
data.transformCount = child->IntAttribute("TransformCount");
data.unk_4 = child->IntAttribute("Unk_4");

std::string skinVerticesPath = child->Attribute("SkinVertices");
auto skinVerts = std::static_pointer_cast<SkinVert>(
Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(skinVerticesPath.c_str()));
skinModif->skinVerticesArrays.push_back(std::move(skinVerts->skinVertexList));
data.skinVertices = skinModif->skinVerticesArrays.back().data();

std::string transformsPath = child->Attribute("LimbTransformations");
auto skinTransforms = std::static_pointer_cast<SkinTransform>(
Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(transformsPath.c_str()));
skinModif->skinTransformationsArrays.push_back(std::move(skinTransforms->skinTransformationList));
data.limbTransformations = skinModif->skinTransformationsArrays.back().data();

skinModif->skinLimbModifArray.push_back(data);
}

child = child->NextSiblingElement();
}
return skinModif;
}

std::shared_ptr<Ship::IResource>
ResourceFactoryXMLSkinAnimDataV0::ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) {
if (!FileHasValidFormatAndReader(file, initData)) {
return nullptr;
}

auto skinAnimatedData = std::make_shared<SkinAnimData>(initData);
auto reader = std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement();


skinAnimatedData->data.totalVtxCount = reader->IntAttribute("TotalVtxCount");
skinAnimatedData->data.limbModifCount = reader->IntAttribute("LimbModifCount");
skinAnimatedData->skinLimbModifArray.reserve(skinAnimatedData->data.limbModifCount);
// skinAnimatedData->skinLimbModifVertexArrays.reserve(skinAnimatedData->data.limbModifCount);
// skinAnimatedData->skinLimbModifTransformationArrays.reserve(skinAnimatedData->data.limbModifCount);

std::string modifsPath = reader->Attribute("LimbModifications");

auto skinModifs = std::static_pointer_cast<SkinModif>(
Ship::Context::GetRawInstance()->GetResourceManager()->LoadResourceProcess(modifsPath.c_str()));
skinAnimatedData->skinLimbModifArray = std::move(skinModifs->skinLimbModifArray);
skinAnimatedData->data.limbModifications = skinAnimatedData->skinLimbModifArray.data();

skinAnimatedData->dListPtr = reader->Attribute("DList");

if (std::string(reader->Attribute("DList")) == "gEmptyDL") {
skinAnimatedData->dListPtr = "";
}

if (skinAnimatedData->dListPtr != "") {
skinAnimatedData->dListPtr = "__OTR__" + skinAnimatedData->dListPtr;
skinAnimatedData->data.dlist = (Gfx*)skinAnimatedData->dListPtr.c_str();
} else {
skinAnimatedData->data.dlist = nullptr;
}

return skinAnimatedData;
}
}// namespace SOH
32 changes: 32 additions & 0 deletions soh/soh/resource/importer/SkinAnimatedLimbDataFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <ship/resource/Resource.h>
#include <ship/resource/ResourceFactoryBinary.h>
#include <ship/resource/ResourceFactoryXML.h>

namespace SOH {

class ResourceFactoryXMLSkinVertV0 final : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) override;
};

class ResourceFactoryXMLSkinTransformV0 final : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) override;
};

class ResourceFactoryXMLSkinModifV0 final : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) override;
};

class ResourceFactoryXMLSkinAnimDataV0 final : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
std::shared_ptr<Ship::ResourceInitData> initData) override;
};
} // namespace SOH
41 changes: 1 addition & 40 deletions soh/soh/resource/type/SkeletonLimb.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "SkinAnimatedLimbData.h"
#include <ship/resource/Resource.h>
#include "libultraship/libultra.h"
#include "z64math.h"
Expand All @@ -21,39 +22,6 @@ enum class ZLimbSkinType {
SkinType_DList = 11, // Segment = DList address
};

/**
* Holds a compact version of a vertex used in the Skin system
* It is used to initialise the Vtx used by an animated limb
*/
typedef struct {
/* 0x00 */ u16 index;
/* 0x02 */ s16 s; // s and t are texture coordinates (also known as u and v)
/* 0x04 */ s16 t;
/* 0x06 */ s8 normX;
/* 0x07 */ s8 normY;
/* 0x08 */ s8 normZ;
/* 0x09 */ u8 alpha;
} SkinVertex; // size = 0xA

/**
* Describes a position displacement and a scale to be applied to a limb at index `limbIndex`
*/
typedef struct {
/* 0x00 */ u8 limbIndex;
/* 0x02 */ s16 x;
/* 0x04 */ s16 y;
/* 0x06 */ s16 z;
/* 0x08 */ u8 scale;
} SkinTransformation; // size = 0xA

typedef struct {
/* 0x00 */ u16 vtxCount; // number of vertices in this modif entry
/* 0x02 */ u16 transformCount;
/* 0x04 */ u16 unk_4; // index of limbTransformations?
/* 0x08 */ SkinVertex* skinVertices;
/* 0x0C */ SkinTransformation* limbTransformations;
} SkinLimbModif; // size = 0x10

typedef struct {
/* 0x00 */ Vec3s jointPos; // Root is position in model space, children are relative to parent
/* 0x06 */ u8 child;
Expand Down Expand Up @@ -83,13 +51,6 @@ typedef struct {
// SKIN_LIMB_TYPE_ANIMATED, NULL otherwise
} SkinLimb; // size = 0x10

typedef struct {
/* 0x00 */ u16 totalVtxCount; // total vertex count for all modif entries
/* 0x02 */ u16 limbModifCount;
/* 0x04 */ SkinLimbModif* limbModifications;
/* 0x08 */ Gfx* dlist;
} SkinAnimatedLimbData; // size = 0xC

union SkeletonLimbData {
LodLimb lodLimb;
StandardLimb standardLimb;
Expand Down
Loading