godot-module-template/engine/thirdparty/jolt_physics/Jolt/Physics/Body/BodyCreationSettings.cpp

235 lines
7.7 KiB
C++

// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#include <Jolt/Jolt.h>
#include <Jolt/Physics/Body/BodyCreationSettings.h>
#include <Jolt/ObjectStream/TypeDeclarations.h>
#include <Jolt/Core/StreamIn.h>
#include <Jolt/Core/StreamOut.h>
JPH_NAMESPACE_BEGIN
JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(BodyCreationSettings)
{
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mPosition)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRotation)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearVelocity)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularVelocity)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUserData)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mShape)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mCollisionGroup)
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mObjectLayer)
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionType)
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mAllowedDOFs)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowDynamicOrKinematic)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mIsSensor)
JPH_ADD_ATTRIBUTE_WITH_ALIAS(BodyCreationSettings, mCollideKinematicVsNonDynamic, "mSensorDetectsStatic") // This is the old name to keep backwards compatibility
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUseManifoldReduction)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mApplyGyroscopicForce)
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionQuality)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mEnhancedInternalEdgeRemoval)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowSleeping)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mFriction)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRestitution)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearDamping)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularDamping)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxLinearVelocity)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxAngularVelocity)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mGravityFactor)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumVelocityStepsOverride)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumPositionStepsOverride)
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mOverrideMassProperties)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mInertiaMultiplier)
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMassPropertiesOverride)
}
void BodyCreationSettings::SaveBinaryState(StreamOut &inStream) const
{
inStream.Write(mPosition);
inStream.Write(mRotation);
inStream.Write(mLinearVelocity);
inStream.Write(mAngularVelocity);
mCollisionGroup.SaveBinaryState(inStream);
inStream.Write(mObjectLayer);
inStream.Write(mMotionType);
inStream.Write(mAllowedDOFs);
inStream.Write(mAllowDynamicOrKinematic);
inStream.Write(mIsSensor);
inStream.Write(mCollideKinematicVsNonDynamic);
inStream.Write(mUseManifoldReduction);
inStream.Write(mApplyGyroscopicForce);
inStream.Write(mMotionQuality);
inStream.Write(mEnhancedInternalEdgeRemoval);
inStream.Write(mAllowSleeping);
inStream.Write(mFriction);
inStream.Write(mRestitution);
inStream.Write(mLinearDamping);
inStream.Write(mAngularDamping);
inStream.Write(mMaxLinearVelocity);
inStream.Write(mMaxAngularVelocity);
inStream.Write(mGravityFactor);
inStream.Write(mNumVelocityStepsOverride);
inStream.Write(mNumPositionStepsOverride);
inStream.Write(mOverrideMassProperties);
inStream.Write(mInertiaMultiplier);
mMassPropertiesOverride.SaveBinaryState(inStream);
}
void BodyCreationSettings::RestoreBinaryState(StreamIn &inStream)
{
inStream.Read(mPosition);
inStream.Read(mRotation);
inStream.Read(mLinearVelocity);
inStream.Read(mAngularVelocity);
mCollisionGroup.RestoreBinaryState(inStream);
inStream.Read(mObjectLayer);
inStream.Read(mMotionType);
inStream.Read(mAllowedDOFs);
inStream.Read(mAllowDynamicOrKinematic);
inStream.Read(mIsSensor);
inStream.Read(mCollideKinematicVsNonDynamic);
inStream.Read(mUseManifoldReduction);
inStream.Read(mApplyGyroscopicForce);
inStream.Read(mMotionQuality);
inStream.Read(mEnhancedInternalEdgeRemoval);
inStream.Read(mAllowSleeping);
inStream.Read(mFriction);
inStream.Read(mRestitution);
inStream.Read(mLinearDamping);
inStream.Read(mAngularDamping);
inStream.Read(mMaxLinearVelocity);
inStream.Read(mMaxAngularVelocity);
inStream.Read(mGravityFactor);
inStream.Read(mNumVelocityStepsOverride);
inStream.Read(mNumPositionStepsOverride);
inStream.Read(mOverrideMassProperties);
inStream.Read(mInertiaMultiplier);
mMassPropertiesOverride.RestoreBinaryState(inStream);
}
Shape::ShapeResult BodyCreationSettings::ConvertShapeSettings()
{
// If we already have a shape, return it
if (mShapePtr != nullptr)
{
mShape = nullptr;
Shape::ShapeResult result;
result.Set(const_cast<Shape *>(mShapePtr.GetPtr()));
return result;
}
// Check if we have shape settings
if (mShape == nullptr)
{
Shape::ShapeResult result;
result.SetError("No shape present!");
return result;
}
// Create the shape
Shape::ShapeResult result = mShape->Create();
if (result.IsValid())
mShapePtr = result.Get();
mShape = nullptr;
return result;
}
const Shape *BodyCreationSettings::GetShape() const
{
// If we already have a shape, return it
if (mShapePtr != nullptr)
return mShapePtr;
// Check if we have shape settings
if (mShape == nullptr)
return nullptr;
// Create the shape
Shape::ShapeResult result = mShape->Create();
if (result.IsValid())
return result.Get();
Trace("Error: %s", result.GetError().c_str());
JPH_ASSERT(false, "An error occurred during shape creation. Use ConvertShapeSettings() to convert the shape and get the error!");
return nullptr;
}
MassProperties BodyCreationSettings::GetMassProperties() const
{
// Calculate mass properties
MassProperties mass_properties;
switch (mOverrideMassProperties)
{
case EOverrideMassProperties::CalculateMassAndInertia:
mass_properties = GetShape()->GetMassProperties();
mass_properties.mInertia *= mInertiaMultiplier;
mass_properties.mInertia(3, 3) = 1.0f;
break;
case EOverrideMassProperties::CalculateInertia:
mass_properties = GetShape()->GetMassProperties();
mass_properties.ScaleToMass(mMassPropertiesOverride.mMass);
mass_properties.mInertia *= mInertiaMultiplier;
mass_properties.mInertia(3, 3) = 1.0f;
break;
case EOverrideMassProperties::MassAndInertiaProvided:
mass_properties = mMassPropertiesOverride;
break;
}
return mass_properties;
}
void BodyCreationSettings::SaveWithChildren(StreamOut &inStream, ShapeToIDMap *ioShapeMap, MaterialToIDMap *ioMaterialMap, GroupFilterToIDMap *ioGroupFilterMap) const
{
// Save creation settings
SaveBinaryState(inStream);
// Save shape
if (ioShapeMap != nullptr && ioMaterialMap != nullptr)
GetShape()->SaveWithChildren(inStream, *ioShapeMap, *ioMaterialMap);
else
inStream.Write(~uint32(0));
// Save group filter
StreamUtils::SaveObjectReference(inStream, mCollisionGroup.GetGroupFilter(), ioGroupFilterMap);
}
BodyCreationSettings::BCSResult BodyCreationSettings::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap &ioShapeMap, IDToMaterialMap &ioMaterialMap, IDToGroupFilterMap &ioGroupFilterMap)
{
BCSResult result;
// Read creation settings
BodyCreationSettings settings;
settings.RestoreBinaryState(inStream);
if (inStream.IsEOF() || inStream.IsFailed())
{
result.SetError("Error reading body creation settings");
return result;
}
// Read shape
Shape::ShapeResult shape_result = Shape::sRestoreWithChildren(inStream, ioShapeMap, ioMaterialMap);
if (shape_result.HasError())
{
result.SetError(shape_result.GetError());
return result;
}
settings.SetShape(shape_result.Get());
// Read group filter
Result gfresult = StreamUtils::RestoreObjectReference(inStream, ioGroupFilterMap);
if (gfresult.HasError())
{
result.SetError(gfresult.GetError());
return result;
}
settings.mCollisionGroup.SetGroupFilter(gfresult.Get());
result.Set(settings);
return result;
}
JPH_NAMESPACE_END