From eb97560e0d345805ec58bd23ec8da5b6a39c9aa0 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 25 Oct 2020 13:14:16 +0100 Subject: [PATCH] Add dumping of T6 physconstraints --- .../AssetDumperPhysConstraints.cpp | 157 ++++++++++++++++++ .../AssetDumpers/AssetDumperPhysConstraints.h | 17 ++ src/ObjWriting/Game/T6/ZoneDumperT6.cpp | 3 +- src/ZoneCommon/Game/T6/T6.h | 7 + 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp create mode 100644 src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.h diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp new file mode 100644 index 00000000..e3c4afe1 --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.cpp @@ -0,0 +1,157 @@ +#include "AssetDumperPhysConstraints.h" + +#include + +#include "Game/T6/InfoStringT6.h" + +using namespace T6; + +cspField_t AssetDumperPhysConstraints::phys_constraints_fields[] +{ + {"c1_type", offsetof(PhysConstraints, data[0].type), CFT_TYPE}, + {"c1_bone1_name", offsetof(PhysConstraints, data[0].target_bone1), CSPFT_STRING}, + {"c1_bone2_name", offsetof(PhysConstraints, data[0].target_bone2), CSPFT_STRING}, + {"c1_offsetX", offsetof(PhysConstraints, data[0].offset.x), CSPFT_FLOAT}, + {"c1_offsetY", offsetof(PhysConstraints, data[0].offset.y), CSPFT_FLOAT}, + {"c1_offsetZ", offsetof(PhysConstraints, data[0].offset.z), CSPFT_FLOAT}, + {"c1_timeout", offsetof(PhysConstraints, data[0].timeout), CSPFT_INT}, + {"c1_min_health", offsetof(PhysConstraints, data[0].min_health), CSPFT_INT}, + {"c1_max_health", offsetof(PhysConstraints, data[0].max_health), CSPFT_INT}, + {"c1_damp", offsetof(PhysConstraints, data[0].damp), CSPFT_FLOAT}, + {"c1_power", offsetof(PhysConstraints, data[0].power), CSPFT_FLOAT}, + {"c1_spin_scale", offsetof(PhysConstraints, data[0].spin_scale), CSPFT_FLOAT}, + {"c1_shakescalex", offsetof(PhysConstraints, data[0].scale.x), CSPFT_FLOAT}, + {"c1_shakescaley", offsetof(PhysConstraints, data[0].scale.y), CSPFT_FLOAT}, + {"c1_shakescalez", offsetof(PhysConstraints, data[0].scale.z), CSPFT_FLOAT}, + {"c1_min_angle", offsetof(PhysConstraints, data[0].minAngle), CSPFT_FLOAT}, + {"c1_max_angle", offsetof(PhysConstraints, data[0].maxAngle), CSPFT_FLOAT}, + {"c1_yaw", offsetof(PhysConstraints, data[0].scale.y), CSPFT_FLOAT}, + {"c1_pitch", offsetof(PhysConstraints, data[0].scale.x), CSPFT_FLOAT}, + {"c2_type", offsetof(PhysConstraints, data[1].type), CFT_TYPE}, + {"c2_bone1_name", offsetof(PhysConstraints, data[1].target_bone1), CSPFT_STRING}, + {"c2_bone2_name", offsetof(PhysConstraints, data[1].target_bone2), CSPFT_STRING}, + {"c2_offsetX", offsetof(PhysConstraints, data[1].offset.x), CSPFT_FLOAT}, + {"c2_offsetY", offsetof(PhysConstraints, data[1].offset.y), CSPFT_FLOAT}, + {"c2_offsetZ", offsetof(PhysConstraints, data[1].offset.z), CSPFT_FLOAT}, + {"c2_timeout", offsetof(PhysConstraints, data[1].timeout), CSPFT_INT}, + {"c2_min_health", offsetof(PhysConstraints, data[1].min_health), CSPFT_INT}, + {"c2_max_health", offsetof(PhysConstraints, data[1].max_health), CSPFT_INT}, + {"c2_damp", offsetof(PhysConstraints, data[1].damp), CSPFT_FLOAT}, + {"c2_power", offsetof(PhysConstraints, data[1].power), CSPFT_FLOAT}, + {"c2_spin_scale", offsetof(PhysConstraints, data[1].spin_scale), CSPFT_FLOAT}, + {"c2_shakescalex", offsetof(PhysConstraints, data[1].scale.x), CSPFT_FLOAT}, + {"c2_shakescaley", offsetof(PhysConstraints, data[1].scale.y), CSPFT_FLOAT}, + {"c2_shakescalez", offsetof(PhysConstraints, data[1].scale.z), CSPFT_FLOAT}, + {"c2_min_angle", offsetof(PhysConstraints, data[1].minAngle), CSPFT_FLOAT}, + {"c2_max_angle", offsetof(PhysConstraints, data[1].maxAngle), CSPFT_FLOAT}, + {"c2_yaw", offsetof(PhysConstraints, data[1].scale.y), CSPFT_FLOAT}, + {"c2_pitch", offsetof(PhysConstraints, data[1].scale.x), CSPFT_FLOAT}, + {"c3_type", offsetof(PhysConstraints, data[2].type), CFT_TYPE}, + {"c3_bone1_name", offsetof(PhysConstraints, data[2].target_bone1), CSPFT_STRING}, + {"c3_bone2_name", offsetof(PhysConstraints, data[2].target_bone2), CSPFT_STRING}, + {"c3_offsetX", offsetof(PhysConstraints, data[2].offset.x), CSPFT_FLOAT}, + {"c3_offsetY", offsetof(PhysConstraints, data[2].offset.y), CSPFT_FLOAT}, + {"c3_offsetZ", offsetof(PhysConstraints, data[2].offset.z), CSPFT_FLOAT}, + {"c3_timeout", offsetof(PhysConstraints, data[2].timeout), CSPFT_INT}, + {"c3_min_health", offsetof(PhysConstraints, data[2].min_health), CSPFT_INT}, + {"c3_max_health", offsetof(PhysConstraints, data[2].max_health), CSPFT_INT}, + {"c3_damp", offsetof(PhysConstraints, data[2].damp), CSPFT_FLOAT}, + {"c3_power", offsetof(PhysConstraints, data[2].power), CSPFT_FLOAT}, + {"c3_spin_scale", offsetof(PhysConstraints, data[2].spin_scale), CSPFT_FLOAT}, + {"c3_shakescalex", offsetof(PhysConstraints, data[2].scale.x), CSPFT_FLOAT}, + {"c3_shakescaley", offsetof(PhysConstraints, data[2].scale.y), CSPFT_FLOAT}, + {"c3_shakescalez", offsetof(PhysConstraints, data[2].scale.z), CSPFT_FLOAT}, + {"c3_min_angle", offsetof(PhysConstraints, data[2].minAngle), CSPFT_FLOAT}, + {"c3_max_angle", offsetof(PhysConstraints, data[2].maxAngle), CSPFT_FLOAT}, + {"c3_yaw", offsetof(PhysConstraints, data[2].scale.y), CSPFT_FLOAT}, + {"c3_pitch", offsetof(PhysConstraints, data[2].scale.x), CSPFT_FLOAT}, + {"c4_type", offsetof(PhysConstraints, data[3].type), CFT_TYPE}, + {"c4_bone1_name", offsetof(PhysConstraints, data[3].target_bone1), CSPFT_STRING}, + {"c4_bone2_name", offsetof(PhysConstraints, data[3].target_bone2), CSPFT_STRING}, + {"c4_offsetX", offsetof(PhysConstraints, data[3].offset.x), CSPFT_FLOAT}, + {"c4_offsetY", offsetof(PhysConstraints, data[3].offset.y), CSPFT_FLOAT}, + {"c4_offsetZ", offsetof(PhysConstraints, data[3].offset.z), CSPFT_FLOAT}, + {"c4_timeout", offsetof(PhysConstraints, data[3].timeout), CSPFT_INT}, + {"c4_min_health", offsetof(PhysConstraints, data[3].min_health), CSPFT_INT}, + {"c4_max_health", offsetof(PhysConstraints, data[3].max_health), CSPFT_INT}, + {"c4_damp", offsetof(PhysConstraints, data[3].damp), CSPFT_FLOAT}, + {"c4_power", offsetof(PhysConstraints, data[3].power), CSPFT_FLOAT}, + {"c4_spin_scale", offsetof(PhysConstraints, data[3].spin_scale), CSPFT_FLOAT}, + {"c4_shakescalex", offsetof(PhysConstraints, data[3].scale.x), CSPFT_FLOAT}, + {"c4_shakescaley", offsetof(PhysConstraints, data[3].scale.y), CSPFT_FLOAT}, + {"c4_shakescalez", offsetof(PhysConstraints, data[3].scale.z), CSPFT_FLOAT}, + {"c4_min_angle", offsetof(PhysConstraints, data[3].minAngle), CSPFT_FLOAT}, + {"c4_max_angle", offsetof(PhysConstraints, data[3].maxAngle), CSPFT_FLOAT}, + {"c4_yaw", offsetof(PhysConstraints, data[3].scale.y), CSPFT_FLOAT}, + {"c4_pitch", offsetof(PhysConstraints, data[3].scale.x), CSPFT_FLOAT}, +}; + +namespace T6 +{ + const char* s_constraintTypeNames[] + { + "none", + "point", + "distance", + "hinge", + "joint", + "actuator", + "fake_shake", + "launch", + "rope", + "light", + }; + + class InfoStringFromPhysConstraintsConverter final : public InfoStringFromStructConverter + { + protected: + void FillFromExtensionField(const cspField_t& field) override + { + switch (static_cast(field.iFieldType)) + { + case CFT_TYPE: + FillFromEnumInt(std::string(field.szName), field.iOffset, s_constraintTypeNames, _countof(s_constraintTypeNames)); + break; + + case CFT_NUM: + default: + assert(false); + break; + } + } + + public: + InfoStringFromPhysConstraintsConverter(const PhysConstraints* structure, const cspField_t* fields, const size_t fieldCount, std::function scriptStringValueCallback) + : InfoStringFromStructConverter(structure, fields, fieldCount, std::move(scriptStringValueCallback)) + { + } + }; +} + +bool AssetDumperPhysConstraints::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +std::string AssetDumperPhysConstraints::GetFileNameForAsset(Zone* zone, XAssetInfo* asset) +{ + return "physconstraints/" + asset->m_name; +} + +void AssetDumperPhysConstraints::DumpAsset(Zone* zone, XAssetInfo* asset, FileAPI::File* out) +{ + assert(asset->Asset()->count <= 4); + + InfoStringFromPhysConstraintsConverter converter(asset->Asset(), phys_constraints_fields, _countof(phys_constraints_fields), [asset](const scr_string_t scrStr) -> std::string + { + assert(scrStr < asset->m_zone->m_script_strings.size()); + if (scrStr >= asset->m_zone->m_script_strings.size()) + return ""; + + return asset->m_zone->m_script_strings[scrStr]; + }); + + const auto infoString = converter.Convert(); + const auto stringValue = infoString.ToString("PHYSCONSTRAINTS"); + out->Write(stringValue.c_str(), 1, stringValue.length()); +} diff --git a/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.h b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.h new file mode 100644 index 00000000..54bb1046 --- /dev/null +++ b/src/ObjWriting/Game/T6/AssetDumpers/AssetDumperPhysConstraints.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/T6/T6.h" + +namespace T6 +{ + class AssetDumperPhysConstraints final : public AbstractAssetDumper + { + static cspField_t phys_constraints_fields[]; + + protected: + bool ShouldDump(XAssetInfo* asset) override; + std::string GetFileNameForAsset(Zone* zone, XAssetInfo* asset) override; + void DumpAsset(Zone* zone, XAssetInfo* asset, FileAPI::File* out) override; + }; +} diff --git a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp index 13c5767b..d683014f 100644 --- a/src/ObjWriting/Game/T6/ZoneDumperT6.cpp +++ b/src/ObjWriting/Game/T6/ZoneDumperT6.cpp @@ -11,6 +11,7 @@ #include "AssetDumpers/AssetDumperLocalizeEntry.h" #include "AssetDumpers/AssetDumperGfxImage.h" #include "AssetDumpers/AssetDumperFontIcon.h" +#include "AssetDumpers/AssetDumperPhysConstraints.h" #include "AssetDumpers/AssetDumperPhysPreset.h" #include "AssetDumpers/AssetDumperTracer.h" #include "AssetDumpers/AssetDumperVehicle.h" @@ -36,7 +37,7 @@ bool ZoneDumper::DumpZone(Zone* zone, const std::string& basePath) const const auto* assetPools = dynamic_cast(zone->m_pools.get()); DUMP_ASSET_POOL(AssetDumperPhysPreset, m_phys_preset); - // DUMP_ASSET_POOL(AssetDumperPhysConstraints, m_phys_constraints); + DUMP_ASSET_POOL(AssetDumperPhysConstraints, m_phys_constraints); // DUMP_ASSET_POOL(AssetDumperDestructibleDef, m_destructible_def); // DUMP_ASSET_POOL(AssetDumperXAnimParts, m_xanim_parts); // DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel); diff --git a/src/ZoneCommon/Game/T6/T6.h b/src/ZoneCommon/Game/T6/T6.h index 440b3a46..219d4105 100644 --- a/src/ZoneCommon/Game/T6/T6.h +++ b/src/ZoneCommon/Game/T6/T6.h @@ -116,4 +116,11 @@ namespace T6 TFT_NUM_FIELD_TYPES }; + + enum constraintsFieldType_t + { + CFT_TYPE = 0x12, + + CFT_NUM + }; }