Merge branch 'main' into SP3-305-configurations
This commit is contained in:
commit
8b4ebc557c
|
@ -33,18 +33,18 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<SHComponentRemovedEvent> eventVec;
|
||||
|
||||
for (uint32_t i = 0; i < componentSet.Size(); ++i)
|
||||
{
|
||||
SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID));
|
||||
if (comp)
|
||||
{
|
||||
comp->OnDestroy();
|
||||
|
||||
SHComponentRemovedEvent eventData;
|
||||
eventData.eid = entityID;
|
||||
eventData.removedComponentType = i;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
|
||||
eventVec.push_back(eventData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,12 @@ namespace SHADE
|
|||
|
||||
componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID));
|
||||
|
||||
for (auto& eventData : eventVec)
|
||||
{
|
||||
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
|
||||
}
|
||||
|
||||
|
||||
//entityHandle.RemoveHandle(entityID);
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace SHADE
|
|||
{
|
||||
system.second->Init();
|
||||
#ifdef _DEBUG
|
||||
std::cout << system.first << " Init" << std::endl;
|
||||
SHLOG_INFO("Initialising System {}...", system.first)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,18 +195,22 @@ namespace SHADE
|
|||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
std::string moveLabel = "Moving EID: ";
|
||||
static std::vector<EntityID> draggingEntities = editor->selectedEntities;
|
||||
if (!isSelected)
|
||||
editor->selectedEntities.push_back(eid);
|
||||
for (int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
||||
{
|
||||
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
||||
if (i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
||||
draggingEntities.clear();
|
||||
draggingEntities.push_back(eid);
|
||||
}
|
||||
for (int i = 0; i < static_cast<int>(draggingEntities.size()); ++i)
|
||||
{
|
||||
moveLabel.append(std::to_string(draggingEntities[i]));
|
||||
if (i + 1 < static_cast<int>(draggingEntities.size()))
|
||||
{
|
||||
moveLabel.append(", ");
|
||||
}
|
||||
}
|
||||
ImGui::Text(moveLabel.c_str());
|
||||
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &editor->selectedEntities);
|
||||
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &draggingEntities);
|
||||
SHDragDrop::EndSource();
|
||||
}
|
||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||
|
|
|
@ -274,8 +274,27 @@ namespace SHADE
|
|||
|
||||
}
|
||||
{
|
||||
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
|
||||
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
|
||||
[&collider]
|
||||
{
|
||||
auto offset = collider->GetRotationOffset();
|
||||
offset.x = SHMath::RadiansToDegrees(offset.x);
|
||||
offset.y = SHMath::RadiansToDegrees(offset.y);
|
||||
offset.z = SHMath::RadiansToDegrees(offset.z);
|
||||
return offset;
|
||||
},
|
||||
[&collider](SHVec3 const& vec)
|
||||
{
|
||||
const SHVec3 vecInRad
|
||||
{
|
||||
SHMath::DegreesToRadians(vec.x)
|
||||
, SHMath::DegreesToRadians(vec.y)
|
||||
, SHMath::DegreesToRadians(vec.z)
|
||||
};
|
||||
collider->SetRotationOffset(vecInRad);
|
||||
});
|
||||
SHEditorWidgets::EndPanel();
|
||||
}
|
||||
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||
|
@ -358,6 +377,7 @@ namespace SHADE
|
|||
[component](AssetID const& id)
|
||||
{
|
||||
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}, SHDragDrop::DRAG_RESOURCE);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -182,20 +182,39 @@ namespace SHADE
|
|||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||
{
|
||||
if(editor->SaveScene())
|
||||
if(editor->SaveScene()) //Set play state and invoke event only if we managed to save successfully
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PLAY;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::PAUSE;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
||||
if(ImGui::SmallButton(ICON_MD_STOP))
|
||||
{
|
||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||
{
|
||||
.previousState = editor->editorState
|
||||
};
|
||||
editor->editorState = SHEditor::State::STOP;
|
||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
|
|
@ -20,4 +20,10 @@ namespace SHADE
|
|||
float menuBarHeight = 20.0f;
|
||||
std::vector<std::filesystem::path> layoutPaths;
|
||||
};//class SHEditorMenuBar
|
||||
|
||||
struct SHEditorStateChangeEvent
|
||||
{
|
||||
SHEditor::State previousState;
|
||||
};
|
||||
|
||||
}//namespace SHADE
|
|
@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// External Dependencies
|
||||
#include <imgui.h>
|
||||
#include "SHEditorWidgets.hpp"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -287,6 +288,35 @@ namespace SHADE
|
|||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
||||
std::ostringstream oss;
|
||||
if (entity)
|
||||
{
|
||||
oss << value << ": " << entity->name;
|
||||
}
|
||||
std::string entityName = oss.str();
|
||||
bool changed = ImGui::InputText("##", &entityName, ImGuiInputTextFlags_ReadOnly);
|
||||
if (SHDragDrop::BeginTarget())
|
||||
{
|
||||
if (const std::vector<EntityID>* payload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID))
|
||||
{
|
||||
if (!payload->empty())
|
||||
{
|
||||
value = payload->at(0);
|
||||
changed = true;
|
||||
}
|
||||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
||||
{
|
||||
// Clamp input value
|
||||
|
|
|
@ -308,6 +308,14 @@ namespace SHADE
|
|||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a drag field widget for int input.
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input.
|
||||
/// </summary>
|
||||
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
||||
|
|
|
@ -13,4 +13,7 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
|||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
||||
|
||||
|
|
|
@ -74,11 +74,12 @@ namespace SHADE
|
|||
|
||||
void SHBatch::Remove(const SHRenderable* renderable)
|
||||
{
|
||||
// Check if we have a SubBatch with the same mesh yet
|
||||
// Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh)
|
||||
Handle<SHMesh> prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh();
|
||||
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
||||
{
|
||||
return batch.Mesh == renderable->GetMesh();
|
||||
});
|
||||
{
|
||||
return batch.Mesh == prevSubBatchMesh;
|
||||
});
|
||||
|
||||
// Attempt to remove if it exists
|
||||
if (subBatch == subBatches.end())
|
||||
|
@ -88,9 +89,7 @@ namespace SHADE
|
|||
|
||||
// Check if other renderables in subBatches contain the same material instance
|
||||
bool matUnused = true;
|
||||
|
||||
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
|
||||
|
||||
for (const auto& sb : subBatches)
|
||||
{
|
||||
// Check material usage
|
||||
|
|
|
@ -37,9 +37,9 @@ namespace SHADE
|
|||
|
||||
// Check if we have a batch with the same pipeline first
|
||||
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
|
||||
{
|
||||
return batch.GetPipeline() == PIPELINE;
|
||||
});
|
||||
{
|
||||
return batch.GetPipeline() == PIPELINE;
|
||||
});
|
||||
|
||||
|
||||
// Create one if not found
|
||||
|
|
|
@ -106,10 +106,7 @@ namespace SHADE
|
|||
descPool = device->CreateDescriptorPools();
|
||||
|
||||
// Create generic command buffer
|
||||
//transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
|
||||
// Load Built In Shaders
|
||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||
|
@ -621,10 +618,14 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsSystem::BuildMeshBuffers()
|
||||
{
|
||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
device->WaitIdle();
|
||||
transferCmdBuffer->BeginRecording();
|
||||
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
||||
transferCmdBuffer->EndRecording();
|
||||
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
||||
device->WaitIdle();
|
||||
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -649,10 +650,14 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsSystem::BuildTextures()
|
||||
{
|
||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
device->WaitIdle();
|
||||
texLibrary.BuildTextures
|
||||
(
|
||||
device, graphicsTexCmdBuffer, graphicsQueue, descPool
|
||||
);
|
||||
device->WaitIdle();
|
||||
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
||||
}
|
||||
|
||||
#pragma endregion ADD_REMOVE
|
||||
|
@ -692,6 +697,7 @@ namespace SHADE
|
|||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -709,8 +715,13 @@ namespace SHADE
|
|||
if (!renderable.HasChanged())
|
||||
continue;
|
||||
|
||||
// Remove from old material's SuperBatch
|
||||
Handle<SHMaterialInstance> prevMaterial = renderable.GetPrevMaterial();
|
||||
if (!renderable.GetMesh())
|
||||
{
|
||||
SHLOG_CRITICAL("NULL Mesh provided!");
|
||||
}
|
||||
|
||||
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
|
||||
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
|
||||
if (prevMaterial)
|
||||
{
|
||||
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||
|
|
|
@ -185,7 +185,7 @@ RTTR_REGISTRATION
|
|||
using namespace rttr;
|
||||
|
||||
registration::class_<SHTransformComponent>("Transform Component")
|
||||
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) ) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation)) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
// Project Headers
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Physics/SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -28,21 +29,9 @@ namespace SHADE
|
|||
|
||||
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
||||
: type { Type::DYNAMIC }
|
||||
, flags { 0 }
|
||||
, dirtyFlags { 0 }
|
||||
, interpolate { true }
|
||||
, rp3dBody { nullptr }
|
||||
, mass { 1.0f }
|
||||
, drag { 0.01f }
|
||||
, angularDrag { 0.01f }
|
||||
{
|
||||
// Set default flags: Gravity & Sleeping enabled
|
||||
flags |= 1U << 0;
|
||||
flags |= 1U << 1;
|
||||
|
||||
// Set all dirty flags to true
|
||||
dirtyFlags = 1023;
|
||||
}
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
|
@ -50,12 +39,24 @@ namespace SHADE
|
|||
|
||||
bool SHRigidBodyComponent::IsGravityEnabled() const noexcept
|
||||
{
|
||||
return flags & (1U << 0);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
return rp3dBody->isGravityEnabled();
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept
|
||||
{
|
||||
return flags & (1U << 1);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
return rp3dBody->isAllowedToSleep();
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
||||
|
@ -70,67 +71,151 @@ namespace SHADE
|
|||
|
||||
float SHRigidBodyComponent::GetMass() const noexcept
|
||||
{
|
||||
return mass;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return rp3dBody->getMass();
|
||||
}
|
||||
|
||||
float SHRigidBodyComponent::GetDrag() const noexcept
|
||||
{
|
||||
return drag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return rp3dBody->getLinearDamping();
|
||||
}
|
||||
|
||||
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
||||
{
|
||||
return angularDrag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return rp3dBody->getAngularDamping();
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
||||
{
|
||||
return flags & (1U << 2);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.x, 0.0f);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionY() const noexcept
|
||||
{
|
||||
return flags & (1U << 3);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.y, 0.0f);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept
|
||||
{
|
||||
return flags & (1U << 4);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& LINEAR_CONSTRAINTS = rp3dBody->getLinearLockAxisFactor();
|
||||
return SHMath::CompareFloat(LINEAR_CONSTRAINTS.z, 0.0f);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept
|
||||
{
|
||||
return flags & (1U << 5);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.x, 0.0f);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept
|
||||
{
|
||||
return flags & (1U << 6);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.y, 0.0f);
|
||||
}
|
||||
|
||||
bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept
|
||||
{
|
||||
return flags & (1U << 7);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
|
||||
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f);
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetForce() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
|
||||
{
|
||||
return force;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return false;
|
||||
}
|
||||
|
||||
return rp3dBody->getForce();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetTorque() const noexcept
|
||||
{
|
||||
return torque;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getTorque();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept
|
||||
{
|
||||
return linearVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getLinearVelocity();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||
SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept
|
||||
{
|
||||
return angularVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return SHVec3::Zero;
|
||||
}
|
||||
|
||||
return rp3dBody->getAngularVelocity();
|
||||
}
|
||||
|
||||
const SHVec3& SHRigidBodyComponent::GetPosition() const noexcept
|
||||
|
@ -157,8 +242,15 @@ namespace SHADE
|
|||
if (type == newType)
|
||||
return;
|
||||
|
||||
dirtyFlags |= 1U << 4;
|
||||
type = newType;
|
||||
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setType(static_cast<rp3d::BodyType>(type));
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
|
||||
|
@ -171,8 +263,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << FLAG_POS;
|
||||
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->enableGravity(enableGravity);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
|
||||
|
@ -185,92 +282,127 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 1;
|
||||
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setIsAllowedToSleep(isAllowedToSleep);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 2;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||
linearConstraints.x = freezePositionX ? 0.0f : 1.0f;
|
||||
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 3;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||
linearConstraints.y = freezePositionY ? 0.0f : 1.0f;
|
||||
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 4;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 2;
|
||||
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto linearConstraints = rp3dBody->getLinearLockAxisFactor();
|
||||
linearConstraints.z = freezePositionZ ? 0.0f : 1.0f;
|
||||
rp3dBody->setLinearLockAxisFactor(linearConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 5;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||
angularConstraints.x = freezeRotationX ? 0.0f : 1.0f;
|
||||
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 6;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||
angularConstraints.y = freezeRotationY ? 0.0f : 1.0f;
|
||||
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
|
||||
{
|
||||
static constexpr int FLAG_POS = 7;
|
||||
|
||||
if (type == Type::STATIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 3;
|
||||
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
auto angularConstraints = rp3dBody->getAngularLockAxisFactor();
|
||||
angularConstraints.z = freezeRotationZ ? 0.0f : 1.0f;
|
||||
rp3dBody->setAngularLockAxisFactor(angularConstraints);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
||||
|
@ -283,11 +415,16 @@ namespace SHADE
|
|||
if (type != Type::DYNAMIC)
|
||||
{
|
||||
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 5;
|
||||
mass = newMass;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setMass(newMass);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||
|
@ -298,8 +435,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 6;
|
||||
drag = newDrag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearDamping(newDrag);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
|
||||
|
@ -310,8 +452,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 7;
|
||||
angularDrag = newAngularDrag;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearDamping(newAngularDrag);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
|
||||
|
@ -322,8 +469,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 8;
|
||||
linearVelocity = newLinearVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setLinearVelocity(newLinearVelocity);
|
||||
}
|
||||
|
||||
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
|
||||
|
@ -334,8 +486,13 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
dirtyFlags |= 1U << 9;
|
||||
angularVelocity = newAngularVelocity;
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
rp3dBody->setAngularVelocity(newAngularVelocity);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -346,7 +503,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -357,7 +514,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,7 +525,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -379,7 +536,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -390,7 +547,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -401,7 +558,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -412,7 +569,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -423,7 +580,7 @@ namespace SHADE
|
|||
{
|
||||
if (rp3dBody == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
|
||||
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,10 +94,10 @@ namespace SHADE
|
|||
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
||||
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetForce () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetTorque () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetLinearVelocity () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetAngularVelocity () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetForce () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetTorque () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetAngularVelocity () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||
|
@ -149,28 +149,13 @@ namespace SHADE
|
|||
static constexpr size_t NUM_FLAGS = 8;
|
||||
static constexpr size_t NUM_DIRTY_FLAGS = 16;
|
||||
|
||||
Type type;
|
||||
|
||||
// rX rY rZ pX pY pZ slp g
|
||||
uint8_t flags;
|
||||
// 0 0 0 0 0 0 aV lV aD d m t ag lc slp g
|
||||
uint16_t dirtyFlags;
|
||||
bool interpolate;
|
||||
Type type;
|
||||
bool interpolate;
|
||||
|
||||
reactphysics3d::RigidBody* rp3dBody;
|
||||
|
||||
float mass;
|
||||
float drag;
|
||||
float angularDrag;
|
||||
|
||||
SHVec3 force;
|
||||
SHVec3 linearVelocity;
|
||||
|
||||
SHVec3 torque;
|
||||
SHVec3 angularVelocity;
|
||||
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
SHVec3 position;
|
||||
SHQuaternion orientation;
|
||||
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "Math/Geometry/SHBoundingSphere.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Reflection/SHReflectionMetadata.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -158,6 +159,11 @@ namespace SHADE
|
|||
return positionOffset;
|
||||
}
|
||||
|
||||
const SHVec3& SHCollider::GetRotationOffset() const noexcept
|
||||
{
|
||||
return rotationOffset;
|
||||
}
|
||||
|
||||
SHShape* SHCollider::GetShape() noexcept
|
||||
{
|
||||
dirty = true;
|
||||
|
@ -275,6 +281,12 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
rotationOffset = rotOffset;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -316,5 +328,6 @@ RTTR_REGISTRATION
|
|||
);
|
||||
|
||||
registration::class_<SHCollider>("Collider")
|
||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
|
||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
||||
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||
}
|
|
@ -80,6 +80,7 @@ namespace SHADE
|
|||
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetRotationOffset () const noexcept;
|
||||
|
||||
[[nodiscard]] SHShape* GetShape () noexcept;
|
||||
|
||||
|
@ -96,7 +97,8 @@ namespace SHADE
|
|||
void SetDensity (float density) noexcept;
|
||||
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
|
||||
|
||||
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||
void SetRotationOffset (const SHVec3& rotOffset) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -110,6 +112,7 @@ namespace SHADE
|
|||
SHShape* shape;
|
||||
SHPhysicsMaterial material;
|
||||
SHVec3 positionOffset;
|
||||
SHVec3 rotationOffset;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace SHADE
|
|||
|
||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
||||
{
|
||||
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||
|
||||
switch (collider->GetType())
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
|
@ -137,7 +139,7 @@ namespace SHADE
|
|||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
||||
|
||||
rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
||||
rp3dBody->addCollider(newBox, OFFSETS);
|
||||
break;
|
||||
}
|
||||
case SHCollider::Type::SPHERE:
|
||||
|
@ -145,7 +147,7 @@ namespace SHADE
|
|||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
||||
|
||||
rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
||||
rp3dBody->addCollider(newSphere, OFFSETS);
|
||||
break;
|
||||
}
|
||||
// TODO(Diren): Add more collider shapes
|
||||
|
@ -168,100 +170,6 @@ namespace SHADE
|
|||
rp3dBody->removeCollider(collider);
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept
|
||||
{
|
||||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
||||
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||
if (rb->dirtyFlags != 0)
|
||||
{
|
||||
const uint16_t RB_FLAGS = rb->dirtyFlags;
|
||||
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
|
||||
{
|
||||
// Check if current dirty flag has been set to true
|
||||
if (RB_FLAGS & 1U << i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: // Gravity
|
||||
{
|
||||
rigidBody->enableGravity(rb->IsGravityEnabled());
|
||||
break;
|
||||
}
|
||||
case 1: // Sleeping
|
||||
{
|
||||
rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep());
|
||||
break;
|
||||
}
|
||||
case 2: // Linear Constraints
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rb->flags & 1U << 2 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 3 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 4 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
|
||||
rigidBody->setLinearLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
}
|
||||
case 3: // Angular Constraints
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rb->flags & 1U << 5 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 6 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 7 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
rigidBody->setAngularLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
}
|
||||
case 4: // Type
|
||||
{
|
||||
rigidBody->setType(static_cast<rp3d::BodyType>(rb->GetType()));
|
||||
break;
|
||||
}
|
||||
case 5: // Mass
|
||||
{
|
||||
rigidBody->setMass(rb->GetMass());
|
||||
break;
|
||||
}
|
||||
case 6: // Drag
|
||||
{
|
||||
rigidBody->setLinearDamping(rb->GetDrag());
|
||||
break;
|
||||
}
|
||||
case 7: // Angular Drag
|
||||
{
|
||||
rigidBody->setAngularDamping(rb->GetAngularDrag());
|
||||
break;
|
||||
}
|
||||
case 8: // Linear Velocity
|
||||
{
|
||||
rigidBody->setLinearVelocity(rb->GetLinearVelocity());
|
||||
break;
|
||||
}
|
||||
case 9: // Angular Velocity
|
||||
{
|
||||
rigidBody->setAngularVelocity(rb->GetAngularVelocity());
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb->dirtyFlags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||
{
|
||||
int index = 0;
|
||||
|
@ -276,7 +184,7 @@ namespace SHADE
|
|||
rp3dCollider->setIsTrigger(collider.IsTrigger());
|
||||
|
||||
// Update offsets
|
||||
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
|
||||
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), collider.GetRotationOffset()));
|
||||
|
||||
switch (collider.GetType())
|
||||
{
|
||||
|
|
|
@ -72,7 +72,6 @@ namespace SHADE
|
|||
int AddCollider (SHCollider* collider);
|
||||
void RemoveCollider (int index);
|
||||
|
||||
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
|
||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||
|
||||
private:
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
|
@ -212,6 +211,12 @@ namespace SHADE
|
|||
const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::RemovePhysicsComponent) };
|
||||
const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(REMOVE_COMPONENT_RECEIVER);
|
||||
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR);
|
||||
|
||||
#ifdef SHEDITOR
|
||||
const std::shared_ptr EDITOR_STOP_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::ResetWorld) };
|
||||
const ReceiverPtr EDITOR_STOP_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(EDITOR_STOP_RECEIVER);
|
||||
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, EDITOR_STOP_RECEIVER_PTR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::Exit()
|
||||
|
@ -289,24 +294,12 @@ namespace SHADE
|
|||
|
||||
if (rigidBodyComponent)
|
||||
{
|
||||
// Clear all forces and velocities if editor is stopped
|
||||
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
||||
{
|
||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||
rp3dRigidBody->resetForce();
|
||||
rp3dRigidBody->resetTorque();
|
||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||
}
|
||||
|
||||
// Sync active states
|
||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncRigidBody(rigidBodyComponent);
|
||||
}
|
||||
|
||||
// Sync colliders
|
||||
|
@ -326,11 +319,11 @@ namespace SHADE
|
|||
|
||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||
{
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (!scriptSys)
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptingSystem == nullptr)
|
||||
{
|
||||
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||
SHLOGV_WARNING("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
||||
|
@ -339,10 +332,9 @@ namespace SHADE
|
|||
int count = 0;
|
||||
while (accumulatedTime > fixedTimeStep)
|
||||
{
|
||||
if (scriptSys)
|
||||
{
|
||||
scriptSys->ExecuteFixedUpdates();
|
||||
}
|
||||
if (scriptingSystem != nullptr)
|
||||
scriptingSystem->ExecuteFixedUpdates();
|
||||
|
||||
physicsSystem->world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
||||
|
||||
accumulatedTime -= fixedTimeStep;
|
||||
|
@ -358,6 +350,11 @@ namespace SHADE
|
|||
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
|
||||
{
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptingSystem == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
// Interpolate transforms for rendering
|
||||
if (physicsSystem->worldUpdated)
|
||||
|
@ -365,15 +362,8 @@ namespace SHADE
|
|||
physicsSystem->SyncTransforms();
|
||||
|
||||
// Collision & Trigger messages
|
||||
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptSys)
|
||||
{
|
||||
scriptSys->ExecuteCollisionFunctions();
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||
}
|
||||
if (scriptingSystem != nullptr)
|
||||
scriptingSystem->ExecuteCollisionFunctions();
|
||||
|
||||
physicsSystem->ClearInvalidCollisions();
|
||||
}
|
||||
|
@ -632,19 +622,17 @@ namespace SHADE
|
|||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||
|
||||
SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!")
|
||||
|
||||
if (REMOVED_ID == RIGID_BODY_ID)
|
||||
// Wake up all physics objects
|
||||
for (auto& [entityID, object] : map)
|
||||
{
|
||||
// Wake up all physics objects
|
||||
for (auto& [entityID, object] : map)
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
||||
}
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
||||
}
|
||||
|
||||
if (REMOVED_ID == RIGID_BODY_ID && physicsObject != nullptr)
|
||||
{
|
||||
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
|
||||
if (colliderComponent != nullptr)
|
||||
{
|
||||
|
@ -659,7 +647,7 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
if (REMOVED_ID == COLLIDER_ID)
|
||||
if (REMOVED_ID == COLLIDER_ID && physicsObject != nullptr)
|
||||
{
|
||||
// Remove all colliders
|
||||
const int NUM_COLLIDERS = static_cast<int>(physicsObject->rp3dBody->getNbColliders());
|
||||
|
@ -675,11 +663,30 @@ namespace SHADE
|
|||
physicsObject->rp3dBody = nullptr;
|
||||
}
|
||||
|
||||
if (physicsObject->rp3dBody == nullptr)
|
||||
DestroyPhysicsObject(ENTITY_ID);
|
||||
if (physicsObject != nullptr && physicsObject->rp3dBody == nullptr)
|
||||
DestroyPhysicsObject(ENTITY_ID);
|
||||
}
|
||||
|
||||
return EVENT_DATA->handle;
|
||||
}
|
||||
|
||||
SHEventHandle SHPhysicsSystem::ResetWorld(SHEventPtr editorStopEvent)
|
||||
{
|
||||
// TODO(Diren): Rebuild world based on how scene reloading is done
|
||||
|
||||
for (auto& [entityID, physicsObject] : map)
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
{
|
||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||
rp3dRigidBody->resetForce();
|
||||
rp3dRigidBody->resetTorque();
|
||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||
}
|
||||
}
|
||||
|
||||
return editorStopEvent->handle;
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -28,11 +28,6 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Concepts */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
@ -194,6 +189,7 @@ namespace SHADE
|
|||
|
||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
||||
|
||||
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace SHADE
|
|||
|
||||
SHCollisionEvent cInfo;
|
||||
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
// Match body and collider for collision event
|
||||
const rp3d::Entity body1 = cp.getBody1()->getEntity();
|
||||
const rp3d::Entity body2 = cp.getBody2()->getEntity();
|
||||
|
@ -76,9 +79,6 @@ namespace SHADE
|
|||
return cInfo;
|
||||
}
|
||||
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
return cInfo;
|
||||
}
|
||||
} // namespace SHADE
|
|
@ -21,9 +21,11 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
SHResourceHub SHResourceManager::resourceHub;
|
||||
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
||||
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||
std::unordered_map<std::type_index, SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
||||
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
||||
bool SHResourceManager::textureChanged = false;
|
||||
bool SHResourceManager::meshChanged = false;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Function Definitions */
|
||||
|
@ -63,8 +65,17 @@ namespace SHADE
|
|||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (gfxSystem == nullptr)
|
||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||
gfxSystem->BuildMeshBuffers();
|
||||
gfxSystem->BuildTextures();
|
||||
|
||||
if (meshChanged)
|
||||
{
|
||||
gfxSystem->BuildMeshBuffers();
|
||||
meshChanged = false;
|
||||
}
|
||||
if (textureChanged)
|
||||
{
|
||||
gfxSystem->BuildTextures();
|
||||
textureChanged = false;
|
||||
}
|
||||
|
||||
// Free CPU Resources
|
||||
for (auto assetId : loadedAssetData)
|
||||
|
|
|
@ -28,33 +28,15 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Template structs that maps a resource to their loaded asset representation type.
|
||||
/// </summary>
|
||||
template<typename T = void>
|
||||
struct SHResourceLoader
|
||||
{
|
||||
using AssetType = void;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SHResourceLoader<SHMesh>
|
||||
{
|
||||
using AssetType = SHMeshAsset;
|
||||
};
|
||||
template<>
|
||||
struct SHResourceLoader<SHTexture>
|
||||
{
|
||||
using AssetType = SHTextureAsset;
|
||||
};
|
||||
template<>
|
||||
struct SHResourceLoader<SHVkShaderModule>
|
||||
{
|
||||
using AssetType = SHShaderAsset;
|
||||
};
|
||||
template<>
|
||||
struct SHResourceLoader<SHMaterial>
|
||||
{
|
||||
using AssetType = SHMaterialAsset;
|
||||
};
|
||||
|
||||
struct SHResourceLoader { using AssetType = void; };
|
||||
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; };
|
||||
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
|
||||
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
|
||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialAsset; };
|
||||
|
||||
/// <summary>
|
||||
/// Static class responsible for loading and caching runtime resources from their
|
||||
|
@ -97,7 +79,7 @@ namespace SHADE
|
|||
/// <param name="assetId">Handle to the resource to unload.</param>
|
||||
static void Unload(AssetID assetId);
|
||||
/// <summary>
|
||||
/// Needs to be called to finalise all changes to loads.
|
||||
/// Needs to be called to finalise all changes to loads, unless at runtime.
|
||||
/// </summary>
|
||||
static void FinaliseChanges();
|
||||
|
||||
|
@ -147,6 +129,9 @@ namespace SHADE
|
|||
static std::unordered_map<std::type_index, std::function<void(AssetID)>> typedFreeFuncMap;
|
||||
// Pointers to temp CPU resources
|
||||
static std::vector<AssetID> loadedAssetData;
|
||||
// Dirty Flags
|
||||
static bool meshChanged;
|
||||
static bool textureChanged;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
auto handle = load<ResourceType>(assetId, *assetData);
|
||||
Handle genericHandle = Handle();
|
||||
Handle genericHandle = Handle(handle);
|
||||
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||
return handle;
|
||||
|
@ -139,6 +139,7 @@ namespace SHADE
|
|||
if constexpr (std::is_same_v<ResourceType, SHMesh>)
|
||||
{
|
||||
loadedAssetData.emplace_back(assetId);
|
||||
meshChanged = true;
|
||||
|
||||
return gfxSystem->AddMesh
|
||||
(
|
||||
|
@ -155,6 +156,7 @@ namespace SHADE
|
|||
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
|
||||
{
|
||||
loadedAssetData.emplace_back(assetId);
|
||||
textureChanged = true;
|
||||
|
||||
return gfxSystem->AddTexture
|
||||
(
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
#include "Camera.hxx"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Camera/SHCameraSystem.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
Camera::Camera(Entity entity)
|
||||
:Component(entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
float Camera::Pitch::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetPitch());
|
||||
}
|
||||
|
||||
void Camera::Pitch::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetPitch(val);
|
||||
}
|
||||
float Camera::Yaw::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetYaw());
|
||||
}
|
||||
|
||||
void Camera::Yaw::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetYaw(val);
|
||||
}
|
||||
float Camera::Roll::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetRoll());
|
||||
}
|
||||
|
||||
void Camera::Roll::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetRoll(val);
|
||||
}
|
||||
float Camera::Width::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetWidth());
|
||||
}
|
||||
|
||||
void Camera::Width::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetWidth(val);
|
||||
}
|
||||
float Camera::Height::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetHeight());
|
||||
}
|
||||
|
||||
void Camera::Height::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetHeight(val);
|
||||
}
|
||||
float Camera::Near::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetNear());
|
||||
}
|
||||
|
||||
void Camera::Near::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetNear(val);
|
||||
}
|
||||
float Camera::Far::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetFar());
|
||||
}
|
||||
|
||||
void Camera::Far::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetFar(val);
|
||||
}
|
||||
float Camera::FOV::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetFOV());
|
||||
}
|
||||
|
||||
void Camera::FOV::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetFOV(val);
|
||||
}
|
||||
|
||||
Vector3 Camera::Position::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetPosition());
|
||||
}
|
||||
|
||||
void Camera::Position::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetPosition(Convert::ToNative(val));
|
||||
}
|
||||
|
||||
void Camera::SetMainCamera(size_t directorIndex)
|
||||
{
|
||||
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
system->SetMainCamera(GetNativeComponent()->GetEID(), directorIndex);
|
||||
}
|
||||
|
||||
void Camera::SetMainCamera()
|
||||
{
|
||||
SetMainCamera(0);
|
||||
}
|
||||
|
||||
void Camera::LookAt(Vector3 targetPosition)
|
||||
{
|
||||
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
system->CameraLookAt(*GetNativeComponent(), Convert::ToNative(targetPosition));
|
||||
}
|
||||
|
||||
Vector3 Camera::GetForward()
|
||||
{
|
||||
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
SHVec3 forward, up, right;
|
||||
system->GetCameraAxis(*GetNativeComponent(), forward, right, up);
|
||||
return Convert::ToCLI(forward);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Components/Component.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
#include "Math/Quaternion.hxx"
|
||||
// External Dependencies
|
||||
#include "Camera/SHCameraComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
public ref class Camera : public Component<SHCameraComponent>
|
||||
{
|
||||
internal:
|
||||
Camera(Entity entity);
|
||||
|
||||
public:
|
||||
property float Pitch
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Yaw
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Roll
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Width
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Height
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Near
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Far
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float FOV
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property Vector3 Position
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
|
||||
|
||||
void SetMainCamera(size_t directorIndex);
|
||||
void SetMainCamera();
|
||||
void LookAt(Vector3 targetPosition);
|
||||
Vector3 GetForward();
|
||||
};
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include "SHpch.h"
|
||||
#include "CameraArm.hxx"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
CameraArm::CameraArm(Entity entity)
|
||||
:Component(entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float CameraArm::Pitch::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetPitch());
|
||||
}
|
||||
|
||||
void CameraArm::Pitch::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetPitch(val);
|
||||
}
|
||||
float CameraArm::Yaw::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetYaw());
|
||||
}
|
||||
|
||||
void CameraArm::Yaw::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetYaw(val);
|
||||
}
|
||||
|
||||
float CameraArm::ArmLength::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetArmLength());
|
||||
}
|
||||
|
||||
void CameraArm::ArmLength::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetArmLength(val);
|
||||
}
|
||||
|
||||
bool CameraArm::LookAtCameraOrigin::get()
|
||||
{
|
||||
return GetNativeComponent()->lookAtCameraOrigin;
|
||||
}
|
||||
|
||||
void CameraArm::LookAtCameraOrigin::set(bool val)
|
||||
{
|
||||
GetNativeComponent()->lookAtCameraOrigin = val;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Components/Component.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
|
||||
// External Dependencies
|
||||
#include "Camera/SHCameraArmComponent.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
public ref class CameraArm : public Component<SHCameraArmComponent>
|
||||
{
|
||||
internal:
|
||||
CameraArm(Entity entity);
|
||||
public:
|
||||
property float Pitch
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Yaw
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float ArmLength
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property bool LookAtCameraOrigin
|
||||
{
|
||||
bool get();
|
||||
void set(bool val);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -87,15 +87,6 @@ namespace SHADE
|
|||
{
|
||||
GetNativeComponent()->SetWorldScale(Convert::ToNative(val));
|
||||
}
|
||||
Transform^ Transform::Parent::get()
|
||||
{
|
||||
auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
const auto PARENT = node->GetParent();
|
||||
return PARENT ? gcnew Transform(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
|
@ -103,21 +94,4 @@ namespace SHADE
|
|||
Transform::Transform(Entity entity)
|
||||
: Component(entity)
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Transform::SetParent(Transform^ parent, bool worldPositionStays)
|
||||
{
|
||||
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
auto node = sceneGraph.GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
if (parent)
|
||||
node->SetParent(sceneGraph.GetNode(parent->owner.GetEntity()));
|
||||
else
|
||||
sceneGraph.SetParent(parent->owner.GetEntity(), nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,30 +107,6 @@ namespace SHADE
|
|||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Parent Transform that affects this Transform.
|
||||
/// </summary>
|
||||
property Transform^ Parent
|
||||
{
|
||||
Transform^ get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the parent of this Transform component.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// Entity that contains the Transform component that this Transform will be
|
||||
/// parented to. If null, unparenting will occur.
|
||||
/// </param>
|
||||
/// <param name="worldPositionStays">
|
||||
/// If true, the transform values of this Transform component will retain their
|
||||
/// pre-parent-change global transforms. The local transform values will be
|
||||
/// modified to ensure that the global transforms do not change.
|
||||
/// </param>
|
||||
void SetParent(Transform^ parent, bool worldPositionStays);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ namespace SHADE
|
|||
|
||||
int val = safe_cast<int>(field->GetValue(object));
|
||||
int oldVal = val;
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames, &isHovered))
|
||||
{
|
||||
field->SetValue(object, val);
|
||||
registerUndoAction(object, field, val, oldVal);
|
||||
|
@ -280,12 +280,23 @@ namespace SHADE
|
|||
// Actual Field
|
||||
std::string val = Convert::ToNative(stringVal);
|
||||
std::string oldVal = val;
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val, &isHovered))
|
||||
{
|
||||
field->SetValue(object, Convert::ToCLI(val));
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||
}
|
||||
}
|
||||
else if (field->FieldType == GameObject::typeid)
|
||||
{
|
||||
GameObject gameObj = safe_cast<GameObject>(field->GetValue(object));
|
||||
uint32_t entityId = gameObj.GetEntity();
|
||||
if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered))
|
||||
{
|
||||
GameObject newVal = GameObject(entityId);
|
||||
field->SetValue(object, newVal);
|
||||
registerUndoAction(object, field, newVal, gameObj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array<System::Type^>^ interfaces = field->FieldType->GetInterfaces();
|
||||
|
|
|
@ -33,6 +33,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Components/Transform.hxx"
|
||||
#include "Components\RigidBody.hxx"
|
||||
#include "Components\Collider.hxx"
|
||||
#include "Components/Camera.hxx"
|
||||
#include "Components/CameraArm.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -248,6 +250,8 @@ namespace SHADE
|
|||
componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
|
||||
componentMap.Add(createComponentSet<SHColliderComponent, Collider>());
|
||||
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
||||
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
||||
componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "GameObject.hxx"
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
// Project Headers
|
||||
#include "ECS.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
|
@ -72,6 +73,31 @@ namespace SHADE
|
|||
}
|
||||
return node->IsActive();
|
||||
}
|
||||
Entity GameObject::EntityId::get()
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
GameObject^ GameObject::Parent::get()
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||
|
||||
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||
if (NODE == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||
|
||||
const auto* PARENT = NODE->GetParent();
|
||||
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
void GameObject::Parent::set(GameObject^ newParent)
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
if (newParent == nullptr)
|
||||
SCENE_GRAPH.SetParent(entity, nullptr);
|
||||
else
|
||||
SCENE_GRAPH.SetParent(entity, newParent->EntityId);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* GameObject Property Functions */
|
||||
|
@ -155,11 +181,13 @@ namespace SHADE
|
|||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
GameObject::GameObject(const SHEntity& entity)
|
||||
: entity { entity.GetEID() }
|
||||
: entity { entity.GetEID() }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
{}
|
||||
|
||||
GameObject::GameObject(Entity entity)
|
||||
: entity { entity }
|
||||
: entity { entity }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -86,6 +86,21 @@ namespace SHADE
|
|||
{
|
||||
bool get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Native Entity ID value for this GameObject.
|
||||
/// </summary>
|
||||
property Entity EntityId
|
||||
{
|
||||
Entity get();
|
||||
}
|
||||
/// <summary>
|
||||
/// The parent entity for this GameObject.
|
||||
/// </summary>
|
||||
property GameObject^ Parent
|
||||
{
|
||||
GameObject^ get();
|
||||
void set(GameObject^);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* GameObject Property Functions */
|
||||
|
@ -105,6 +120,7 @@ namespace SHADE
|
|||
/// Whether to activate or deactivate this GameObject.
|
||||
/// </param>
|
||||
void SetActive(bool active);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Component Access Functions */
|
||||
|
@ -235,7 +251,8 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Entity entity;
|
||||
Entity entity;
|
||||
System::Collections::ArrayList^ children;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -29,6 +29,12 @@ namespace SHADE
|
|||
{
|
||||
return SHFrameRateController::GetRawDeltaTime();
|
||||
}
|
||||
|
||||
|
||||
float Time::DeltaTimeF::get()
|
||||
{
|
||||
return static_cast<float>(SHFrameRateController::GetRawDeltaTime());
|
||||
}
|
||||
double Time::FixedDeltaTime::get()
|
||||
{
|
||||
return SHPhysicsSystemInterface::GetFixedDT();
|
||||
|
|
|
@ -32,6 +32,16 @@ namespace SHADE
|
|||
{
|
||||
double get();
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Time taken to process the previous frame.
|
||||
/// </summary>
|
||||
static property float DeltaTimeF
|
||||
{
|
||||
float get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Time taken for Physics simulations. You should use this for operations
|
||||
/// within Script.FixedUpdate()
|
||||
|
|
|
@ -99,4 +99,11 @@ namespace SHADE
|
|||
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
Vector2 Input::GetMouseVelocity()
|
||||
{
|
||||
double velX, velY;
|
||||
SHInputManager::GetMouseVelocity(&velX, &velY);
|
||||
|
||||
return Convert::ToCLI(SHVec2{ (float)velX,(float)velY });
|
||||
}
|
||||
}
|
|
@ -471,5 +471,7 @@ namespace SHADE
|
|||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetMouseReleasedTime(MouseCode mouseButton);
|
||||
|
||||
static Vector2 GetMouseVelocity();
|
||||
};
|
||||
}
|
|
@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Math/Vector2.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
#include "Engine/GameObject.hxx"
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Macro Functions */
|
||||
|
@ -167,6 +168,11 @@ namespace SHADE
|
|||
fieldNode.push_back(vec.y);
|
||||
fieldNode.push_back(vec.z);
|
||||
}
|
||||
else if (fieldInfo->FieldType == GameObject::typeid)
|
||||
{
|
||||
GameObject gameObj = safe_cast<GameObject>(fieldInfo->GetValue(object));
|
||||
fieldNode = gameObj.GetEntity();
|
||||
}
|
||||
else // Not any of the supported types
|
||||
{
|
||||
Debug::LogWarning(Convert::ToNative(System::String::Format
|
||||
|
@ -242,6 +248,10 @@ namespace SHADE
|
|||
);
|
||||
}
|
||||
}
|
||||
else if (fieldInfo->FieldType == GameObject::typeid)
|
||||
{
|
||||
fieldInfo->SetValue(object, GameObject(node.as<uint32_t>()));
|
||||
}
|
||||
else // Not any of the supported types
|
||||
{
|
||||
Debug::LogWarning(Convert::ToNative(System::String::Format
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using SHADE;
|
||||
|
||||
namespace SHADE_Scripting
|
||||
{
|
||||
public class CameraControl :Script
|
||||
{
|
||||
public float turnSpeed = 0.5f;
|
||||
|
||||
public CameraControl(GameObject go) : base(go) { }
|
||||
protected override void update()
|
||||
{
|
||||
//Camera
|
||||
Camera cam = GetComponent<Camera>();
|
||||
Vector2 mouseVel = Input.GetMouseVelocity();
|
||||
|
||||
cam.Pitch -= mouseVel.y * turnSpeed * (float)Time.DeltaTime;
|
||||
cam.Yaw += mouseVel.x * turnSpeed * (float)Time.DeltaTime;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ public class PhysicsTest : Script
|
|||
RigidBody.AddForce(Force);
|
||||
Debug.Log($"Jump!");
|
||||
}
|
||||
Debug.Log($"{Transform.LocalPosition.y}");
|
||||
}
|
||||
|
||||
protected override void fixedUpdate()
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SHADE;
|
||||
|
||||
|
||||
namespace SHADE_Scripting
|
||||
{
|
||||
public class ThirdPersonCamera: Script
|
||||
{
|
||||
|
||||
public float armLength = 4.0f;
|
||||
public float turnSpeedPitch = 0.3f;
|
||||
public float turnSpeedYaw = 0.5f;
|
||||
public float pitchClamp = 45.0f;
|
||||
public ThirdPersonCamera(GameObject go) : base(go) { }
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
if(!GetComponent<Camera>())
|
||||
{
|
||||
AddComponent<Camera>();
|
||||
}
|
||||
if (!GetComponent<CameraArm>())
|
||||
{
|
||||
AddComponent<CameraArm>();
|
||||
}
|
||||
GetComponent<CameraArm>().ArmLength = armLength;
|
||||
}
|
||||
|
||||
protected override void update()
|
||||
{
|
||||
CameraArm arm = GetComponent<CameraArm>();
|
||||
if(arm)
|
||||
{
|
||||
Vector2 vel = Input.GetMouseVelocity();
|
||||
arm.Pitch -= vel.y * turnSpeedPitch * Time.DeltaTimeF;
|
||||
arm.Yaw += vel.x * turnSpeedYaw * Time.DeltaTimeF;
|
||||
|
||||
if(arm.Pitch > pitchClamp)
|
||||
{
|
||||
arm.Pitch = pitchClamp;
|
||||
}
|
||||
else if(arm.Pitch < -pitchClamp)
|
||||
{
|
||||
arm.Pitch = -pitchClamp;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue