Merge branch 'main' into SP3-10-input-management

This commit is contained in:
mushgunAX 2022-11-02 11:37:23 +08:00
commit 3826406f55
78 changed files with 16620 additions and 541 deletions

View File

@ -0,0 +1,17 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
layout(location = 0) in struct
{
vec4 vertColor;
} In;
layout(location = 0) out vec4 outColor;
void main()
{
outColor = In.vertColor;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDraw_FS
ID: 36671027
Type: 2

View File

@ -0,0 +1,24 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec4 aVertexPos;
layout(location = 1) in vec4 aVertColor;
layout(location = 0) out struct
{
vec4 vertColor; // location 0
} Out;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
} cameraData;
void main()
{
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f);
Out.vertColor = aVertColor;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDraw_VS
ID: 48002439
Type: 2

View File

@ -31,6 +31,7 @@
#include "FRC/SHFramerateController.h"
#include "AudioSystem/SHAudioSystem.h"
#include "Camera/SHCameraSystem.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
// Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -42,6 +43,7 @@
#include "Assets/SHAssetManager.h"
#include "Tools/SHLogger.h"
#include "Tools/SHDebugDraw.h"
using namespace SHADE;
@ -69,6 +71,7 @@ namespace Sandbox
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
@ -90,6 +93,7 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
@ -123,6 +127,9 @@ namespace Sandbox
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHFrameRateController::UpdateFRC();
// Link up SHDebugDraw
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
}
void SBApplication::Update(void)

View File

@ -16,7 +16,10 @@
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Math/SHColour.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Tools/SHDebugDraw.h"
using namespace SHADE;
@ -159,7 +162,7 @@ namespace Sandbox
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
auto ambientLight = SHEntityManager::CreateEntity<SHLightComponent>();
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHColour::WHITE);
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetStrength(0.25f);
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetType(SH_LIGHT_TYPE::AMBIENT);
}
@ -186,6 +189,8 @@ namespace Sandbox
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->RemoveAllScripts(testObj);
}
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
}
void SBTestScene::Render()

View File

@ -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);

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -175,19 +175,37 @@ namespace SHADE
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
{
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);
}
ImGui::EndDisabled();
ImGui::EndMenuBar();

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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 };

View File

@ -282,6 +282,11 @@ namespace SHADE
}
void SHVkCommandBuffer::SetLineWidth(float lineWidth) noexcept
{
vkCommandBuffer.setLineWidth(lineWidth);
}
/***************************************************************************/
/*!

View File

@ -115,6 +115,7 @@ namespace SHADE
// Dynamic State
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
void SetLineWidth (float lineWidth) noexcept;
// Binding Commands
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;

View File

@ -74,10 +74,11 @@ 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
@ -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

View File

@ -0,0 +1,202 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of functions of the SHDebugDrawSystem class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHDebugDrawSystem.h"
// STL Includes
#include <algorithm>
// Project Includes
#include "../Meshes/SHMeshData.h"
#include "../Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "../../SHVkUtil.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* DrawRoutine */
/*---------------------------------------------------------------------------------*/
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
: SHSystemRoutine("Debug Draw", true)
{
SystemFamily::GetID<SHDebugDrawSystem>();
}
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Get current frame index
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
// Create the buffer if it doesn't exist or just update it
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
system->numPoints[FRAME_IDX] = system->points.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
if (DATA_SIZE > 0)
{
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
}
// Reset for next frame
system->points.clear();
}
/*---------------------------------------------------------------------------------*/
/* SHSystem overrides */
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::Init()
{
// Register function for subpass
const auto* GFX_SYSTEM = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
// Don't draw if no points
if (numPoints[FRAME_IDX] <= 0)
return;
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
});
// Reset trackers
std::fill_n(numPoints.begin(), numPoints.size(), 0);
// Allocate buffers
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
{
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
(
BUFFER_SIZE,
nullptr,
0,
vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
);
}
}
void SHDebugDrawSystem::Exit()
{
for (auto vertexBuffer : vertexBuffers)
{
if (vertexBuffer)
vertexBuffer.Free();
}
}
/*---------------------------------------------------------------------------------*/
/* Draw Functions */
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
{
if (points.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
points.emplace_back(PointVertex{ startPt, color });
points.emplace_back(PointVertex{ endPt, color });
}
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
{
DrawPoly(color, { pt1, pt2, pt3 });
}
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
{
DrawPoly(color, { pt1, pt2, pt3, pt4 });
}
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
{
DrawPoly(color, pointList.begin(), pointList.end());
}
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
{
static const SHVec3 EXTENTS = SHVec3 { 0.5f, 0.5f, 0.5f };
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3 { pos - EXTENTS };
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3 { pos + EXTENTS };
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
DrawPoly
(
color,
{
// Bottom Square
BOT_LEFT_BACK , BOT_RIGHT_BACK,
BOT_RIGHT_BACK , BOT_RIGHT_FRONT,
BOT_RIGHT_FRONT, BOT_LEFT_FRONT,
BOT_LEFT_FRONT , BOT_LEFT_BACK,
// Top Square
TOP_LEFT_BACK , TOP_RIGHT_BACK,
TOP_RIGHT_BACK , TOP_RIGHT_FRONT,
TOP_RIGHT_FRONT, TOP_LEFT_FRONT,
TOP_LEFT_FRONT , TOP_LEFT_BACK,
// Middle Lines
TOP_LEFT_BACK , BOT_LEFT_BACK,
TOP_RIGHT_BACK , BOT_RIGHT_BACK,
TOP_RIGHT_FRONT, BOT_RIGHT_FRONT,
TOP_LEFT_FRONT , BOT_LEFT_FRONT
}
);
}
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius)
{
if (spherePoints.empty())
{
// Generate
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
for (const auto& idx : SPHERE.Indices)
{
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
}
}
DrawPoly(color, spherePoints.begin(), spherePoints.end());
}
}

View File

@ -0,0 +1,159 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of the SHDebugDrawSystem class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <vector>
// Project Includes
#include "SH_API.h"
#include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "SHGraphicsConstants.h"
#include "Math/SHColour.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHVkBuffer;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary>
/// Manages the Debug Draw system.
/// </summary>
class SH_API SHDebugDrawSystem final : public SHSystem
{
public:
/*---------------------------------------------------------------------------------*/
/* System Routines */
/*---------------------------------------------------------------------------------*/
class SH_API ProcessPointsRoutine final : public SHSystemRoutine
{
public:
ProcessPointsRoutine();
virtual void Execute(double dt) noexcept override final;
};
/*---------------------------------------------------------------------------------*/
/* SHSystem overrides */
/*---------------------------------------------------------------------------------*/
virtual void Init() override final;
virtual void Exit() override final;
/*---------------------------------------------------------------------------------*/
/* Configuration Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Configures the line width used to draw all lines in the Debug Draw system.
/// </summary>
float LineWidth = 1.0f;
/*---------------------------------------------------------------------------------*/
/* Draw Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Renders a line between two points in world space.
/// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param>
void DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
/// <summary>
/// Renders a triangle indicated by three points in world space.
/// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param>
void DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary>
/// Renders a quadrilateral indicated by four points in world space.
/// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param>
void DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointListBegin">
/// Iterator to the first point of the point container.
/// </param>
/// <param name="pointListEnd">
/// One past last iterator of the point container.
/// </param>
template<typename IterType>
void DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world space.
/// </summary>
/// <param name="color">Colour of the cube.</param>
/// <param name="pos">Position where the cube wil be centered at.</param>
/// <param name="size">Size of the rendered cube.</param>
void DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
/// <summary>
/// Renders a wireframe sphere centered around the position specified in world space.
/// </summary>
/// <param name="color">Colour of the sphere.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param>
/// <param name="size">Size of the rendered sphere.</param>
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
private:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
struct SH_API PointVertex
{
SHVec4 Position;
SHVec4 Color;
};
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/*---------------------------------------------------------------------------------*/
/* Constants */
/*---------------------------------------------------------------------------------*/
static constexpr uint32_t MAX_POINTS = 100'000;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
// CPU Buffers
std::vector<PointVertex> points;
// GPU Buffers
TripleBuffer vertexBuffers;
TripleUInt numPoints;
// Cached Points for polygon drawing
std::vector<SHVec3> spherePoints;
};
}
#include "SHDebugDrawSystem.hpp"

View File

@ -0,0 +1,48 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of template functions the SHDebugDrawSystem
class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "SHDebugDrawSystem.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Draw Functions */
/*-----------------------------------------------------------------------------------*/
template<typename IterType>
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
{
// Ensure dereferenced type is SHVec3
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
// Check if points exceeded max
if (points.size() > MAX_POINTS)
{
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
return;
}
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
// Invalid polygon
if (POINTS_COUNT < 2)
{
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly().");
return;
}
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
{
points.emplace_back(PointVertex{ *pointIter, color });
}
}
}

View File

@ -39,6 +39,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Assets/SHAssetManager.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE
{
@ -106,14 +107,13 @@ 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);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
}
@ -186,12 +186,16 @@ namespace SHADE
// deferred composite
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
// Set up Debug Draw Pass
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, {"G-Buffer"});
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
debugDrawSubpass->AddColorOutput("Scene");
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
// Dummy Node
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
dummySubpass->AddInput("Scene");
// Generate world render graph
worldRenderGraph->Generate();
@ -201,7 +205,57 @@ namespace SHADE
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
// Create default materials
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
// Create debug draw pipeline
auto debugDrawPipelineLayout = resourceManager.Create<SHVkPipelineLayout>
(
device, SHPipelineLayoutParams
{
.shaderModules = { debugVertShader, debugFragShader },
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
}
);
debugDrawPipeline = resourceManager.Create<SHVkPipeline>(device, debugDrawPipelineLayout, nullptr, debugDrawNode->GetRenderpass(), debugDrawSubpass);
debugDrawPipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
{
.polygonMode = vk::PolygonMode::eLine,
.cull_mode = vk::CullModeFlagBits::eNone
});
debugDrawPipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
{
.topology = vk::PrimitiveTopology::eLineList
});
SHVertexInputState debugDrawVertexInputState;
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
debugDrawPipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = debugDrawSubpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(subpassColorReferences.size());
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(debugDrawSubpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
debugDrawPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
debugDrawPipeline->ConstructPipeline();
}
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -621,10 +675,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 +707,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 +754,7 @@ namespace SHADE
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
SHResourceManager::FinaliseChanges();
}
/*-----------------------------------------------------------------------------------*/
@ -709,8 +772,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();

View File

@ -288,9 +288,8 @@ namespace SHADE
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
/*-----------------------------------------------------------------------------*/
/* Getters */
@ -339,10 +338,6 @@ namespace SHADE
Handle<SHViewport> worldViewport; // Whole screen
std::vector<Handle<SHViewport>> viewports; // Additional viewports
// Debug Renderers
Handle<SHRenderer> debugWorldRenderer;
Handle<SHRenderer> debugScreenRenderer;
// Temp renderers
Handle<SHRenderer> worldRenderer;
@ -353,10 +348,13 @@ namespace SHADE
// Built-In Shaders
Handle<SHVkShaderModule> defaultVertShader;
Handle<SHVkShaderModule> defaultFragShader;
Handle<SHVkShaderModule> debugVertShader;
Handle<SHVkShaderModule> debugFragShader;
Handle<SHVkShaderModule> deferredCompositeShader;
// Built-In Materials
Handle<SHMaterial> defaultMaterial;
Handle<SHVkPipeline> debugDrawPipeline;
Handle<SHRenderGraph> worldRenderGraph;

View File

@ -18,6 +18,15 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::cubeMesh;
SHMeshData SHPrimitiveGenerator::sphereMesh;
/*-----------------------------------------------------------------------------------*/
/* Primitive Generation Functions */
/*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::Cube() noexcept
{
SHMeshData mesh;
@ -26,26 +35,26 @@ namespace SHADE
{
// front
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
// back
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, -0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
SHVec3(0.5f, -0.5f, -0.5f),
// top
SHVec3(-0.5f, 0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
// bottom
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3(0.5f, -0.5f, -0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
// right
@ -193,7 +202,90 @@ namespace SHADE
Handle<SHMesh> SHPrimitiveGenerator::Cube(SHMeshLibrary& meshLibrary) noexcept
{
static SHMeshData meshData = Cube();
if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube();
return addMeshDataTo(cubeMesh, meshLibrary);
}
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
{
if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube();
return addMeshDataTo(cubeMesh, gfxSystem);
}
SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept
{
SHMeshData meshData;
const int LAT_SLICES = 12;
const int LONG_SLICES = 12;
float radius = 1;
for (int latNum = 0; latNum <= LAT_SLICES; ++latNum)
{
float theta = static_cast<float>(latNum * std::numbers::pi / LAT_SLICES);
float sinTheta = sin(theta);
float cosTheta = cos(theta);
for (int longNum = 0; longNum <= LONG_SLICES; ++longNum)
{
float phi = static_cast<float>(longNum * 2 * std::numbers::pi / LONG_SLICES);
float sinPhi = sin(phi);
float cosPhi = cos(phi);
const SHVec3 NORMAL = SHVec3(cosPhi * sinTheta, cosTheta, sinPhi * sinTheta);
meshData.VertexNormals.emplace_back(NORMAL);
meshData.VertexTangents.emplace_back(/* TODO */);
meshData.VertexTexCoords.emplace_back
(
1.0f - (longNum / static_cast<float>(LONG_SLICES)),
1.0f - (latNum / static_cast<float>(LAT_SLICES))
);
meshData.VertexPositions.emplace_back(radius * NORMAL.x, radius * NORMAL.y, radius * NORMAL.z);
}
}
for (int latNumber{}; latNumber < LAT_SLICES; latNumber++)
{
for (int longNumber{}; longNumber < LONG_SLICES; longNumber++)
{
const auto FIRST = (latNumber * (LONG_SLICES + 1)) + longNumber;
const auto SECOND = (FIRST + LONG_SLICES + 1);
meshData.Indices.emplace_back(FIRST);
meshData.Indices.emplace_back(SECOND);
meshData.Indices.emplace_back(FIRST + 1);
meshData.Indices.emplace_back(SECOND);
meshData.Indices.emplace_back(SECOND + 1);
meshData.Indices.emplace_back(FIRST + 1);
}
}
return meshData;
}
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept
{
if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere();
return addMeshDataTo(sphereMesh, meshLibrary);
}
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept
{
if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere();
return addMeshDataTo(sphereMesh, gfxSystem);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept
{
return meshLibrary.AddMesh
(
static_cast<uint32_t>(meshData.VertexPositions.size()),
@ -206,9 +298,8 @@ namespace SHADE
);
}
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept
{
static SHMeshData meshData = Cube();
return gfxSystem.AddMesh
(
static_cast<uint32_t>(meshData.VertexPositions.size()),

View File

@ -59,7 +59,7 @@ namespace SHADE
Produces a cube and constructs a SHMesh using the SHMeshLibrary provided.
\param meshLibrary
Reference to the SHMeshLibrary to procude and store a cube mesh in.
Reference to the SHMeshLibrary to produce and store a cube mesh in.
\return
SHMesh object that points to the generated cube mesh in the SHMeshLibrary.
@ -79,11 +79,54 @@ namespace SHADE
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and stores the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the sphere.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData Sphere() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and constructs a SHMesh using the SHMeshLibrary provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a sphere mesh in.
\return
SHMesh object that points to the generated sphere mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and constructs a SHMesh using the SHGraphicsSystem provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a sphere mesh in.
\return
SHMesh object that points to the generated sphere mesh in the SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHMeshData genCubeData() noexcept;
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept;
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static SHMeshData cubeMesh;
static SHMeshData sphereMesh;
};
}

View File

@ -47,12 +47,13 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
//! For constructing a graphics pipeline
SHVkPipeline (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout,
SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl,
Handle<SHSubpass> subpass) noexcept;
//! For constructing a compute pipeline
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;

View File

@ -87,19 +87,19 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHColour::SHColour() noexcept
: SHVec4 { 0.0f, 0.0f, 0.0f, 1.0f }
: XMFLOAT4 { 0.0f, 0.0f, 0.0f, 1.0f }
{}
SHColour::SHColour(float r, float g, float b) noexcept
: SHVec4 { r, g, b, 1.0f }
: XMFLOAT4 { r, g, b, 1.0f }
{}
SHColour::SHColour(float r, float g, float b, float a) noexcept
: SHVec4 { r, g, b, a }
: XMFLOAT4 { r, g, b, a }
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept
: SHVec4
: XMFLOAT4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
@ -109,7 +109,7 @@ namespace SHADE
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
: SHVec4
: XMFLOAT4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
@ -118,12 +118,24 @@ namespace SHADE
}
{}
SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept
: SHVec4 { colour.x, colour.y, colour.z, 1.0f }
SHColour::SHColour(const SHVec3& rgb) noexcept
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
{}
SHColour::SHColour(const SHVec4& rgba) noexcept
: XMFLOAT4 { rgba.x, rgba.y, rgba.z, rgba.w }
{}
SHColour::SHColour(const DirectX::XMFLOAT3& rgb) noexcept
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
{}
SHColour::SHColour(const DirectX::XMFLOAT4& rgba) noexcept
: XMFLOAT4 { rgba.x, rgba.y, rgba.z, rgba.w }
{}
SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept
: SHVec4
: XMFLOAT4
{
XMVectorGetX(colour),
XMVectorGetY(colour),
@ -136,6 +148,86 @@ namespace SHADE
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHColour::operator XMVECTOR() const noexcept
{
return XMLoadFloat4(this);
}
SHColour::operator SHVec4() const noexcept
{
return SHVec4{ *this };
}
SHColour& SHColour::operator+=(const SHColour& rhs) noexcept
{
return *this = *this + rhs;
}
SHColour& SHColour::operator-=(const SHColour& rhs) noexcept
{
return *this = *this - rhs;
}
SHColour& SHColour::operator*=(const SHColour& rhs) noexcept
{
return *this = *this * rhs;
}
SHColour& SHColour::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHColour& SHColour::operator/=(const SHColour& rhs) noexcept
{
return *this = *this / rhs;
}
SHColour SHColour::operator+(const SHColour& rhs) const noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorAdd(*this, rhs));
return result;
}
SHColour SHColour::operator-(const SHColour& rhs) const noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorSubtract(*this, rhs));
return result;
}
SHColour SHColour::operator-() const noexcept
{
return SHColour{ -x, -y, -z, -w };
}
SHColour SHColour::operator*(const SHColour& rhs) const noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorMultiply(*this, rhs));
return result;
}
SHColour SHColour::operator*(float rhs) const noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorScale(*this, rhs));
return result;
}
SHColour SHColour::operator/(const SHColour& rhs) const noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorDivide(*this, rhs));
return result;
}
bool SHColour::operator==(const SHColour& rhs) const noexcept
{
return XMColorEqual(*this, rhs);
@ -146,6 +238,70 @@ namespace SHADE
return XMColorNotEqual(*this, rhs);
}
float& SHColour::operator[](int index)
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
}
}
float& SHColour::operator[](size_t index)
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
}
}
float SHColour::operator[](int index) const
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
}
}
float SHColour::operator[](size_t index) const
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
}
}
SHColour operator* (float lhs, const SHColour& rhs) noexcept
{
SHColour result;
XMStoreFloat4(&result, XMVectorScale(rhs, lhs));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/

View File

@ -19,12 +19,6 @@
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHColour;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
@ -40,7 +34,7 @@ namespace SHADE
float v = 0.0f;
};
class SH_API SHColour : private SHVec4
class SH_API SHColour : public DirectX::XMFLOAT4
{
public:
/*---------------------------------------------------------------------------------*/
@ -53,9 +47,11 @@ namespace SHADE
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
SHColour (const SHVec3& colour) noexcept;
SHColour (const DirectX::XMFLOAT3& colour) noexcept;
SHColour (const DirectX::XMVECTORF32& colour) noexcept;
SHColour (const SHVec3& rgb) noexcept;
SHColour (const SHVec4& rgba) noexcept;
SHColour (const DirectX::XMFLOAT3& rgb) noexcept;
SHColour (const DirectX::XMFLOAT4& rgba) noexcept;
SHColour (const DirectX::XMVECTORF32& rgba) noexcept;
SHColour (const SHColour&) = default;
SHColour (SHColour&&) = default;
@ -69,8 +65,29 @@ namespace SHADE
SHColour& operator= (const SHColour&) = default;
SHColour& operator= (SHColour&&) = default;
bool operator== (const SHColour& rhs) const noexcept;
bool operator!= (const SHColour& rhs) const noexcept;
operator DirectX::XMVECTOR () const noexcept;
operator SHVec4 () const noexcept;
SHColour& operator+= (const SHColour& rhs) noexcept;
SHColour& operator-= (const SHColour& rhs) noexcept;
SHColour& operator*= (const SHColour& rhs) noexcept;
SHColour& operator*= (float rhs) noexcept;
SHColour& operator/= (const SHColour& rhs) noexcept;
[[nodiscard]] SHColour operator+ (const SHColour& rhs) const noexcept;
[[nodiscard]] SHColour operator- (const SHColour& rhs) const noexcept;
[[nodiscard]] SHColour operator- () const noexcept;
[[nodiscard]] SHColour operator* (const SHColour& rhs) const noexcept;
[[nodiscard]] SHColour operator* (float rhs) const noexcept;
[[nodiscard]] SHColour operator/ (const SHColour& rhs) const noexcept;
[[nodiscard]] bool operator== (const SHColour& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHColour& rhs) const noexcept;
[[nodiscard]] float& operator[] (int index);
[[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Properties */
@ -105,6 +122,8 @@ namespace SHADE
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t SIZE = 4U;
static const SHColour BEIGE ;
static const SHColour BLACK ;
static const SHColour BLUE ;
@ -159,8 +178,9 @@ namespace SHADE
static const SHColour TURQUOISE ;
static const SHColour VIOLET ;
static const SHColour WHITE ;
static const SHColour YELLOW;
static const SHColour YELLOW ;
};
SHColour operator* (float lhs, const SHColour& rhs) noexcept;
} // namespace SHADE

View File

@ -9,4 +9,6 @@
#include "SHQuaternion.h"
#include "SHMatrix.h"
#include "SHColour.h"
#include "Transform/SHTransform.h"

View File

@ -191,7 +191,7 @@ namespace SHADE
SHVec4 SHMatrix::operator*(const SHVec4& rhs) const noexcept
{
return SHVec4::Transform3D(rhs, *this);
return SHVec4::Transform(rhs, *this);
}
SHMatrix SHMatrix::operator*(float rhs) const noexcept

View File

@ -186,6 +186,6 @@ RTTR_REGISTRATION
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("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"));
}

View File

@ -261,7 +261,7 @@ namespace SHADE
auto* node = EVENT_DATA->data->node;
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
if(tf == nullptr)
if (tf == nullptr)
return EVENT_DATA->handle;
// Recompute local transform and store localToWorld Matrix

View File

@ -445,9 +445,7 @@ namespace SHADE
{
SHVec3 result;
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat3(&result, XMVector3TransformCoord(v, TF));
XMStoreFloat3(&result, XMVector3TransformCoord(v, transformMtx));
return result;
}
}

View File

@ -14,6 +14,7 @@
#include "SHVec4.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Math/SHColour.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
@ -460,13 +461,19 @@ namespace SHADE
return result;
}
SHVec4 SHVec4::Transform(const SHVec4& v, const SHMatrix& transformMtx) noexcept
{
SHVec4 result;
XMStoreFloat4(&result, XMVector4Transform(v, transformMtx));
return result;
}
SHVec4 SHVec4::Transform3D(const SHVec4& v, const SHMatrix& transformMtx) noexcept
{
SHVec4 result;
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat4(&result, XMVector3TransformCoord(v, TF));
XMStoreFloat4(&result, XMVector3TransformCoord(v, transformMtx));
return result;
}
}

View File

@ -23,7 +23,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMatrix;
class SHColour;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
@ -134,6 +136,7 @@ namespace SHADE
[[nodiscard]] static SHVec4 Project3D (const SHVec4& v, const SHVec4& u) noexcept;
[[nodiscard]] static SHVec4 Reflect (const SHVec4& v, const SHVec4& normal) noexcept;
[[nodiscard]] static SHVec4 Reflect3D (const SHVec4& v, const SHVec4& normal) noexcept;
[[nodiscard]] static SHVec4 Transform (const SHVec4& v, const SHMatrix& transformMtx) noexcept;
[[nodiscard]] static SHVec4 Transform3D (const SHVec4& v, const SHMatrix& transformMtx) noexcept;
};

View File

@ -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 SHVec3& SHRigidBodyComponent::GetForce() const noexcept
{
return force;
const auto& ANGULAR_CONSTRAINTS = rp3dBody->getAngularLockAxisFactor();
return SHMath::CompareFloat(ANGULAR_CONSTRAINTS.z, 0.0f);
}
const SHVec3& SHRigidBodyComponent::GetTorque() const noexcept
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
{
return torque;
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return false;
}
const SHVec3& SHRigidBodyComponent::GetLinearVelocity() const noexcept
{
return linearVelocity;
return rp3dBody->getForce();
}
const SHVec3& SHRigidBodyComponent::GetAngularVelocity() const noexcept
SHVec3 SHRigidBodyComponent::GetTorque() const noexcept
{
return angularVelocity;
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return SHVec3::Zero;
}
return rp3dBody->getTorque();
}
SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept
{
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Missing rp3dBody from Entity {}", GetEID())
return SHVec3::Zero;
}
return rp3dBody->getLinearVelocity();
}
SHVec3 SHRigidBodyComponent::GetAngularVelocity() const noexcept
{
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
@ -286,8 +418,13 @@ namespace SHADE
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;
}

View File

@ -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;
@ -150,25 +150,10 @@ namespace SHADE
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;
reactphysics3d::RigidBody* rp3dBody;
float mass;
float drag;
float angularDrag;
SHVec3 force;
SHVec3 linearVelocity;
SHVec3 torque;
SHVec3 angularVelocity;
SHVec3 position;
SHQuaternion orientation;

View File

@ -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));
}

View File

@ -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;
@ -97,6 +98,7 @@ namespace SHADE
void SetMaterial (const SHPhysicsMaterial& newMaterial) 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 */

View File

@ -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())
{

View File

@ -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:

View File

@ -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
@ -327,10 +320,10 @@ namespace SHADE
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
{
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
if (!scriptSys)
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,10 +622,6 @@ 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)
{
@ -643,6 +629,8 @@ namespace SHADE
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;
@ -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)
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

View File

@ -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>

View File

@ -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

View File

@ -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.");
if (meshChanged)
{
gfxSystem->BuildMeshBuffers();
meshChanged = false;
}
if (textureChanged)
{
gfxSystem->BuildTextures();
textureChanged = false;
}
// Free CPU Resources
for (auto assetId : loadedAssetData)

View File

@ -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 */

View File

@ -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
(

View File

@ -0,0 +1,73 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 2, 2022
\brief Contains the definition of functions of the SHDebugDrawSystem class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Header
#include "SHpch.h"
// Primary Include
#include "SHDebugDraw.h"
// Project Includes
#include "Math/Vector/SHVec4.h"
#include "Math/SHColour.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "ECS_Base/Managers/SHSystemManager.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHDebugDrawSystem* SHDebugDraw::dbgDrawSys = nullptr;
/*-----------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Init(SHDebugDrawSystem* sys)
{
dbgDrawSys = sys;
if (dbgDrawSys == nullptr)
{
SHLOG_ERROR("[SHDebugDraw] Invalid SHDebugDrawSystem provided for initialization!");
}
}
/*-----------------------------------------------------------------------------------*/
/* Draw Functions */
/*-----------------------------------------------------------------------------------*/
void SHDebugDraw::Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
{
dbgDrawSys->DrawLine(color, startPt, endPt);
}
void SHDebugDraw::Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
{
dbgDrawSys->DrawTri(color, pt1, pt2, pt3);
}
void SHDebugDraw::Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
{
dbgDrawSys->DrawQuad(color, pt1, pt2, pt3, pt4);
}
void SHDebugDraw::Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
{
dbgDrawSys->DrawPoly(color, pointList);
}
void SHDebugDraw::Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
{
dbgDrawSys->DrawCube(color, pos, size);
}
void SHDebugDraw::Sphere(const SHVec4& color, const SHVec3& pos, double radius)
{
dbgDrawSys->DrawSphere(color, pos, radius);
}
}

View File

@ -0,0 +1,101 @@
/************************************************************************************//*!
\file SHDebugDraw.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 2, 2022
\brief Contains the definition of the SHDebugDraw static class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Project Includes
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHDebugDrawSystem;
class SHVec4;
class SHVec3;
class SHColour;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary>
/// Static helper class to make it easier to do debug drawing and enable support for
/// managed code to execute it withot dependency hell due to graphics system
/// dependencies.
/// </summary>
class SH_API SHDebugDraw final
{
public:
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Sets up the link with the SHDebugDrawSystem. Must be called after the
/// SHDebugDrawSystem is spawned.
/// </summary>
static void Init(SHDebugDrawSystem* sys);
/*---------------------------------------------------------------------------------*/
/* Draw Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Renders a line between two points in world space.
/// </summary>
/// <param name="color">Colour of the line.</param>
/// <param name="startPt">First point of the line.</param>
/// <param name="endPt">Second point of the line.</param>
static void Line(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
/// <summary>
/// Renders a triangle indicated by three points in world space.
/// </summary>
/// <param name="color">Colour of the triangle.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the triangle.</param>
/// <param name="pt3">Third point of the triangle.</param>
static void Tri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary>
/// Renders a quadrilateral indicated by four points in world space.
/// </summary>
/// <param name="color">Colour of the quadrilateral.</param>
/// <param name="pt1">First point of the triangle.</param>
/// <param name="pt2">Second point of the quadrilateral.</param>
/// <param name="pt3">Third point of the quadrilateral.</param>
/// <param name="pt4">Third point of the quadrilateral.</param>
static void Quad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
static void Poly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world space.
/// </summary>
/// <param name="color">Colour of the cube.</param>
/// <param name="pos">Position where the cube wil be centered at.</param>
/// <param name="size">Size of the rendered cube.</param>
static void Cube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
/// <summary>
/// Renders a wireframe sphere centered around the position specified in world space.
/// </summary>
/// <param name="color">Colour of the sphere.</param>
/// <param name="pos">Position where the sphere wil be centered at.</param>
/// <param name="size">Size of the rendered sphere.</param>
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius);
private:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static SHDebugDrawSystem* dbgDrawSys;
};
}

View File

@ -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);
}
}

View File

@ -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();
};
}

View File

@ -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;
}
}

View File

@ -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);
}
};
}

View File

@ -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);
}
}

View File

@ -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);
};
}

View File

@ -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();

View File

@ -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>());
}
/*---------------------------------------------------------------------------------*/

View File

@ -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 */
@ -156,10 +182,12 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
GameObject::GameObject(const SHEntity& entity)
: entity { entity.GetEID() }
, children{ gcnew System::Collections::ArrayList }
{}
GameObject::GameObject(Entity entity)
: entity { entity }
, children{ gcnew System::Collections::ArrayList }
{}
/*---------------------------------------------------------------------------------*/

View File

@ -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 */
@ -106,6 +121,7 @@ namespace SHADE
/// </param>
void SetActive(bool active);
/*-----------------------------------------------------------------------------*/
/* Component Access Functions */
/*-----------------------------------------------------------------------------*/
@ -236,6 +252,7 @@ namespace SHADE
/* Data Members */
/*-----------------------------------------------------------------------------*/
Entity entity;
System::Collections::ArrayList^ children;
public:
/*-----------------------------------------------------------------------------*/

View File

@ -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();

View File

@ -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()

View File

@ -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 });
}
}

View File

@ -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();
};
}

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -38,7 +38,6 @@ public class PhysicsTest : Script
RigidBody.AddForce(Force);
Debug.Log($"Jump!");
}
Debug.Log($"{Transform.LocalPosition.y}");
}
protected override void fixedUpdate()

View File

@ -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;
}
}
}
}
}

View File

@ -1,83 +0,0 @@
#version 450
struct DirectionalLightStruct
{
vec3 direction;
uint isActive;
uint cullingMask;
vec4 diffuseColor;
};
struct AmbientLightStruct
{
vec4 ambientColor;
float strength;
uint isActive;
uint cullingMask;
};
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
layout(set = 4, binding = 4, rgba8) uniform image2D targetImage;
layout(set = 1, binding = 0) uniform LightCounts
{
uint directionalLights;
uint pointLights;
uint spotLights;
uint ambientLights;
} lightCounts;
layout(std430, set = 1, binding = 1) buffer DirectionalLightData
{
DirectionalLightStruct dLightData[];
} DirLightData;
layout(std430, set = 1, binding = 4) buffer AmbientLightData
{
AmbientLightStruct aLightData[];
} AmbLightData;
void main()
{
// convenient variables
ivec2 globalThread = ivec2(gl_GlobalInvocationID);
// Get the diffuse color of the pixel
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
// Get position of fragment in world space
vec3 positionWorld = imageLoad (positions, globalThread).rgb;
// normal of fragment
vec3 normalWorld = imageLoad(normals, globalThread).rgb;
vec3 fragColor = vec3 (0.0f);
for (int i = 0; i < lightCounts.directionalLights; ++i)
{
// get normalized direction of light
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
// Get diffuse strength
float diffuseStrength = max (0, dot (dLightNormalized, normalWorld));
// Calculate the fragment color
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
}
for (int i = 0; i < lightCounts.ambientLights; ++i)
{
// Just do some add
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
}
// store result into result image
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor, 1.0f));
}

Binary file not shown.

Binary file not shown.

1029
bin/Debug/SHADE_CSharp.xml Normal file

File diff suppressed because it is too large Load Diff

6250
bin/Debug/SHADE_Managed.xml Normal file

File diff suppressed because it is too large Load Diff

1029
bin/Release/SHADE_CSharp.xml Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff