From 8030a0238f199d3cd55205e9711a115537c2342a Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 27 Mar 2021 10:50:20 +0100 Subject: [PATCH] Add phys preset loading --- .../T6/AssetLoaders/AssetLoaderPhysPreset.cpp | 102 ++++++++++++++++++ .../T6/AssetLoaders/AssetLoaderPhysPreset.h | 18 ++++ src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 3 +- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.cpp create mode 100644 src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.h diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.cpp b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.cpp new file mode 100644 index 00000000..a630a67e --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.cpp @@ -0,0 +1,102 @@ +#include "AssetLoaderPhysPreset.h" + +#include +#include +#include +#include +#include + +#include "Game/T6/ObjConstantsT6.h" +#include "Game/T6/T6.h" +#include "Game/T6/InfoString/InfoStringToStructConverter.h" +#include "Game/T6/InfoString/PhysPresetFields.h" +#include "InfoString/InfoString.h" + +using namespace T6; + +namespace T6 +{ + class InfoStringToPhysPresetConverter final : public InfoStringToStructConverter + { + protected: + bool ConvertExtensionField(const cspField_t& field, const std::string& value) override + { + assert(false); + return false; + } + + public: + InfoStringToPhysPresetConverter(const InfoString& infoString, PhysPresetInfo* physPreset, ZoneScriptStrings& zoneScriptStrings, MemoryManager* memory, IAssetLoadingManager* manager, + const cspField_t* fields, const size_t fieldCount) + : InfoStringToStructConverter(infoString, physPreset, zoneScriptStrings, memory, manager, fields, fieldCount) + { + } + }; +} + +void AssetLoaderPhysPreset::CopyFromPhysPresetInfo(const PhysPresetInfo* physPresetInfo, PhysPreset* physPreset) +{ + physPreset->mass = std::clamp(physPresetInfo->mass, 1.0f, 2000.0f) * 0.001f; + physPreset->bounce = physPresetInfo->bounce; + + if (physPresetInfo->isFrictionInfinity != 0) + physPreset->friction = std::numeric_limits::infinity(); + else + physPreset->friction = physPresetInfo->friction; + + physPreset->bulletForceScale = physPresetInfo->bulletForceScale; + physPreset->explosiveForceScale = physPresetInfo->explosiveForceScale; + physPreset->piecesSpreadFraction = physPresetInfo->piecesSpreadFraction; + physPreset->piecesUpwardVelocity = physPresetInfo->piecesUpwardVelocity; + physPreset->canFloat = physPresetInfo->canFloat; + physPreset->gravityScale = std::clamp(physPresetInfo->gravityScale, 0.01f, 10.0f); + physPreset->centerOfMassOffset = physPresetInfo->centerOfMassOffset; + physPreset->buoyancyBoxMin = physPresetInfo->buoyancyBoxMin; + physPreset->buoyancyBoxMax = physPresetInfo->buoyancyBoxMax; +} + +void* AssetLoaderPhysPreset::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) +{ + auto* physPreset = memory->Create(); + memset(physPreset, 0, sizeof(PhysPreset)); + physPreset->name = memory->Dup(assetName.c_str()); + return physPreset; +} + +bool AssetLoaderPhysPreset::CanLoadFromRaw() const +{ + return true; +} + +bool AssetLoaderPhysPreset::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const +{ + const auto fileName = "physic/" + assetName; + const auto file = searchPath->Open(fileName); + if (!file.IsOpen()) + return false; + + InfoString infoString; + if (!infoString.FromStream(ObjConstants::INFO_STRING_PREFIX_PHYS_PRESET, *file.m_stream)) + { + std::cout << "Failed to read phys preset raw file: \"" << fileName << "\"" << std::endl; + return true; + } + + auto presetInfo = std::make_unique(); + memset(presetInfo.get(), 0, sizeof(PhysPresetInfo)); + InfoStringToPhysPresetConverter converter(infoString, presetInfo.get(), zone->m_script_strings, memory, manager, phys_preset_fields, std::extent::value); + if (!converter.Convert()) + { + std::cout << "Failed to parse phys preset raw file: \"" << fileName << "\"" << std::endl; + return true; + } + + auto* physPreset = memory->Create(); + + CopyFromPhysPresetInfo(presetInfo.get(), physPreset); + physPreset->name = memory->Dup(assetName.c_str()); + + manager->AddAsset(ASSET_TYPE_PHYSPRESET, assetName, physPreset, converter.GetDependencies(), converter.GetUsedScriptStrings()); + + return true; +} diff --git a/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.h b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.h new file mode 100644 index 00000000..a974f8f1 --- /dev/null +++ b/src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderPhysPreset.h @@ -0,0 +1,18 @@ +#pragma once +#include "Game/T6/T6.h" +#include "AssetLoading/BasicAssetLoader.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" + +namespace T6 +{ + class AssetLoaderPhysPreset final : public BasicAssetLoader + { + static void CopyFromPhysPresetInfo(const PhysPresetInfo* physPresetInfo, PhysPreset* physPreset); + + public: + _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; + _NODISCARD bool CanLoadFromRaw() const override; + bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; + }; +} diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index af14c619..354da947 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -6,6 +6,7 @@ #include "ObjLoading.h" #include "AssetLoaders/AssetLoaderFontIcon.h" #include "AssetLoaders/AssetLoaderLocalizeEntry.h" +#include "AssetLoaders/AssetLoaderPhysPreset.h" #include "AssetLoaders/AssetLoaderQdb.h" #include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoaders/AssetLoaderScriptParseTree.h" @@ -32,7 +33,7 @@ namespace T6 #define REGISTER_ASSET_LOADER(t) {auto l = std::make_unique(); m_asset_loaders_by_type[l->GetHandlingAssetType()] = std::move(l);} #define BASIC_LOADER(assetType, assetClass) BasicAssetLoader - REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSPRESET, PhysPreset)) + REGISTER_ASSET_LOADER(AssetLoaderPhysPreset) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_XANIMPARTS, XAnimParts))