#include "MetaCorePhysics/MetaCorePhysics.h" #include "MetaCoreFoundation/MetaCoreArchive.h" #include #include #include namespace MetaCore { MetaCorePhysicsSettingsDocument MetaCoreBuildDefaultPhysicsSettings() { MetaCorePhysicsSettingsDocument result; result.LayerNames.resize(32U); result.CollisionMasks.assign(32U, 0xFFFFFFFFU); result.LayerNames[0] = "Default"; for (std::size_t index = 1; index < result.LayerNames.size(); ++index) result.LayerNames[index] = "Layer " + std::to_string(index); return result; } bool MetaCoreValidatePhysicsSettings(MetaCorePhysicsSettingsDocument& document, std::vector* issues) { bool valid = true; const auto report = [&](std::string value) { valid = false; if (issues) issues->push_back(std::move(value)); }; if (!std::isfinite(document.Gravity.x) || !std::isfinite(document.Gravity.y) || !std::isfinite(document.Gravity.z)) { report("Gravity 必须为有限值"); document.Gravity = glm::vec3(0.0F, 0.0F, -9.81F); } if (!std::isfinite(document.FixedTimeStep) || document.FixedTimeStep < 0.001 || document.FixedTimeStep > 1.0) { report("FixedTimeStep 必须位于 [0.001, 1.0]"); document.FixedTimeStep = 1.0 / 60.0; } if (!std::isfinite(document.MaxFrameDelta) || document.MaxFrameDelta < document.FixedTimeStep || document.MaxFrameDelta > 1.0) { report("MaxFrameDelta 无效"); document.MaxFrameDelta = 0.25; } if (document.MaxFixedStepsPerFrame == 0U || document.MaxFixedStepsPerFrame > 32U) { report("MaxFixedStepsPerFrame 必须位于 [1, 32]"); document.MaxFixedStepsPerFrame = 4U; } if (document.LayerNames.size() != 32U) { report("碰撞层名称必须恰好为 32 项"); document.LayerNames.resize(32U); } if (document.CollisionMasks.size() != 32U) { report("碰撞矩阵必须恰好为 32 项"); document.CollisionMasks.resize(32U, 0xFFFFFFFFU); } for (std::uint32_t lhs = 0; lhs < 32U; ++lhs) for (std::uint32_t rhs = lhs + 1U; rhs < 32U; ++rhs) { const bool enabled = ((document.CollisionMasks[lhs] >> rhs) & 1U) != 0U && ((document.CollisionMasks[rhs] >> lhs) & 1U) != 0U; if (enabled) { document.CollisionMasks[lhs] |= 1U << rhs; document.CollisionMasks[rhs] |= 1U << lhs; } else { document.CollisionMasks[lhs] &= ~(1U << rhs); document.CollisionMasks[rhs] &= ~(1U << lhs); } } return valid; } bool MetaCoreWritePhysicsSettings(const std::filesystem::path& path, const MetaCorePhysicsSettingsDocument& document, const MetaCoreTypeRegistry& registry) { const auto bytes = MetaCoreSerializeToBytes(document, registry); if (!bytes) return false; std::error_code error; std::filesystem::create_directories(path.parent_path(), error); std::ofstream output(path, std::ios::binary | std::ios::trunc); if (!output) return false; output.write(reinterpret_cast(bytes->data()), static_cast(bytes->size())); return output.good(); } std::optional MetaCoreReadPhysicsSettings(const std::filesystem::path& path, const MetaCoreTypeRegistry& registry) { std::ifstream input(path, std::ios::binary | std::ios::ate); if (!input) return std::nullopt; const auto size = static_cast(input.tellg()); input.seekg(0); std::vector bytes(size); if (size && !input.read(reinterpret_cast(bytes.data()), static_cast(size))) return std::nullopt; MetaCorePhysicsSettingsDocument result; if (!MetaCoreDeserializeFromBytes(std::span(bytes.data(), bytes.size()), result, registry)) return std::nullopt; // Version 1 used Bullet's Y-up convention. MetaCore is Z-up, so migrate the // complete gravity vector instead of only replacing the old default value. if (result.Version < 2U) { result.Gravity = glm::vec3(result.Gravity.x, result.Gravity.z, result.Gravity.y); result.Version = 2U; } (void)MetaCoreValidatePhysicsSettings(result); return result; } bool MetaCoreWritePhysicsMaterial(const std::filesystem::path& path, const MetaCorePhysicsMaterialDocument& document, const MetaCoreTypeRegistry& registry) { const auto bytes=MetaCoreSerializeToBytes(document,registry);if(!bytes)return false;std::error_code error;std::filesystem::create_directories(path.parent_path(),error); std::ofstream output(path,std::ios::binary|std::ios::trunc);if(!output)return false;output.write(reinterpret_cast(bytes->data()),static_cast(bytes->size()));return output.good(); } std::optional MetaCoreReadPhysicsMaterial(const std::filesystem::path& path, const MetaCoreTypeRegistry& registry) { std::ifstream input(path,std::ios::binary|std::ios::ate);if(!input)return std::nullopt;const auto size=static_cast(input.tellg());input.seekg(0);std::vector bytes(size); if(size&&!input.read(reinterpret_cast(bytes.data()),static_cast(size)))return std::nullopt;MetaCorePhysicsMaterialDocument result;if(!MetaCoreDeserializeFromBytes(std::span(bytes.data(),bytes.size()),result,registry))return std::nullopt;return result; } } // namespace MetaCore