Skip to content

Commit

Permalink
Misc fixes - no more crash
Browse files Browse the repository at this point in the history
  • Loading branch information
Lamakaio committed Jun 5, 2024
1 parent 0c2db9f commit 638be0b
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 44 deletions.
87 changes: 79 additions & 8 deletions src/ospjolt/activescene/joltinteg.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,55 @@
#include <Jolt/Physics/PhysicsSystem.h>
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
#include <Jolt/Physics/Collision/Shape/SphereShape.h>
#include <Jolt/Physics/Collision/Shape/CylinderShape.h>
#include <Jolt/Physics/Body/BodyCreationSettings.h>
#include <Jolt/Physics/Body/BodyActivationListener.h>
#include <Jolt/Core/TempAllocator.h>
#include <Jolt/Physics/Collision/Shape/CompoundShape.h>
#include <Jolt/Physics/Collision/Shape/MutableCompoundShape.h>
#include <Jolt/Core/JobSystemSingleThreaded.h>

#include <longeron/id_management/registry_stl.hpp>
#include <longeron/id_management/id_set_stl.hpp>

#include <entt/core/any.hpp>
#include <JobSystemSingleThreaded.h>

#include <iostream>
#include <cstdarg>
#include <thread>

// Callback for traces, connect this to your own trace function if you have one
static void TraceImpl(const char *inFMT, ...)
{
// Format the message
va_list list;
va_start(list, inFMT);
char buffer[1024];
vsnprintf(buffer, sizeof(buffer), inFMT, list);
va_end(list);

// Print to the TTY
std::cout << buffer << std::endl;
}

#ifdef JPH_ENABLE_ASSERTS

// Callback for asserts, connect this to your own assert handler if you have one
static bool AssertFailedImpl(const char *inExpression, const char *inMessage, const char *inFile, uint inLine)
{
// Print to the TTY
std::cout << inFile << ":" << inLine << ": (" << inExpression << ") " << (inMessage != nullptr? inMessage : "") << std::endl;

// Breakpoint
return true;
};

#endif // JPH_ENABLE_ASSERTS



//disable common warning triggered by Jolt
JPH_SUPPRESS_WARNINGS

namespace ospjolt
{
Expand Down Expand Up @@ -123,6 +160,19 @@ class BPLayerInterfaceImpl final : public BroadPhaseLayerInterface
return mObjectToBroadPhase[inLayer];
}

#if defined(JPH_EXTERNAL_PROFILE) || defined(JPH_PROFILE_ENABLED)
/// Get the user readable name of a broadphase layer (debugging purposes)
virtual const char * GetBroadPhaseLayerName(BroadPhaseLayer inLayer) const override
{
if (inLayer == BroadPhaseLayers::NON_MOVING) {
return "NON_MOVING";
}
else {
return "MOVING";
}
}
#endif // JPH_EXTERNAL_PROFILE || JPH_PROFILE_ENABLED

private:
BroadPhaseLayer mObjectToBroadPhase[Layers::NUM_LAYERS];
};
Expand All @@ -146,8 +196,8 @@ class ObjectVsBroadPhaseLayerFilterImpl : public ObjectVsBroadPhaseLayerFilter
}
}
};

using ShapeStorage_t = osp::Storage_t<osp::active::ActiveEnt, Ref<TransformedShape>>;
using TransformedShapePtr_t = std::unique_ptr<TransformedShape>;
using ShapeStorage_t = osp::Storage_t<osp::active::ActiveEnt, TransformedShapePtr_t>;

/**
* @brief Represents an instance of a Jolt physics world in the scene
Expand All @@ -165,25 +215,46 @@ struct ACtxJoltWorld
};
// The default values are the one suggested in the Jolt hello world exemple for a "real" project.
// It might be overkill here.
//TODO temp allocator
ACtxJoltWorld(
uint maxBodies = 65536,
uint numBodyMutexes = 0,
uint maxBodyPairs = 65536,
uint maxContactConstraints = 10240
) : m_temp_allocator(10 * 1024 * 1024),
m_joltJobSystem(std::make_unique<JobSystemSingleThreaded>(16)) //TODO multithreading
) : m_world(std::make_unique<PhysicsSystem>()),
m_joltJobSystem(std::make_unique<JobSystemSingleThreaded>(cMaxPhysicsJobs)) //TODO multithreading
{
m_world.get()->Init(maxBodies,
m_world->Init(maxBodies,
numBodyMutexes,
maxBodyPairs,
maxContactConstraints,
m_bPLInterface,
m_bPLInterface,
m_objectVsBPLFilter,
m_objectLayerFilter);
}

static void initJoltGlobal()
{

RegisterDefaultAllocator();

// Install trace and assert callbacks
Trace = TraceImpl;
JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl;)

// Create a factory, this class is responsible for creating instances of classes based on their name or hash and is mainly used for deserialization of saved data.
// It is not directly used in this example but still required.
Factory::sInstance = new Factory();

// Register all physics types with the factory and install their collision handlers with the CollisionDispatch class.
// If you have your own custom shape types you probably need to register their handlers with the CollisionDispatch before calling this function.
// If you implement your own default material (PhysicsMaterial::sDefault) make sure to initialize it before this function or else this function will create one for you.
RegisterTypes();

}


TempAllocatorImpl m_temp_allocator;
TempAllocatorMalloc m_temp_allocator;
ObjectLayerPairFilterImpl m_objectLayerFilter;
BPLayerInterfaceImpl m_bPLInterface;
ObjectVsBroadPhaseLayerFilterImpl m_objectVsBPLFilter;
Expand Down
30 changes: 14 additions & 16 deletions src/ospjolt/activescene/joltinteg_fn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/

#include "joltinteg_fn.h" // IWYU pragma: associated
#include <CylinderShape.h>
#include <osp/activescene/basic_fn.h>

#include <utility> // for std::exchange
Expand Down Expand Up @@ -106,7 +105,7 @@ void SysJolt::update_world(
rCtxWorld.m_pTransform = std::addressof(rTf);

// Update the world
pJoltWorld->Update(timestep, 1, &rCtxWorld.m_temp_allocator, NULL); //TODO : job system
pJoltWorld->Update(timestep, 1, &rCtxWorld.m_temp_allocator, rCtxWorld.m_joltJobSystem.get()); //TODO : job system
}

void SysJolt::remove_components(ACtxJoltWorld& rCtxWorld, ActiveEnt ent) noexcept
Expand All @@ -122,35 +121,34 @@ void SysJolt::remove_components(ACtxJoltWorld& rCtxWorld, ActiveEnt ent) noexcep

}

Ref<TransformedShape> SysJolt::create_primitive(ACtxJoltWorld &rCtxWorld, osp::EShape shape)
TransformedShapePtr_t SysJolt::create_primitive(ACtxJoltWorld &rCtxWorld, osp::EShape shape)
{
Ref<Shape> jolt_shape;
Shape* joltShape;
switch (shape)
{
case EShape::Sphere:
jolt_shape = Ref((Shape *) new SphereShape(1.0f));
joltShape = (Shape *) new SphereShape(1.0f);
break;
case EShape::Box:
jolt_shape = Ref((Shape *) new BoxShape(Vec3Arg(1.0f, 1.0f, 1.0f)));
joltShape = (Shape *) new BoxShape(Vec3Arg(1.0f, 1.0f, 1.0f));
break;
case EShape::Cylinder:
jolt_shape = Ref((Shape *) new CylinderShape(1.0f, 2.0f));
joltShape = (Shape *) new CylinderShape(1.0f, 2.0f);
break;
default:
// TODO: support other shapes, sphere is used for now
jolt_shape = Ref((Shape *) new SphereShape(1.0f));
joltShape = (Shape *) new SphereShape(1.0f);
break;
}

return Ref(new TransformedShape(RVec3::sZero(), Quat::sZero(), jolt_shape, BodyID(), SubShapeIDCreator()));
return TransformedShapePtr_t(new TransformedShape(RVec3::sZero(), Quat::sZero(), joltShape, BodyID(), SubShapeIDCreator()));
}

void SysJolt::orient_shape(Ref<TransformedShape> &jolt_shape, osp::EShape osp_shape, osp::Vector3 const &translation, osp::Matrix3 const &rotation, osp::Vector3 const &scale)
void SysJolt::orient_shape(TransformedShapePtr_t& pJoltShape, osp::EShape ospShape, osp::Vector3 const &translation, osp::Matrix3 const &rotation, osp::Vector3 const &scale)
{
auto rawQuat = Magnum::Quaternion::fromMatrix(rotation).data();
Quat joltRotation(rawQuat[0], rawQuat[1], rawQuat[2], rawQuat[3]);

jolt_shape->SetWorldTransform(RVec3Arg(translation.x(), translation.y(), translation.z()), joltRotation, Vec3Arg(scale.x(), scale.y(), scale.z()));
pJoltShape->SetWorldTransform(RVec3Arg(translation.x(), translation.y(), translation.z()), joltRotation, Vec3Arg(scale.x(), scale.y(), scale.z()));

}

Expand All @@ -167,7 +165,7 @@ void SysJolt::find_shapes_recurse(
// Add jolt shape if exists
if (rCtxWorld.m_shapes.contains(ent))
{
Ref<TransformedShape> rShape
TransformedShapePtr_t& pShape
= rCtxWorld.m_shapes.get(ent);

// Set transform relative to root body
Expand All @@ -178,9 +176,9 @@ void SysJolt::find_shapes_recurse(
// = (rCtxPhys.m_shape[ent] != EShape::Cylinder)
// ? transform : transform * Matrix4::rotationZ(90.0_degf);

SysJolt::orient_shape(rShape, rCtxPhys.m_shape[ent], transform.translation(), transform.rotation(), transform.scaling());
Ref<Shape> rScaledShape = rShape->mShape->ScaleShape(Vec3(rShape->mShapeScale)).Get();
pCompound.AddShape(rShape->mShapePositionCOM, rShape->mShapeRotation, rScaledShape);
SysJolt::orient_shape(pShape, rCtxPhys.m_shape[ent], transform.translation(), transform.rotation(), transform.scaling());
Ref<Shape> rScaledShape = pShape->mShape->ScaleShape(Vec3(pShape->mShapeScale)).Get();
pCompound.AddShape(pShape->mShapePositionCOM, pShape->mShapeRotation, rScaledShape);
}

if ( ! rCtxPhys.m_hasColliders.contains(ent) )
Expand Down
6 changes: 3 additions & 3 deletions src/ospjolt/activescene/joltinteg_fn.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class SysJolt
static void remove_components(
ACtxJoltWorld& rCtxWorld, ActiveEnt ent) noexcept;

[[nodiscard]] static Ref<TransformedShape> create_primitive(ACtxJoltWorld &rCtxWorld, osp::EShape shape);
[[nodiscard]] static TransformedShapePtr_t create_primitive(ACtxJoltWorld &rCtxWorld, osp::EShape shape);

template<typename IT_T>
static void update_delete(
Expand All @@ -107,8 +107,8 @@ class SysJolt
}

static void orient_shape(
Ref<TransformedShape>& jolt_shape,
osp::EShape osp_shape,
TransformedShapePtr_t& rJoltShape,
osp::EShape ospShape,
osp::Vector3 const& translation,
osp::Matrix3 const& rotation,
osp::Vector3 const& scale);
Expand Down
41 changes: 24 additions & 17 deletions src/testapp/sessions/jolt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ Session setup_jolt(
Session const& commonScene,
Session const& physics)
{
//Mandatory Jolt setup steps (start of program)
ACtxJoltWorld::initJoltGlobal();
JPH_IF_ENABLE_ASSERTS(AssertFailed = AssertFailedImpl;)


OSP_DECLARE_GET_DATA_IDS(scene, TESTAPP_DATA_SCENE);
OSP_DECLARE_GET_DATA_IDS(commonScene, TESTAPP_DATA_COMMON_SCENE);
OSP_DECLARE_GET_DATA_IDS(physics, TESTAPP_DATA_PHYSICS);
Expand Down Expand Up @@ -205,21 +210,23 @@ Session setup_phys_shapes_jolt(
ActiveEnt const root = rPhysShapes.m_ents[i * 2];
ActiveEnt const child = rPhysShapes.m_ents[i * 2 + 1];

Ref<TransformedShape> shape = SysJolt::create_primitive(rJolt, spawn.m_shape);
SysJolt::orient_shape(shape, spawn.m_shape, spawn.m_position, Matrix3{}, spawn.m_size);
TransformedShapePtr_t pShape = SysJolt::create_primitive(rJolt, spawn.m_shape);
SysJolt::orient_shape(pShape, spawn.m_shape, spawn.m_position, Matrix3{}, spawn.m_size);

OspBodyId const bodyId = rJolt.m_bodyIds.create();
SysJolt::resize_body_data(rJolt);

BodyCreationSettings bodyCreation(shape->mShape, shape->mShapePositionCOM, shape->mShapeRotation, EMotionType::Dynamic, Layers::MOVING);
MassProperties massProp;
BodyCreationSettings bodyCreation(pShape->mShape, pShape->mShapePositionCOM, pShape->mShapeRotation, EMotionType::Dynamic, Layers::MOVING);

//Vector3 const inertia = collider_inertia_tensor(spawn.m_shape, spawn.m_size, spawn.m_mass);
massProp.mMass = spawn.m_mass;
//massProp.mInertia = Mat44::sScale(Vec3Arg(inertia.x(), inertia.y(), inertia.z()));
bodyCreation.mMassPropertiesOverride = massProp;
bodyCreation.mOverrideMassProperties = EOverrideMassProperties::CalculateInertia;

if (spawn.m_mass > 0.0f)
{
MassProperties massProp;
//Vector3 const inertia = collider_inertia_tensor(spawn.m_shape, spawn.m_size, spawn.m_mass);
massProp.mMass = spawn.m_mass;
//massProp.mInertia = Mat44::sScale(Vec3Arg(inertia.x(), inertia.y(), inertia.z()));
bodyCreation.mMassPropertiesOverride = massProp;
bodyCreation.mOverrideMassProperties = EOverrideMassProperties::CalculateInertia;
}
PhysicsSystem *pJoltWorld = rJolt.m_world.get();
BodyInterface &bodyInterface = pJoltWorld->GetBodyInterface();

Expand Down Expand Up @@ -250,22 +257,22 @@ void compound_collect_recurse(

if (shape != EShape::None)
{

Ref<TransformedShape> rShape = rCtxWorld.m_shapes.contains(ent)
bool entExists = rCtxWorld.m_shapes.contains(ent);
TransformedShapePtr_t& pShape = entExists
? rCtxWorld.m_shapes.get(ent)
: rCtxWorld.m_shapes.emplace(ent);

if (rShape.GetPtr() == nullptr)
if (!entExists)
{
rShape = SysJolt::create_primitive(rCtxWorld, shape);
pShape = SysJolt::create_primitive(rCtxWorld, shape);
}

SysJolt::orient_shape(rShape, shape, transform.translation(), transform.rotation(), transform.scaling());
SysJolt::orient_shape(pShape, shape, transform.translation(), transform.rotation(), transform.scaling());
//scale the shape itself
Ref<Shape> scaledShape = rShape->mShape->ScaleShape(rShape->GetShapeScale()).Get();
Ref<Shape> scaledShape = pShape->mShape->ScaleShape(pShape->GetShapeScale()).Get();

//and add it to the compound shape
pCompound.AddShape(rShape->mShapePositionCOM, rShape->mShapeRotation, scaledShape);
pCompound.AddShape(pShape->mShapePositionCOM, pShape->mShapeRotation, scaledShape);
}

if ( ! rCtxPhys.m_hasColliders.contains(ent) )
Expand Down

0 comments on commit 638be0b

Please sign in to comment.