Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/StateRecorder.h
9906 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Core/StreamIn.h>7#include <Jolt/Core/StreamOut.h>89JPH_NAMESPACE_BEGIN1011class Body;12class Constraint;13class BodyID;1415JPH_SUPPRESS_WARNING_PUSH16JPH_GCC_SUPPRESS_WARNING("-Wshadow") // GCC complains about the 'Constraints' value conflicting with the 'Constraints' typedef1718/// A bit field that determines which aspects of the simulation to save19enum class EStateRecorderState : uint820{21None = 0, ///< Save nothing22Global = 1, ///< Save global physics system state (delta time, gravity, etc.)23Bodies = 2, ///< Save the state of bodies24Contacts = 4, ///< Save the state of contacts25Constraints = 8, ///< Save the state of constraints26All = Global | Bodies | Contacts | Constraints ///< Save all state27};2829JPH_SUPPRESS_WARNING_POP3031/// Bitwise OR operator for EStateRecorderState32constexpr EStateRecorderState operator | (EStateRecorderState inLHS, EStateRecorderState inRHS)33{34return EStateRecorderState(uint8(inLHS) | uint8(inRHS));35}3637/// Bitwise AND operator for EStateRecorderState38constexpr EStateRecorderState operator & (EStateRecorderState inLHS, EStateRecorderState inRHS)39{40return EStateRecorderState(uint8(inLHS) & uint8(inRHS));41}4243/// Bitwise XOR operator for EStateRecorderState44constexpr EStateRecorderState operator ^ (EStateRecorderState inLHS, EStateRecorderState inRHS)45{46return EStateRecorderState(uint8(inLHS) ^ uint8(inRHS));47}4849/// Bitwise NOT operator for EStateRecorderState50constexpr EStateRecorderState operator ~ (EStateRecorderState inAllowedDOFs)51{52return EStateRecorderState(~uint8(inAllowedDOFs));53}5455/// Bitwise OR assignment operator for EStateRecorderState56constexpr EStateRecorderState & operator |= (EStateRecorderState &ioLHS, EStateRecorderState inRHS)57{58ioLHS = ioLHS | inRHS;59return ioLHS;60}6162/// Bitwise AND assignment operator for EStateRecorderState63constexpr EStateRecorderState & operator &= (EStateRecorderState &ioLHS, EStateRecorderState inRHS)64{65ioLHS = ioLHS & inRHS;66return ioLHS;67}6869/// Bitwise XOR assignment operator for EStateRecorderState70constexpr EStateRecorderState & operator ^= (EStateRecorderState &ioLHS, EStateRecorderState inRHS)71{72ioLHS = ioLHS ^ inRHS;73return ioLHS;74}7576/// User callbacks that allow determining which parts of the simulation should be saved by a StateRecorder77class JPH_EXPORT StateRecorderFilter78{79public:80/// Destructor81virtual ~StateRecorderFilter() = default;8283///@name Functions called during SaveState84///@{8586/// If the state of a specific body should be saved87virtual bool ShouldSaveBody([[maybe_unused]] const Body &inBody) const { return true; }8889/// If the state of a specific constraint should be saved90virtual bool ShouldSaveConstraint([[maybe_unused]] const Constraint &inConstraint) const { return true; }9192/// If the state of a specific contact should be saved93virtual bool ShouldSaveContact([[maybe_unused]] const BodyID &inBody1, [[maybe_unused]] const BodyID &inBody2) const { return true; }9495///@}96///@name Functions called during RestoreState97///@{9899/// If the state of a specific contact should be restored100virtual bool ShouldRestoreContact([[maybe_unused]] const BodyID &inBody1, [[maybe_unused]] const BodyID &inBody2) const { return true; }101102///@}103};104105/// Class that records the state of a physics system. Can be used to check if the simulation is deterministic by putting the recorder in validation mode.106/// Can be used to restore the state to an earlier point in time. Note that only the state that is modified by the simulation is saved, configuration settings107/// like body friction or restitution, motion quality etc. are not saved and need to be saved by the user if desired.108class JPH_EXPORT StateRecorder : public StreamIn, public StreamOut109{110public:111/// Constructor112StateRecorder() = default;113StateRecorder(const StateRecorder &inRHS) : mIsValidating(inRHS.mIsValidating) { }114115/// Sets the stream in validation mode. In this case the physics system ensures that before it calls ReadBytes that it will116/// ensure that those bytes contain the current state. This makes it possible to step and save the state, restore to the previous117/// step and step again and when the recorded state is not the same it can restore the expected state and any byte that changes118/// due to a ReadBytes function can be caught to find out which part of the simulation is not deterministic.119/// Note that validation only works when saving the full state of the simulation (EStateRecorderState::All, StateRecorderFilter == nullptr).120void SetValidating(bool inValidating) { mIsValidating = inValidating; }121bool IsValidating() const { return mIsValidating; }122123/// This allows splitting the state in multiple parts. While restoring, only the last part should have this flag set to true.124/// Note that you should ensure that the different parts contain information for disjoint sets of bodies, constraints and contacts.125/// E.g. if you restore the same contact twice, you get undefined behavior. In order to create disjoint sets you can use the StateRecorderFilter.126/// Note that validation is not compatible with restoring a simulation state in multiple parts.127void SetIsLastPart(bool inIsLastPart) { mIsLastPart = inIsLastPart; }128bool IsLastPart() const { return mIsLastPart; }129130private:131bool mIsValidating = false;132bool mIsLastPart = true;133};134135JPH_NAMESPACE_END136137138