Added more debug drawing & Fixed Physics running without SHEDITOR #237
|
@ -87,7 +87,7 @@ project "SHADE_Application"
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG", "SHEDITOR"}
|
defines {"_DEBUG"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
|
|
|
@ -84,6 +84,7 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||||
|
SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
|
||||||
// Link up SHDebugDraw
|
// Link up SHDebugDraw
|
||||||
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||||
|
@ -175,11 +176,15 @@ namespace Sandbox
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
if(editor->editorState == SHEditor::State::PLAY)
|
if(editor->editorState == SHEditor::State::PLAY)
|
||||||
SHSceneManager::SceneUpdate(0.016f);
|
|
||||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
|
||||||
editor->PollPicking();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
SHSceneManager::SceneUpdate(0.016f);
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime());
|
||||||
|
editor->PollPicking();
|
||||||
|
#else
|
||||||
|
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
||||||
|
#endif
|
||||||
// TODO: Move into an Editor menu
|
// TODO: Move into an Editor menu
|
||||||
static bool drawColliders = false;
|
static bool drawColliders = false;
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
||||||
|
@ -193,6 +198,13 @@ namespace Sandbox
|
||||||
drawRays = !drawRays;
|
drawRays = !drawRays;
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||||
}
|
}
|
||||||
|
static bool drawContacts = false;
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
|
||||||
|
{
|
||||||
|
drawContacts = !drawContacts;
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "Physics/System/SHPhysicsSystem.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
@ -43,6 +44,15 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
||||||
|
|
||||||
|
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
|
if (!physicsSystem)
|
||||||
|
{
|
||||||
|
SHLOGV_CRITICAL("Failed to get the physics system for building the scene!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph());
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* TESTING CODE */
|
/* TESTING CODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -252,7 +252,7 @@ namespace SHADE
|
||||||
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity");
|
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity");
|
||||||
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
//SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
||||||
}
|
}
|
||||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||||
{
|
{
|
||||||
|
@ -284,6 +284,7 @@ namespace SHADE
|
||||||
//Debug Info (Read-Only)
|
//Debug Info (Read-Only)
|
||||||
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
|
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
|
||||||
{
|
{
|
||||||
|
SHEditorWidgets::DragFloat("Mass", [component] { return component->GetMass(); }, [](float value){}, "Mass", 0.1f, 0.0f, std::numeric_limits<float>::infinity(), "%.3f", ImGuiSliderFlags_ReadOnly);
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||||
|
|
|
@ -80,6 +80,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
system = physicsSystem;
|
system = physicsSystem;
|
||||||
|
|
||||||
|
// Sync with transform if one already exists
|
||||||
|
if (auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(GetEID()); transformComponent)
|
||||||
|
{
|
||||||
|
position = transformComponent->GetWorldPosition();
|
||||||
|
orientation = transformComponent->GetWorldOrientation();
|
||||||
|
scale = transformComponent->GetWorldScale();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHColliderComponent::OnDestroy()
|
void SHColliderComponent::OnDestroy()
|
||||||
|
|
|
@ -322,25 +322,25 @@ namespace SHADE
|
||||||
// dirtyFlags |= 1U << FLAG_POS;
|
// dirtyFlags |= 1U << FLAG_POS;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetMass(float newMass) noexcept
|
//void SHRigidBodyComponent::SetMass(float newMass) noexcept
|
||||||
{
|
//{
|
||||||
static constexpr int FLAG_POS = 9;
|
// static constexpr int FLAG_POS = 9;
|
||||||
|
|
||||||
if (newMass < 0.0f)
|
// if (newMass < 0.0f)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
if (type != Type::DYNAMIC)
|
// if (type != Type::DYNAMIC)
|
||||||
{
|
// {
|
||||||
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
|
// SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
dirtyFlags |= 1U << FLAG_POS;
|
// dirtyFlags |= 1U << FLAG_POS;
|
||||||
mass = newMass;
|
// mass = newMass;
|
||||||
|
|
||||||
// Turn off automass
|
// // Turn off automass
|
||||||
flags &= ~(1U << FLAG_POS);
|
// flags &= ~(1U << FLAG_POS);
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||||
{
|
{
|
||||||
|
@ -411,6 +411,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
system = physicsSystem;
|
system = physicsSystem;
|
||||||
|
|
||||||
|
// Sync with transform if one already exists
|
||||||
|
if (auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(GetEID()); transformComponent)
|
||||||
|
{
|
||||||
|
position = transformComponent->GetWorldPosition();
|
||||||
|
orientation = transformComponent->GetWorldOrientation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
|
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
|
||||||
|
@ -489,7 +496,7 @@ RTTR_REGISTRATION
|
||||||
|
|
||||||
registration::class_<SHRigidBodyComponent>("RigidBody Component")
|
registration::class_<SHRigidBodyComponent>("RigidBody Component")
|
||||||
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
|
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
|
||||||
.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
|
//.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
|
||||||
.property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag )
|
.property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag )
|
||||||
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
|
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
|
||||||
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
|
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace SHADE
|
||||||
void SetInterpolate (bool allowInterpolation) noexcept;
|
void SetInterpolate (bool allowInterpolation) noexcept;
|
||||||
//void SetAutoMass (bool autoMass) noexcept;
|
//void SetAutoMass (bool autoMass) noexcept;
|
||||||
|
|
||||||
void SetMass (float newMass) noexcept;
|
//void SetMass (float newMass) noexcept;
|
||||||
void SetDrag (float newDrag) noexcept;
|
void SetDrag (float newDrag) noexcept;
|
||||||
void SetAngularDrag (float newAngularDrag) noexcept;
|
void SetAngularDrag (float newAngularDrag) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int SHPhysicsObject::AddCollisionShape(int index) const
|
int SHPhysicsObject::AddCollisionShape(int index)
|
||||||
{
|
{
|
||||||
// Get collider component
|
// Get collider component
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||||
|
@ -123,13 +123,19 @@ namespace SHADE
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rp3dBody->updateLocalCenterOfMassFromColliders();
|
if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC)
|
||||||
rp3dBody->updateLocalInertiaTensorFromColliders();
|
{
|
||||||
|
rp3dBody->updateMassPropertiesFromColliders();
|
||||||
|
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
rigidBodyComponent->mass = rp3dBody->getMass();
|
||||||
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsObject::RemoveCollisionShape(int index) const
|
void SHPhysicsObject::RemoveCollisionShape(int index)
|
||||||
{
|
{
|
||||||
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
|
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
|
||||||
if (NUM_COLLIDERS == 0)
|
if (NUM_COLLIDERS == 0)
|
||||||
|
@ -140,6 +146,15 @@ namespace SHADE
|
||||||
|
|
||||||
auto* collider = rp3dBody->getCollider(index);
|
auto* collider = rp3dBody->getCollider(index);
|
||||||
rp3dBody->removeCollider(collider);
|
rp3dBody->removeCollider(collider);
|
||||||
|
|
||||||
|
if (rp3dBody->getType() == rp3d::BodyType::DYNAMIC)
|
||||||
|
{
|
||||||
|
rp3dBody->updateMassPropertiesFromColliders();
|
||||||
|
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
rigidBodyComponent->mass = rp3dBody->getMass();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsObject::RemoveAllCollisionShapes() const noexcept
|
void SHPhysicsObject::RemoveAllCollisionShapes() const noexcept
|
||||||
|
@ -254,9 +269,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
case 9: // Mass
|
case 9: // Mass
|
||||||
{
|
{
|
||||||
rp3dBody->setMass(component.mass);
|
//rp3dBody->setMass(component.mass);
|
||||||
rp3dBody->updateLocalCenterOfMassFromColliders();
|
|
||||||
rp3dBody->updateLocalInertiaTensorFromColliders();
|
|
||||||
|
|
||||||
//if (component.GetAutoMass())
|
//if (component.GetAutoMass())
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -71,8 +71,8 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int AddCollisionShape (int index) const;
|
int AddCollisionShape (int index);
|
||||||
void RemoveCollisionShape (int index) const;
|
void RemoveCollisionShape (int index);
|
||||||
void RemoveAllCollisionShapes () const noexcept;
|
void RemoveAllCollisionShapes () const noexcept;
|
||||||
|
|
||||||
void SyncRigidBody (SHRigidBodyComponent& component) const noexcept;
|
void SyncRigidBody (SHRigidBodyComponent& component) const noexcept;
|
||||||
|
@ -98,12 +98,12 @@ namespace SHADE
|
||||||
|
|
||||||
// Box Shapes
|
// Box Shapes
|
||||||
|
|
||||||
void addBoxShape (SHCollisionShape& boxShape) const noexcept;
|
void addBoxShape (SHCollisionShape& boxShape) const noexcept;
|
||||||
void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept;
|
void syncBoxShape (int index, SHCollisionShape& boxShape) const noexcept;
|
||||||
|
|
||||||
// Sphere Shapes
|
// Sphere Shapes
|
||||||
|
|
||||||
void addSphereShape (SHCollisionShape& sphereShape) const noexcept;
|
void addSphereShape (SHCollisionShape& sphereShape) const noexcept;
|
||||||
void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept;
|
void syncSphereShape (int index, SHCollisionShape& sphereShape) const noexcept;
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -118,11 +119,22 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rp3d::DebugRenderer* rp3dRenderer = nullptr;
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
||||||
|
{
|
||||||
|
rp3dRenderer = &system->physicsSystem->worldState.world->getDebugRenderer();
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, false);
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
|
for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i)
|
||||||
{
|
{
|
||||||
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
|
const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0;
|
||||||
if (DRAW)
|
if (DRAW)
|
||||||
drawFunctions[i](debugDrawSystem);
|
drawFunctions[i](debugDrawSystem, rp3dRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically clear the container of raycasts despite debug drawing state
|
// Automatically clear the container of raycasts despite debug drawing state
|
||||||
|
@ -134,7 +146,7 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
|
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
|
||||||
for (const auto& COLLIDER : COLLIDER_SET)
|
for (const auto& COLLIDER : COLLIDER_SET)
|
||||||
|
@ -155,27 +167,53 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
||||||
|
{
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_POINT, true);
|
||||||
|
const int NUM_TRIS = static_cast<int>(rp3dRenderer->getNbTriangles());
|
||||||
|
if (NUM_TRIS == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& TRI_ARRAY = rp3dRenderer->getTrianglesArray();
|
||||||
|
for (int i = 0; i < NUM_TRIS; ++i)
|
||||||
|
debugRenderer->DrawTri(SHColour::RED, TRI_ARRAY[i].point1, TRI_ARRAY[i].point2, TRI_ARRAY[i].point3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
||||||
|
{
|
||||||
|
rp3dRenderer->setIsDebugItemDisplayed(rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL, true);
|
||||||
|
const int NUM_LINES = static_cast<int>(rp3dRenderer->getNbLines());
|
||||||
|
if (NUM_LINES == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& LINE_ARRAY = rp3dRenderer->getLinesArray();
|
||||||
|
for (int i = 0; i < NUM_LINES; ++i)
|
||||||
|
debugRenderer->DrawLine(SHColour::RED, LINE_ARRAY[i].point1, LINE_ARRAY[i].point2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer) noexcept
|
void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept
|
||||||
{
|
{
|
||||||
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
if (!physicsSystem)
|
if (!physicsSystem)
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
using DebugDrawFunction = void(*)(SHDebugDrawSystem*) noexcept;
|
using DebugDrawFunction = void(*)(SHDebugDrawSystem*, rp3d::DebugRenderer*) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
|
@ -118,12 +118,12 @@ namespace SHADE
|
||||||
|
|
||||||
// Generic Draw Functions
|
// Generic Draw Functions
|
||||||
|
|
||||||
static void drawColliders (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawColliders (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
static void drawContactPoints (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawContactPoints (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
static void drawContactNormals (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawContactNormals (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
static void drawRaycasts (SHDebugDrawSystem* debugRenderer) noexcept;
|
static void drawRaycasts (SHDebugDrawSystem* debugRenderer, rp3d::DebugRenderer* rp3dRenderer) noexcept;
|
||||||
|
|
||||||
// Shape Generation Functions
|
// Shape Generation Functions
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,13 @@ namespace SHADE
|
||||||
defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig");
|
defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig");
|
||||||
SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath);
|
SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath);
|
||||||
|
|
||||||
|
// Link Physics Object Manager with System & Raycaster
|
||||||
|
objectManager.SetFactory(factory);
|
||||||
|
raycaster.SetObjectManager(&objectManager);
|
||||||
|
|
||||||
|
// Link Collision Listener with System
|
||||||
|
collisionListener.BindToSystem(this);
|
||||||
|
|
||||||
// Subscribe to component events
|
// Subscribe to component events
|
||||||
const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::addPhysicsComponent) };
|
const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::addPhysicsComponent) };
|
||||||
const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ADD_COMPONENT_RECEIVER);
|
const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ADD_COMPONENT_RECEIVER);
|
||||||
|
@ -118,12 +125,7 @@ namespace SHADE
|
||||||
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR);
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// Link Physics Object Manager with System & Raycaster
|
|
||||||
objectManager.SetFactory(factory);
|
|
||||||
raycaster.SetObjectManager(&objectManager);
|
|
||||||
|
|
||||||
// Link Collision Listener with System
|
|
||||||
collisionListener.BindToSystem(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::Exit()
|
void SHPhysicsSystem::Exit()
|
||||||
|
@ -136,6 +138,55 @@ namespace SHADE
|
||||||
SHCollisionTagMatrix::Exit(defaultCollisionTagNameFilePath);
|
SHCollisionTagMatrix::Exit(defaultCollisionTagNameFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::BuildScene(SHSceneGraph& sceneGraph)
|
||||||
|
{
|
||||||
|
static const auto BUILD_NEW_SCENE_PHYSICS_OBJECT = [&](SHSceneNode* node)
|
||||||
|
{
|
||||||
|
const EntityID EID = node->GetEntityID();
|
||||||
|
|
||||||
|
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(EID))
|
||||||
|
objectManager.AddRigidBody(EID);
|
||||||
|
|
||||||
|
if (SHComponentManager::HasComponent<SHColliderComponent>(EID))
|
||||||
|
objectManager.AddCollider(EID);
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Destroy an existing world
|
||||||
|
if (worldState.world != nullptr)
|
||||||
|
{
|
||||||
|
objectManager.RemoveAllObjects();
|
||||||
|
objectManager.SetWorld(nullptr);
|
||||||
|
|
||||||
|
collisionListener.ClearContainers();
|
||||||
|
raycaster.ClearFrame();
|
||||||
|
|
||||||
|
worldState.DestroyWorld(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
worldState.CreateWorld(factory);
|
||||||
|
#ifdef _PUBLISH
|
||||||
|
worldState.world->setIsDebugRenderingEnabled(false);
|
||||||
|
#else
|
||||||
|
worldState.world->setIsDebugRenderingEnabled(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Link Collision Listener & Raycaster
|
||||||
|
collisionListener.BindToWorld(worldState.world);
|
||||||
|
raycaster.BindToWorld(worldState.world);
|
||||||
|
|
||||||
|
// Link with object manager & create all physics objects
|
||||||
|
objectManager.SetWorld(worldState.world);
|
||||||
|
|
||||||
|
// When building a scene, clear the object manager command queue and build scene objects again.
|
||||||
|
// This is done to avoid duplicate adds.
|
||||||
|
while (!objectManager.commandQueue.empty())
|
||||||
|
objectManager.commandQueue.pop();
|
||||||
|
|
||||||
|
sceneGraph.Traverse(BUILD_NEW_SCENE_PHYSICS_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::ForceUpdate()
|
void SHPhysicsSystem::ForceUpdate()
|
||||||
{
|
{
|
||||||
if (!worldState.world)
|
if (!worldState.world)
|
||||||
|
@ -228,10 +279,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
objectManager.AddCollisionShape(entityID, index);
|
objectManager.AddCollisionShape(entityID, index);
|
||||||
|
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
|
||||||
|
auto& collisionShape = colliderComponent->GetCollisionShape(index);
|
||||||
|
|
||||||
const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA
|
const SHPhysicsColliderAddedEvent COLLIDER_ADDED_EVENT_DATA
|
||||||
{
|
{
|
||||||
.entityID = entityID
|
.entityID = entityID
|
||||||
, .colliderType = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetCollisionShape(index).GetType()
|
, .colliderType = collisionShape.GetType()
|
||||||
, .colliderIndex = index
|
, .colliderIndex = index
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -367,6 +421,11 @@ namespace SHADE
|
||||||
return onPlayEvent->handle;
|
return onPlayEvent->handle;
|
||||||
|
|
||||||
worldState.CreateWorld(factory);
|
worldState.CreateWorld(factory);
|
||||||
|
#ifdef _PUBLISH
|
||||||
|
worldState.world->setIsDebugRenderingEnabled(false);
|
||||||
|
#else
|
||||||
|
worldState.world->setIsDebugRenderingEnabled(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Link Collision Listener & Raycaster
|
// Link Collision Listener & Raycaster
|
||||||
collisionListener.BindToWorld(worldState.world);
|
collisionListener.BindToWorld(worldState.world);
|
||||||
|
@ -375,8 +434,8 @@ namespace SHADE
|
||||||
// Link with object manager & create all physics objects
|
// Link with object manager & create all physics objects
|
||||||
objectManager.SetWorld(worldState.world);
|
objectManager.SetWorld(worldState.world);
|
||||||
|
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
// Build scene
|
||||||
SCENE_GRAPH.Traverse(BUILD_PHYSICS_OBJECT);
|
SHSceneManager::GetCurrentSceneGraph().Traverse(BUILD_PHYSICS_OBJECT);
|
||||||
|
|
||||||
return onPlayEvent->handle;
|
return onPlayEvent->handle;
|
||||||
}
|
}
|
||||||
|
@ -390,11 +449,11 @@ namespace SHADE
|
||||||
// Clear all collision info
|
// Clear all collision info
|
||||||
// Collision listener is automatically unbound when world is destroyed
|
// Collision listener is automatically unbound when world is destroyed
|
||||||
collisionListener.ClearContainers();
|
collisionListener.ClearContainers();
|
||||||
|
raycaster.ClearFrame();
|
||||||
|
|
||||||
// Destroy the world
|
// Destroy the world
|
||||||
worldState.DestroyWorld(factory);
|
worldState.DestroyWorld(factory);
|
||||||
|
|
||||||
return onStopEvent->handle;
|
return onStopEvent->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -27,7 +27,7 @@
|
||||||
#include "Physics/Interface/SHColliderComponent.h"
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
#include "Physics/PhysicsObject/SHPhysicsObjectManager.h"
|
#include "Physics/PhysicsObject/SHPhysicsObjectManager.h"
|
||||||
#include "Physics/SHPhysicsWorld.h"
|
#include "Physics/SHPhysicsWorld.h"
|
||||||
|
#include "Scene/SHSceneGraph.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -74,10 +74,12 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () override;
|
void Exit () override;
|
||||||
|
|
||||||
|
void BuildScene (SHSceneGraph& sceneGraph);
|
||||||
|
void ForceUpdate ();
|
||||||
|
|
||||||
void ForceUpdate ();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Casts a ray into the world.
|
* @brief Casts a ray into the world.
|
||||||
|
@ -280,11 +282,11 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept;
|
SHEventHandle addPhysicsComponent (SHEventPtr addComponentEvent) noexcept;
|
||||||
SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept;
|
SHEventHandle removePhysicsComponent (SHEventPtr removeComponentEvent) noexcept;
|
||||||
|
|
||||||
SHEventHandle onPlay (SHEventPtr onPlayEvent);
|
|
||||||
SHEventHandle onStop (SHEventPtr onStopEvent);
|
|
||||||
|
|
||||||
|
SHEventHandle onPlay (SHEventPtr onPlayEvent);
|
||||||
|
SHEventHandle onStop (SHEventPtr onStopEvent);
|
||||||
|
SHEventHandle buildScene (SHEventPtr onSceneChangeEvent);
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHSceneGraphEvents.h
|
* \file SHSceneEvents.h
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Interface for Scene Graph Events.
|
* \brief Interface for Scene Events.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -21,21 +21,21 @@ namespace SHADE
|
||||||
|
|
||||||
struct SHSceneGraphChangeParentEvent
|
struct SHSceneGraphChangeParentEvent
|
||||||
{
|
{
|
||||||
SHSceneNode* node;
|
SHSceneNode* node = nullptr;
|
||||||
SHSceneNode* oldParent;
|
SHSceneNode* oldParent = nullptr;
|
||||||
SHSceneNode* newParent;
|
SHSceneNode* newParent = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHSceneGraphAddChildEvent
|
struct SHSceneGraphAddChildEvent
|
||||||
{
|
{
|
||||||
SHSceneNode* parent;
|
SHSceneNode* parent = nullptr;
|
||||||
SHSceneNode* childAdded;
|
SHSceneNode* childAdded = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHSceneGraphRemoveChildEvent
|
struct SHSceneGraphRemoveChildEvent
|
||||||
{
|
{
|
||||||
SHSceneNode* parent;
|
SHSceneNode* parent = nullptr;
|
||||||
SHSceneNode* childRemoved;
|
SHSceneNode* childRemoved = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -16,7 +16,7 @@
|
||||||
#include "ECS_Base/Entity/SHEntity.h"
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "SHSceneNode.h"
|
#include "SHSceneNode.h"
|
||||||
#include "SHSceneGraphEvents.h"
|
#include "SHSceneEvents.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,7 +85,6 @@ namespace SHADE
|
||||||
currentScene->Load();
|
currentScene->Load();
|
||||||
currentScene->Init();
|
currentScene->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else // restarting scene
|
else // restarting scene
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Physics/System/SHPhysicsSystem.h"
|
#include "Physics/System/SHPhysicsSystem.h"
|
||||||
#include "Physics/SHPhysicsEvents.h"
|
#include "Physics/SHPhysicsEvents.h"
|
||||||
#include "Scene/SHSceneGraphEvents.h"
|
#include "Scene/SHSceneEvents.h"
|
||||||
|
|
||||||
#include "Assets/SHAssetMacros.h"
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ namespace YAML
|
||||||
static constexpr const char* Bounciness = "Bounciness";
|
static constexpr const char* Bounciness = "Bounciness";
|
||||||
static constexpr const char* Density = "Density";
|
static constexpr const char* Density = "Density";
|
||||||
static constexpr const char* PositionOffset = "Position Offset";
|
static constexpr const char* PositionOffset = "Position Offset";
|
||||||
|
static constexpr const char* RotationOffset = "Rotation Offset";
|
||||||
|
|
||||||
static Node encode(SHCollisionShape& rhs)
|
static Node encode(SHCollisionShape& rhs)
|
||||||
{
|
{
|
||||||
|
@ -148,6 +149,7 @@ namespace YAML
|
||||||
node[Bounciness] = rhs.GetBounciness();
|
node[Bounciness] = rhs.GetBounciness();
|
||||||
node[Density] = rhs.GetDensity();
|
node[Density] = rhs.GetDensity();
|
||||||
node[PositionOffset] = rhs.GetPositionOffset();
|
node[PositionOffset] = rhs.GetPositionOffset();
|
||||||
|
node[RotationOffset] = rhs.GetRotationOffset();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +190,8 @@ namespace YAML
|
||||||
rhs.SetDensity(node[Density].as<float>());
|
rhs.SetDensity(node[Density].as<float>());
|
||||||
if (node[PositionOffset].IsDefined())
|
if (node[PositionOffset].IsDefined())
|
||||||
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||||
|
if (node[RotationOffset].IsDefined())
|
||||||
|
rhs.SetRotationOffset(node[RotationOffset].as<SHVec3>());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
void RigidBody::Mass::set(float value)
|
void RigidBody::Mass::set(float value)
|
||||||
{
|
{
|
||||||
return GetNativeComponent()->SetMass(value);
|
/*return GetNativeComponent()->SetMass(value);*/
|
||||||
}
|
}
|
||||||
float RigidBody::Drag::get()
|
float RigidBody::Drag::get()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue