Merge branch 'main' into SP3-4-Editor
This commit is contained in:
commit
86254a5bf3
|
@ -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.
|
@ -0,0 +1,3 @@
|
|||
Name: DebugDraw_FS
|
||||
ID: 36671027
|
||||
Type: 2
|
|
@ -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.
|
@ -0,0 +1,3 @@
|
|||
Name: DebugDraw_VS
|
||||
ID: 48002439
|
||||
Type: 2
|
|
@ -21,7 +21,8 @@ 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 = 4, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||
layout(set = 4, binding = 5, rgba8) uniform image2D targetImage;
|
||||
|
||||
layout(set = 1, binding = 0) uniform LightCounts
|
||||
{
|
||||
|
@ -51,33 +52,46 @@ void main()
|
|||
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
||||
|
||||
// Get position of fragment in world space
|
||||
vec3 positionWorld = imageLoad (positions, globalThread).rgb;
|
||||
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||
|
||||
// normal of fragment
|
||||
vec3 normalWorld = imageLoad(normals, globalThread).rgb;
|
||||
vec3 normalView = imageLoad(normals, globalThread).rgb;
|
||||
|
||||
// light layer index
|
||||
uint lightLayer = imageLoad (lightLayerData, globalThread).r;
|
||||
|
||||
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);
|
||||
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||
{
|
||||
// get normalized direction of light
|
||||
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
|
||||
|
||||
// Get diffuse strength
|
||||
float diffuseStrength = max (0, dot (dLightNormalized, normalWorld));
|
||||
// Get diffuse strength
|
||||
float diffuseStrength = max (0, dot (dLightNormalized, normalView));
|
||||
|
||||
// Calculate the fragment color
|
||||
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
||||
// 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);
|
||||
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
|
||||
fragColor *= ssaoVal;
|
||||
|
||||
// store result into result image
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor, 1.0f));
|
||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,58 @@
|
|||
#version 450
|
||||
|
||||
#define BLUR_WIDTH 5
|
||||
#define BLUR_HALF_WIDTH BLUR_WIDTH / 2
|
||||
#define SHM_WIDTH BLUR_WIDTH + 16 - 1
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 16) in;
|
||||
layout(set = 4, binding = 0, r8) uniform image2D ssaoImage;
|
||||
layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage;
|
||||
|
||||
|
||||
float GetSSAOValue(ivec2 uv, ivec2 imageSize)
|
||||
{
|
||||
if (uv.x >= 0 && uv.y >= 0 && uv.x < imageSize.x && uv.y < imageSize.y)
|
||||
{
|
||||
return imageLoad (ssaoImage, uv).r;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
shared float sharedPixels[16 + BLUR_WIDTH - 1][16 + BLUR_WIDTH - 1];
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||
ivec2 localThread = ivec2 (gl_LocalInvocationID.xy);
|
||||
ivec2 inputImageSize = imageSize(ssaoImage);
|
||||
|
||||
// Load color into shared memory
|
||||
ivec2 start = ivec2 (gl_WorkGroupID) * ivec2 (gl_WorkGroupSize) - (BLUR_HALF_WIDTH);
|
||||
for (int i = localThread.x; i < SHM_WIDTH; i += int (gl_WorkGroupSize.x))
|
||||
{
|
||||
for (int j = localThread.y; j < SHM_WIDTH; j += int (gl_WorkGroupSize.y))
|
||||
{
|
||||
float value = GetSSAOValue (start + ivec2 (i, j), inputImageSize);
|
||||
sharedPixels[i][j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for all shared memory to load
|
||||
barrier();
|
||||
|
||||
ivec2 shmStart = ivec2 (localThread + (BLUR_HALF_WIDTH));
|
||||
|
||||
float sum = 0;
|
||||
for (int i = -BLUR_HALF_WIDTH; i <= BLUR_HALF_WIDTH; ++i)
|
||||
{
|
||||
for (int j = -BLUR_HALF_WIDTH; j <= BLUR_HALF_WIDTH; ++j)
|
||||
{
|
||||
float sharedVal = sharedPixels[shmStart.x + i][shmStart.y + j];
|
||||
sum += sharedVal;
|
||||
}
|
||||
}
|
||||
|
||||
sum /= (BLUR_WIDTH * BLUR_WIDTH);
|
||||
imageStore(ssaoBlurImage, globalThread, vec4(sum.rrr, 1.0f));
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: SSAOBlur_CS
|
||||
ID: 39760835
|
||||
Type: 2
|
|
@ -0,0 +1,104 @@
|
|||
#version 450
|
||||
|
||||
const uint NUM_SAMPLES = 64;
|
||||
const uint NUM_ROTATIONS = 16;
|
||||
const int ROTATION_KERNEL_W = 4;
|
||||
const int ROTATION_KERNEL_H = 4;
|
||||
|
||||
// can perhaps pass in as push constant.
|
||||
const float RADIUS = 0.5f;
|
||||
const float BIAS = 0.025f;
|
||||
|
||||
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, rgba32f) uniform image2D outputImage;
|
||||
|
||||
|
||||
// SSAO data
|
||||
layout(std430, set = 5, binding = 0) buffer SSAOData
|
||||
{
|
||||
vec4 samples[NUM_SAMPLES];
|
||||
|
||||
} ssaoData;
|
||||
|
||||
layout (set = 5, binding = 1) uniform sampler2D noiseTexture;
|
||||
|
||||
layout(set = 2, binding = 0) uniform CameraData
|
||||
{
|
||||
vec4 position;
|
||||
mat4 vpMat;
|
||||
mat4 viewMat;
|
||||
mat4 projMat;
|
||||
|
||||
} cameraData;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// image size of the SSAO image
|
||||
ivec2 ssaoSize = imageSize (outputImage);
|
||||
|
||||
// global thread
|
||||
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||
|
||||
// load all the necessary variables
|
||||
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
|
||||
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
|
||||
|
||||
// Get the noise dimension. This should be 4x4
|
||||
vec2 noiseDim = vec2 (textureSize(noiseTexture, 0));
|
||||
|
||||
// Get normlized thread UV coordinates
|
||||
vec2 threadUV = (vec2(globalThread)) / vec2(ssaoSize);
|
||||
vec2 noiseUVMult = vec2 (vec2(ssaoSize) / noiseDim);
|
||||
noiseUVMult *= threadUV;
|
||||
|
||||
// sample from the noise
|
||||
vec3 randomVec = texture(noiseTexture, noiseUVMult).rgb;
|
||||
|
||||
// Gram schmidt
|
||||
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
|
||||
vec3 bitangent = normalize (cross (tangent, viewSpaceNormal));
|
||||
|
||||
// matrix for tangent space to view space
|
||||
mat3 TBN = mat3(tangent, bitangent, viewSpaceNormal);
|
||||
|
||||
float occlusion = 0.0f;
|
||||
for (int i = 0; i < NUM_SAMPLES; ++i)
|
||||
{
|
||||
// We want to get a position at an offset from the view space position. Offset scaled by radius.
|
||||
vec3 displacementVector = TBN * ssaoData.samples[i].rgb;
|
||||
|
||||
// Why are we adding positions?
|
||||
displacementVector = viewSpacePos + displacementVector * RADIUS;
|
||||
|
||||
// Now we take that offset position and bring it to clip space
|
||||
vec4 offsetPos = vec4 (displacementVector, 1.0f);
|
||||
offsetPos = cameraData.projMat * offsetPos;
|
||||
|
||||
// then we do perspective division
|
||||
offsetPos.xyz /= offsetPos.w;
|
||||
|
||||
// and bring it from [-1, 1] to screen coordinates
|
||||
offsetPos.xyz = ((offsetPos.xyz * 0.5f) + 0.5f);
|
||||
offsetPos.xy *= vec2(ssaoSize.xy);
|
||||
|
||||
// Now we attempt to get a position at that point.
|
||||
float sampleDepth = imageLoad (positions, ivec2 (offsetPos.xy)).z;
|
||||
|
||||
// skip checks
|
||||
if (sampleDepth == 0.0f)
|
||||
continue;
|
||||
|
||||
// if sampled fragment is in front of current fragment, just occlude
|
||||
float rangeCheck = smoothstep (0.0f, 1.0f, RADIUS / abs (viewSpacePos.z - sampleDepth));
|
||||
occlusion += (sampleDepth <= displacementVector.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||
}
|
||||
|
||||
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
|
||||
|
||||
// store result into result image
|
||||
imageStore(outputImage, globalThread, occlusion.rrrr);
|
||||
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: SSAO_CS
|
||||
ID: 38430899
|
||||
Type: 2
|
|
@ -33,18 +33,31 @@ layout(set = 2, binding = 0) uniform CameraData
|
|||
{
|
||||
vec4 position;
|
||||
mat4 vpMat;
|
||||
mat4 viewMat;
|
||||
mat4 projMat;
|
||||
} cameraData;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
Out2.materialIndex = gl_InstanceIndex;
|
||||
Out2.eid = integerData[0];
|
||||
Out2.lightLayerIndex = integerData[1];
|
||||
|
||||
Out.vertPos = worldTransform * vec4(aVertexPos, 1.0f);
|
||||
// for transforming gBuffer position and normal data
|
||||
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||
|
||||
// gBuffer position will be in view space
|
||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||
|
||||
// uvs for texturing in fragment shader
|
||||
Out.uv = aUV;
|
||||
Out.normal.rgb = mat3(transpose(inverse(worldTransform))) * aNormal.rgb;
|
||||
|
||||
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||
|
||||
// normals are also in view space
|
||||
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||
|
||||
// clip space for rendering
|
||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
}
|
Binary file not shown.
|
@ -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,10 @@ namespace Sandbox
|
|||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||
|
||||
// Link up SHDebugDraw
|
||||
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
@ -88,8 +94,10 @@ namespace Sandbox
|
|||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
|
||||
|
||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||
|
||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||
|
@ -123,6 +131,9 @@ namespace Sandbox
|
|||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||
|
||||
SHFrameRateController::UpdateFRC();
|
||||
|
||||
// Link up SHDebugDraw
|
||||
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||
}
|
||||
|
||||
void SBApplication::Update(void)
|
||||
|
@ -141,6 +152,13 @@ namespace Sandbox
|
|||
#endif
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||
editor->PollPicking();
|
||||
|
||||
static bool drawColliders = false;
|
||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::SPACE))
|
||||
{
|
||||
drawColliders = !drawColliders;
|
||||
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
|
||||
}
|
||||
}
|
||||
// Finish all graphics jobs first
|
||||
graphicsSystem->AwaitGraphicsExecution();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace SHADE
|
|||
{
|
||||
system.second->Init();
|
||||
#ifdef _DEBUG
|
||||
std::cout << system.first << " Init" << std::endl;
|
||||
SHLOG_INFO("Initialising System {}...", system.first)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,18 +195,22 @@ namespace SHADE
|
|||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
std::string moveLabel = "Moving EID: ";
|
||||
static std::vector<EntityID> draggingEntities = editor->selectedEntities;
|
||||
if (!isSelected)
|
||||
editor->selectedEntities.push_back(eid);
|
||||
for (int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
||||
{
|
||||
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
||||
if (i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
||||
draggingEntities.clear();
|
||||
draggingEntities.push_back(eid);
|
||||
}
|
||||
for (int i = 0; i < static_cast<int>(draggingEntities.size()); ++i)
|
||||
{
|
||||
moveLabel.append(std::to_string(draggingEntities[i]));
|
||||
if (i + 1 < static_cast<int>(draggingEntities.size()))
|
||||
{
|
||||
moveLabel.append(", ");
|
||||
}
|
||||
}
|
||||
ImGui::Text(moveLabel.c_str());
|
||||
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &editor->selectedEntities);
|
||||
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &draggingEntities);
|
||||
SHDragDrop::EndSource();
|
||||
}
|
||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||
|
|
|
@ -244,9 +244,12 @@ namespace SHADE
|
|||
SHCollider* collider = &component->GetCollider(i);
|
||||
auto cursorPos = ImGui::GetCursorPos();
|
||||
|
||||
//collider->IsTrigger
|
||||
|
||||
if (collider->GetType() == SHCollider::Type::BOX)
|
||||
{
|
||||
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
||||
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||
SHEditorWidgets::DragVec3
|
||||
(
|
||||
|
@ -257,6 +260,7 @@ namespace SHADE
|
|||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
||||
{
|
||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
||||
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||
SHEditorWidgets::DragFloat
|
||||
(
|
||||
|
@ -265,19 +269,42 @@ namespace SHADE
|
|||
{
|
||||
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
||||
return sphere->GetRadius() / MAX_SCALE;
|
||||
return (sphere->GetRadius() / MAX_SCALE) * 2.0f;
|
||||
},
|
||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||
}
|
||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
|
||||
|
||||
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||
{
|
||||
colliderToDelete = i;
|
||||
|
@ -359,6 +386,7 @@ namespace SHADE
|
|||
[component](AssetID const& id)
|
||||
{
|
||||
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}, SHDragDrop::DRAG_RESOURCE);
|
||||
|
||||
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
|
@ -46,6 +46,7 @@
|
|||
#include <backends/imgui_impl_vulkan.h>
|
||||
|
||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||
#include "Tools/SHDebugDraw.h"
|
||||
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
|
@ -77,7 +78,6 @@ namespace SHADE
|
|||
//#==============================================================#
|
||||
void SHEditor::Init()
|
||||
{
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
if(auto context = ImGui::CreateContext())
|
||||
{
|
||||
|
@ -122,6 +122,17 @@ namespace SHADE
|
|||
window->Init();
|
||||
}
|
||||
|
||||
/* Editor View Gridlines */
|
||||
SetUpGridLines(true, true);
|
||||
// Handle state changes so that we only show in edit mode
|
||||
std::shared_ptr<SHEventReceiverSpec<SHEditor>> stateChangeEventReceiver
|
||||
{
|
||||
std::make_shared<SHEventReceiverSpec<SHEditor>>(this, &SHEditor::onEditorStateChanged)
|
||||
};
|
||||
SHEventManager::SubscribeTo(SH_EDITOR_ON_PLAY_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||
SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||
|
||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||
}
|
||||
|
||||
|
@ -182,6 +193,97 @@ namespace SHADE
|
|||
io->Fonts->Build();
|
||||
}
|
||||
|
||||
void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes)
|
||||
{
|
||||
// Clear existing lines
|
||||
SHDebugDraw::ClearPersistentDraws();
|
||||
|
||||
static constexpr float DELTA = 1.0f;
|
||||
static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA);
|
||||
static constexpr float LINE_HALF_LENGTH = (DELTA * static_cast<float>(EXTENT_COUNT)) * 0.5f;
|
||||
|
||||
// Render Grid
|
||||
static const SHColour GRID_COL = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
if (drawGrid)
|
||||
{
|
||||
for (int i = 1; i < EXTENT_COUNT; ++i)
|
||||
{
|
||||
// X-Axis Lines
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
GRID_COL,
|
||||
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA },
|
||||
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA }
|
||||
);
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
GRID_COL,
|
||||
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA },
|
||||
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA }
|
||||
);
|
||||
// Y-Axis Lines
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
GRID_COL,
|
||||
SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||
SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||
);
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
GRID_COL,
|
||||
SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||
SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Render World Axes
|
||||
if (drawAxes || drawGrid)
|
||||
{
|
||||
const SHColour X_AXIS_COL = drawAxes ? SHColour::RED : GRID_COL;
|
||||
const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL;
|
||||
const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL;
|
||||
// X
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
X_AXIS_COL,
|
||||
SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f },
|
||||
SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f }
|
||||
);
|
||||
// Y
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
Y_AXIS_COL,
|
||||
SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f },
|
||||
SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f }
|
||||
);
|
||||
// Z
|
||||
SHDebugDraw::PersistentLine
|
||||
(
|
||||
Z_AXIS_COL,
|
||||
SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH },
|
||||
SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SHEventHandle SHEditor::onEditorStateChanged(SHEventPtr eventPtr)
|
||||
{
|
||||
auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get());
|
||||
switch (editorState)
|
||||
{
|
||||
case State::PAUSE:
|
||||
case State::STOP:
|
||||
SetUpGridLines(true, true);
|
||||
break;
|
||||
case State::PLAY:
|
||||
default:
|
||||
SHDebugDraw::ClearPersistentDraws();
|
||||
break;
|
||||
}
|
||||
return eventData->handle;
|
||||
}
|
||||
|
||||
void SHEditor::Exit()
|
||||
{
|
||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
#include "Resource/SHHandle.h"
|
||||
#include "EditorWindow/SHEditorWindow.h"
|
||||
#include "Tools/SHLog.h"
|
||||
#include "Gizmos/SHTransformGizmo.h"
|
||||
|
||||
#include "Gizmos/SHTransformGizmo.h"`
|
||||
#include "Events/SHEventDefines.h"
|
||||
#include "Events/SHEvent.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
|
@ -194,6 +195,10 @@ namespace SHADE
|
|||
|
||||
void InitFonts() noexcept;
|
||||
|
||||
void SetUpGridLines(bool drawGrid, bool drawAxes);
|
||||
|
||||
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||
|
||||
// Handle to command pool used for ImGui Vulkan Backend
|
||||
Handle<SHVkCommandPool> imguiCommandPool;
|
||||
// Handle to command buffer used for ImGui Vulkan Backend
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -156,7 +157,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::Checkbox("#", &value);
|
||||
return ImGui::Checkbox("##", &value);
|
||||
}
|
||||
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||
{
|
||||
|
@ -164,7 +165,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputInt("#", &value,
|
||||
return ImGui::InputInt("##", &value,
|
||||
1, 10,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
@ -175,7 +176,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = InputInt("#", signedVal);
|
||||
const bool CHANGED = InputInt("##", signedVal);
|
||||
if (CHANGED)
|
||||
{
|
||||
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||
|
@ -189,7 +190,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputFloat("#", &value,
|
||||
return ImGui::InputFloat("##", &value,
|
||||
0.1f, 1.0f, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
return ImGui::InputDouble("##", &value,
|
||||
0.1, 1.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
@ -209,7 +210,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
return ImGui::InputDouble("##", &value,
|
||||
1.0, 45.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||
if (CHANGED)
|
||||
{
|
||||
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||
|
@ -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
|
||||
|
@ -297,7 +327,7 @@ namespace SHADE
|
|||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||
{
|
||||
for (int i = 0; i < enumNames.size(); ++i)
|
||||
{
|
||||
|
|
|
@ -308,6 +308,14 @@ namespace SHADE
|
|||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a drag field widget for int input.
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input.
|
||||
/// </summary>
|
||||
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
||||
|
|
|
@ -13,4 +13,7 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
|||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
||||
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
||||
|
||||
|
|
|
@ -64,6 +64,11 @@ namespace SHADE
|
|||
return bufferUsageFlags;
|
||||
}
|
||||
|
||||
uint32_t SHVkBuffer::GetSizeStored(void) const noexcept
|
||||
{
|
||||
return sizeStored;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -102,8 +102,9 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
vk::Buffer GetVkBuffer (void) const noexcept;
|
||||
vk::Buffer GetVkBuffer (void) const noexcept;
|
||||
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
||||
uint32_t GetSizeStored (void) const noexcept;
|
||||
|
||||
template <typename T>
|
||||
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
||||
|
|
|
@ -282,6 +282,11 @@ namespace SHADE
|
|||
|
||||
}
|
||||
|
||||
void SHVkCommandBuffer::SetLineWidth(float lineWidth) noexcept
|
||||
{
|
||||
vkCommandBuffer.setLineWidth(lineWidth);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -119,6 +119,18 @@ namespace SHADE
|
|||
return setIndex;
|
||||
}
|
||||
|
||||
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
|
||||
{
|
||||
uint32_t numDynamicBindings = 0;
|
||||
for (auto& binding : layoutDesc)
|
||||
{
|
||||
if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic)
|
||||
++numDynamicBindings;
|
||||
}
|
||||
|
||||
return numDynamicBindings;
|
||||
}
|
||||
|
||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||
{
|
||||
if (&rhs == this)
|
||||
|
|
|
@ -99,6 +99,7 @@ namespace SHADE
|
|||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||
SetIndex GetSetIndex (void) const noexcept;
|
||||
uint32_t GetNumDynamicOffsetsRequired (void) const noexcept;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -74,11 +74,12 @@ namespace SHADE
|
|||
|
||||
void SHBatch::Remove(const SHRenderable* renderable)
|
||||
{
|
||||
// Check if we have a SubBatch with the same mesh yet
|
||||
// Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh)
|
||||
Handle<SHMesh> prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh();
|
||||
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
||||
{
|
||||
return batch.Mesh == renderable->GetMesh();
|
||||
});
|
||||
{
|
||||
return batch.Mesh == prevSubBatchMesh;
|
||||
});
|
||||
|
||||
// Attempt to remove if it exists
|
||||
if (subBatch == subBatches.end())
|
||||
|
@ -88,9 +89,7 @@ namespace SHADE
|
|||
|
||||
// Check if other renderables in subBatches contain the same material instance
|
||||
bool matUnused = true;
|
||||
|
||||
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
|
||||
|
||||
for (const auto& sb : subBatches)
|
||||
{
|
||||
// Check material usage
|
||||
|
|
|
@ -37,9 +37,9 @@ namespace SHADE
|
|||
|
||||
// Check if we have a batch with the same pipeline first
|
||||
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
|
||||
{
|
||||
return batch.GetPipeline() == PIPELINE;
|
||||
});
|
||||
{
|
||||
return batch.GetPipeline() == PIPELINE;
|
||||
});
|
||||
|
||||
|
||||
// Create one if not found
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace SHADE
|
|||
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
||||
{
|
||||
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eVertex,
|
||||
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
|
||||
.DescriptorCount = 1,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,326 @@
|
|||
/************************************************************************************//*!
|
||||
\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 the system
|
||||
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
|
||||
|
||||
// Get current frame index
|
||||
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
|
||||
|
||||
/* Non-Persistent Buffer */
|
||||
// Update the buffer
|
||||
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();
|
||||
|
||||
/* Persistent Buffer */
|
||||
// Check if there are changes
|
||||
if (system->persistentBuffersCleared[FRAME_IDX]
|
||||
||
|
||||
system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size())
|
||||
{
|
||||
// Update Buffer
|
||||
system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size();
|
||||
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->persistentPoints.size();
|
||||
if (DATA_SIZE > 0)
|
||||
{
|
||||
system->persistentVertexBuffers[FRAME_IDX]->WriteToMemory(system->persistentPoints.data(), DATA_SIZE, 0, 0);
|
||||
}
|
||||
|
||||
// Reset Flag
|
||||
system->persistentBuffersCleared[FRAME_IDX] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* 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)
|
||||
{
|
||||
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
||||
cmdBuffer->SetLineWidth(LineWidth);
|
||||
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
||||
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
|
||||
}
|
||||
});
|
||||
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
|
||||
subPassWithDepth->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 (numPersistentPoints[FRAME_IDX] > 0)
|
||||
{
|
||||
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
|
||||
cmdBuffer->SetLineWidth(LineWidth);
|
||||
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
|
||||
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Reset trackers
|
||||
std::fill_n(numPoints.begin(), numPoints.size(), 0);
|
||||
std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0);
|
||||
for (bool& cleared : persistentBuffersCleared)
|
||||
cleared = true;
|
||||
|
||||
// Allocate buffers
|
||||
// - Non-Persistent Draws
|
||||
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
|
||||
);
|
||||
}
|
||||
// - Persistent Draws
|
||||
for (Handle<SHVkBuffer>& bufHandle : persistentVertexBuffers)
|
||||
{
|
||||
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();
|
||||
}
|
||||
for (auto vertexBuffer : persistentVertexBuffers)
|
||||
{
|
||||
if (vertexBuffer)
|
||||
vertexBuffer.Free();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Draw Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||
{
|
||||
drawLine(points, color, startPt, endPt);
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||
{
|
||||
drawPoly(points, color, { pt1, pt2, pt3 });
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||
{
|
||||
drawPoly(points, color, { pt1, pt2, pt3, pt4 });
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||
{
|
||||
drawPoly(points, color, pointList.begin(), pointList.end());
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||
{
|
||||
drawCube(points, color, pos, size);
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||
{
|
||||
drawSphere(points, color, pos, radius);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Persistent Draw Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||
{
|
||||
drawLine(persistentPoints, color, startPt, endPt);
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||
{
|
||||
drawPoly(persistentPoints, color, { pt1, pt2, pt3 });
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||
{
|
||||
drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 });
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||
{
|
||||
drawPoly(persistentPoints, color, pointList.begin(), pointList.end());
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||
{
|
||||
drawCube(persistentPoints, color, pos, size);
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||
{
|
||||
drawSphere(persistentPoints, color, pos, radius);
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::ClearPersistentDraws()
|
||||
{
|
||||
persistentPoints.clear();
|
||||
for (bool& cleared : persistentBuffersCleared)
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||
{
|
||||
if (storage.size() > MAX_POINTS)
|
||||
{
|
||||
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||
return;
|
||||
}
|
||||
|
||||
storage.emplace_back(PointVertex{ startPt, color });
|
||||
storage.emplace_back(PointVertex{ endPt, color });
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||
{
|
||||
drawLineSet(storage, color, pointList.begin(), pointList.end());
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||
{
|
||||
drawPoly(storage, color, pointList.begin(), pointList.end());
|
||||
}
|
||||
|
||||
void SHDebugDrawSystem::drawCube(std::vector<PointVertex>& storage, 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;
|
||||
|
||||
drawLineSet
|
||||
(
|
||||
storage,
|
||||
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(std::vector<PointVertex>& storage, 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]);
|
||||
}
|
||||
}
|
||||
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
/************************************************************************************//*!
|
||||
\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);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Persistent Draw Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Renders a line between two points in world space that will persist until
|
||||
/// ClearPersistentDraws() is called. These lines are depth tested.
|
||||
/// </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 DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||
/// <summary>
|
||||
/// Renders a triangle indicated by three points in world space that will persist
|
||||
/// until ClearPersistentDraws() is called. These lines are depth tested.
|
||||
/// </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 DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
|
||||
/// <summary>
|
||||
/// Renders a quadrilateral indicated by four points in world space that will persist
|
||||
/// until ClearPersistentDraws() is called. These lines are depth tested.
|
||||
/// </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 DrawPersistentQuad(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 that
|
||||
/// will persist until ClearPersistentDraws() is called. These lines are depth
|
||||
/// tested.
|
||||
/// </summary>
|
||||
/// <param name="color">Colour of the polygon.</param>
|
||||
/// <param name="pointList">List of points for the polygon.</param>
|
||||
void DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||
/// <summary>
|
||||
/// Renders a polygon indicated by the specified set of points in world space that
|
||||
/// will persist until ClearPersistentDraws() is called. These lines are depth
|
||||
/// tested.
|
||||
/// </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 DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||
/// <summary>
|
||||
/// Renders a wireframe cube centered around the position specified in world space
|
||||
/// that will persist until ClearPersistentDraws() is called. These lines are depth
|
||||
/// tested.
|
||||
/// </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 DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||
/// <summary>
|
||||
/// Renders a wireframe sphere centered around the position specified in world space
|
||||
/// that will persist until ClearPersistentDraws() is called. These lines are depth
|
||||
/// tested.
|
||||
/// </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 DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||
/// <summary>
|
||||
/// Clears any persistent drawn debug primitives.
|
||||
/// </summary>
|
||||
void ClearPersistentDraws();
|
||||
|
||||
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>;
|
||||
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constants */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static constexpr uint32_t MAX_POINTS = 100'000;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
// CPU Buffers
|
||||
std::vector<PointVertex> points;
|
||||
std::vector<PointVertex> persistentPoints;
|
||||
// GPU Buffers
|
||||
TripleBuffer vertexBuffers;
|
||||
TripleUInt numPoints;
|
||||
TripleBuffer persistentVertexBuffers;
|
||||
TripleUInt numPersistentPoints;
|
||||
TripleBool persistentBuffersCleared;
|
||||
// Cached Points for polygon drawing
|
||||
std::vector<SHVec3> spherePoints;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Draw Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||
template<typename IterType>
|
||||
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||
template<typename IterType>
|
||||
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||
void drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||
void drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius);
|
||||
};
|
||||
}
|
||||
|
||||
#include "SHDebugDrawSystem.hpp"
|
|
@ -0,0 +1,89 @@
|
|||
/************************************************************************************//*!
|
||||
\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)
|
||||
{
|
||||
drawPoly(points, color, pointListBegin, pointListEnd);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Draw Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
template<typename IterType>
|
||||
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, 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 (storage.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)
|
||||
{
|
||||
storage.emplace_back(PointVertex{ *pointIter, color });
|
||||
}
|
||||
}
|
||||
template<typename IterType>
|
||||
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, 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 (storage.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;
|
||||
}
|
||||
|
||||
// Trace the polygon
|
||||
for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter)
|
||||
{
|
||||
storage.emplace_back(PointVertex{ *(pointIter - 1), color });
|
||||
storage.emplace_back(PointVertex{ *pointIter , color });
|
||||
}
|
||||
|
||||
// Close the line loop
|
||||
storage.emplace_back(PointVertex{ *(pointListEnd - 1), color });
|
||||
storage.emplace_back(PointVertex{ *pointListBegin , color });
|
||||
}
|
||||
}
|
|
@ -70,7 +70,17 @@ namespace SHADE
|
|||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
DescriptorSet Index for render graph node compute resources. For data
|
||||
that we wish to pass to compute shaders in the render graph, this is
|
||||
the set to use. Unlike the sets from 1 to 3, this set index does not have
|
||||
hard coded bindings and is NOT part of the layouts included in the global
|
||||
data.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
|
||||
|
||||
};
|
||||
|
||||
|
@ -119,6 +129,7 @@ namespace SHADE
|
|||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
|
||||
|
||||
};
|
||||
|
||||
struct VertexBufferBindings
|
||||
|
|
|
@ -39,6 +39,8 @@ 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"
|
||||
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -106,15 +108,16 @@ 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);
|
||||
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
|
||||
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||
|
@ -153,55 +156,121 @@ namespace SHADE
|
|||
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SCENE RENDER GRAPH RESOURCES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
// Initialize world render graph
|
||||
worldRenderGraph->Init(device, swapchain);
|
||||
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||
worldRenderGraph->AddResource("Albedo", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("SSAO", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||
worldRenderGraph->AddResource("SSAO Blur", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MAIN NODE */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer",
|
||||
{
|
||||
"Position",
|
||||
"Entity ID",
|
||||
"Light Layer Indices",
|
||||
"Normals",
|
||||
//"Tangents",
|
||||
"Albedo",
|
||||
"Depth Buffer",
|
||||
"Scene"
|
||||
"Scene",
|
||||
"SSAO",
|
||||
"SSAO Blur"
|
||||
},
|
||||
{}); // no predecessors
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* G-BUFFER SUBPASS INIT */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
|
||||
gBufferSubpass->AddColorOutput("Position");
|
||||
gBufferSubpass->AddColorOutput("Entity ID");
|
||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||
gBufferSubpass->AddColorOutput("Normals");
|
||||
//gBufferSubpass->AddColorOutput("Tangents");
|
||||
gBufferSubpass->AddColorOutput("Albedo");
|
||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||
|
||||
// deferred composite
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SSAO PASS AND DATA INIT */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
ssaoStorage = resourceManager.Create<SHSSAO>();
|
||||
|
||||
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
ssaoTransferCmdBuffer->BeginRecording();
|
||||
|
||||
ssaoStorage->Init(device, ssaoTransferCmdBuffer);
|
||||
|
||||
ssaoTransferCmdBuffer->EndRecording();
|
||||
graphicsQueue->SubmitCommandBuffer({ ssaoTransferCmdBuffer });
|
||||
// Set up Debug Draw Passes
|
||||
// - Depth Tested
|
||||
auto debugDrawNodeDepth = worldRenderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer"});
|
||||
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth");
|
||||
debugDrawDepthSubpass->AddColorOutput("Scene");
|
||||
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
||||
// - No Depth Test
|
||||
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
|
||||
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
|
||||
debugDrawSubpass->AddColorOutput("Scene");
|
||||
|
||||
graphicsQueue->WaitIdle();
|
||||
|
||||
ssaoStorage->PrepareRotationVectorsVkData(device);
|
||||
|
||||
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
|
||||
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
||||
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
||||
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
||||
|
||||
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||
|
||||
|
||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
|
||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
||||
|
||||
// Dummy Node
|
||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
||||
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
|
||||
dummySubpass->AddInput("Scene");
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* GENERATE RENDER GRAPH */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
// Generate world render graph
|
||||
worldRenderGraph->Generate();
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* BIND RENDER GRAPH TO RENDERER */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
// Add world renderer to default viewport
|
||||
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||
worldRenderer->SetCamera(worldCamera);
|
||||
|
||||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||
|
||||
// Create default materials
|
||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||
|
||||
// Create debug draw pipeline
|
||||
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||
|
@ -240,6 +309,7 @@ namespace SHADE
|
|||
|
||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||
lightingSubSystem->Init(device, descPool);
|
||||
|
||||
}
|
||||
|
||||
#ifdef SHEDITOR
|
||||
|
@ -345,6 +415,17 @@ namespace SHADE
|
|||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
|
||||
|
||||
{
|
||||
#ifdef SHEDITOR
|
||||
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
||||
if (editorSystem->editorState != SHEditor::State::PLAY)
|
||||
lightingSubSystem->Run(cameraSystem->GetEditorCamera()->GetViewMatrix(), frameIndex);
|
||||
else
|
||||
lightingSubSystem->Run(worldRenderer->GetCameraDirector()->GetViewMatrix(), frameIndex);
|
||||
#else
|
||||
lightingSubSystem->Run(worldRenderer->GetCameraDirector()->GetViewMatrix(), frameIndex);
|
||||
#endif
|
||||
}
|
||||
|
||||
// For every viewport
|
||||
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
||||
|
@ -381,8 +462,7 @@ namespace SHADE
|
|||
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
||||
}
|
||||
|
||||
// Bind the descriptor set for lights
|
||||
lightingSubSystem->Run(currentCmdBuffer, frameIndex);
|
||||
lightingSubSystem->BindDescSet(currentCmdBuffer, frameIndex);
|
||||
|
||||
// Bind textures
|
||||
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
|
||||
|
@ -406,7 +486,7 @@ namespace SHADE
|
|||
{
|
||||
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
||||
if (editorSystem->editorState != SHEditor::State::PLAY)
|
||||
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix()));
|
||||
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix());
|
||||
else
|
||||
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||
}
|
||||
|
@ -621,10 +701,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 +733,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 = {};
|
||||
}
|
||||
|
||||
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
|
||||
|
@ -697,6 +785,7 @@ namespace SHADE
|
|||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||
{
|
||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -714,8 +803,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();
|
||||
|
@ -804,5 +898,57 @@ namespace SHADE
|
|||
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
||||
}
|
||||
|
||||
Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass)
|
||||
{
|
||||
auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout>
|
||||
(
|
||||
device, SHPipelineLayoutParams
|
||||
{
|
||||
.shaderModules = { debugVertShader, debugFragShader },
|
||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||
}
|
||||
);
|
||||
auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass);
|
||||
pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
|
||||
{
|
||||
.polygonMode = vk::PolygonMode::eLine,
|
||||
.cull_mode = vk::CullModeFlagBits::eNone
|
||||
});
|
||||
pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
|
||||
{
|
||||
.topology = vk::PrimitiveTopology::eLineList
|
||||
});
|
||||
|
||||
SHVertexInputState debugDrawVertexInputState;
|
||||
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
|
||||
pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
|
||||
SHColorBlendState colorBlendState{};
|
||||
colorBlendState.logic_op_enable = VK_FALSE;
|
||||
colorBlendState.logic_op = vk::LogicOp::eCopy;
|
||||
|
||||
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
||||
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||
|
||||
for (auto& att : subpassColorReferences)
|
||||
{
|
||||
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||
{
|
||||
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->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,
|
||||
});
|
||||
}
|
||||
|
||||
pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
||||
pipeline->ConstructPipeline();
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
#pragma endregion MISC
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "../Textures/SHVkSamplerCache.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
|
||||
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
||||
#include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -303,9 +304,9 @@ 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; }
|
||||
Handle<SHVkPipeline> GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; }
|
||||
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getters */
|
||||
|
@ -331,6 +332,7 @@ namespace SHADE
|
|||
Handle<SHVkDescriptorPool> descPool;
|
||||
Handle<SHVkCommandPool> graphicsCmdPool;
|
||||
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
||||
Handle<SHVkCommandBuffer> ssaoTransferCmdBuffer;
|
||||
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
||||
SHRenderContext renderContext;
|
||||
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
|
||||
|
@ -354,10 +356,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;
|
||||
|
||||
|
@ -368,10 +366,17 @@ namespace SHADE
|
|||
// Built-In Shaders
|
||||
Handle<SHVkShaderModule> defaultVertShader;
|
||||
Handle<SHVkShaderModule> defaultFragShader;
|
||||
Handle<SHVkShaderModule> debugVertShader;
|
||||
Handle<SHVkShaderModule> debugFragShader;
|
||||
Handle<SHVkShaderModule> deferredCompositeShader;
|
||||
Handle<SHVkShaderModule> ssaoShader;
|
||||
Handle<SHVkShaderModule> ssaoBlurShader;
|
||||
|
||||
|
||||
// Built-In Materials
|
||||
Handle<SHMaterial> defaultMaterial;
|
||||
Handle<SHVkPipeline> debugDrawPipeline;
|
||||
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
||||
|
||||
Handle<SHRenderGraph> worldRenderGraph;
|
||||
|
||||
|
@ -379,10 +384,15 @@ namespace SHADE
|
|||
Handle<SHMousePickSystem> mousePickSystem;
|
||||
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
|
||||
Handle<SHLightingSubSystem> lightingSubSystem;
|
||||
Handle<SHSSAO> ssaoStorage;
|
||||
|
||||
uint32_t resizeWidth;
|
||||
uint32_t resizeHeight;
|
||||
bool restoredFromMinimize = false;
|
||||
uint32_t resizeWidth = 1;
|
||||
uint32_t resizeHeight = 1;
|
||||
bool restoredFromMinimize = false;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass);
|
||||
};
|
||||
}
|
|
@ -83,13 +83,14 @@ namespace SHADE
|
|||
{
|
||||
if (camera && cameraDirector)
|
||||
{
|
||||
UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
|
||||
//UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
|
||||
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix());
|
||||
}
|
||||
}
|
||||
|
||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept
|
||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
|
||||
{
|
||||
SetViewProjectionMatrix(exteriorMatrix);
|
||||
SetViewProjectionMatrix(viewMatrix, projMatrix);
|
||||
|
||||
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||
|
@ -97,16 +98,19 @@ namespace SHADE
|
|||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||
|
||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||
}
|
||||
|
||||
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& vpMatrix) noexcept
|
||||
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
|
||||
{
|
||||
//cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix();
|
||||
cpuCameraData.viewProjectionMatrix = vpMatrix;
|
||||
cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
|
||||
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
|
||||
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
|
||||
}
|
||||
|
||||
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
|
||||
|
@ -119,4 +123,9 @@ namespace SHADE
|
|||
return commandBuffers[frameIndex];
|
||||
}
|
||||
|
||||
Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept
|
||||
{
|
||||
return cameraDirector;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ namespace SHADE
|
|||
{
|
||||
SHVec4 cameraPosition;
|
||||
SHMatrix viewProjectionMatrix;
|
||||
SHMatrix viewMatrix;
|
||||
SHMatrix projectionMatrix;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -79,15 +81,16 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept;
|
||||
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
|
||||
void UpdateCameraDataToBuffer (void) noexcept;
|
||||
void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept;
|
||||
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Setters and Getters */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
||||
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
||||
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
|
||||
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -9,9 +9,9 @@ namespace SHADE
|
|||
{
|
||||
lightData.Reset();
|
||||
SetType(SH_LIGHT_TYPE::DIRECTIONAL);
|
||||
indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||
isActive = true;
|
||||
Unbind();
|
||||
//Unbind();
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,28 +23,28 @@ namespace SHADE
|
|||
void SHLightComponent::SetPosition(SHVec3 const& position) noexcept
|
||||
{
|
||||
lightData.position = position;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept
|
||||
{
|
||||
lightData.type = type;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetDirection(SHVec3 const& direction) noexcept
|
||||
{
|
||||
lightData.direction = direction;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetColor(SHVec4 const& color) noexcept
|
||||
{
|
||||
lightData.color = color;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::ModifyCullingMask(uint8_t layerIndex, bool value) noexcept
|
||||
|
@ -54,7 +54,7 @@ namespace SHADE
|
|||
else
|
||||
lightData.cullingMask &= ~(1u << layerIndex);
|
||||
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::SetCullingMask(uint32_t const& value) noexcept
|
||||
|
@ -65,43 +65,43 @@ namespace SHADE
|
|||
void SHLightComponent::SetAllLayers(void) noexcept
|
||||
{
|
||||
lightData.cullingMask = std::numeric_limits<uint32_t>::max();
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::ClearAllLayers(void) noexcept
|
||||
{
|
||||
lightData.cullingMask = 0;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::MakeDirty(void) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
//void SHLightComponent::MakeDirty(void) noexcept
|
||||
//{
|
||||
// dirty = true;
|
||||
//}
|
||||
|
||||
void SHLightComponent::ClearDirtyFlag(void) noexcept
|
||||
{
|
||||
dirty = false;
|
||||
}
|
||||
//void SHLightComponent::ClearDirtyFlag(void) noexcept
|
||||
//{
|
||||
// dirty = false;
|
||||
//}
|
||||
|
||||
void SHLightComponent::Unbind(void) noexcept
|
||||
{
|
||||
bound = false;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
|
||||
{
|
||||
bound = true;
|
||||
indexInBuffer = inIndexInBuffer;
|
||||
}
|
||||
// void SHLightComponent::Unbind(void) noexcept
|
||||
// {
|
||||
// bound = false;
|
||||
// MakeDirty();
|
||||
// }
|
||||
//
|
||||
// void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
|
||||
//{
|
||||
// bound = true;
|
||||
// indexInBuffer = inIndexInBuffer;
|
||||
// }
|
||||
|
||||
|
||||
void SHLightComponent::SetStrength(float value) noexcept
|
||||
{
|
||||
lightData.strength = value;
|
||||
MakeDirty();
|
||||
//MakeDirty();
|
||||
}
|
||||
|
||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||
|
@ -135,20 +135,20 @@ namespace SHADE
|
|||
}
|
||||
|
||||
|
||||
bool SHLightComponent::IsDirty(void) const noexcept
|
||||
{
|
||||
return dirty;
|
||||
}
|
||||
//bool SHLightComponent::IsDirty(void) const noexcept
|
||||
//{
|
||||
// return dirty;
|
||||
//}
|
||||
|
||||
bool SHLightComponent::GetBound(void) const noexcept
|
||||
{
|
||||
return bound;
|
||||
}
|
||||
//bool SHLightComponent::GetBound(void) const noexcept
|
||||
//{
|
||||
// return bound;
|
||||
//}
|
||||
|
||||
uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
|
||||
{
|
||||
return indexInBuffer;
|
||||
}
|
||||
//uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
|
||||
//{
|
||||
// return indexInBuffer;
|
||||
//}
|
||||
|
||||
float SHLightComponent::GetStrength(void) const noexcept
|
||||
{
|
||||
|
|
|
@ -17,13 +17,13 @@ namespace SHADE
|
|||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||
uint32_t indexInBuffer;
|
||||
//uint32_t indexInBuffer;
|
||||
|
||||
//! If the light component changed some value we mark this true.
|
||||
bool dirty;
|
||||
////! If the light component changed some value we mark this true.
|
||||
//bool dirty;
|
||||
|
||||
//! If the light's data is already in the buffers, this will be set to true.
|
||||
bool bound;
|
||||
////! If the light's data is already in the buffers, this will be set to true.
|
||||
//bool bound;
|
||||
|
||||
|
||||
public:
|
||||
|
@ -44,10 +44,10 @@ namespace SHADE
|
|||
void SetCullingMask (uint32_t const& value) noexcept;
|
||||
void SetAllLayers (void) noexcept; // serialized
|
||||
void ClearAllLayers (void) noexcept; // serialized
|
||||
void MakeDirty (void) noexcept;
|
||||
void ClearDirtyFlag (void) noexcept;
|
||||
void Unbind (void) noexcept;
|
||||
void SetBound (uint32_t inIndexInBuffer) noexcept;
|
||||
//void MakeDirty (void) noexcept;
|
||||
//void ClearDirtyFlag (void) noexcept;
|
||||
//void Unbind (void) noexcept;
|
||||
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
||||
void SetStrength (float value) noexcept; // serialized
|
||||
|
||||
|
||||
|
@ -57,8 +57,8 @@ namespace SHADE
|
|||
SHVec3 const& GetDirection (void) const noexcept; // serialized
|
||||
SHVec4 const& GetColor (void) const noexcept; // serialized
|
||||
uint32_t const& GetCullingMask (void) const noexcept; // serialized
|
||||
bool IsDirty (void) const noexcept;
|
||||
bool GetBound (void) const noexcept;
|
||||
//bool IsDirty (void) const noexcept;
|
||||
//bool GetBound (void) const noexcept;
|
||||
uint32_t GetIndexInBuffer (void) const noexcept;
|
||||
float GetStrength (void) const noexcept;
|
||||
RTTR_ENABLE()
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "SHLightComponent.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "SHLightComponent.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -31,7 +33,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::WriteLightToAddress(void* address, SHLightComponent* lightComp) noexcept
|
||||
void SHLightingSubSystem::PerTypeData::WriteLightToAddress(void* address, SHMatrix const& viewMat, SHLightComponent* lightComp) noexcept
|
||||
{
|
||||
auto const& lightData = lightComp->GetLightData();
|
||||
switch (lightData.type)
|
||||
|
@ -40,8 +42,12 @@ namespace SHADE
|
|||
{
|
||||
SHDirectionalLightData* lightPtr = reinterpret_cast<SHDirectionalLightData*>(address);
|
||||
|
||||
// #NoteToSelf: NEED TO TRANSPOSE HERE BECAUSE MULTIPLICATION IS ROW MAJOR.
|
||||
SHVec4 transformedDir = SHMatrix::Transpose(viewMat) * SHVec4(lightData.direction[0], lightData.direction[1], lightData.direction[2], 0.0f);
|
||||
|
||||
lightPtr->cullingMask = lightData.cullingMask;
|
||||
lightPtr->direction = lightData.direction;
|
||||
lightPtr->direction = SHVec3 (transformedDir.x, transformedDir.y, transformedDir.z);
|
||||
//lightPtr->direction = lightData.direction;
|
||||
lightPtr->diffuseColor = lightData.color;
|
||||
lightPtr->active = lightComp->isActive;
|
||||
break;
|
||||
|
@ -240,7 +246,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::AddLight(Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept
|
||||
void SHLightingSubSystem::PerTypeData::AddLight(Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, SHMatrix const& viewMat, bool& expanded) noexcept
|
||||
{
|
||||
if (unboundLight)
|
||||
{
|
||||
|
@ -259,10 +265,10 @@ namespace SHADE
|
|||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * numLights);
|
||||
|
||||
// Write the light data to address
|
||||
WriteLightToAddress(writeLocation, unboundLight);
|
||||
WriteLightToAddress(writeLocation, viewMat, unboundLight);
|
||||
|
||||
// Set the light component to be bound to that location
|
||||
unboundLight->SetBound(numLights);
|
||||
//unboundLight->SetBound(numLights);
|
||||
|
||||
// Increase light count
|
||||
++numLights;
|
||||
|
@ -280,11 +286,11 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
|
||||
{
|
||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
|
||||
WriteLightToAddress(writeLocation, lightComp);
|
||||
}
|
||||
//void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
|
||||
//{
|
||||
// void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
|
||||
// WriteLightToAddress(writeLocation, lightComp);
|
||||
//}
|
||||
|
||||
void SHLightingSubSystem::PerTypeData::WriteToGPU(uint32_t frameIndex) noexcept
|
||||
{
|
||||
|
@ -406,7 +412,7 @@ namespace SHADE
|
|||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||
}
|
||||
|
||||
numLightComponents = 0;
|
||||
//numLightComponents = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -419,21 +425,25 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||
void SHLightingSubSystem::Run(SHMatrix const& viewMat, uint32_t frameIndex) noexcept
|
||||
{
|
||||
static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES);
|
||||
|
||||
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||
bool expanded = false;
|
||||
bool rewrite = false;
|
||||
|
||||
if (numLightComponents > lightComps.size())
|
||||
{
|
||||
rewrite = true;
|
||||
ResetNumLights();
|
||||
}
|
||||
// First we reset the number of lights. We do this every frame so that we can count how many lights we have
|
||||
ResetNumLights();
|
||||
|
||||
numLightComponents = lightComps.size();
|
||||
//bool rewrite = false;
|
||||
|
||||
//if (numLightComponents > lightComps.size())
|
||||
//{
|
||||
// rewrite = true;
|
||||
// ResetNumLights();
|
||||
//}
|
||||
|
||||
//numLightComponents = lightComps.size();
|
||||
|
||||
for (auto& light : lightComps)
|
||||
{
|
||||
|
@ -441,22 +451,22 @@ namespace SHADE
|
|||
|
||||
// First we want to make sure the light is already bound to the system. if it
|
||||
// isn't, we write it to the correct buffer.
|
||||
if (!light.GetBound() || rewrite)
|
||||
//if (!light.GetBound() || rewrite)
|
||||
{
|
||||
perTypeData[enumValue].AddLight(logicalDevice, &light, expanded);
|
||||
perTypeData[enumValue].AddLight(logicalDevice, &light, viewMat, expanded);
|
||||
|
||||
//// add to light count
|
||||
// add to light count
|
||||
//++lightCountsData[enumValue];
|
||||
}
|
||||
|
||||
// if there was modification to the light data
|
||||
if (light.IsDirty())
|
||||
//if (light.IsDirty())
|
||||
{
|
||||
// Write the data to the CPU
|
||||
perTypeData[enumValue].ModifyLight(&light);
|
||||
//perTypeData[enumValue].ModifyLight(&light);
|
||||
|
||||
// Light is now updated in the container
|
||||
light.ClearDirtyFlag();
|
||||
//light.ClearDirtyFlag();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,8 +498,6 @@ namespace SHADE
|
|||
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
||||
ComputeDynamicOffsets();
|
||||
|
||||
// Bind descriptor set (We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
|
||||
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, {dynamicOffsets[frameIndex]});
|
||||
|
||||
}
|
||||
|
||||
|
@ -505,4 +513,12 @@ namespace SHADE
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
void SHLightingSubSystem::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||
{
|
||||
//Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
|
||||
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { dynamicOffsets[frameIndex] });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,15 +95,15 @@ namespace SHADE
|
|||
//! to the GPU that stores NUM_FRAME_BUFFERS copies.
|
||||
std::unique_ptr<uint8_t[]> intermediateData;
|
||||
|
||||
void WriteLightToAddress (void* address, SHLightComponent* lightComp) noexcept;
|
||||
void WriteLightToAddress (void* address, SHMatrix const& viewMat, SHLightComponent* lightComp) noexcept;
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void InitializeData (Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept;
|
||||
void Expand (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept;
|
||||
void ModifyLight (SHLightComponent* lightComp) noexcept;
|
||||
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, SHMatrix const& viewMat, bool& expanded) noexcept;
|
||||
//void ModifyLight (SHLightComponent* lightComp) noexcept;
|
||||
void WriteToGPU (uint32_t frameIndex) noexcept;
|
||||
void ResetNumLights (void) noexcept;
|
||||
|
||||
|
@ -144,7 +144,7 @@ namespace SHADE
|
|||
//! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense
|
||||
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
|
||||
//! don't do anything.
|
||||
uint32_t numLightComponents;
|
||||
//uint32_t numLightComponents;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
|
@ -159,8 +159,10 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void Run (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
||||
void Exit (void) noexcept;
|
||||
|
||||
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Aug 30, 2022
|
||||
\brief Contains definitions for all of the functions of the classes that deal
|
||||
\brief Contains definitions for all of the functions of the classes that deal
|
||||
with storage and management of vertex and index buffers of meshes.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
|
@ -18,50 +18,59 @@ 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;
|
||||
|
||||
mesh.VertexPositions =
|
||||
mesh.VertexPositions =
|
||||
{
|
||||
// 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),
|
||||
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),
|
||||
SHVec3(0.5f, 0.5f, -0.5f),
|
||||
SHVec3(0.5f, -0.5f, -0.5f),
|
||||
|
||||
// top
|
||||
// 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),
|
||||
SHVec3(0.5f, -0.5f, 0.5f),
|
||||
SHVec3(-0.5f, -0.5f, 0.5f),
|
||||
|
||||
// right
|
||||
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),
|
||||
SHVec3(0.5f, 0.5f, 0.5f),
|
||||
SHVec3(0.5f, -0.5f, 0.5f),
|
||||
|
||||
// left
|
||||
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),
|
||||
SHVec3(-0.5f, 0.5f, 0.5f),
|
||||
SHVec3(-0.5f, 0.5f, -0.5f)
|
||||
};
|
||||
|
||||
mesh.VertexTexCoords =
|
||||
mesh.VertexTexCoords =
|
||||
{
|
||||
SHVec2(0.0f, 1.0f),
|
||||
SHVec2(1.0f, 1.0f),
|
||||
|
@ -99,7 +108,7 @@ namespace SHADE
|
|||
SHVec2(0.0f, 0.0f)
|
||||
};
|
||||
|
||||
mesh.VertexTangents =
|
||||
mesh.VertexTangents =
|
||||
{
|
||||
// front
|
||||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
|
@ -118,7 +127,7 @@ namespace SHADE
|
|||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
|
||||
|
||||
// bottom
|
||||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
SHVec3(1.0f, 0.0f, 0.0f),
|
||||
|
@ -193,10 +202,93 @@ 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()),
|
||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||
meshData.VertexPositions.data(),
|
||||
meshData.VertexTexCoords.data(),
|
||||
meshData.VertexTangents.data(),
|
||||
|
@ -206,17 +298,16 @@ 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()),
|
||||
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||
meshData.VertexPositions.data(),
|
||||
meshData.VertexTexCoords.data(),
|
||||
meshData.VertexTangents.data(),
|
||||
meshData.VertexNormals.data(),
|
||||
static_cast<uint32_t>(meshData.Indices.size()),
|
||||
static_cast<uint32_t>(meshData.Indices.size()),
|
||||
meshData.Indices.data()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 18, 2022
|
||||
\brief Contains the static class definition of SHPrimitiveGenerator.
|
||||
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
@ -29,12 +29,12 @@ namespace SHADE
|
|||
/*************************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Static class that contains functions for generating 3D primitives.
|
||||
Static class that contains functions for generating 3D primitives.
|
||||
*/
|
||||
/*************************************************************************************/
|
||||
class SH_API SHPrimitiveGenerator
|
||||
{
|
||||
public:
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -42,7 +42,7 @@ namespace SHADE
|
|||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Primitive Generation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -52,20 +52,20 @@ namespace SHADE
|
|||
SHMeshData object containing vertex data for the cube.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData Cube() noexcept;
|
||||
[[nodiscard]] static SHMeshData Cube() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
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.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static Handle<SHMesh> Cube(SHMeshLibrary& meshLibrary) noexcept;
|
||||
[[nodiscard]] static Handle<SHMesh> Cube(SHMeshLibrary& meshLibrary) noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -78,12 +78,55 @@ namespace SHADE
|
|||
SHMesh object that points to the generated cube mesh in the SHGraphicsSystem.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
|
||||
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Produces a sphere and stores the data in a SHMeshData object.
|
||||
|
||||
private:
|
||||
\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;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHSSAO.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/Images/SHVkImage.h"
|
||||
#include "Graphics/Images/SHVkSampler.h"
|
||||
#include <random>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHSSAO::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||
{
|
||||
// Initialize a distribution to get values from 0 to 1
|
||||
std::uniform_real_distribution<float> distrib{0.0f, 1.0f};
|
||||
|
||||
// generator for random number
|
||||
std::default_random_engine generator;
|
||||
|
||||
// generate samples
|
||||
for (uint32_t i = 0; i < NUM_SAMPLES; ++i)
|
||||
{
|
||||
//SHVec3 temp
|
||||
//{
|
||||
// distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
// distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
// distrib(generator), // 0.0f - 1.0f so that sample space is a hemisphere
|
||||
//};
|
||||
|
||||
//temp = SHVec3::Normalise(temp);
|
||||
//temp *= distrib(generator);
|
||||
|
||||
//// This makes sure that most points are closer to fragment's position
|
||||
//float scale = 1.0f / static_cast<float>(NUM_SAMPLES);
|
||||
//scale = std::lerp(0.1f, 1.0f, scale * scale);
|
||||
//temp *= scale;
|
||||
//samples[i] = SHVec4 (temp.x, temp.y, temp.z, 0.0f);
|
||||
|
||||
|
||||
samples[i] = SHVec4
|
||||
{
|
||||
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
distrib(generator), // 0.0f - 1.0f so that sample space is a hemisphere
|
||||
0.0f
|
||||
};
|
||||
|
||||
// This makes sure that most points are closer to fragment's position
|
||||
float scale = 1.0f / static_cast<float>(NUM_SAMPLES);
|
||||
scale = std::lerp(0.1f, 1.0f, scale * scale);
|
||||
samples[i] *= scale;
|
||||
}
|
||||
|
||||
// generate rotation vector
|
||||
for (uint32_t i = 0; i < NUM_ROTATION_VECTORS; ++i)
|
||||
{
|
||||
rotationVectors[i] = SHVec4
|
||||
{
|
||||
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||
0.0f, // we want to rotate about the z axis in tangent space
|
||||
0.0f
|
||||
};
|
||||
}
|
||||
|
||||
SHImageCreateParams imageDetails =
|
||||
{
|
||||
.imageType = vk::ImageType::e2D,
|
||||
.width = NUM_ROTATION_VECTORS_W,
|
||||
.height = NUM_ROTATION_VECTORS_H,
|
||||
.depth = 1,
|
||||
.levels = 1,
|
||||
.arrayLayers = 1,
|
||||
.imageFormat = vk::Format::eR32G32B32A32Sfloat,
|
||||
.usageFlags = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||
.createFlags = {}
|
||||
};
|
||||
|
||||
uint32_t mipOffset = 0;
|
||||
rotationVectorsImage = logicalDevice->CreateImage(imageDetails, reinterpret_cast<unsigned char*>( rotationVectors.data()), static_cast<uint32_t>(sizeof(rotationVectors)), {&mipOffset, 1}, VMA_MEMORY_USAGE_AUTO, {});
|
||||
|
||||
vk::ImageMemoryBarrier transferBarrier{};
|
||||
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, transferBarrier);
|
||||
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, {transferBarrier});
|
||||
|
||||
rotationVectorsImage->TransferToDeviceResource(cmdBuffer);
|
||||
|
||||
vk::ImageMemoryBarrier shaderReadBarrier{};
|
||||
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, shaderReadBarrier);
|
||||
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, { shaderReadBarrier });
|
||||
|
||||
|
||||
// Get aligned size for buffer
|
||||
uint32_t alignedSize = logicalDevice->PadSSBOSize(sizeof (samples));
|
||||
|
||||
// Create buffer
|
||||
ssaoDataBuffer = logicalDevice->CreateBuffer(alignedSize, samples.data(), alignedSize, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, {});
|
||||
|
||||
ssaoDataBuffer->TransferToDeviceResource(cmdBuffer);
|
||||
}
|
||||
|
||||
void SHSSAO::PrepareRotationVectorsVkData(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||
{
|
||||
SHImageViewDetails DETAILS =
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1
|
||||
};
|
||||
rotationVectorsImageView = rotationVectorsImage->CreateImageView(logicalDevice, rotationVectorsImage, DETAILS);
|
||||
|
||||
SHVkSamplerParams samplerParams
|
||||
{
|
||||
.minFilter = vk::Filter::eNearest,
|
||||
.magFilter = vk::Filter::eNearest,
|
||||
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||
.mipmapMode = vk::SamplerMipmapMode::eNearest,
|
||||
.maxLod = 1u
|
||||
};
|
||||
|
||||
rotationVectorsSampler = logicalDevice->CreateSampler(samplerParams);
|
||||
}
|
||||
|
||||
SHVkDescriptorSetGroup::viewSamplerLayout SHSSAO::GetViewSamplerLayout(void) const noexcept
|
||||
{
|
||||
return std::make_tuple(rotationVectorsImageView, rotationVectorsSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||
}
|
||||
|
||||
Handle<SHVkBuffer> SHSSAO::GetBuffer(void) const noexcept
|
||||
{
|
||||
return ssaoDataBuffer;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkBuffer;
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkImage;
|
||||
class SHVkImageView;
|
||||
class SHVkSampler;
|
||||
|
||||
class SHSSAO
|
||||
{
|
||||
public:
|
||||
static constexpr uint32_t DESC_SET_BUFFER_BINDING = 0;
|
||||
static constexpr uint32_t DESC_SET_IMAGE_BINDING = 1;
|
||||
|
||||
private:
|
||||
static constexpr uint32_t NUM_SAMPLES = 64;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS_W = 4;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS_H = 4;
|
||||
static constexpr uint32_t NUM_ROTATION_VECTORS = NUM_ROTATION_VECTORS_W * NUM_ROTATION_VECTORS_H;
|
||||
|
||||
private:
|
||||
//! distances from a pixel we want to sample
|
||||
std::array<SHVec4, NUM_SAMPLES> samples;
|
||||
|
||||
//! For passing SSAO samples and kernel to GPU
|
||||
Handle<SHVkBuffer> ssaoDataBuffer;
|
||||
|
||||
std::array<SHVec4, NUM_ROTATION_VECTORS> rotationVectors;
|
||||
|
||||
Handle<SHVkImage> rotationVectorsImage;
|
||||
Handle<SHVkImageView> rotationVectorsImageView;
|
||||
Handle<SHVkSampler> rotationVectorsSampler;
|
||||
|
||||
public:
|
||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||
void PrepareRotationVectorsVkData (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
SHVkDescriptorSetGroup::viewSamplerLayout GetViewSamplerLayout (void) const noexcept;
|
||||
|
||||
Handle<SHVkBuffer> GetBuffer (void) const noexcept;
|
||||
};
|
||||
}
|
|
@ -2,8 +2,10 @@
|
|||
#define SH_PIPELINE_LAYOUT_PARAMS_H
|
||||
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include "Graphics/SHVulkanDefines.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||
#include <unordered_set>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -24,6 +26,12 @@ namespace SHADE
|
|||
//! want to use the layout to initialize the pipeline layout but we do not
|
||||
//! want to use it for allocating descriptor sets.
|
||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
||||
|
||||
//! Since both SPIRV-Reflect and GLSL don't provide ways to describe UBOs or
|
||||
//! SSBOs as dynamic, we need to do it ourselves. This will store bindings
|
||||
//! which we will use when parsing for descriptor set layouts. If a parsed
|
||||
//! binding is in this container, we make that binding's descriptor dynamic.
|
||||
std::unordered_set<BindingAndSetHash> dynamicBufferBindings;
|
||||
};
|
||||
|
||||
struct SHPipelineLayoutParamsDummy
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -165,6 +165,28 @@ namespace SHADE
|
|||
newBinding.Stage = shaderModule->GetShaderStageFlagBits();
|
||||
newBinding.Type = descBindingInfo.ConvertFromReflectDescType(reflectedBinding->descriptor_type);
|
||||
|
||||
// Here we want to check if a binding is supposed to be dynamic. If it is, make it dynamic.
|
||||
if (newBinding.Type == vk::DescriptorType::eUniformBuffer || newBinding.Type == vk::DescriptorType::eStorageBuffer)
|
||||
{
|
||||
for (auto& bsHash : dynamicBufferBindings)
|
||||
{
|
||||
uint32_t set = static_cast<uint32_t>(bsHash >> 32);
|
||||
uint32_t binding = static_cast<uint32_t>(bsHash & 0xFFFFFFFF);
|
||||
if (set == CURRENT_SET && binding == newBinding.BindPoint)
|
||||
{
|
||||
switch (newBinding.Type)
|
||||
{
|
||||
case vk::DescriptorType::eUniformBuffer:
|
||||
newBinding.Type = vk::DescriptorType::eUniformBufferDynamic;
|
||||
break;
|
||||
case vk::DescriptorType::eStorageBuffer:
|
||||
newBinding.Type = vk::DescriptorType::eStorageBufferDynamic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In reality, the check for variable descriptor sets do not exists in spirv-reflect. Fortunately, when a shader
|
||||
// defines a boundless descriptor binding in the shader, the information reflected makes the array dimensions
|
||||
// contain a 1 element of value 1. Knowing that having an array [1] doesn't make sense, we can use this to
|
||||
|
@ -300,6 +322,7 @@ namespace SHADE
|
|||
, vkDescriptorSetLayoutsAllocate{}
|
||||
, descriptorSetLayoutsPipeline{}
|
||||
, vkDescriptorSetLayoutsPipeline{}
|
||||
, dynamicBufferBindings{std::move (pipelineLayoutParams.dynamicBufferBindings)}
|
||||
{
|
||||
for (auto& mod : shaderModules)
|
||||
{
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace SHADE
|
|||
//! Push constant interface
|
||||
SHPushConstantInterface pushConstantInterface;
|
||||
|
||||
//! See SHPipelineLayoutParams for details
|
||||
std::unordered_set<BindingAndSetHash> dynamicBufferBindings;
|
||||
|
||||
//! Push constant ranges
|
||||
std::vector<vk::PushConstantRange> vkPcRanges;
|
||||
|
||||
|
|
|
@ -129,4 +129,9 @@ namespace SHADE
|
|||
return vkQueue;
|
||||
}
|
||||
|
||||
void SHVkQueue::WaitIdle(void) const noexcept
|
||||
{
|
||||
vkQueue.waitIdle();
|
||||
}
|
||||
|
||||
}
|
|
@ -50,6 +50,8 @@ namespace SHADE
|
|||
void SubmitCommandBuffer (std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems = {}, std::initializer_list<Handle<SHVkSemaphore>> waitSems = {}, vk::PipelineStageFlags waitDstStageMask = {}, Handle<SHVkFence> const& fence = {}) noexcept;
|
||||
vk::Result Present (Handle<SHVkSwapchain> const& swapchain, std::initializer_list<Handle<SHVkSemaphore>> waitSems, uint32_t frameIndex) noexcept;
|
||||
vk::Queue GetVkQueue() noexcept;
|
||||
|
||||
void WaitIdle (void) const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ namespace SHADE
|
|||
return subpass;
|
||||
}
|
||||
|
||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||
{
|
||||
// Look for the required resources in the graph
|
||||
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||
|
@ -276,7 +276,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Create the subpass compute with the resources
|
||||
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), nodeComputes.empty());
|
||||
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
||||
nodeComputes.push_back(nodeCompute);
|
||||
|
||||
return nodeCompute;
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace SHADE
|
|||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
||||
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale = 1.0f) noexcept;
|
||||
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
|
||||
void AddDummySubpassIfNeeded (void) noexcept;
|
||||
|
||||
// TODO: RemoveSubpass()
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||
: computePipeline{}
|
||||
, pipelineLayout{}
|
||||
, resources{}
|
||||
|
@ -21,11 +21,13 @@ namespace SHADE
|
|||
, groupSizeY{0}
|
||||
, followingEndRenderpass {followingEndRP}
|
||||
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
||||
, computeResource{}
|
||||
{
|
||||
SHPipelineLayoutParams pipelineLayoutParams
|
||||
{
|
||||
.shaderModules = {computeShaderModule},
|
||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
|
||||
.dynamicBufferBindings = std::move(dynamicBufferBindings),
|
||||
};
|
||||
|
||||
// Create pipeline layout from parameters
|
||||
|
@ -42,16 +44,31 @@ namespace SHADE
|
|||
|
||||
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
|
||||
//global descriptors are already bound in the main system.
|
||||
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
||||
|
||||
//Variable counts for the descriptor sets (all should be 1).
|
||||
std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(layouts.size()) };
|
||||
std::fill(variableCounts.begin(), variableCounts.end(), 0);
|
||||
auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
|
||||
|
||||
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||
{
|
||||
descSetGroups[i] = graphStorage->descriptorPool->Allocate(layouts, variableCounts);
|
||||
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
|
||||
}
|
||||
|
||||
|
||||
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
|
||||
|
||||
if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1)
|
||||
{
|
||||
// create compute resources
|
||||
computeResource = graphStorage->resourceManager->Create<ComputeResource>();
|
||||
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
|
||||
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
||||
|
||||
// Allocate for descriptor offsets
|
||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||
computeResource->dynamicOffsets[i].resize(computeResourceLayout->GetNumDynamicOffsetsRequired());
|
||||
|
||||
// 1st set all start at 0
|
||||
for (auto& index : computeResource->dynamicOffsets[0])
|
||||
index = 0;
|
||||
}
|
||||
|
||||
HandleResize();
|
||||
|
@ -63,7 +80,12 @@ namespace SHADE
|
|||
cmdBuffer->BindPipeline(computePipeline);
|
||||
|
||||
// bind descriptor sets
|
||||
cmdBuffer->BindDescriptorSet(descSetGroups[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
|
||||
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
|
||||
|
||||
if (computeResource)
|
||||
{
|
||||
cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, computeResource->dynamicOffsets[frameIndex]);
|
||||
}
|
||||
|
||||
// dispatch compute
|
||||
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
|
||||
|
@ -89,8 +111,8 @@ namespace SHADE
|
|||
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
|
||||
|
||||
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
|
||||
descSetGroups[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
|
||||
descSetGroups[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||
graphResourceDescSets[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
|
||||
graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -137,4 +159,27 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
||||
{
|
||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||
{
|
||||
auto dynamicOffsets = computeResource->dynamicOffsets[i];
|
||||
for (uint32_t j = 0; j < perFrameSizes.size(); ++j)
|
||||
dynamicOffsets[j] = perFrameSizes[j] * i;
|
||||
}
|
||||
}
|
||||
|
||||
void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||
{
|
||||
computeResource->descSet->ModifyWriteDescBuffer(set, binding, buffers, offset, range);
|
||||
computeResource->descSet->UpdateDescriptorSetBuffer(set, binding);
|
||||
}
|
||||
|
||||
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept
|
||||
{
|
||||
computeResource->descSet->ModifyWriteDescImage(set, binding, viewSamplerLayouts);
|
||||
computeResource->descSet->UpdateDescriptorSetImages(set, binding);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/SHVulkanIncludes.h"
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
|
@ -10,7 +11,6 @@
|
|||
namespace SHADE
|
||||
{
|
||||
class SHVkPipeline;
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkDescriptorPool;
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkPipelineLayout;
|
||||
|
@ -18,9 +18,22 @@ namespace SHADE
|
|||
class SHRenderGraphResource;
|
||||
class SHVkShaderModule;
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkBuffer;
|
||||
|
||||
|
||||
class SHRenderGraphNodeCompute
|
||||
{
|
||||
private:
|
||||
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
||||
struct ComputeResource
|
||||
{
|
||||
//! Descriptor set (initialized by parent class)
|
||||
Handle<SHVkDescriptorSetGroup> descSet {};
|
||||
|
||||
//! Dynamic offsets into these resources (initialized from the outside).
|
||||
std::array<std::vector<uint32_t>, SHGraphicsConstants::NUM_FRAME_BUFFERS> dynamicOffsets {};
|
||||
};
|
||||
|
||||
private:
|
||||
static constexpr uint32_t workGroupSizeX = 16;
|
||||
static constexpr uint32_t workGroupSizeY = 16;
|
||||
|
@ -32,7 +45,10 @@ namespace SHADE
|
|||
Handle<SHVkPipelineLayout> pipelineLayout;
|
||||
|
||||
//! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
||||
std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS> descSetGroups;
|
||||
std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS> graphResourceDescSets;
|
||||
|
||||
//! Compute resources
|
||||
Handle<ComputeResource> computeResource;
|
||||
|
||||
//! vector of resources needed by the subpass compute
|
||||
std::vector<Handle<SHRenderGraphResource>> resources;
|
||||
|
@ -50,11 +66,17 @@ namespace SHADE
|
|||
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
|
||||
|
||||
public:
|
||||
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||
|
||||
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||
void HandleResize (void) noexcept;
|
||||
|
||||
void SetDynamicOffsets (std::span<uint32_t> perFrameSizes) noexcept;
|
||||
|
||||
void ModifyWriteDescBufferComputeResource (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||
void ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||
|
||||
|
||||
friend class SHRenderGraph;
|
||||
friend class SHRenderGraphNode;
|
||||
};
|
||||
|
|
|
@ -142,6 +142,16 @@ namespace SHADE
|
|||
case SpvOp::SpvOpTypeRuntimeArray:
|
||||
recurseForInfo(&member, interfaceHdl, member.offset, biggestAlignment, parentVarName + std::string(member.name) + ".");
|
||||
break;
|
||||
case SpvOp::SpvOpTypeArray:
|
||||
interfaceHdl->AddVariable(parentVarName + std::string (member.name),
|
||||
SHShaderBlockInterface::Variable
|
||||
(
|
||||
parentOffset + member.offset,
|
||||
SHShaderBlockInterface::Variable::Type::OTHER
|
||||
)
|
||||
);
|
||||
biggestAlignment = std::max(biggestAlignment, member.size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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,35 @@ namespace SHADE
|
|||
}
|
||||
{}
|
||||
|
||||
SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept
|
||||
: SHVec4 { colour.x, colour.y, colour.z, 1.0f }
|
||||
SHColour::SHColour(uint32_t rgba) noexcept
|
||||
: XMFLOAT4 { 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
{
|
||||
const SHColour32 TMP { ._32bitValue = rgba };
|
||||
|
||||
x = static_cast<float>(TMP._8bitValues[0]) / 255.0f;
|
||||
y = static_cast<float>(TMP._8bitValues[1]) / 255.0f;
|
||||
z = static_cast<float>(TMP._8bitValues[2]) / 255.0f;
|
||||
w = static_cast<float>(TMP._8bitValues[3]) / 255.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 +159,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 +249,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 */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -19,12 +19,6 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SHColour;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -40,7 +34,13 @@ namespace SHADE
|
|||
float v = 0.0f;
|
||||
};
|
||||
|
||||
class SH_API SHColour : private SHVec4
|
||||
union SH_API SHColour32
|
||||
{
|
||||
uint32_t _32bitValue;
|
||||
uint8_t _8bitValues[4];
|
||||
};
|
||||
|
||||
class SH_API SHColour : public DirectX::XMFLOAT4
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -52,10 +52,13 @@ namespace SHADE
|
|||
SHColour (float r, float g, float b, float a) noexcept;
|
||||
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 (uint32_t rgba) 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;
|
||||
|
@ -66,11 +69,32 @@ namespace SHADE
|
|||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHColour& operator= (const SHColour&) = default;
|
||||
SHColour& operator= (SHColour&&) = default;
|
||||
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 +129,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 +185,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
|
||||
|
|
|
@ -9,4 +9,6 @@
|
|||
#include "SHQuaternion.h"
|
||||
#include "SHMatrix.h"
|
||||
|
||||
#include "SHColour.h"
|
||||
|
||||
#include "Transform/SHTransform.h"
|
|
@ -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
|
||||
|
|
|
@ -185,7 +185,7 @@ RTTR_REGISTRATION
|
|||
using namespace rttr;
|
||||
|
||||
registration::class_<SHTransformComponent>("Transform Component")
|
||||
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation) ) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||
.property("Translate" ,&SHTransformComponent::GetLocalPosition ,&SHTransformComponent::SetLocalPosition ) (metadata(META::tooltip, "Translate"))
|
||||
.property("Rotate" ,&SHTransformComponent::GetLocalRotation ,select_overload<void(const SHVec3&)>(&SHTransformComponent::SetLocalRotation)) (metadata(META::tooltip, "Rotate"), metadata(META::angleInRad, true))
|
||||
.property("Scale" ,&SHTransformComponent::GetLocalScale ,&SHTransformComponent::SetLocalScale ) (metadata(META::tooltip, "Scale"));
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
@ -206,7 +212,7 @@ namespace SHADE
|
|||
const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
||||
|
||||
worldRadius *= MAX_SCALE;
|
||||
worldRadius *= MAX_SCALE * 0.5f;
|
||||
}
|
||||
|
||||
if (type == Type::SPHERE)
|
||||
|
@ -275,6 +281,12 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
rotationOffset = rotOffset;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -316,5 +328,6 @@ RTTR_REGISTRATION
|
|||
);
|
||||
|
||||
registration::class_<SHCollider>("Collider")
|
||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
|
||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
||||
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||
}
|
|
@ -80,6 +80,7 @@ namespace SHADE
|
|||
[[nodiscard]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||
|
||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetRotationOffset () const noexcept;
|
||||
|
||||
[[nodiscard]] SHShape* GetShape () noexcept;
|
||||
|
||||
|
@ -96,7 +97,8 @@ namespace SHADE
|
|||
void SetDensity (float density) noexcept;
|
||||
void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
|
||||
|
||||
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||
void SetPositionOffset (const SHVec3& posOffset) noexcept;
|
||||
void SetRotationOffset (const SHVec3& rotOffset) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -110,6 +112,7 @@ namespace SHADE
|
|||
SHShape* shape;
|
||||
SHPhysicsMaterial material;
|
||||
SHVec3 positionOffset;
|
||||
SHVec3 rotationOffset;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace SHADE
|
|||
|
||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
||||
{
|
||||
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||
|
||||
switch (collider->GetType())
|
||||
{
|
||||
case SHCollider::Type::BOX:
|
||||
|
@ -137,7 +139,7 @@ namespace SHADE
|
|||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
||||
|
||||
rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
||||
rp3dBody->addCollider(newBox, OFFSETS);
|
||||
break;
|
||||
}
|
||||
case SHCollider::Type::SPHERE:
|
||||
|
@ -145,7 +147,7 @@ namespace SHADE
|
|||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
||||
|
||||
rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
|
||||
rp3dBody->addCollider(newSphere, OFFSETS);
|
||||
break;
|
||||
}
|
||||
// TODO(Diren): Add more collider shapes
|
||||
|
@ -182,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())
|
||||
{
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Tools/SHUtilities.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -31,6 +32,7 @@ namespace SHADE
|
|||
|
||||
SHPhysicsSystem::SHPhysicsSystem()
|
||||
: worldUpdated { false }
|
||||
, debugDrawFlags { 0 }
|
||||
, interpolationFactor { 0.0 }
|
||||
, fixedDT { 60.0 }
|
||||
, world { nullptr }
|
||||
|
@ -48,6 +50,11 @@ namespace SHADE
|
|||
: SHSystemRoutine { "Physics PostUpdate", false }
|
||||
{}
|
||||
|
||||
SHPhysicsSystem::PhysicsDebugDraw::PhysicsDebugDraw()
|
||||
: SHSystemRoutine { "Physics DebugDraw", true }
|
||||
{}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -100,6 +107,31 @@ namespace SHADE
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::GetDrawColliders() const noexcept
|
||||
{
|
||||
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER);
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::GetDrawColliderAABBs() const noexcept
|
||||
{
|
||||
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB);
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::GetDrawBroadPhase() const noexcept
|
||||
{
|
||||
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB);
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::GetDrawContactPoints() const noexcept
|
||||
{
|
||||
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS);
|
||||
}
|
||||
|
||||
bool SHPhysicsSystem::GetDrawContactNormals() const noexcept
|
||||
{
|
||||
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_NORMALS);
|
||||
}
|
||||
|
||||
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
|
||||
{
|
||||
return collisionInfo;
|
||||
|
@ -182,6 +214,96 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetDrawColliders(bool shouldDraw) noexcept
|
||||
{
|
||||
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER);
|
||||
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||
|
||||
if (world == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return;
|
||||
}
|
||||
|
||||
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||
(
|
||||
rp3d::DebugRenderer::DebugItem::COLLISION_SHAPE,
|
||||
shouldDraw
|
||||
);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetDrawColliderAABBs(bool shouldDraw) noexcept
|
||||
{
|
||||
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB);
|
||||
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||
|
||||
if (world == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return;
|
||||
}
|
||||
|
||||
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||
(
|
||||
rp3d::DebugRenderer::DebugItem::COLLIDER_AABB,
|
||||
shouldDraw
|
||||
);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetDrawBroadPhase(bool shouldDraw) noexcept
|
||||
{
|
||||
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB);
|
||||
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||
|
||||
if (world == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return;
|
||||
}
|
||||
|
||||
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||
(
|
||||
rp3d::DebugRenderer::DebugItem::COLLIDER_BROADPHASE_AABB,
|
||||
shouldDraw
|
||||
);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetDrawContactPoints(bool shouldDraw) noexcept
|
||||
{
|
||||
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS);
|
||||
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||
|
||||
if (world == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return;
|
||||
}
|
||||
|
||||
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||
(
|
||||
rp3d::DebugRenderer::DebugItem::CONTACT_POINT,
|
||||
shouldDraw
|
||||
);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SetDrawContactNormals(bool shouldDraw) noexcept
|
||||
{
|
||||
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_NORMALS);
|
||||
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||
|
||||
if (world == nullptr)
|
||||
{
|
||||
SHLOGV_WARNING("No physics world has been initialised!")
|
||||
return;
|
||||
}
|
||||
|
||||
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||
(
|
||||
rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL,
|
||||
shouldDraw
|
||||
);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -199,6 +321,7 @@ namespace SHADE
|
|||
|
||||
world = factory.createPhysicsWorld(settings);
|
||||
world->setEventListener(this);
|
||||
world->setIsDebugRenderingEnabled(true);
|
||||
|
||||
// Set up solvers
|
||||
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
||||
|
@ -212,6 +335,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,16 +418,6 @@ 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);
|
||||
|
@ -324,11 +443,11 @@ namespace SHADE
|
|||
|
||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||
{
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto scriptSys = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (!scriptSys)
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptingSystem == nullptr)
|
||||
{
|
||||
SHLOG_WARNING("[SHPhysicsSystem] Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
||||
|
@ -337,10 +456,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;
|
||||
|
@ -356,6 +474,11 @@ namespace SHADE
|
|||
void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept
|
||||
{
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||
if (scriptingSystem == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||
}
|
||||
|
||||
// Interpolate transforms for rendering
|
||||
if (physicsSystem->worldUpdated)
|
||||
|
@ -363,20 +486,47 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::PhysicsDebugDraw::Execute(double) noexcept
|
||||
{
|
||||
const auto* PHYSICS_SYSTEM = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
if (PHYSICS_SYSTEM->debugDrawFlags == 0)
|
||||
return;
|
||||
|
||||
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
|
||||
if (debugDrawSystem == nullptr)
|
||||
{
|
||||
SHLOGV_ERROR("Unable to debug draw physics objects due to missing SHDebugDrawSystem!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& RP3D_DEBUG_RENDERER = PHYSICS_SYSTEM->world->getDebugRenderer();
|
||||
|
||||
const auto& LINES = RP3D_DEBUG_RENDERER.getLines();
|
||||
const auto& TRIANGLES = RP3D_DEBUG_RENDERER.getTriangles();
|
||||
|
||||
// Draw all lines
|
||||
for (uint32_t i = 0; i < RP3D_DEBUG_RENDERER.getNbLines(); ++i)
|
||||
{
|
||||
const auto& LINE = LINES[i];
|
||||
debugDrawSystem->DrawLine(SHColour{ LINE.color1 }, LINE.point1, LINE.point2);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < RP3D_DEBUG_RENDERER.getNbTriangles(); ++i)
|
||||
{
|
||||
const auto& TRIANGLE = TRIANGLES[i];
|
||||
SHColour triColour{ TRIANGLE.color1 };
|
||||
triColour.a() = 1.0f;
|
||||
debugDrawSystem->DrawTri(triColour, TRIANGLE.point1, TRIANGLE.point2, TRIANGLE.point3);
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::onContact(const CallbackData& callbackData)
|
||||
{
|
||||
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||
|
@ -630,19 +780,17 @@ namespace SHADE
|
|||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||
|
||||
SHASSERT(physicsObject != nullptr, "Physics object " + std::to_string(ENTITY_ID) + " has been lost from the world!")
|
||||
|
||||
if (REMOVED_ID == RIGID_BODY_ID)
|
||||
// Wake up all physics objects
|
||||
for (auto& [entityID, object] : map)
|
||||
{
|
||||
// Wake up all physics objects
|
||||
for (auto& [entityID, object] : map)
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
||||
}
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
|
||||
}
|
||||
|
||||
if (REMOVED_ID == RIGID_BODY_ID && physicsObject != nullptr)
|
||||
{
|
||||
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
|
||||
if (colliderComponent != nullptr)
|
||||
{
|
||||
|
@ -657,7 +805,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());
|
||||
|
@ -673,11 +821,30 @@ namespace SHADE
|
|||
physicsObject->rp3dBody = nullptr;
|
||||
}
|
||||
|
||||
if (physicsObject->rp3dBody == nullptr)
|
||||
DestroyPhysicsObject(ENTITY_ID);
|
||||
if (physicsObject != nullptr && physicsObject->rp3dBody == nullptr)
|
||||
DestroyPhysicsObject(ENTITY_ID);
|
||||
}
|
||||
|
||||
return EVENT_DATA->handle;
|
||||
}
|
||||
|
||||
SHEventHandle SHPhysicsSystem::ResetWorld(SHEventPtr editorStopEvent)
|
||||
{
|
||||
// TODO(Diren): Rebuild world based on how scene reloading is done
|
||||
|
||||
for (auto& [entityID, physicsObject] : map)
|
||||
{
|
||||
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
|
||||
{
|
||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||
rp3dRigidBody->resetForce();
|
||||
rp3dRigidBody->resetTorque();
|
||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||
}
|
||||
}
|
||||
|
||||
return editorStopEvent->handle;
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -51,6 +51,15 @@ namespace SHADE
|
|||
|
||||
using CollisionEvents = std::vector<SHCollisionEvent>;
|
||||
|
||||
enum class DebugDrawFlags : uint8_t
|
||||
{
|
||||
COLLIDER = 1
|
||||
, COLLIDER_AABB = 2
|
||||
, BROAD_PHASE_AABB = 4
|
||||
, CONTACT_POINTS = 8
|
||||
, CONTACT_NORMALS = 16
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -69,6 +78,12 @@ namespace SHADE
|
|||
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
||||
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
||||
|
||||
[[nodiscard]] bool GetDrawColliders () const noexcept;
|
||||
[[nodiscard]] bool GetDrawColliderAABBs () const noexcept;
|
||||
[[nodiscard]] bool GetDrawBroadPhase () const noexcept;
|
||||
[[nodiscard]] bool GetDrawContactPoints () const noexcept;
|
||||
[[nodiscard]] bool GetDrawContactNormals () const noexcept;
|
||||
|
||||
[[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept;
|
||||
[[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept;
|
||||
|
||||
|
@ -85,6 +100,13 @@ namespace SHADE
|
|||
|
||||
void SetWorldSettings (const WorldSettings& settings) const noexcept;
|
||||
|
||||
// TODO(Diren): Can the debug draw flags be done through an enum?
|
||||
void SetDrawColliders (bool shouldDraw) noexcept;
|
||||
void SetDrawColliderAABBs (bool shouldDraw) noexcept;
|
||||
void SetDrawBroadPhase (bool shouldDraw) noexcept;
|
||||
void SetDrawContactPoints (bool shouldDraw) noexcept;
|
||||
void SetDrawContactNormals (bool shouldDraw) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -105,48 +127,31 @@ namespace SHADE
|
|||
class SH_API PhysicsPreUpdate final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsPreUpdate();
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsFixedUpdate();
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
void Execute (double dt) noexcept override;
|
||||
};
|
||||
|
||||
class SH_API PhysicsPostUpdate final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
PhysicsPostUpdate();
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API PhysicsDebugDraw final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
PhysicsDebugDraw();
|
||||
void Execute(double dt) noexcept override;
|
||||
};
|
||||
|
||||
|
@ -162,6 +167,7 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
bool worldUpdated;
|
||||
uint8_t debugDrawFlags;
|
||||
|
||||
double interpolationFactor;
|
||||
double fixedDT;
|
||||
|
@ -189,6 +195,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>
|
||||
|
|
|
@ -21,9 +21,11 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
SHResourceHub SHResourceManager::resourceHub;
|
||||
std::unordered_map<std::type_index, std::unordered_map<AssetID, Handle<void>>> SHResourceManager::handlesMap;
|
||||
std::unordered_map<std::type_index, SHADE::SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||
std::unordered_map<std::type_index, SHResourceManager::HandleAssetMap> SHResourceManager::assetIdMap;
|
||||
std::unordered_map<std::type_index, std::function<void(AssetID)>> SHResourceManager::typedFreeFuncMap;
|
||||
std::vector<AssetID> SHResourceManager::loadedAssetData;
|
||||
bool SHResourceManager::textureChanged = false;
|
||||
bool SHResourceManager::meshChanged = false;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Function Definitions */
|
||||
|
@ -63,8 +65,17 @@ namespace SHADE
|
|||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
if (gfxSystem == nullptr)
|
||||
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||
gfxSystem->BuildMeshBuffers();
|
||||
gfxSystem->BuildTextures();
|
||||
|
||||
if (meshChanged)
|
||||
{
|
||||
gfxSystem->BuildMeshBuffers();
|
||||
meshChanged = false;
|
||||
}
|
||||
if (textureChanged)
|
||||
{
|
||||
gfxSystem->BuildTextures();
|
||||
textureChanged = false;
|
||||
}
|
||||
|
||||
// Free CPU Resources
|
||||
for (auto assetId : loadedAssetData)
|
||||
|
|
|
@ -31,37 +31,17 @@ namespace SHADE { class SHMaterial; }
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
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<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
||||
template<>
|
||||
struct SHResourceLoader<SHMaterial>
|
||||
{
|
||||
using AssetType = SHMaterialSpec;
|
||||
};
|
||||
|
||||
|
||||
/// <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<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
|
||||
/// <summary>
|
||||
/// Static class responsible for loading and caching runtime resources from their
|
||||
/// serialised Asset IDs.
|
||||
/// </summary>
|
||||
|
@ -104,7 +84,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();
|
||||
|
||||
|
@ -154,6 +134,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 */
|
||||
|
|
|
@ -176,6 +176,7 @@ namespace SHADE
|
|||
if constexpr (std::is_same_v<ResourceType, SHMesh>)
|
||||
{
|
||||
loadedAssetData.emplace_back(assetId);
|
||||
meshChanged = true;
|
||||
|
||||
return gfxSystem->AddMesh
|
||||
(
|
||||
|
@ -192,6 +193,7 @@ namespace SHADE
|
|||
else if constexpr (std::is_same_v<ResourceType, SHTexture>)
|
||||
{
|
||||
loadedAssetData.emplace_back(assetId);
|
||||
textureChanged = true;
|
||||
|
||||
return gfxSystem->AddTexture
|
||||
(
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/************************************************************************************//*!
|
||||
\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);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentLine(color, startPt, endPt);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentTri(color, pt1, pt2, pt3);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentQuad(color, pt1, pt2, pt3, pt4);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentPoly(color, pointList);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentCube(color, pos, size);
|
||||
}
|
||||
|
||||
void SHDebugDraw::PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||
{
|
||||
dbgDrawSys->DrawPersistentSphere(color, pos, radius);
|
||||
}
|
||||
|
||||
void SHDebugDraw::ClearPersistentDraws()
|
||||
{
|
||||
dbgDrawSys->ClearPersistentDraws();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/************************************************************************************//*!
|
||||
\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);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Persistent Draw Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Renders a line between two points in world space that will persist until
|
||||
/// ClearPersistentDraws() is called.
|
||||
/// </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 PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||
/// <summary>
|
||||
/// Renders a triangle indicated by three points in world space that will persist
|
||||
/// until ClearPersistentDraws() is called.
|
||||
/// </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 PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
|
||||
/// <summary>
|
||||
/// Renders a quadrilateral indicated by four points in world space that will persist
|
||||
/// until ClearPersistentDraws() is called.
|
||||
/// </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 PersistentQuad(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 that
|
||||
/// will persist until ClearPersistentDraws() is called.
|
||||
/// </summary>
|
||||
/// <param name="color">Colour of the polygon.</param>
|
||||
/// <param name="pointList">List of points for the polygon.</param>
|
||||
static void PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||
/// <summary>
|
||||
/// Renders a wireframe cube centered around the position specified in world space
|
||||
/// that will persist until ClearPersistentDraws() is called.
|
||||
/// </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 PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||
/// <summary>
|
||||
/// Renders a wireframe sphere centered around the position specified in world space
|
||||
/// that will persist until ClearPersistentDraws() is called.
|
||||
/// </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 PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||
/// <summary>
|
||||
/// Clears any persistent drawn debug primitives.
|
||||
/// </summary>
|
||||
static void ClearPersistentDraws();
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static SHDebugDrawSystem* dbgDrawSys;
|
||||
};
|
||||
}
|
|
@ -39,7 +39,7 @@ namespace SHADE
|
|||
* @param[in] enumClassMember A member of the specified enum class.
|
||||
* @returns The value of the enum class member in the output type.
|
||||
*/
|
||||
template <IsEnum InputType, IsIntegral OutputType = int>
|
||||
template <IsEnum InputType, IsIntegral OutputType = std::underlying_type_t<InputType>>
|
||||
static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
#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);
|
||||
|
||||
}
|
||||
|
||||
Vector3 Camera::GetRight()
|
||||
{
|
||||
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||
SHVec3 forward, up, right;
|
||||
system->GetCameraAxis(*GetNativeComponent(), forward, right, up);
|
||||
return Convert::ToCLI(right);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#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();
|
||||
Vector3 GetRight();
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include "SHpch.h"
|
||||
#include "CameraArm.hxx"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
CameraArm::CameraArm(Entity entity)
|
||||
:Component(entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float CameraArm::Pitch::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetPitch());
|
||||
}
|
||||
|
||||
void CameraArm::Pitch::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetPitch(val);
|
||||
}
|
||||
float CameraArm::Yaw::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetYaw());
|
||||
}
|
||||
|
||||
void CameraArm::Yaw::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetYaw(val);
|
||||
}
|
||||
|
||||
float CameraArm::ArmLength::get()
|
||||
{
|
||||
return (GetNativeComponent()->GetArmLength());
|
||||
}
|
||||
|
||||
void CameraArm::ArmLength::set(float val)
|
||||
{
|
||||
GetNativeComponent()->SetArmLength(val);
|
||||
}
|
||||
|
||||
bool CameraArm::LookAtCameraOrigin::get()
|
||||
{
|
||||
return GetNativeComponent()->lookAtCameraOrigin;
|
||||
}
|
||||
|
||||
void CameraArm::LookAtCameraOrigin::set(bool val)
|
||||
{
|
||||
GetNativeComponent()->lookAtCameraOrigin = val;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Components/Component.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
|
||||
// External Dependencies
|
||||
#include "Camera/SHCameraArmComponent.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
public ref class CameraArm : public Component<SHCameraArmComponent>
|
||||
{
|
||||
internal:
|
||||
CameraArm(Entity entity);
|
||||
public:
|
||||
property float Pitch
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float Yaw
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property float ArmLength
|
||||
{
|
||||
float get();
|
||||
void set(float val);
|
||||
}
|
||||
property bool LookAtCameraOrigin
|
||||
{
|
||||
bool get();
|
||||
void set(bool val);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -148,6 +148,14 @@ namespace SHADE
|
|||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetTorque());
|
||||
}
|
||||
bool RigidBody::Interpolating::get()
|
||||
{
|
||||
return GetNativeComponent()->IsInterpolating();
|
||||
}
|
||||
void RigidBody::Interpolating::set(bool value)
|
||||
{
|
||||
GetNativeComponent()->SetInterpolate(value);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Force Functions */
|
||||
|
|
|
@ -129,6 +129,11 @@ namespace SHADE
|
|||
{
|
||||
Vector3 get();
|
||||
}
|
||||
property bool Interpolating
|
||||
{
|
||||
bool get();
|
||||
void set(bool value);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Force Functions */
|
||||
|
|
|
@ -87,15 +87,6 @@ namespace SHADE
|
|||
{
|
||||
GetNativeComponent()->SetWorldScale(Convert::ToNative(val));
|
||||
}
|
||||
Transform^ Transform::Parent::get()
|
||||
{
|
||||
auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
const auto PARENT = node->GetParent();
|
||||
return PARENT ? gcnew Transform(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
|
@ -103,21 +94,4 @@ namespace SHADE
|
|||
Transform::Transform(Entity entity)
|
||||
: Component(entity)
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Transform::SetParent(Transform^ parent, bool worldPositionStays)
|
||||
{
|
||||
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
auto node = sceneGraph.GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
if (parent)
|
||||
node->SetParent(sceneGraph.GetNode(parent->owner.GetEntity()));
|
||||
else
|
||||
sceneGraph.SetParent(parent->owner.GetEntity(), nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,30 +107,6 @@ namespace SHADE
|
|||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Parent Transform that affects this Transform.
|
||||
/// </summary>
|
||||
property Transform^ Parent
|
||||
{
|
||||
Transform^ get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the parent of this Transform component.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// Entity that contains the Transform component that this Transform will be
|
||||
/// parented to. If null, unparenting will occur.
|
||||
/// </param>
|
||||
/// <param name="worldPositionStays">
|
||||
/// If true, the transform values of this Transform component will retain their
|
||||
/// pre-parent-change global transforms. The local transform values will be
|
||||
/// modified to ensure that the global transforms do not change.
|
||||
/// </param>
|
||||
void SetParent(Transform^ parent, bool worldPositionStays);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ namespace SHADE
|
|||
|
||||
int val = safe_cast<int>(field->GetValue(object));
|
||||
int oldVal = val;
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames, &isHovered))
|
||||
{
|
||||
field->SetValue(object, val);
|
||||
registerUndoAction(object, field, val, oldVal);
|
||||
|
@ -280,12 +280,23 @@ namespace SHADE
|
|||
// Actual Field
|
||||
std::string val = Convert::ToNative(stringVal);
|
||||
std::string oldVal = val;
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val, &isHovered))
|
||||
{
|
||||
field->SetValue(object, Convert::ToCLI(val));
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||
}
|
||||
}
|
||||
else if (field->FieldType == GameObject::typeid)
|
||||
{
|
||||
GameObject gameObj = safe_cast<GameObject>(field->GetValue(object));
|
||||
uint32_t entityId = gameObj.GetEntity();
|
||||
if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered))
|
||||
{
|
||||
GameObject newVal = GameObject(entityId);
|
||||
field->SetValue(object, newVal);
|
||||
registerUndoAction(object, field, newVal, gameObj);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array<System::Type^>^ interfaces = field->FieldType->GetInterfaces();
|
||||
|
|
|
@ -33,6 +33,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Components/Transform.hxx"
|
||||
#include "Components\RigidBody.hxx"
|
||||
#include "Components\Collider.hxx"
|
||||
#include "Components/Camera.hxx"
|
||||
#include "Components/CameraArm.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -248,6 +250,8 @@ namespace SHADE
|
|||
componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
|
||||
componentMap.Add(createComponentSet<SHColliderComponent, Collider>());
|
||||
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
||||
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
||||
componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "GameObject.hxx"
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
// Project Headers
|
||||
#include "ECS.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
|
@ -72,6 +73,31 @@ namespace SHADE
|
|||
}
|
||||
return node->IsActive();
|
||||
}
|
||||
Entity GameObject::EntityId::get()
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
GameObject^ GameObject::Parent::get()
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||
|
||||
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||
if (NODE == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||
|
||||
const auto* PARENT = NODE->GetParent();
|
||||
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
void GameObject::Parent::set(GameObject^ newParent)
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
if (newParent == nullptr)
|
||||
SCENE_GRAPH.SetParent(entity, nullptr);
|
||||
else
|
||||
SCENE_GRAPH.SetParent(entity, newParent->EntityId);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* GameObject Property Functions */
|
||||
|
@ -155,11 +181,13 @@ namespace SHADE
|
|||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
GameObject::GameObject(const SHEntity& entity)
|
||||
: entity { entity.GetEID() }
|
||||
: entity { entity.GetEID() }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
{}
|
||||
|
||||
GameObject::GameObject(Entity entity)
|
||||
: entity { entity }
|
||||
: entity { entity }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -86,6 +86,21 @@ namespace SHADE
|
|||
{
|
||||
bool get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Native Entity ID value for this GameObject.
|
||||
/// </summary>
|
||||
property Entity EntityId
|
||||
{
|
||||
Entity get();
|
||||
}
|
||||
/// <summary>
|
||||
/// The parent entity for this GameObject.
|
||||
/// </summary>
|
||||
property GameObject^ Parent
|
||||
{
|
||||
GameObject^ get();
|
||||
void set(GameObject^);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* GameObject Property Functions */
|
||||
|
@ -105,6 +120,7 @@ namespace SHADE
|
|||
/// Whether to activate or deactivate this GameObject.
|
||||
/// </param>
|
||||
void SetActive(bool active);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Component Access Functions */
|
||||
|
@ -235,7 +251,8 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Entity entity;
|
||||
Entity entity;
|
||||
System::Collections::ArrayList^ children;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -29,6 +29,12 @@ namespace SHADE
|
|||
{
|
||||
return SHFrameRateController::GetRawDeltaTime();
|
||||
}
|
||||
|
||||
|
||||
float Time::DeltaTimeF::get()
|
||||
{
|
||||
return static_cast<float>(SHFrameRateController::GetRawDeltaTime());
|
||||
}
|
||||
double Time::FixedDeltaTime::get()
|
||||
{
|
||||
return SHPhysicsSystemInterface::GetFixedDT();
|
||||
|
|
|
@ -32,6 +32,16 @@ namespace SHADE
|
|||
{
|
||||
double get();
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Time taken to process the previous frame.
|
||||
/// </summary>
|
||||
static property float DeltaTimeF
|
||||
{
|
||||
float get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Time taken for Physics simulations. You should use this for operations
|
||||
/// within Script.FixedUpdate()
|
||||
|
|
|
@ -99,4 +99,11 @@ namespace SHADE
|
|||
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
Vector2 Input::GetMouseVelocity()
|
||||
{
|
||||
double velX, velY;
|
||||
SHInputManager::GetMouseVelocity(&velX, &velY);
|
||||
|
||||
return Convert::ToCLI(SHVec2{ (float)velX,(float)velY });
|
||||
}
|
||||
}
|
|
@ -471,5 +471,7 @@ namespace SHADE
|
|||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetMouseReleasedTime(MouseCode mouseButton);
|
||||
|
||||
static Vector2 GetMouseVelocity();
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue