Merge branch 'main' into SP3-141-Camera-System
This commit is contained in:
commit
922d5b0996
|
@ -0,0 +1,8 @@
|
||||||
|
- VertexShader: 39210065
|
||||||
|
FragmentShader: 46377769
|
||||||
|
SubPass: G-Buffer Write
|
||||||
|
Properties:
|
||||||
|
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
data.textureIndex: 58303057
|
||||||
|
data.alpha: 0
|
||||||
|
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: BagMaterial
|
||||||
|
ID: 123745521
|
||||||
|
Type: 7
|
|
@ -50,7 +50,7 @@
|
||||||
Colliders:
|
Colliders:
|
||||||
- Is Trigger: false
|
- Is Trigger: false
|
||||||
Type: Box
|
Type: Box
|
||||||
Half Extents: {x: 0.0170898438, y: 0.00048828125, z: 0.0170898438}
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
Friction: 0.400000006
|
Friction: 0.400000006
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
- EID: 2
|
- EID: 2
|
||||||
Name: Player
|
Name: Player
|
||||||
IsActive: true
|
IsActive: true
|
||||||
NumberOfChildren: 2
|
NumberOfChildren: 3
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: -3.06177855, y: -2, z: -5}
|
Translate: {x: -3.06177855, y: -2, z: -5}
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
Colliders:
|
Colliders:
|
||||||
- Is Trigger: false
|
- Is Trigger: false
|
||||||
Type: Box
|
Type: Box
|
||||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
Friction: 0.400000006
|
Friction: 0.400000006
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
|
@ -111,47 +111,18 @@
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 5
|
- EID: 9
|
||||||
Name: item
|
Name: Default
|
||||||
IsActive: true
|
IsActive: true
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: -2, z: -5}
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 2, y: 2, z: 2}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 144838771
|
||||||
Material: 126974645
|
Material: 123745521
|
||||||
RigidBody Component:
|
|
||||||
Type: Dynamic
|
|
||||||
Mass: 1
|
|
||||||
Drag: 0
|
|
||||||
Angular Drag: 0
|
|
||||||
Use Gravity: true
|
|
||||||
Interpolate: false
|
|
||||||
Freeze Position X: false
|
|
||||||
Freeze Position Y: false
|
|
||||||
Freeze Position Z: false
|
|
||||||
Freeze Rotation X: true
|
|
||||||
Freeze Rotation Y: true
|
|
||||||
Freeze Rotation Z: true
|
|
||||||
Collider Component:
|
|
||||||
Colliders:
|
|
||||||
- Is Trigger: false
|
|
||||||
Type: Box
|
|
||||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
|
||||||
Friction: 0.400000006
|
|
||||||
Bounciness: 0
|
|
||||||
Density: 1
|
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
|
||||||
- Is Trigger: true
|
|
||||||
Type: Box
|
|
||||||
Half Extents: {x: 0.001953125, y: 0.001953125, z: 0.001953125}
|
|
||||||
Friction: 0.400000006
|
|
||||||
Bounciness: 0
|
|
||||||
Density: 1
|
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 6
|
- EID: 6
|
||||||
Name: AI
|
Name: AI
|
||||||
|
@ -161,7 +132,7 @@
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: -8, y: -2, z: 2.5}
|
Translate: {x: -8, y: -2, z: 2.5}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 2, y: 2, z: 2}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
|
@ -182,7 +153,7 @@
|
||||||
Colliders:
|
Colliders:
|
||||||
- Is Trigger: false
|
- Is Trigger: false
|
||||||
Type: Box
|
Type: Box
|
||||||
Half Extents: {x: 0.0009765625, y: 0.0009765625, z: 0.0009765625}
|
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
Friction: 0.400000006
|
Friction: 0.400000006
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
|
@ -194,9 +165,9 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 3, y: -1, z: -1}
|
Translate: {x: 0, y: -16.8647861, z: -14.039052}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
Scale: {x: 5, y: 5, z: 5}
|
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
|
@ -214,3 +185,45 @@
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0.25
|
Strength: 0.25
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: item
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -2, z: -5}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 2, y: 2, z: 2}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 144838771
|
||||||
|
Material: 123745521
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: false
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: false
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: true
|
||||||
|
Freeze Rotation Y: true
|
||||||
|
Freeze Rotation Z: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
- Is Trigger: true
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2, y: 2, z: 2}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,72 @@
|
||||||
|
- EID: 0
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Camera Component:
|
||||||
|
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
|
Pitch: 0
|
||||||
|
Yaw: 0
|
||||||
|
Roll: 0
|
||||||
|
Width: 1200
|
||||||
|
Height: 1080
|
||||||
|
Near: 0.00999999978
|
||||||
|
Far: 10000
|
||||||
|
Perspective: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 1
|
||||||
|
Name: Raccoon
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 1
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 3
|
||||||
|
Name: Bag
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
||||||
|
Rotate: {x: -0, y: 2.79945588, z: 0}
|
||||||
|
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 144838771
|
||||||
|
Material: 123745521
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 2
|
||||||
|
Name: DirectionalLight
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Directional
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 4
|
||||||
|
Name: AmbientLight
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Ambient
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0.600000024
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: Scene2
|
||||||
|
ID: 87285316
|
||||||
|
Type: 5
|
|
@ -15,7 +15,7 @@ public class PlayerController : Script
|
||||||
TOTAL
|
TOTAL
|
||||||
}
|
}
|
||||||
|
|
||||||
public RigidBody rb;
|
public RigidBody rb { get; set; }
|
||||||
private Transform tranform;
|
private Transform tranform;
|
||||||
private Camera cam;
|
private Camera cam;
|
||||||
private PickAndThrow pat;
|
private PickAndThrow pat;
|
|
@ -27,6 +27,11 @@ public class RaccoonShowcase : Script
|
||||||
Debug.LogError("Transform is NULL!");
|
Debug.LogError("Transform is NULL!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var child in Owner)
|
||||||
|
{
|
||||||
|
Debug.Log(child.Name);
|
||||||
|
}
|
||||||
|
|
||||||
originalScale = Transform.LocalScale.z;
|
originalScale = Transform.LocalScale.z;
|
||||||
}
|
}
|
||||||
protected override void update()
|
protected override void update()
|
||||||
|
@ -36,4 +41,10 @@ public class RaccoonShowcase : Script
|
||||||
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
||||||
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void onDrawGizmos()
|
||||||
|
{
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f));
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 0.0f), Color.Red);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -8,14 +8,23 @@ public class RaccoonSpin : Script
|
||||||
private float RotateSpeed = 1.0f;
|
private float RotateSpeed = 1.0f;
|
||||||
private float rotation = 0.0f;
|
private float rotation = 0.0f;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
private CallbackEvent emptyEvent;
|
||||||
|
[SerializeField]
|
||||||
private CallbackEvent<int> testEvent;
|
private CallbackEvent<int> testEvent;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
|
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
|
||||||
private Transform Transform;
|
private Transform Transform;
|
||||||
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
|
||||||
protected override void awake()
|
protected override void awake()
|
||||||
{
|
{
|
||||||
|
emptyEvent = new CallbackEvent();
|
||||||
|
emptyEvent.RegisterAction(() => Debug.Log("Empty event action!"));
|
||||||
|
testEvent = new CallbackEvent<int>();
|
||||||
|
Action<int> action = (x) => Debug.Log($"{x}");
|
||||||
|
testEvent.RegisterAction(action);
|
||||||
|
|
||||||
Transform = GetComponent<Transform>();
|
Transform = GetComponent<Transform>();
|
||||||
if (Transform == null)
|
if (Transform == null)
|
||||||
{
|
{
|
|
@ -59,7 +59,7 @@ if %_e%==3 (goto :done) else (goto :ModelCompiler)
|
||||||
echo -----------------------ModelCompiler----------------------------
|
echo -----------------------ModelCompiler----------------------------
|
||||||
rmdir "Dependencies/ModelCompiler" /S /Q
|
rmdir "Dependencies/ModelCompiler" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/ModelCompiler.git "Dependencies/ModelCompiler"
|
git clone https://github.com/SHADE-DP/ModelCompiler.git "Dependencies/ModelCompiler"
|
||||||
Dependencies/ModelCompiler/Dependencies.bat
|
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/ModelCompiler/Dependencies/assimp"
|
||||||
if %_e%==4 (goto :done) else (goto :spdlog)
|
if %_e%==4 (goto :done) else (goto :spdlog)
|
||||||
|
|
||||||
@REM :ktx
|
@REM :ktx
|
||||||
|
|
|
@ -106,6 +106,7 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Sandbox
|
||||||
|
|
||||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
auto* floorBox = floorCollider.AddBoundingBox();
|
floorCollider.AddBoundingBox();
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
@ -114,8 +114,8 @@ namespace Sandbox
|
||||||
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
racoonCollider.AddBoundingBox();
|
racoonCollider.AddBoundingBox();
|
||||||
racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||||
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
||||||
|
@ -140,13 +140,13 @@ namespace Sandbox
|
||||||
|
|
||||||
itemCollider.AddBoundingBox();
|
itemCollider.AddBoundingBox();
|
||||||
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||||
itemCollider.GetCollider(1).SetIsTrigger(true);
|
itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||||
|
|
||||||
itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
itemRigidBody.SetInterpolate(false);
|
itemRigidBody.SetInterpolate(false);
|
||||||
itemRigidBody.SetFreezeRotationX(true);
|
itemRigidBody.SetFreezeRotationX(true);
|
||||||
|
@ -168,8 +168,8 @@ namespace Sandbox
|
||||||
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||||
|
|
||||||
AICollider.AddBoundingBox();
|
AICollider.AddBoundingBox();
|
||||||
AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
AIRigidBody.SetInterpolate(false);
|
AIRigidBody.SetInterpolate(false);
|
||||||
AIRigidBody.SetFreezeRotationX(true);
|
AIRigidBody.SetFreezeRotationX(true);
|
||||||
|
|
|
@ -34,6 +34,99 @@ namespace SHADE
|
||||||
Object TargetObject { get; }
|
Object TargetObject { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
|
/// This variant accepts functions with 0 parameter.
|
||||||
|
/// </summary>
|
||||||
|
public class CallbackAction : ICallbackAction
|
||||||
|
{
|
||||||
|
#region Properties ------------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public Object TargetObject { get; private set; }
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string TargetMethodName => targetMethod == null ? "" : targetMethod.Name;
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsRuntimeAction => targetAction != null;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields ------------------------------------------------------------------
|
||||||
|
private MethodInfo targetMethod;
|
||||||
|
private Action targetAction;
|
||||||
|
private Object[] parameters;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors ------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs an empty Callback action.
|
||||||
|
/// </summary>
|
||||||
|
public CallbackAction() {}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a CallbackAction that represents a call to the specified static
|
||||||
|
/// method.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if a method that is not compatible with the target is specified. The method's
|
||||||
|
/// source type must match the target's type.
|
||||||
|
/// </exception>
|
||||||
|
public CallbackAction(MethodInfo method)
|
||||||
|
{
|
||||||
|
// No errors, assign
|
||||||
|
targetMethod = method;
|
||||||
|
|
||||||
|
// Create storage for parameters for calling
|
||||||
|
parameters = new Object[0];
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a CallbackAction that represents a call to a specified member
|
||||||
|
/// method on the specified target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">Object to call the method on.</param>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if a method that is not compatible with the target is specified. The method's
|
||||||
|
/// source type must match the target's type.
|
||||||
|
/// </exception>
|
||||||
|
public CallbackAction(Object target, MethodInfo method)
|
||||||
|
{
|
||||||
|
// Error Checks
|
||||||
|
if (method.DeclaringType != target.GetType())
|
||||||
|
throw new ArgumentException("[CallbackAction] Attempted register an action using an incompatible target object and method.");
|
||||||
|
|
||||||
|
// No errors, assign
|
||||||
|
TargetObject = target;
|
||||||
|
targetMethod = method;
|
||||||
|
|
||||||
|
// Create storage for parameters for calling
|
||||||
|
parameters = new Object[0];
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a Callback action based on an action.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">Action that wraps a function to be called.</param>
|
||||||
|
public CallbackAction(Action action)
|
||||||
|
{
|
||||||
|
targetAction = action;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usage Functions ---------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the CallbackAction's stored method/action with the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
if (targetAction != null)
|
||||||
|
{
|
||||||
|
targetAction.Invoke();
|
||||||
|
}
|
||||||
|
else if (targetMethod != null)
|
||||||
|
{
|
||||||
|
_ = targetMethod.Invoke(TargetObject, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a function call that can be serialised and put togetheer with scripts.
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
/// This variant accepts functions with 1 parameter.
|
/// This variant accepts functions with 1 parameter.
|
||||||
|
|
|
@ -50,12 +50,12 @@ namespace SHADE
|
||||||
Object TargetObject { get; }
|
Object TargetObject { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<# for (int i = 1; i <= max; ++i) { #>
|
<# for (int i = 0; i <= max; ++i) { #>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a function call that can be serialised and put togetheer with scripts.
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
|
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackAction
|
public class CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackAction
|
||||||
{
|
{
|
||||||
#region Properties ------------------------------------------------------------
|
#region Properties ------------------------------------------------------------
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -68,7 +68,7 @@ namespace SHADE
|
||||||
|
|
||||||
#region Fields ------------------------------------------------------------------
|
#region Fields ------------------------------------------------------------------
|
||||||
private MethodInfo targetMethod;
|
private MethodInfo targetMethod;
|
||||||
private Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> targetAction;
|
private Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> targetAction;
|
||||||
private Object[] parameters;
|
private Object[] parameters;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace SHADE
|
||||||
/// Constructs a Callback action based on an action.
|
/// Constructs a Callback action based on an action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">Action that wraps a function to be called.</param>
|
/// <param name="action">Action that wraps a function to be called.</param>
|
||||||
public CallbackAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public CallbackAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
targetAction = action;
|
targetAction = action;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,92 @@ namespace SHADE
|
||||||
IEnumerable<ICallbackAction> Actions { get; }
|
IEnumerable<ICallbackAction> Actions { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
|
/// specified by the user of this class.
|
||||||
|
/// This variant accepts CallbackEvents with 1 generic parameter.
|
||||||
|
/// </summary>
|
||||||
|
public class CallbackEvent : ICallbackEvent
|
||||||
|
{
|
||||||
|
#region Properties --------------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<ICallbackAction> Actions => actions;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields ------------------------------------------------------------------
|
||||||
|
private List<ICallbackAction> actions = new List<ICallbackAction>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usage Functions ---------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void RegisterAction()
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction());
|
||||||
|
}
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void RegisterAction(ICallbackAction action)
|
||||||
|
{
|
||||||
|
// Check if valid action
|
||||||
|
if (action.GetType() != typeof(CallbackAction))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.Add(action);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">CallbackAction to add.</param>
|
||||||
|
public void RegisterAction(CallbackAction action)
|
||||||
|
{
|
||||||
|
actions.Add(action);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
|
public void RegisterAction(Action action)
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction(action));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">Object to call the method on.</param>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
public void RegisterAction(Object target, MethodInfo method)
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction(target, method));
|
||||||
|
}
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void DeregisterAction(ICallbackAction action)
|
||||||
|
{
|
||||||
|
if (!actions.Remove(action))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Attempted to deregister invalid action. Ignored.", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes all stored CallbackActions with the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
foreach (CallbackAction action in actions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container of CallbackActions that is correlated to a specific scenario as
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
/// specified by the user of this class.
|
/// specified by the user of this class.
|
||||||
|
@ -88,7 +174,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1> action)
|
public void RegisterAction(Action<T1> action)
|
||||||
|
@ -96,7 +182,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1>(action));
|
actions.Add(new CallbackAction<T1>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -174,7 +260,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2> action)
|
public void RegisterAction(Action<T1, T2> action)
|
||||||
|
@ -182,7 +268,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2>(action));
|
actions.Add(new CallbackAction<T1, T2>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -260,7 +346,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3> action)
|
public void RegisterAction(Action<T1, T2, T3> action)
|
||||||
|
@ -268,7 +354,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3>(action));
|
actions.Add(new CallbackAction<T1, T2, T3>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -346,7 +432,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
||||||
|
@ -354,7 +440,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -432,7 +518,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
||||||
|
@ -440,7 +526,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -518,7 +604,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
||||||
|
@ -526,7 +612,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -604,7 +690,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||||
|
@ -612,7 +698,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -690,7 +776,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||||
|
@ -698,7 +784,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -776,7 +862,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
|
||||||
|
@ -784,7 +870,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -862,7 +948,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
|
||||||
|
@ -870,7 +956,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
|
|
@ -61,13 +61,13 @@ namespace SHADE
|
||||||
IEnumerable<ICallbackAction> Actions { get; }
|
IEnumerable<ICallbackAction> Actions { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<# for (int i = 1; i <= max; ++i) { #>
|
<# for (int i = 0; i <= max; ++i) { #>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container of CallbackActions that is correlated to a specific scenario as
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
/// specified by the user of this class.
|
/// specified by the user of this class.
|
||||||
/// This variant accepts CallbackEvents with 1 generic parameter.
|
/// This variant accepts CallbackEvents with 1 generic parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CallbackEvent<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackEvent
|
public class CallbackEvent<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackEvent
|
||||||
{
|
{
|
||||||
#region Properties --------------------------------------------------------------
|
#region Properties --------------------------------------------------------------
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -82,13 +82,13 @@ namespace SHADE
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RegisterAction()
|
public void RegisterAction()
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>());
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>());
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RegisterAction(ICallbackAction action)
|
public void RegisterAction(ICallbackAction action)
|
||||||
{
|
{
|
||||||
// Check if valid action
|
// Check if valid action
|
||||||
if (action.GetType() != typeof(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>))
|
if (action.GetType() != typeof(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>))
|
||||||
{
|
{
|
||||||
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
||||||
return;
|
return;
|
||||||
|
@ -100,26 +100,26 @@ namespace SHADE
|
||||||
/// Adds a CallbackAction into the event.
|
/// Adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">CallbackAction to add.</param>
|
/// <param name="action">CallbackAction to add.</param>
|
||||||
public void RegisterAction(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public void RegisterAction(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public void RegisterAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(action));
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
public void RegisterAction(Object target, MethodInfo method)
|
public void RegisterAction(Object target, MethodInfo method)
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(target, method));
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(target, method));
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void DeregisterAction(ICallbackAction action)
|
public void DeregisterAction(ICallbackAction action)
|
||||||
|
@ -132,9 +132,9 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invokes all stored CallbackActions with the specified parameters.
|
/// Invokes all stored CallbackActions with the specified parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Invoke(<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } #>)
|
public void Invoke(<# if (i != 0) { for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } } #>)
|
||||||
{
|
{
|
||||||
foreach (CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action in actions)
|
foreach (CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action in actions)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,8 @@ enum class AssetType : AssetTypeMeta
|
||||||
PREFAB,
|
PREFAB,
|
||||||
MATERIAL,
|
MATERIAL,
|
||||||
MESH,
|
MESH,
|
||||||
|
SCRIPT,
|
||||||
|
FONT,
|
||||||
MAX_COUNT
|
MAX_COUNT
|
||||||
};
|
};
|
||||||
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
||||||
|
@ -85,32 +87,39 @@ constexpr std::string_view SCENE_EXTENSION {".shade"};
|
||||||
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
||||||
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
||||||
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
||||||
constexpr std::string_view MODEL_EXTENSION {".shmodel"};
|
constexpr std::string_view MODEL_EXTENSION{ ".shmodel" };
|
||||||
|
constexpr std::string_view FONT_EXTENSION{ ".shfont" };
|
||||||
|
|
||||||
constexpr std::string_view EXTENSIONS[] = {
|
constexpr std::string_view EXTENSIONS[] = {
|
||||||
AUDIO_EXTENSION,
|
AUDIO_EXTENSION,
|
||||||
SHADER_EXTENSION,
|
SHADER_EXTENSION,
|
||||||
SHADER_BUILT_IN_EXTENSION,
|
SHADER_BUILT_IN_EXTENSION,
|
||||||
MATERIAL_EXTENSION,
|
TEXTURE_EXTENSION,
|
||||||
TEXTURE_EXTENSION,
|
|
||||||
MODEL_EXTENSION,
|
MODEL_EXTENSION,
|
||||||
SCRIPT_EXTENSION,
|
SCENE_EXTENSION,
|
||||||
SCENE_EXTENSION,
|
|
||||||
PREFAB_EXTENSION,
|
PREFAB_EXTENSION,
|
||||||
|
MATERIAL_EXTENSION,
|
||||||
|
"dummy",
|
||||||
|
SCRIPT_EXTENSION,
|
||||||
|
FONT_EXTENSION,
|
||||||
AUDIO_WAV_EXTENSION,
|
AUDIO_WAV_EXTENSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr size_t EXTENSIONS_COUNT{ 11 };
|
||||||
|
|
||||||
// EXTERNAL EXTENSIONS
|
// EXTERNAL EXTENSIONS
|
||||||
constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
|
constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
|
||||||
constexpr std::string_view DDS_EXTENSION{ ".dds" };
|
constexpr std::string_view DDS_EXTENSION{ ".dds" };
|
||||||
constexpr std::string_view FBX_EXTENSION{ ".fbx" };
|
constexpr std::string_view FBX_EXTENSION{ ".fbx" };
|
||||||
constexpr std::string_view GLTF_EXTENSION{ ".gltf" };
|
constexpr std::string_view GLTF_EXTENSION{ ".gltf" };
|
||||||
|
constexpr std::string_view TTF_EXTENSION{ ".ttf" };
|
||||||
|
|
||||||
constexpr std::string_view EXTERNALS[] = {
|
constexpr std::string_view EXTERNALS[] = {
|
||||||
GLSL_EXTENSION,
|
GLSL_EXTENSION,
|
||||||
DDS_EXTENSION,
|
DDS_EXTENSION,
|
||||||
FBX_EXTENSION,
|
FBX_EXTENSION,
|
||||||
GLTF_EXTENSION
|
GLTF_EXTENSION,
|
||||||
|
TTF_EXTENSION
|
||||||
};
|
};
|
||||||
|
|
||||||
// SHADER IDENTIFIERS
|
// SHADER IDENTIFIERS
|
||||||
|
@ -125,11 +134,4 @@ constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
|
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
|
||||||
|
|
||||||
// Error flags
|
|
||||||
constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"};
|
|
||||||
constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"};
|
|
||||||
constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"};
|
|
||||||
constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"};
|
|
||||||
|
|
||||||
#endif // !SH_ASSET_MACROS_H
|
#endif // !SH_ASSET_MACROS_H
|
||||||
|
|
|
@ -338,7 +338,7 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
|
void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept
|
||||||
{
|
{
|
||||||
if (!std::filesystem::exists(path))
|
if (!std::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
|
@ -360,10 +360,12 @@ namespace SHADE
|
||||||
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
||||||
modelPath += MODEL_EXTENSION;
|
modelPath += MODEL_EXTENSION;
|
||||||
newPath = modelPath;
|
newPath = modelPath;
|
||||||
|
|
||||||
GenerateNewMeta(newPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (genMeta)
|
||||||
|
{
|
||||||
|
GenerateNewMeta(newPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
||||||
|
@ -371,6 +373,13 @@ namespace SHADE
|
||||||
return folderRoot;
|
return folderRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::RefreshDirectory() noexcept
|
||||||
|
{
|
||||||
|
SHFileSystem::DestroyDirectory(folderRoot);
|
||||||
|
assetCollection.clear();
|
||||||
|
BuildAssetCollection();
|
||||||
|
}
|
||||||
|
|
||||||
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
||||||
{
|
{
|
||||||
for (auto const& e : EXTENSIONS)
|
for (auto const& e : EXTENSIONS)
|
||||||
|
@ -396,51 +405,6 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::CompileAll() noexcept
|
|
||||||
{
|
|
||||||
std::vector<AssetPath> paths;
|
|
||||||
|
|
||||||
for (auto const& dir : std::filesystem::recursive_directory_iterator{ ASSET_ROOT })
|
|
||||||
{
|
|
||||||
if (dir.is_regular_file())
|
|
||||||
{
|
|
||||||
for (auto const& ext : EXTERNALS)
|
|
||||||
{
|
|
||||||
if (dir.path().extension().string() == ext.data())
|
|
||||||
{
|
|
||||||
paths.push_back(dir.path());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& path : paths)
|
|
||||||
{
|
|
||||||
AssetPath newPath;
|
|
||||||
auto const ext{ path.extension().string() };
|
|
||||||
if (ext == GLSL_EXTENSION.data())
|
|
||||||
{
|
|
||||||
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
|
||||||
}
|
|
||||||
else if (ext == DDS_EXTENSION.data())
|
|
||||||
{
|
|
||||||
newPath = SHTextureCompiler::CompileTextureAsset(path).value();
|
|
||||||
}
|
|
||||||
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
|
|
||||||
{
|
|
||||||
std::string command = MODEL_COMPILER_EXE.data();
|
|
||||||
command += " " + path.string();
|
|
||||||
std::system(command.c_str());
|
|
||||||
|
|
||||||
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
|
||||||
modelPath += MODEL_EXTENSION;
|
|
||||||
newPath = modelPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerateNewMeta(newPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept
|
bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept
|
||||||
{
|
{
|
||||||
//TODO Move this to dedicated library
|
//TODO Move this to dedicated library
|
||||||
|
|
|
@ -87,9 +87,10 @@ namespace SHADE
|
||||||
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
||||||
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
||||||
|
|
||||||
static void CompileAsset(AssetPath const& path) noexcept;
|
static void CompileAsset(AssetPath const& path, bool genMeta) noexcept;
|
||||||
|
|
||||||
static FolderPointer GetRootFolder() noexcept;
|
static FolderPointer GetRootFolder() noexcept;
|
||||||
|
static void RefreshDirectory() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -106,8 +107,6 @@ namespace SHADE
|
||||||
|
|
||||||
static SHAsset CreateAssetFromPath(AssetPath path) noexcept;
|
static SHAsset CreateAssetFromPath(AssetPath path) noexcept;
|
||||||
|
|
||||||
static void CompileAll() noexcept;
|
|
||||||
|
|
||||||
static bool DeleteLocalFile(AssetPath path) noexcept;
|
static bool DeleteLocalFile(AssetPath path) noexcept;
|
||||||
|
|
||||||
//TODO use this function to create asset data internall at all calls to generate id
|
//TODO use this function to create asset data internall at all calls to generate id
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
|
AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
|
||||||
{
|
{
|
||||||
for (int i{0}; i < EXTENSIONS->size(); ++i)
|
for (auto i{0}; i < EXTENSIONS_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0)
|
if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0)
|
||||||
{
|
{
|
||||||
|
@ -98,6 +98,7 @@ namespace SHADE
|
||||||
meta.type = static_cast<AssetType>(type);
|
meta.type = static_cast<AssetType>(type);
|
||||||
|
|
||||||
meta.isSubAsset = false;
|
meta.isSubAsset = false;
|
||||||
|
meta.parent = 0;
|
||||||
|
|
||||||
// Burn Line
|
// Burn Line
|
||||||
if (std::getline(metaFile, line))
|
if (std::getline(metaFile, line))
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <FMOD/fmod_studio.hpp>
|
#include <FMOD/fmod_studio.hpp>
|
||||||
#include <SDL_keyboard.h>
|
#include <SDL_keyboard.h>
|
||||||
|
|
||||||
|
const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAudioSystem::SHAudioSystem()
|
SHAudioSystem::SHAudioSystem()
|
||||||
|
@ -79,10 +81,10 @@ namespace SHADE
|
||||||
//SHResourceManager::LoadAllAudio(system, soundList);
|
//SHResourceManager::LoadAllAudio(system, soundList);
|
||||||
|
|
||||||
|
|
||||||
LoadBank("../../Assets/Audio/Master.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
|
||||||
LoadBank("../../Assets/Audio/Master.strings.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
|
||||||
//LoadBank("../../Assets/Audio/Music.bank");
|
//LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data());
|
||||||
LoadBank("../../Assets/Audio/footsteps.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data());
|
||||||
|
|
||||||
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
||||||
//clip->Play();
|
//clip->Play();
|
||||||
|
|
|
@ -10,63 +10,102 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
|
||||||
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize);
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize);
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize);
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize);
|
||||||
|
|
||||||
|
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
|
||||||
|
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
|
||||||
|
|
||||||
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||||
{
|
{
|
||||||
redoStack = CommandStack();
|
*pCurrRedoStack = CommandStack(defaultStackSize);
|
||||||
commandPtr->Execute();
|
commandPtr->Execute();
|
||||||
if (overrideValue && !undoStack.empty())
|
if (overrideValue && !pCurrUndoStack->Empty())
|
||||||
{
|
{
|
||||||
undoStack.top()->Merge(commandPtr);
|
pCurrUndoStack->Top()->Merge(commandPtr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
undoStack.push(commandPtr);
|
pCurrUndoStack->Push(commandPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
||||||
{
|
{
|
||||||
undoStack.push(commandPtr);
|
pCurrUndoStack->Push(commandPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::UndoCommand()
|
void SHCommandManager::UndoCommand()
|
||||||
{
|
{
|
||||||
if (undoStack.empty())
|
if (pCurrUndoStack->Empty())
|
||||||
return;
|
return;
|
||||||
undoStack.top()->Undo();
|
pCurrUndoStack->Top()->Undo();
|
||||||
redoStack.push(undoStack.top());
|
pCurrRedoStack->Push(pCurrUndoStack->Top());
|
||||||
undoStack.pop();
|
pCurrUndoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::RedoCommand()
|
void SHCommandManager::RedoCommand()
|
||||||
{
|
{
|
||||||
if (redoStack.empty())
|
if (pCurrRedoStack->Empty())
|
||||||
return;
|
return;
|
||||||
redoStack.top()->Execute();
|
pCurrRedoStack->Top()->Execute();
|
||||||
undoStack.push(redoStack.top());
|
pCurrUndoStack->Push(pCurrRedoStack->Top());
|
||||||
redoStack.pop();
|
pCurrRedoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t SHCommandManager::GetUndoStackSize()
|
std::size_t SHCommandManager::GetUndoStackSize()
|
||||||
{
|
{
|
||||||
return undoStack.size();
|
return pCurrUndoStack->Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t SHCommandManager::GetRedoStackSize()
|
std::size_t SHCommandManager::GetRedoStackSize()
|
||||||
{
|
{
|
||||||
return redoStack.size();
|
return pCurrRedoStack->Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||||
{
|
{
|
||||||
redoStack.pop();
|
pCurrRedoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||||
{
|
{
|
||||||
undoStack.pop();
|
pCurrUndoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::SwapStacks()
|
||||||
|
{
|
||||||
|
if (pCurrUndoStack == &undoStack)
|
||||||
|
{
|
||||||
|
pCurrUndoStack = &secondaryUndoStack;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
secondaryUndoStack.Clear();
|
||||||
|
pCurrUndoStack = &undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCurrRedoStack == &redoStack)
|
||||||
|
{
|
||||||
|
pCurrRedoStack = &secondaryRedoStack;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
secondaryRedoStack.Clear();
|
||||||
|
pCurrRedoStack = &redoStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::ClearAll()
|
||||||
|
{
|
||||||
|
undoStack.Clear();
|
||||||
|
redoStack.Clear();
|
||||||
|
|
||||||
|
secondaryUndoStack.Clear();
|
||||||
|
secondaryRedoStack.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHCommand.hpp"
|
#include "SHCommand.hpp"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "Tools/SHDeque.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -22,7 +23,8 @@ namespace SHADE
|
||||||
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
|
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
|
||||||
using CommandStack = std::stack<BaseCommandPtr>;
|
using CommandStack = SHDeque<BaseCommandPtr>;
|
||||||
|
using CommandStackPtr = CommandStack*;
|
||||||
|
|
||||||
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
static void RegisterCommand(BaseCommandPtr commandPtr);
|
static void RegisterCommand(BaseCommandPtr commandPtr);
|
||||||
|
@ -34,8 +36,17 @@ namespace SHADE
|
||||||
static void PopLatestCommandFromRedoStack();
|
static void PopLatestCommandFromRedoStack();
|
||||||
static void PopLatestCommandFromUndoStack();
|
static void PopLatestCommandFromUndoStack();
|
||||||
|
|
||||||
|
static void SwapStacks();
|
||||||
|
static void ClearAll();
|
||||||
|
|
||||||
|
static constexpr CommandStack::SizeType defaultStackSize = 100;
|
||||||
private:
|
private:
|
||||||
|
static CommandStackPtr pCurrUndoStack;
|
||||||
|
static CommandStackPtr pCurrRedoStack;
|
||||||
|
|
||||||
static CommandStack undoStack;
|
static CommandStack undoStack;
|
||||||
|
static CommandStack secondaryUndoStack;
|
||||||
static CommandStack redoStack;
|
static CommandStack redoStack;
|
||||||
|
static CommandStack secondaryRedoStack;
|
||||||
};
|
};
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAssetBrowser::SHAssetBrowser()
|
SHAssetBrowser::SHAssetBrowser()
|
||||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt)
|
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,23 +34,48 @@ namespace SHADE
|
||||||
RecursivelyDrawTree(rootFolder);
|
RecursivelyDrawTree(rootFolder);
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
DrawCurrentFolder();
|
DrawCurrentFolder();
|
||||||
|
DrawAssetBeingCreated();
|
||||||
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
if(refreshQueued)
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetBrowser::QueueRefresh() noexcept
|
||||||
|
{
|
||||||
|
refreshQueued = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetBrowser::Refresh() noexcept
|
||||||
|
{
|
||||||
|
SHAssetManager::RefreshDirectory();
|
||||||
|
rootFolder = SHAssetManager::GetRootFolder();
|
||||||
|
refreshQueued = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetBrowser::DrawMenuBar()
|
void SHAssetBrowser::DrawMenuBar()
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
if(ImGui::SmallButton(ICON_MD_SYNC))
|
||||||
|
{
|
||||||
|
QueueRefresh();
|
||||||
|
}
|
||||||
|
if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS))
|
||||||
|
{
|
||||||
|
isAssetBeingCreated = true;
|
||||||
|
}
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if !compiled, set genMeta to true
|
||||||
|
|
||||||
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
|
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
|
||||||
{
|
{
|
||||||
auto const& subFolders = folder->subFolders;
|
auto const& subFolders = folder->subFolders;
|
||||||
auto const& files = folder->files;
|
auto files = folder->files;
|
||||||
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
|
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
|
||||||
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
|
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
|
@ -62,21 +87,10 @@ namespace SHADE
|
||||||
ImGuiID folderID = ImGui::GetItemID();
|
ImGuiID folderID = ImGui::GetItemID();
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
if (ImGui::BeginPopupContextItem())
|
//if (ImGui::BeginPopupContextItem())
|
||||||
{
|
//{
|
||||||
if (ImGui::BeginMenu("Create Asset"))
|
// ImGui::EndPopup();
|
||||||
{
|
//}
|
||||||
//TODO: Change to rttr type enum align
|
|
||||||
if (ImGui::Selectable("Material"))
|
|
||||||
{
|
|
||||||
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
|
|
||||||
ImGui::TreeNodeSetOpen(folderID, true);
|
|
||||||
isOpen = true;
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::IsItemClicked())
|
if (ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
|
@ -100,7 +114,7 @@ namespace SHADE
|
||||||
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
vertLineEnd.y = midPoint;
|
vertLineEnd.y = midPoint;
|
||||||
}
|
}
|
||||||
for (auto const& file : files)
|
for (auto& file : files)
|
||||||
{
|
{
|
||||||
const float horizontalLineSize = 25.0f;
|
const float horizontalLineSize = 25.0f;
|
||||||
const ImRect childRect = DrawFile(file);
|
const ImRect childRect = DrawFile(file);
|
||||||
|
@ -109,8 +123,6 @@ namespace SHADE
|
||||||
vertLineEnd.y = midPoint;
|
vertLineEnd.y = midPoint;
|
||||||
}
|
}
|
||||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
|
|
||||||
DrawAssetBeingCreated();
|
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
@ -146,47 +158,74 @@ namespace SHADE
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept
|
ImRect SHAssetBrowser::DrawFile(SHFile& file) noexcept
|
||||||
{
|
{
|
||||||
if (file.assetMeta == nullptr)
|
if(file.compilable)
|
||||||
|
{
|
||||||
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
||||||
|
static constexpr std::string_view icon = ICON_MD_FILE_PRESENT;
|
||||||
|
ImGui::PushID(file.name.data());
|
||||||
|
bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data());
|
||||||
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
if(ImGui::BeginPopupContextItem())
|
||||||
|
{
|
||||||
|
if(ImGui::Selectable("Compile"))
|
||||||
|
{
|
||||||
|
SHAssetManager::CompileAsset(file.path, !file.compiled);
|
||||||
|
QueueRefresh();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
ImGui::TreePop();
|
||||||
|
ImGui::PopID();
|
||||||
|
return nodeRect;
|
||||||
|
}
|
||||||
|
if(file.assetMeta)
|
||||||
|
DrawAsset(file.assetMeta, file.ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept
|
||||||
|
{
|
||||||
|
if (asset == nullptr)
|
||||||
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end();
|
const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end();
|
||||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf;
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
flags |= ImGuiTreeNodeFlags_Selected;
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
std::string icon{};
|
std::string icon{};
|
||||||
|
|
||||||
switch (file.assetMeta->type)
|
switch (asset->type)
|
||||||
{
|
{
|
||||||
case AssetType::INVALID: break;
|
case AssetType::INVALID: break;
|
||||||
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||||
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||||
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||||
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
case AssetType::MODEL: icon = ICON_FA_CUBES_STACKED; break;
|
||||||
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||||
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||||
case AssetType::MATERIAL: break;
|
case AssetType::MATERIAL: break;
|
||||||
|
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||||
case AssetType::MAX_COUNT: break;
|
case AssetType::MAX_COUNT: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
|
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data());
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
if (SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
auto id = file.assetMeta->id;
|
auto id = asset->id;
|
||||||
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
|
ImGui::Text("Moving Asset: %s [%zu]", asset->name.data(), asset->id);
|
||||||
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemClicked())
|
if (ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
selectedAssets.clear();
|
selectedAssets.clear();
|
||||||
selectedAssets.push_back(file.assetMeta->id);
|
selectedAssets.push_back(asset->id);
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
switch (file.assetMeta->type)
|
switch (asset->type)
|
||||||
{
|
{
|
||||||
case AssetType::INVALID: break;
|
case AssetType::INVALID: break;
|
||||||
case AssetType::SHADER: break;
|
case AssetType::SHADER: break;
|
||||||
|
@ -196,40 +235,92 @@ namespace SHADE
|
||||||
case AssetType::SCENE:
|
case AssetType::SCENE:
|
||||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
{
|
{
|
||||||
editor->LoadScene(file.assetMeta->id);
|
editor->LoadScene(asset->id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AssetType::PREFAB: break;
|
case AssetType::PREFAB: break;
|
||||||
case AssetType::MATERIAL:
|
case AssetType::MATERIAL:
|
||||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||||
{
|
{
|
||||||
matInspector->OpenMaterial(file.assetMeta->id);
|
matInspector->OpenMaterial(asset->id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AssetType::MAX_COUNT: break;
|
case AssetType::MAX_COUNT: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
|
||||||
|
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
if(isOpen)
|
||||||
|
{
|
||||||
|
for(auto const& subAsset : asset->subAssets)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 25.0f;
|
||||||
|
const ImRect childRect = DrawAsset(subAsset);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
|
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
|
||||||
{
|
{
|
||||||
if (!assetBeingCreated.has_value())
|
if(isAssetBeingCreated)
|
||||||
return;
|
ImGui::OpenPopup(newAssetPopup.data());
|
||||||
auto& path = std::get<0>(assetBeingCreated.value());
|
|
||||||
auto& type = std::get<1>(assetBeingCreated.value());
|
if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated))
|
||||||
auto& assetName = std::get<2>(assetBeingCreated.value());
|
|
||||||
if (ImGui::InputText("##newAssetname", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
|
|
||||||
{
|
{
|
||||||
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
|
ImGui::RadioButton("Material", true);
|
||||||
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
ImGui::SameLine();
|
||||||
|
if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
|
||||||
{
|
{
|
||||||
matInspector->OpenMaterial(assetId, true);
|
AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated);
|
||||||
|
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||||
|
{
|
||||||
|
matInspector->OpenMaterial(assetId, true);
|
||||||
|
}
|
||||||
|
nameOfAssetBeingCreated.clear();
|
||||||
|
QueueRefresh();
|
||||||
|
isAssetBeingCreated = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
assetBeingCreated.reset();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
//if (ImGui::BeginMenu("Create Asset"))
|
||||||
|
//{
|
||||||
|
// //TODO: Change to rttr type enum align
|
||||||
|
// if (ImGui::Selectable("Material"))
|
||||||
|
// {
|
||||||
|
// assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" };
|
||||||
|
// ImGui::TreeNodeSetOpen(folderID, true);
|
||||||
|
// isOpen = true;
|
||||||
|
// }
|
||||||
|
// ImGui::EndMenu();
|
||||||
|
//}
|
||||||
|
//if (!assetBeingCreated.has_value())
|
||||||
|
// return;
|
||||||
|
//auto& path = std::get<0>(assetBeingCreated.value());
|
||||||
|
//auto& type = std::get<1>(assetBeingCreated.value());
|
||||||
|
//auto& assetName = std::get<2>(assetBeingCreated.value());
|
||||||
|
//if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
|
||||||
|
//{
|
||||||
|
// AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
|
||||||
|
// if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||||
|
// {
|
||||||
|
// matInspector->OpenMaterial(assetId, true);
|
||||||
|
// }
|
||||||
|
// assetBeingCreated.reset();
|
||||||
|
// QueueRefresh();
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,24 +10,29 @@ namespace SHADE
|
||||||
class SHAssetBrowser final : public SHEditorWindow
|
class SHAssetBrowser final : public SHEditorWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
|
|
||||||
SHAssetBrowser();
|
SHAssetBrowser();
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
void Refresh();
|
void QueueRefresh() noexcept;
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar();
|
void DrawMenuBar();
|
||||||
ImRect RecursivelyDrawTree(FolderPointer folder);
|
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||||
void DrawCurrentFolder();
|
void DrawCurrentFolder();
|
||||||
ImRect DrawFile(SHFile const& file) noexcept;
|
ImRect DrawFile(SHFile& file) noexcept;
|
||||||
|
ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept;
|
||||||
void DrawAssetBeingCreated() noexcept;
|
void DrawAssetBeingCreated() noexcept;
|
||||||
|
|
||||||
|
void Refresh() noexcept;
|
||||||
|
|
||||||
FolderPointer rootFolder, prevFolder, currentFolder;
|
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||||
std::optional<AssetEntry> assetBeingCreated;
|
|
||||||
std::vector<FolderPointer> selectedFolders;
|
std::vector<FolderPointer> selectedFolders;
|
||||||
std::vector<AssetID> selectedAssets;
|
std::vector<AssetID> selectedAssets;
|
||||||
static constexpr float tileWidth = 50.0f;
|
static constexpr float tileWidth = 50.0f;
|
||||||
|
bool refreshQueued = false;
|
||||||
|
bool isAssetBeingCreated = false;
|
||||||
|
static constexpr std::string_view newAssetPopup = "Create New Asset";
|
||||||
|
std::string nameOfAssetBeingCreated;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,7 +419,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Execute()
|
void SHEntityParentCommand::Execute()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].newParentEID == MAX_EID)
|
if (entityParentData[eid].newParentEID == MAX_EID)
|
||||||
|
@ -431,7 +431,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Undo()
|
void SHEntityParentCommand::Undo()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].oldParentEID == MAX_EID)
|
if (entityParentData[eid].oldParentEID == MAX_EID)
|
||||||
|
|
|
@ -224,9 +224,6 @@ namespace SHADE
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get transform component for extrapolating relative sizes
|
|
||||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
|
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -234,46 +231,39 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
auto& colliders = component->GetColliders();
|
auto& colliders = component->GetCollisionShapes();
|
||||||
int const size = static_cast<int>(colliders.size());
|
int const size = static_cast<int>(colliders.size());
|
||||||
ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
||||||
std::optional<int> colliderToDelete{ std::nullopt };
|
std::optional<int> colliderToDelete{ std::nullopt };
|
||||||
for (int i{}; i < size; ++i)
|
for (int i{}; i < size; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
SHCollider* collider = &component->GetCollider(i);
|
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
//collider->IsTrigger
|
//collider->IsTrigger
|
||||||
|
|
||||||
if (collider->GetType() == SHCollider::Type::BOX)
|
if (collider->GetType() == SHCollisionShape::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", 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());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
|
[box] { return box->GetRelativeExtents(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", 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());
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[sphere, transformComponent]
|
[sphere] { return sphere->GetRelativeRadius(); },
|
||||||
{
|
|
||||||
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) * 2.0f;
|
|
||||||
},
|
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,13 +93,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
EntityID const& eid = editor->selectedEntities[0];
|
EntityID const& eid = editor->selectedEntities[0];
|
||||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
if(!entity)
|
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid);
|
||||||
|
if(!entity || !entityNode)
|
||||||
{
|
{
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::InputText("##EntityName", &entity->name);
|
ImGui::InputText("##EntityName", &entity->name);
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
@ -43,8 +46,7 @@ namespace SHADE
|
||||||
void SHEditorMenuBar::Init()
|
void SHEditorMenuBar::Init()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Init();
|
SHEditorWindow::Init();
|
||||||
constexpr std::string_view path = "../../Assets/Editor/Layouts";
|
for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
|
||||||
for(auto const& entry : std::filesystem::directory_iterator(path))
|
|
||||||
{
|
{
|
||||||
layoutPaths.push_back(entry.path());
|
layoutPaths.push_back(entry.path());
|
||||||
}
|
}
|
||||||
|
@ -117,16 +119,22 @@ namespace SHADE
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->GenerateScriptsCsProjFile();
|
scriptEngine->GenerateScriptsCsProjFile();
|
||||||
}
|
}
|
||||||
|
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
||||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
{
|
{
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
scriptEngine->BuildScriptAssembly(true, true);
|
scriptEngine->BuildScriptAssembly(true, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Build Scripts - Release"))
|
if (ImGui::Selectable("Build Scripts - Release"))
|
||||||
{
|
{
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
scriptEngine->BuildScriptAssembly(false, true);
|
scriptEngine->BuildScriptAssembly(false, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,39 +223,20 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if(editor->SaveScene())
|
if(editor->SaveScene())
|
||||||
{
|
{
|
||||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
editor->Play();
|
||||||
{
|
|
||||||
.previousState = editor->editorState
|
|
||||||
};
|
|
||||||
editor->editorState = SHEditor::State::PLAY;
|
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||||
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
||||||
{
|
{
|
||||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
editor->Pause();
|
||||||
{
|
|
||||||
.previousState = editor->editorState
|
|
||||||
};
|
|
||||||
editor->editorState = SHEditor::State::PAUSE;
|
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
|
||||||
if(ImGui::SmallButton(ICON_MD_STOP))
|
if(ImGui::SmallButton(ICON_MD_STOP))
|
||||||
{
|
{
|
||||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
editor->Stop();
|
||||||
{
|
|
||||||
.previousState = editor->editorState
|
|
||||||
};
|
|
||||||
editor->editorState = SHEditor::State::STOP;
|
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
|
||||||
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace SHADE
|
||||||
shouldUpdateCamera = false;
|
shouldUpdateCamera = false;
|
||||||
}
|
}
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
|
@ -51,7 +52,6 @@ namespace SHADE
|
||||||
beginCursorPos = ImGui::GetCursorScreenPos();
|
beginCursorPos = ImGui::GetCursorScreenPos();
|
||||||
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
|
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
|
||||||
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
|
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
|
||||||
|
|
||||||
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
|
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
|
||||||
|
|
||||||
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
|
@ -64,24 +64,25 @@ namespace SHADE
|
||||||
|
|
||||||
shouldUpdateCamera = true;
|
shouldUpdateCamera = true;
|
||||||
}
|
}
|
||||||
if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
{
|
{
|
||||||
if (ImGui::IsKeyReleased(ImGuiKey_Q))
|
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
}
|
}
|
||||||
if (ImGui::IsKeyReleased(ImGuiKey_W))
|
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
}
|
}
|
||||||
if (ImGui::IsKeyReleased(ImGuiKey_E))
|
if (ImGui::IsKeyReleased(ImGuiKey_R))
|
||||||
{
|
{
|
||||||
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||||
transformGizmo.Draw();
|
if(editor->editorState != SHEditor::State::PLAY)
|
||||||
|
transformGizmo.Draw();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ RTTR_REGISTRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" };
|
||||||
|
const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" };
|
||||||
|
const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"};
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -106,7 +110,7 @@ namespace SHADE
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
io->IniFilename = USER_LAYOUT_PATH.data();
|
||||||
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
InitLayout();
|
InitLayout();
|
||||||
|
|
||||||
|
@ -164,6 +168,18 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHCommandManager::UndoCommand();
|
SHCommandManager::UndoCommand();
|
||||||
}
|
}
|
||||||
|
if(ImGui::IsKeyReleased(ImGuiKey_F5))
|
||||||
|
{
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
|
||||||
|
{
|
||||||
|
Pause();
|
||||||
|
}
|
||||||
|
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
|
@ -236,20 +252,20 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if(!std::filesystem::exists(io->IniFilename))
|
if(!std::filesystem::exists(io->IniFilename))
|
||||||
{
|
{
|
||||||
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename);
|
std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename);
|
||||||
}
|
}
|
||||||
//eventually load preferred layout here
|
//eventually load preferred layout here
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::InitFonts() noexcept
|
void SHEditor::InitFonts() noexcept
|
||||||
{
|
{
|
||||||
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path
|
||||||
|
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,9 +517,12 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd)
|
||||||
|
{
|
||||||
|
cmd->BeginLabeledSegment("ImGui Draw");
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
});
|
cmd->EndLabeledSegment();
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,6 +609,48 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::Play()
|
||||||
|
{
|
||||||
|
if(editorState == State::PLAY)
|
||||||
|
return;
|
||||||
|
if (SaveScene())
|
||||||
|
{
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editorState
|
||||||
|
};
|
||||||
|
editorState = State::PLAY;
|
||||||
|
SHCommandManager::SwapStacks();
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditor::Pause()
|
||||||
|
{
|
||||||
|
if (editorState == State::PAUSE)
|
||||||
|
return;
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editorState
|
||||||
|
};
|
||||||
|
editorState = State::PAUSE;
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditor::Stop()
|
||||||
|
{
|
||||||
|
if (editorState == State::STOP)
|
||||||
|
return;
|
||||||
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
|
{
|
||||||
|
.previousState = editorState
|
||||||
|
};
|
||||||
|
editorState = SHEditor::State::STOP;
|
||||||
|
SHCommandManager::SwapStacks();
|
||||||
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
|
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::NewFrame()
|
void SHEditor::NewFrame()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
|
@ -184,6 +184,10 @@ namespace SHADE
|
||||||
|
|
||||||
void LoadScene(AssetID const& assetID) noexcept;
|
void LoadScene(AssetID const& assetID) noexcept;
|
||||||
|
|
||||||
|
void Play();
|
||||||
|
void Pause();
|
||||||
|
void Stop();
|
||||||
|
|
||||||
// List of selected entities
|
// List of selected entities
|
||||||
std::vector<EntityID> selectedEntities;
|
std::vector<EntityID> selectedEntities;
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ namespace SHADE
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
|
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
|
@ -296,7 +296,7 @@ namespace SHADE
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
if (entity)
|
if (!alwaysNull && entity)
|
||||||
{
|
{
|
||||||
oss << value << ": " << entity->name;
|
oss << value << ": " << entity->name;
|
||||||
}
|
}
|
||||||
|
@ -314,6 +314,13 @@ namespace SHADE
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Clear"))
|
||||||
|
{
|
||||||
|
value = MAX_EID;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,8 +313,12 @@ namespace SHADE
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</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>
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <param name="alwaysNull>
|
||||||
|
/// If set, the field displayed will always be blank regardless of specified
|
||||||
|
/// GameObject.
|
||||||
|
/// </param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a combo box for enumeration input.
|
/// Creates a combo box for enumeration input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
||||||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "SHFileSystem.h"
|
#include "SHFileSystem.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "Assets/SHAssetMetaHandler.h"
|
#include "Assets/SHAssetMetaHandler.h"
|
||||||
|
|
||||||
|
@ -24,29 +25,77 @@ namespace SHADE
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
|
bool SHFileSystem::IsCompilable(std::string ext) noexcept
|
||||||
|
{
|
||||||
|
for (auto const& external : EXTERNALS)
|
||||||
|
{
|
||||||
|
if (ext == external)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHFileSystem::MatchExtention(FileExt raw, FileExt compiled) noexcept
|
||||||
|
{
|
||||||
|
if (raw == GLSL_EXTENSION)
|
||||||
|
{
|
||||||
|
if (compiled == SHADER_EXTENSION ||
|
||||||
|
compiled == SHADER_BUILT_IN_EXTENSION)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (raw == DDS_EXTENSION)
|
||||||
|
{
|
||||||
|
if (compiled == TEXTURE_EXTENSION)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (raw == FBX_EXTENSION)
|
||||||
|
{
|
||||||
|
if (compiled == MODEL_EXTENSION)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (raw == GLTF_EXTENSION)
|
||||||
|
{
|
||||||
|
if (compiled == MODEL_EXTENSION)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
|
||||||
{
|
{
|
||||||
std::queue<FolderPointer> folderQueue;
|
std::stack<FolderPointer> folderStack;
|
||||||
root = new SHFolder("root");
|
root = new SHFolder("root");
|
||||||
root->path = path;
|
root->path = path;
|
||||||
folderQueue.push(root);
|
folderStack.push(root);
|
||||||
|
|
||||||
while (!folderQueue.empty())
|
while (!folderStack.empty())
|
||||||
{
|
{
|
||||||
auto const folder = folderQueue.front();
|
auto const folder = folderStack.top();
|
||||||
folderQueue.pop();
|
folderStack.pop();
|
||||||
|
|
||||||
std::vector<SHAsset> assets;
|
std::vector<SHAsset> assets;
|
||||||
|
|
||||||
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
|
// Get all subfolders/files in this current folder
|
||||||
|
for (auto& dirEntry : std::filesystem::directory_iterator(folder->path))
|
||||||
{
|
{
|
||||||
auto const& path = dirEntry.path();
|
auto path = dirEntry.path();
|
||||||
|
path.make_preferred();
|
||||||
if (!dirEntry.is_directory())
|
if (!dirEntry.is_directory())
|
||||||
{
|
{
|
||||||
if (path.extension().string() == META_EXTENSION)
|
if (path.extension().string() == META_EXTENSION)
|
||||||
{
|
{
|
||||||
//auto asset = SHAssetMetaHandler::RetrieveMetaData(path);
|
|
||||||
//assetCollection.insert({ asset.id, asset });
|
|
||||||
assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path));
|
assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -55,14 +104,17 @@ namespace SHADE
|
||||||
path.stem().string(),
|
path.stem().string(),
|
||||||
path.string(),
|
path.string(),
|
||||||
path.extension().string(),
|
path.extension().string(),
|
||||||
nullptr
|
nullptr,
|
||||||
|
IsCompilable(path.extension().string()),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If item is folder
|
||||||
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
||||||
folderQueue.push(newFolder);
|
folderStack.push(newFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& asset : assets)
|
for (auto const& asset : assets)
|
||||||
|
@ -72,11 +124,58 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (file.name == asset.name)
|
if (file.name == asset.name)
|
||||||
{
|
{
|
||||||
file.assetMeta = &assetCollection[asset.id];
|
AssetPath path{ file.path };
|
||||||
break;
|
if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
|
||||||
|
{
|
||||||
|
file.assetMeta = &assetCollection[asset.id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i {0}; i < folder->files.size(); ++i)
|
||||||
|
{
|
||||||
|
auto& file = folder->files[i];
|
||||||
|
if (file.compilable)
|
||||||
|
{
|
||||||
|
for (auto j{ 0 }; j < folder->files.size(); ++j)
|
||||||
|
{
|
||||||
|
auto& check = folder->files[j];
|
||||||
|
if (i == j || check.compilable)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.name == check.name)
|
||||||
|
{
|
||||||
|
if (MatchExtention(file.ext, check.ext))
|
||||||
|
{
|
||||||
|
file.compiled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHFileSystem::DestroyDirectory(FolderPointer root) noexcept
|
||||||
|
{
|
||||||
|
std::stack<FolderPointer> folderStack;
|
||||||
|
folderStack.push(root);
|
||||||
|
|
||||||
|
while(!folderStack.empty())
|
||||||
|
{
|
||||||
|
auto const folder = folderStack.top();
|
||||||
|
folderStack.pop();
|
||||||
|
|
||||||
|
for (auto const& ptr : folder->subFolders)
|
||||||
|
{
|
||||||
|
folderStack.push(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete folder;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
|
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
|
||||||
|
static void DestroyDirectory(FolderPointer root) noexcept;
|
||||||
private:
|
private:
|
||||||
static bool DeleteFolder(FolderPointer location) noexcept;
|
static bool DeleteFolder(FolderPointer location) noexcept;
|
||||||
|
static bool IsCompilable(std::string ext) noexcept;
|
||||||
|
static bool MatchExtention(FileExt raw, FileExt compiled) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -33,6 +33,8 @@ namespace SHADE
|
||||||
FilePath path;
|
FilePath path;
|
||||||
FileExt ext;
|
FileExt ext;
|
||||||
SHAsset const* assetMeta;
|
SHAsset const* assetMeta;
|
||||||
|
bool compilable;
|
||||||
|
bool compiled;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHFolder
|
class SHFolder
|
||||||
|
|
|
@ -217,9 +217,11 @@ namespace SHADE
|
||||||
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
|
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &stagingAlloc, &allocInfo);
|
&tempBuffer, &stagingAlloc, &allocInfo);
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name);
|
||||||
|
|
||||||
// then assign it to the hpp version
|
// then assign it to the hpp version
|
||||||
stagingBuffer = tempBuffer;
|
stagingBuffer = tempBuffer;
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name);
|
||||||
|
|
||||||
// Just map, copy then unmap
|
// Just map, copy then unmap
|
||||||
void* stagingBufferMappedPtr = nullptr;
|
void* stagingBufferMappedPtr = nullptr;
|
||||||
|
@ -251,7 +253,11 @@ namespace SHADE
|
||||||
auto result = vmaCreateBuffer(vmaAllocator,
|
auto result = vmaCreateBuffer(vmaAllocator,
|
||||||
&bufferCreateInfo.operator VkBufferCreateInfo & (),
|
&bufferCreateInfo.operator VkBufferCreateInfo & (),
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &alloc, &allocInfo);
|
&tempBuffer, &alloc, &allocInfo);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (!name.empty())
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] " + name);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
|
||||||
|
@ -269,7 +275,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkBuffer::SHVkBuffer(std::reference_wrapper<VmaAllocator const> allocator) noexcept
|
SHVkBuffer::SHVkBuffer(Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept
|
||||||
: vkBuffer{}
|
: vkBuffer{}
|
||||||
, stagingBuffer{}
|
, stagingBuffer{}
|
||||||
, sizeStored{ 0 }
|
, sizeStored{ 0 }
|
||||||
|
@ -277,19 +283,23 @@ namespace SHADE
|
||||||
, alloc {nullptr}
|
, alloc {nullptr}
|
||||||
, randomAccessOptimized{false}
|
, randomAccessOptimized{false}
|
||||||
, vmaAllocator{allocator}
|
, vmaAllocator{allocator}
|
||||||
|
, device { logicalDevice }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHVkBuffer::SHVkBuffer(
|
SHVkBuffer::SHVkBuffer(
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice,
|
||||||
uint32_t inSize,
|
uint32_t inSize,
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
std::reference_wrapper<VmaAllocator const> allocator,
|
std::reference_wrapper<VmaAllocator const> allocator,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
|
const std::string& name,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept
|
) noexcept
|
||||||
: SHVkBuffer(allocator)
|
: SHVkBuffer(logicalDevice, allocator)
|
||||||
{
|
{
|
||||||
|
this->name = name;
|
||||||
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
|
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +314,8 @@ namespace SHADE
|
||||||
, bufferUsageFlags {rhs.bufferUsageFlags}
|
, bufferUsageFlags {rhs.bufferUsageFlags}
|
||||||
, bufferCreateInfo { rhs.bufferCreateInfo }
|
, bufferCreateInfo { rhs.bufferCreateInfo }
|
||||||
, allocCreateInfo { rhs.allocCreateInfo }
|
, allocCreateInfo { rhs.allocCreateInfo }
|
||||||
|
, name { std::move(rhs.name) }
|
||||||
|
, device { rhs.device }
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.vkBuffer = VK_NULL_HANDLE;
|
rhs.vkBuffer = VK_NULL_HANDLE;
|
||||||
|
@ -325,6 +337,8 @@ namespace SHADE
|
||||||
bufferCreateInfo = rhs.bufferCreateInfo;
|
bufferCreateInfo = rhs.bufferCreateInfo;
|
||||||
allocCreateInfo = rhs.allocCreateInfo;
|
allocCreateInfo = rhs.allocCreateInfo;
|
||||||
bufferUsageFlags = rhs.bufferUsageFlags;
|
bufferUsageFlags = rhs.bufferUsageFlags;
|
||||||
|
name = std::move(rhs.name);
|
||||||
|
device = rhs.device;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -402,6 +416,8 @@ namespace SHADE
|
||||||
|
|
||||||
auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
|
auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
|
||||||
vkBuffer = tempBuffer;
|
vkBuffer = tempBuffer;
|
||||||
|
if (!name.empty())
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, vkBuffer, "[Buffer] " + name);
|
||||||
|
|
||||||
// This probably means that a HOST_CACHED memory type is used on allocation
|
// This probably means that a HOST_CACHED memory type is used on allocation
|
||||||
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
|
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace SHADE
|
||||||
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
|
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
|
||||||
|
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
|
||||||
class SHVkBuffer
|
class SHVkBuffer
|
||||||
{
|
{
|
||||||
|
@ -51,6 +52,11 @@ namespace SHADE
|
||||||
//VmaAllocator const& vmaAllocator;
|
//VmaAllocator const& vmaAllocator;
|
||||||
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
||||||
|
|
||||||
|
//! Name of this buffer if any
|
||||||
|
std::string name;
|
||||||
|
//! Handle to the logical device that created this buffer
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -62,13 +68,15 @@ namespace SHADE
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHVkBuffer (void) noexcept = delete;
|
SHVkBuffer (void) noexcept = delete;
|
||||||
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept;
|
SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
|
||||||
SHVkBuffer (
|
SHVkBuffer (
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice,
|
||||||
uint32_t inSize,
|
uint32_t inSize,
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
std::reference_wrapper<VmaAllocator const> allocator,
|
std::reference_wrapper<VmaAllocator const> allocator,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
|
const std::string& name = "",
|
||||||
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlags allocFlags = {}
|
VmaAllocationCreateFlags allocFlags = {}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
|
@ -105,6 +105,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Set the state to recording if the call above succeeded.
|
// Set the state to recording if the call above succeeded.
|
||||||
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
|
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
|
||||||
|
|
||||||
|
// Reset segment count
|
||||||
|
segmentDepth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -507,6 +510,41 @@ namespace SHADE
|
||||||
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::BeginLabeledSegment(const std::string& label) noexcept
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static const std::array SEGMENT_COLOURS =
|
||||||
|
{
|
||||||
|
SHColour::LIGHTPINK,
|
||||||
|
SHColour::LIGHTBLUE,
|
||||||
|
SHColour::LIGHTGREEN,
|
||||||
|
SHColour::YELLOW,
|
||||||
|
SHColour::PINK,
|
||||||
|
SHColour::TEAL,
|
||||||
|
SHColour::LIME,
|
||||||
|
SHColour::ORANGE,
|
||||||
|
SHColour::VIOLET,
|
||||||
|
SHColour::MAROON,
|
||||||
|
SHColour::DARKGREEN,
|
||||||
|
SHColour::SANDYBROWN
|
||||||
|
};
|
||||||
|
|
||||||
|
const SHColour COLOR = SEGMENT_COLOURS[segmentDepth];
|
||||||
|
++segmentDepth;
|
||||||
|
if (segmentDepth >= static_cast<int>(SEGMENT_COLOURS.size()))
|
||||||
|
segmentDepth = 0;
|
||||||
|
vkCommandBuffer.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT().setPLabelName(label.data()).setColor({ COLOR.x, COLOR.y, COLOR.z, COLOR.w }));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::EndLabeledSegment() noexcept
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
vkCommandBuffer.endDebugUtilsLabelEXT();
|
||||||
|
segmentDepth = std::max(segmentDepth - 1, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
||||||
//{
|
//{
|
||||||
// //vkCommandBuffer.pipelineBarrier()
|
// //vkCommandBuffer.pipelineBarrier()
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Resource/SHResourceLibrary.h"
|
#include "Resource/SHResourceLibrary.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
||||||
#include "Graphics/Pipeline/SHPipelineType.h"
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -80,6 +81,9 @@ namespace SHADE
|
||||||
//! The push constant data for the command buffer
|
//! The push constant data for the command buffer
|
||||||
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
||||||
|
|
||||||
|
//! Depth of segmenting of the command buffer (used for debug data)
|
||||||
|
int segmentDepth;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -107,7 +111,7 @@ namespace SHADE
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
// Begins and Ends
|
// Begins and Ends
|
||||||
void BeginRecording (void) noexcept;
|
void BeginRecording () noexcept;
|
||||||
void EndRecording (void) noexcept;
|
void EndRecording (void) noexcept;
|
||||||
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
||||||
void EndRenderpass (void) noexcept;
|
void EndRenderpass (void) noexcept;
|
||||||
|
@ -148,6 +152,10 @@ namespace SHADE
|
||||||
bool IsReadyToSubmit (void) const noexcept;
|
bool IsReadyToSubmit (void) const noexcept;
|
||||||
void HandlePostSubmit (void) noexcept;
|
void HandlePostSubmit (void) noexcept;
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
void BeginLabeledSegment(const std::string& label) noexcept;
|
||||||
|
void EndLabeledSegment() noexcept;
|
||||||
|
|
||||||
// Push Constant variable setting
|
// Push Constant variable setting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
|
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
|
||||||
|
|
|
@ -220,6 +220,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
|
||||||
|
SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device");
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVMA();
|
InitializeVMA();
|
||||||
|
@ -419,9 +420,9 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept
|
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags, const std::string& name) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags);
|
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -455,12 +456,12 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, w, h, levels, format, usage, create);
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef SH_LOGICAL_DEVICE_H
|
#pragma once
|
||||||
#define SH_LOGICAL_DEVICE_H
|
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -67,7 +66,6 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
|
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -147,7 +145,8 @@ namespace SHADE
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags,
|
||||||
|
const std::string& name = ""
|
||||||
) const noexcept;
|
) const noexcept;
|
||||||
|
|
||||||
Handle<SHVkImage> CreateImage (
|
Handle<SHVkImage> CreateImage (
|
||||||
|
@ -202,7 +201,33 @@ namespace SHADE
|
||||||
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
||||||
|
|
||||||
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
||||||
void UpdateDescriptorSet (vk::WriteDescriptorSet const& writeDescSet) noexcept;
|
void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Debug Tools */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a Vulkan HPP object's name for debugging purposes. This function will not be
|
||||||
|
/// compiled outside of Debug configurations. Hence, it is advised to use provided
|
||||||
|
/// macro function SET_VK_OBJ_NAME() instead of using this function directly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objType">Type of the object.</param>
|
||||||
|
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
|
||||||
|
/// <param name="objName">Object's name.</param>
|
||||||
|
template<typename T>
|
||||||
|
inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName);
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a Vulkan object's name for debugging purposes. This function will not be
|
||||||
|
/// compiled outside of Debug configurations. Hence, it is advised to use provided
|
||||||
|
/// macro function SET_VK_OBJ_NAME_VK() instead of using this function directly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objType">Type of the object.</param>
|
||||||
|
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
|
||||||
|
/// <param name="objName">Object's name.</param>
|
||||||
|
template<typename T>
|
||||||
|
inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
@ -220,4 +245,4 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#include "SHVkLogicalDevice.hpp"
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkLogicalDevice.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 4, 2022
|
||||||
|
\brief Contains implementation of inline and template functions of
|
||||||
|
SHVkLogicalDevice.
|
||||||
|
|
||||||
|
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 "SHVkLogicalDevice.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Debug Tools */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
template<typename T>
|
||||||
|
void SHVkLogicalDevice::SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName)
|
||||||
|
{
|
||||||
|
if (objName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk::DebugUtilsObjectNameInfoEXT info;
|
||||||
|
info.objectType = objType;
|
||||||
|
info.objectHandle = (uint64_t) static_cast<typename T::NativeType>(objHandle);
|
||||||
|
info.pObjectName = objName.data();
|
||||||
|
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void SHVkLogicalDevice::SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName)
|
||||||
|
{
|
||||||
|
if (objName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk::DebugUtilsObjectNameInfoEXT info;
|
||||||
|
info.objectType = objType;
|
||||||
|
info.objectHandle = (uint64_t) objVkHandle;
|
||||||
|
info.pObjectName = objName.data();
|
||||||
|
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------*/
|
||||||
|
/* Macro Definitions */
|
||||||
|
/*-------------------------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
|
||||||
|
DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
|
||||||
|
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
|
||||||
|
DEVICE->SetVulkanObjectNameVk(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
|
||||||
|
#else
|
||||||
|
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
|
||||||
|
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
|
||||||
|
#endif
|
|
@ -61,6 +61,7 @@ namespace SHADE
|
||||||
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
|
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &stagingAlloc, &allocInfo);
|
&tempBuffer, &stagingAlloc, &allocInfo);
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging Buffer for Image");
|
||||||
|
|
||||||
// then assign it to the hpp version
|
// then assign it to the hpp version
|
||||||
stagingBuffer = tempBuffer;
|
stagingBuffer = tempBuffer;
|
||||||
|
@ -107,6 +108,8 @@ namespace SHADE
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
vkImage = tempImage;
|
vkImage = tempImage;
|
||||||
|
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
@ -115,7 +118,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
Handle<SHVkLogicalDevice> logicalDeviceHdl,
|
||||||
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
const unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
|
@ -137,6 +141,7 @@ namespace SHADE
|
||||||
, boundToCoherent{false}
|
, boundToCoherent{false}
|
||||||
, randomAccessOptimized {false}
|
, randomAccessOptimized {false}
|
||||||
, mappedPtr{nullptr}
|
, mappedPtr{nullptr}
|
||||||
|
, device { logicalDeviceHdl }
|
||||||
{
|
{
|
||||||
usageFlags = imageDetails.usageFlags;
|
usageFlags = imageDetails.usageFlags;
|
||||||
createFlags = imageDetails.createFlags;
|
createFlags = imageDetails.createFlags;
|
||||||
|
@ -175,7 +180,9 @@ namespace SHADE
|
||||||
VmaAllocationInfo allocInfo{};
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
|
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
@ -220,7 +227,7 @@ namespace SHADE
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
SHVkImage::SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
||||||
: width {w}
|
: width {w}
|
||||||
, height{h}
|
, height{h}
|
||||||
, depth {1}
|
, depth {1}
|
||||||
|
@ -230,11 +237,12 @@ namespace SHADE
|
||||||
, usageFlags{usage}
|
, usageFlags{usage}
|
||||||
, createFlags {create}
|
, createFlags {create}
|
||||||
, vmaAllocator {allocator}
|
, vmaAllocator {allocator}
|
||||||
|
, device { logicalDeviceHdl }
|
||||||
{
|
{
|
||||||
CreateFramebufferImage();
|
CreateFramebufferImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,9 @@ namespace SHADE
|
||||||
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
|
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
|
||||||
std::span<uint32_t> mipOffsets;
|
std::span<uint32_t> mipOffsets;
|
||||||
|
|
||||||
|
//! Handle to the device that creates these images
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -117,6 +120,7 @@ namespace SHADE
|
||||||
SHVkImage(void) noexcept = default;
|
SHVkImage(void) noexcept = default;
|
||||||
|
|
||||||
SHVkImage(
|
SHVkImage(
|
||||||
|
Handle<SHVkLogicalDevice> logicalDeviceHdl,
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
const unsigned char* data,
|
const unsigned char* data,
|
||||||
|
@ -126,7 +130,7 @@ namespace SHADE
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
|
SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
|
||||||
|
|
||||||
SHVkImage(SHVkImage&& rhs) noexcept = default;
|
SHVkImage(SHVkImage&& rhs) noexcept = default;
|
||||||
SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
|
SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
|
||||||
|
@ -134,7 +138,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||||
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||||
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||||
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
|
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
|
@ -392,20 +392,23 @@ namespace SHADE
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
||||||
BuffUsage::eIndirectBuffer
|
BuffUsage::eIndirectBuffer,
|
||||||
|
"Batch Draw Data Buffer"
|
||||||
);
|
);
|
||||||
// - Transform Buffer
|
// - Transform Buffer
|
||||||
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Batch Transform Buffer"
|
||||||
);
|
);
|
||||||
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData));
|
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
|
device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Batch Instance Data Buffer"
|
||||||
);
|
);
|
||||||
// - Material Properties Buffer
|
// - Material Properties Buffer
|
||||||
rebuildMaterialBuffers(frameIndex, descPool);
|
rebuildMaterialBuffers(frameIndex, descPool);
|
||||||
|
@ -427,6 +430,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Bind all required objects before drawing
|
// Bind all required objects before drawing
|
||||||
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
||||||
|
cmdBuffer->BeginLabeledSegment("SHBatch");
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||||
|
@ -441,6 +445,7 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
||||||
|
cmdBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -460,7 +465,8 @@ namespace SHADE
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
vk::BufferUsageFlagBits::eStorageBuffer
|
vk::BufferUsageFlagBits::eStorageBuffer,
|
||||||
|
"Batch Material Data"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!matPropsDescSet[frameIndex])
|
if (!matPropsDescSet[frameIndex])
|
||||||
|
@ -470,6 +476,13 @@ namespace SHADE
|
||||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
);
|
);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const auto& DESC_SETS = matPropsDescSet[frameIndex]->GetVkHandle();
|
||||||
|
for (auto descSet : DESC_SETS)
|
||||||
|
{
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, descSet, "[Descriptor Set] Batch Material Data");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
|
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
|
||||||
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
|
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace SHADE
|
||||||
/* Static Definitions */
|
/* Static Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
|
||||||
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
|
|
||||||
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
|
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
|
||||||
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
|
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
|
||||||
|
|
||||||
|
@ -45,7 +44,8 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// For global data (generic data and textures)
|
// For global data (generic data and textures)
|
||||||
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding });
|
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals");
|
||||||
|
|
||||||
|
|
||||||
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
|
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
|
||||||
|
@ -71,11 +71,11 @@ namespace SHADE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// For Dynamic global data (lights)
|
// For Dynamic global data (lights)
|
||||||
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
|
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals");
|
||||||
|
|
||||||
|
// For High frequency global data (camera)
|
||||||
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
||||||
{
|
{
|
||||||
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
||||||
|
@ -83,10 +83,10 @@ namespace SHADE
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
|
||||||
.DescriptorCount = 1,
|
.DescriptorCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// For High frequency global data (camera)
|
|
||||||
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
|
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals");
|
||||||
|
|
||||||
|
// For per instance data (transforms, materials, etc.)
|
||||||
SHVkDescriptorSetLayout::Binding materialDataBinding
|
SHVkDescriptorSetLayout::Binding materialDataBinding
|
||||||
{
|
{
|
||||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||||
|
@ -94,9 +94,8 @@ namespace SHADE
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||||
.DescriptorCount = 1,
|
.DescriptorCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// For High frequency global data (camera)
|
|
||||||
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
|
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
|
||||||
|
|
||||||
globalDescSetLayouts.push_back(staticGlobalLayout);
|
globalDescSetLayouts.push_back(staticGlobalLayout);
|
||||||
globalDescSetLayouts.push_back(dynamicGlobalLayout);
|
globalDescSetLayouts.push_back(dynamicGlobalLayout);
|
||||||
|
|
|
@ -17,9 +17,6 @@ namespace SHADE
|
||||||
//! Global descriptor set layouts. Used to allocate descriptor sets
|
//! Global descriptor set layouts. Used to allocate descriptor sets
|
||||||
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
|
||||||
|
|
||||||
//! Global Descriptor sets
|
|
||||||
static Handle<SHVkDescriptorSetGroup> globalDescSets;
|
|
||||||
|
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
static SHVertexInputState defaultVertexInputState;
|
static SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ namespace SHADE
|
||||||
// Don't draw if no points
|
// Don't draw if no points
|
||||||
if (numPoints[FRAME_IDX] > 0)
|
if (numPoints[FRAME_IDX] > 0)
|
||||||
{
|
{
|
||||||
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw");
|
||||||
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
||||||
cmdBuffer->SetLineWidth(LineWidth);
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
||||||
|
@ -113,10 +114,12 @@ namespace SHADE
|
||||||
// Don't draw if no points
|
// Don't draw if no points
|
||||||
if (numPersistentPoints[FRAME_IDX] > 0)
|
if (numPersistentPoints[FRAME_IDX] > 0)
|
||||||
{
|
{
|
||||||
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)");
|
||||||
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
|
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
|
||||||
cmdBuffer->SetLineWidth(LineWidth);
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
|
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
|
||||||
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
|
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
|
||||||
|
cmdBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -138,7 +141,8 @@ namespace SHADE
|
||||||
0,
|
0,
|
||||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
"Debug Draw Non-Persistent Vertex Buffer"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// - Persistent Draws
|
// - Persistent Draws
|
||||||
|
@ -151,7 +155,8 @@ namespace SHADE
|
||||||
0,
|
0,
|
||||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
"Debug Draw Persistent Vertex Buffer"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,7 +323,7 @@ namespace SHADE
|
||||||
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
|
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
|
||||||
for (const auto& idx : SPHERE.Indices)
|
for (const auto& idx : SPHERE.Indices)
|
||||||
{
|
{
|
||||||
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
|
spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/************************************************************************************//*!
|
/************************************************************************************//*!
|
||||||
\file SHGraphicsSystem.cpp
|
\file SHGrphicsSystem.cpp
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Aug 21, 2022
|
\date Aug 21, 2022
|
||||||
|
@ -41,6 +41,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
#include "../Meshes/SHPrimitiveGenerator.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -164,7 +165,7 @@ namespace SHADE
|
||||||
/* SCENE RENDER GRAPH RESOURCES */
|
/* SCENE RENDER GRAPH RESOURCES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
worldRenderGraph->Init(device, swapchain);
|
worldRenderGraph->Init("World Render Graph", 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("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("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("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);
|
||||||
|
@ -212,6 +213,7 @@ namespace SHADE
|
||||||
ssaoStorage = resourceManager.Create<SHSSAO>();
|
ssaoStorage = resourceManager.Create<SHSSAO>();
|
||||||
|
|
||||||
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)");
|
||||||
ssaoTransferCmdBuffer->BeginRecording();
|
ssaoTransferCmdBuffer->BeginRecording();
|
||||||
|
|
||||||
ssaoStorage->Init(device, ssaoTransferCmdBuffer);
|
ssaoStorage->Init(device, ssaoTransferCmdBuffer);
|
||||||
|
@ -233,7 +235,7 @@ namespace SHADE
|
||||||
|
|
||||||
ssaoStorage->PrepareRotationVectorsVkData(device);
|
ssaoStorage->PrepareRotationVectorsVkData(device);
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
|
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" });
|
||||||
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
auto ssaoDataBuffer = ssaoStorage->GetBuffer();
|
||||||
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
|
||||||
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
|
||||||
|
@ -241,12 +243,12 @@ namespace SHADE
|
||||||
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||||
|
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"});
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"});
|
||||||
|
|
||||||
// Dummy Node
|
// Dummy Node
|
||||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
||||||
|
@ -259,7 +261,6 @@ namespace SHADE
|
||||||
// Generate world render graph
|
// Generate world render graph
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* BIND RENDER GRAPH TO RENDERER */
|
/* BIND RENDER GRAPH TO RENDERER */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -269,20 +270,13 @@ namespace SHADE
|
||||||
|
|
||||||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||||
|
|
||||||
// Create default materials
|
|
||||||
std::array<SHTexture::PixelChannel, 4> defaultTexture = { 255, 255, 255, 255 };
|
|
||||||
std::vector<uint32_t> mipOffsets{};
|
|
||||||
mipOffsets.push_back(0);
|
|
||||||
auto tex = AddTexture(4, defaultTexture.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets);
|
|
||||||
BuildTextures();
|
|
||||||
|
|
||||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
|
||||||
defaultMaterial->SetProperty("data.textureIndex", tex->TextureArrayIndex);
|
|
||||||
|
|
||||||
|
|
||||||
// Create debug draw pipeline
|
// Create debug draw pipeline
|
||||||
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw");
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout");
|
||||||
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test");
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||||
|
@ -321,7 +315,29 @@ namespace SHADE
|
||||||
|
|
||||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||||
lightingSubSystem->Init(device, descPool);
|
lightingSubSystem->Init(device, descPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::InitBuiltInResources(void)
|
||||||
|
{
|
||||||
|
// Create default texture
|
||||||
|
std::array<SHTexture::PixelChannel, 4> defaultTextureData = { 255, 255, 255, 255 };
|
||||||
|
std::vector<uint32_t> mipOffsets{};
|
||||||
|
mipOffsets.push_back(0);
|
||||||
|
defaultTexture = AddTexture(4, defaultTextureData.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets);
|
||||||
|
BuildTextures();
|
||||||
|
|
||||||
|
// Create default meshes
|
||||||
|
primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary);
|
||||||
|
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
|
||||||
|
BuildMeshBuffers();
|
||||||
|
|
||||||
|
// Create default materials
|
||||||
|
defaultMaterial = AddMaterial
|
||||||
|
(
|
||||||
|
defaultVertShader, defaultFragShader,
|
||||||
|
worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
||||||
|
);
|
||||||
|
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
@ -339,7 +355,7 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||||
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
||||||
|
|
||||||
editorRenderGraph->Init(device, swapchain);
|
editorRenderGraph->Init("Editor Render Graph", device, swapchain);
|
||||||
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,8 +380,7 @@ namespace SHADE
|
||||||
InitBoilerplate();
|
InitBoilerplate();
|
||||||
InitMiddleEnd();
|
InitMiddleEnd();
|
||||||
InitSubsystems();
|
InitSubsystems();
|
||||||
|
InitBuiltInResources();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
|
@ -667,6 +682,8 @@ namespace SHADE
|
||||||
|
|
||||||
auto renderGraphNode = subpass->GetParentNode();
|
auto renderGraphNode = subpass->GetParentNode();
|
||||||
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass);
|
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, pipeline->GetVkPipeline(), "[Pipeline] Custom Pipeline");
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, pipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Custom Pipeline Layout");
|
||||||
|
|
||||||
mat->SetPipeline(pipeline);
|
mat->SetPipeline(pipeline);
|
||||||
|
|
||||||
|
@ -690,7 +707,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst)
|
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst)
|
||||||
{
|
{
|
||||||
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
|
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
||||||
|
@ -703,24 +720,37 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices)
|
SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices)
|
||||||
{
|
{
|
||||||
return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices);
|
return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::RemoveMesh(Handle<SHMesh> mesh)
|
void SHGraphicsSystem::RemoveMesh(Handle<SHMesh> mesh)
|
||||||
{
|
{
|
||||||
meshLibrary.RemoveMesh(mesh);
|
meshLibrary.RemoveMesh(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::BuildMeshBuffers()
|
void SHGraphicsSystem::BuildMeshBuffers()
|
||||||
{
|
{
|
||||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
device->WaitIdle();
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, transferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Mesh Buffer Building (Transfer)");
|
||||||
transferCmdBuffer->BeginRecording();
|
device->WaitIdle();
|
||||||
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
transferCmdBuffer->BeginRecording();
|
||||||
transferCmdBuffer->EndRecording();
|
meshLibrary.BuildBuffers(device, transferCmdBuffer);
|
||||||
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
transferCmdBuffer->EndRecording();
|
||||||
device->WaitIdle();
|
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
|
||||||
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
device->WaitIdle();
|
||||||
|
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHMesh> SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PrimitiveType::Cube:
|
||||||
|
case PrimitiveType::Sphere:
|
||||||
|
return primitiveMeshes[static_cast<int>(type)];
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -728,14 +758,18 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
|
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
|
||||||
{
|
{
|
||||||
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) });
|
const int MIPS = texAsset.mipOffsets.size();
|
||||||
return texLibrary.Add(texAsset, sampler);
|
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(MIPS) });
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
|
||||||
|
return texLibrary.Add(texAsset, sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
|
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
|
||||||
{
|
{
|
||||||
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) });
|
const int MIPS = mipOffsets.size();
|
||||||
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
|
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(MIPS) });
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
|
||||||
|
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
|
void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
|
||||||
|
@ -746,6 +780,7 @@ namespace SHADE
|
||||||
void SHGraphicsSystem::BuildTextures()
|
void SHGraphicsSystem::BuildTextures()
|
||||||
{
|
{
|
||||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, graphicsTexCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Texture Building (Graphics)");
|
||||||
device->WaitIdle();
|
device->WaitIdle();
|
||||||
texLibrary.BuildTextures
|
texLibrary.BuildTextures
|
||||||
(
|
(
|
||||||
|
@ -809,7 +844,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
|
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
|
||||||
for (auto& renderable : renderables)
|
for (auto& renderable : renderables)
|
||||||
{
|
{
|
||||||
if (!renderable.HasChanged())
|
if (!renderable.HasChanged())
|
||||||
|
|
|
@ -58,6 +58,19 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Type of built-in primitive meshes that are available.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
enum class PrimitiveType
|
||||||
|
{
|
||||||
|
Cube,
|
||||||
|
Sphere
|
||||||
|
};
|
||||||
|
static constexpr int MAX_PRIMITIVE_TYPES = 2;
|
||||||
|
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
\brief
|
\brief
|
||||||
|
@ -72,6 +85,7 @@ namespace SHADE
|
||||||
void InitSceneRenderGraph (void) noexcept;
|
void InitSceneRenderGraph (void) noexcept;
|
||||||
void InitMiddleEnd (void) noexcept;
|
void InitMiddleEnd (void) noexcept;
|
||||||
void InitSubsystems (void) noexcept;
|
void InitSubsystems (void) noexcept;
|
||||||
|
void InitBuiltInResources (void);
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
void InitEditorRenderGraph (void) noexcept;
|
void InitEditorRenderGraph (void) noexcept;
|
||||||
|
@ -81,25 +95,25 @@ namespace SHADE
|
||||||
class SH_API BeginRoutine final : public SHSystemRoutine
|
class SH_API BeginRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BeginRoutine();
|
BeginRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API RenderRoutine final : public SHSystemRoutine
|
class SH_API RenderRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderRoutine();
|
RenderRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API EndRoutine final : public SHSystemRoutine
|
class SH_API EndRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EndRoutine();
|
EndRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
|
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BatcherDispatcherRoutine();
|
BatcherDispatcherRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,34 +166,34 @@ namespace SHADE
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Adds a mesh to the Mesh Library. But this does not mean that the meshes have
|
Adds a mesh to the Mesh Library. But this does not mean that the meshes have
|
||||||
been added yet. A call to "BuildBuffers()" is required to transfer all
|
been added yet. A call to "BuildBuffers()" is required to transfer all
|
||||||
meshes into the GPU.
|
meshes into the GPU.
|
||||||
|
|
||||||
\param vertexCount
|
\param vertexCount
|
||||||
Number of vertices in this Mesh.
|
Number of vertices in this Mesh.
|
||||||
\param positions
|
\param positions
|
||||||
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||||
positions.
|
positions.
|
||||||
\param texCoords
|
\param texCoords
|
||||||
Pointer to the first in a contiguous array of SHMathVec2s that define vertex
|
Pointer to the first in a contiguous array of SHMathVec2s that define vertex
|
||||||
texture coordinates.
|
texture coordinates.
|
||||||
\param tangents
|
\param tangents
|
||||||
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||||
tangents.
|
tangents.
|
||||||
\param normals
|
\param normals
|
||||||
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||||
normals.
|
normals.
|
||||||
\param indexCount
|
\param indexCount
|
||||||
Number of indices in this mesh.
|
Number of indices in this mesh.
|
||||||
\param indices
|
\param indices
|
||||||
Pointer to the first in a contiguous array of uint32_ts that define mesh
|
Pointer to the first in a contiguous array of uint32_ts that define mesh
|
||||||
indices.
|
indices.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
Handle to the created Mesh. This is not valid to be used until a call to
|
Handle to the created Mesh. This is not valid to be used until a call to
|
||||||
BuildBuffers().
|
BuildBuffers().
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
@ -188,9 +202,9 @@ namespace SHADE
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Removes a mesh from the MeshLibrary. But this does not mean that the meshes
|
Removes a mesh from the MeshLibrary. But this does not mean that the meshes
|
||||||
have been removed yet. A call to "BuildBuffers()" is required to finalise all
|
have been removed yet. A call to "BuildBuffers()" is required to finalise all
|
||||||
changes.
|
changes.
|
||||||
|
|
||||||
\param mesh
|
\param mesh
|
||||||
Handle to the mesh to remove.
|
Handle to the mesh to remove.
|
||||||
|
@ -207,6 +221,21 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildMeshBuffers();
|
void BuildMeshBuffers();
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Retrieves the built-in mesh specified.
|
||||||
|
|
||||||
|
\param type
|
||||||
|
Type of built-in mesh to retrieve.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the mesh that was specfied. However, if an invalid type is specified,
|
||||||
|
a null Handle will be returned.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
Handle<SHMesh> GetMeshPrimitive(PrimitiveType type) const noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Texture Registration Functions */
|
/* Texture Registration Functions */
|
||||||
|
@ -278,6 +307,18 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const;
|
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const;
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
\brief
|
||||||
|
Retrieves the handle to the default texture. A white 1x1 texture.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the default texture.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHTexture> GetDefaultTexture() const noexcept { return defaultTexture; }
|
||||||
|
|
||||||
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
void HandleResize(void) noexcept;
|
void HandleResize(void) noexcept;
|
||||||
|
@ -378,6 +419,13 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawPipeline;
|
Handle<SHVkPipeline> debugDrawPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
||||||
|
|
||||||
|
// Built-In Textures
|
||||||
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
||||||
|
// Built-In Meshes
|
||||||
|
std::array<Handle<SHMesh>, MAX_PRIMITIVE_TYPES> primitiveMeshes;
|
||||||
|
|
||||||
|
// Render Graphs
|
||||||
Handle<SHRenderGraph> worldRenderGraph;
|
Handle<SHRenderGraph> worldRenderGraph;
|
||||||
|
|
||||||
// Sub systems
|
// Sub systems
|
||||||
|
|
|
@ -165,35 +165,40 @@ namespace SHADE
|
||||||
device, cmdBuffer, vertPosBuffer,
|
device, cmdBuffer, vertPosBuffer,
|
||||||
vertPosStorage.data(),
|
vertPosStorage.data(),
|
||||||
static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition),
|
static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition),
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Mesh Library Vertex Positions"
|
||||||
);
|
);
|
||||||
SHVkUtil::EnsureBufferAndCopyData
|
SHVkUtil::EnsureBufferAndCopyData
|
||||||
(
|
(
|
||||||
device, cmdBuffer, vertTexCoordBuffer,
|
device, cmdBuffer, vertTexCoordBuffer,
|
||||||
vertTexCoordStorage.data(),
|
vertTexCoordStorage.data(),
|
||||||
static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord),
|
static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord),
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Mesh Library Vertex TexCoords"
|
||||||
);
|
);
|
||||||
SHVkUtil::EnsureBufferAndCopyData
|
SHVkUtil::EnsureBufferAndCopyData
|
||||||
(
|
(
|
||||||
device, cmdBuffer, vertTangentBuffer,
|
device, cmdBuffer, vertTangentBuffer,
|
||||||
vertTangentStorage.data(),
|
vertTangentStorage.data(),
|
||||||
static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent),
|
static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent),
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Mesh Library Vertex Tangents"
|
||||||
);
|
);
|
||||||
SHVkUtil::EnsureBufferAndCopyData
|
SHVkUtil::EnsureBufferAndCopyData
|
||||||
(
|
(
|
||||||
device, cmdBuffer, vertNormalBuffer,
|
device, cmdBuffer, vertNormalBuffer,
|
||||||
vertNormalStorage.data(),
|
vertNormalStorage.data(),
|
||||||
static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal),
|
static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal),
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer,
|
||||||
|
"Mesh Library Vertex Normals"
|
||||||
);
|
);
|
||||||
SHVkUtil::EnsureBufferAndCopyData
|
SHVkUtil::EnsureBufferAndCopyData
|
||||||
(
|
(
|
||||||
device, cmdBuffer, indexBuffer,
|
device, cmdBuffer, indexBuffer,
|
||||||
indexStorage.data(),
|
indexStorage.data(),
|
||||||
static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index),
|
static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index),
|
||||||
BuffUsage::eIndexBuffer
|
BuffUsage::eIndexBuffer,
|
||||||
|
"Mesh Library Indices"
|
||||||
);
|
);
|
||||||
|
|
||||||
isDirty = false;
|
isDirty = false;
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace SHADE
|
||||||
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
|
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
|
||||||
|
|
||||||
// Create the buffer
|
// Create the buffer
|
||||||
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Mouse Pick Image Data Destination");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept
|
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept
|
||||||
|
|
|
@ -39,9 +39,15 @@ namespace SHADE
|
||||||
|
|
||||||
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
|
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle();
|
||||||
|
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Camera Data Frame #" + std::to_string(i));
|
||||||
|
#endif
|
||||||
|
|
||||||
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
|
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
|
||||||
|
|
||||||
cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Camera Data");
|
||||||
|
|
||||||
std::array cameraBufferArray{cameraBuffer};
|
std::array cameraBufferArray{cameraBuffer};
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ namespace SHADE
|
||||||
lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights);
|
lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights);
|
||||||
|
|
||||||
// We want to initialize 3 times the amount of data required.
|
// We want to initialize 3 times the amount of data required.
|
||||||
dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Data");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -385,8 +385,12 @@ namespace SHADE
|
||||||
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
||||||
|
|
||||||
// Create the descriptor set
|
// Create the descriptor set
|
||||||
lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes);
|
lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle();
|
||||||
|
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Light Data Frame #" + std::to_string(i));
|
||||||
|
#endif
|
||||||
|
|
||||||
for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i)
|
for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i)
|
||||||
{
|
{
|
||||||
|
@ -402,7 +406,7 @@ namespace SHADE
|
||||||
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
|
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
|
||||||
|
|
||||||
// Create the GPU buffer to hold light count
|
// Create the GPU buffer to hold light count
|
||||||
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data");
|
||||||
|
|
||||||
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
|
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
|
||||||
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
|
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept
|
void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept
|
||||||
{
|
{
|
||||||
// Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line.
|
// Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line.
|
||||||
//swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex);
|
//swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex);
|
||||||
|
@ -44,14 +44,17 @@ namespace SHADE
|
||||||
|
|
||||||
// Create image views for the swapchain
|
// Create image views for the swapchain
|
||||||
swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails);
|
swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails);
|
||||||
|
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain");
|
||||||
|
|
||||||
// Create a fence
|
// Create a fence
|
||||||
fenceHdl = logicalDeviceHdl->CreateFence();
|
fenceHdl = logicalDeviceHdl->CreateFence();
|
||||||
|
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain");
|
||||||
|
|
||||||
// scope makes it easier to navigate
|
// scope makes it easier to navigate
|
||||||
semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
|
semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
|
||||||
|
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available");
|
||||||
semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
|
semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
|
||||||
|
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semRenderFinishHdl->GetVkSem(), "[Semaphore] Swap Chain Render Finish");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window
|
// These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window
|
||||||
void Recreate (Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept;
|
void Recreate (Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept;
|
||||||
void Destroy (void);
|
void Destroy (void);
|
||||||
|
|
||||||
friend class SHRenderContext;
|
friend class SHRenderContext;
|
||||||
|
|
|
@ -50,7 +50,13 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t j = 0; j < params.numThreads; ++j)
|
for (uint32_t j = 0; j < params.numThreads; ++j)
|
||||||
{
|
{
|
||||||
frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient));
|
auto cmdPool = logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient);
|
||||||
|
SET_VK_OBJ_NAME
|
||||||
|
(
|
||||||
|
logicalDeviceHdl, vk::ObjectType::eCommandPool, cmdPool->GetVkCommandPool(),
|
||||||
|
"[Command Pool] Render Context #" + std::to_string(i) + " Pool #" + std::to_string(j)
|
||||||
|
);
|
||||||
|
frameData[i].cmdPoolHdls.push_back(cmdPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/Images/SHVkImage.h"
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
#include "Assets/Asset Types/SHTextureAsset.h"
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
job.Image = resourceManager.Create<SHVkImage>
|
job.Image = resourceManager.Create<SHVkImage>
|
||||||
(
|
(
|
||||||
|
device,
|
||||||
&device->GetVMAAllocator(),
|
&device->GetVMAAllocator(),
|
||||||
SHImageCreateParams
|
SHImageCreateParams
|
||||||
{
|
{
|
||||||
|
@ -142,6 +144,7 @@ namespace SHADE
|
||||||
.layerCount = 1
|
.layerCount = 1
|
||||||
};
|
};
|
||||||
job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Textures
|
// Add Textures
|
||||||
|
@ -150,6 +153,9 @@ namespace SHADE
|
||||||
texOrder.emplace_back(job.TextureHandle);
|
texOrder.emplace_back(job.TextureHandle);
|
||||||
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
||||||
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
|
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
|
||||||
|
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eImage, job.Image->GetVkImage(), "[Image] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
|
||||||
}
|
}
|
||||||
addJobs.clear();
|
addJobs.clear();
|
||||||
|
|
||||||
|
@ -165,6 +171,10 @@ namespace SHADE
|
||||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||||
{ static_cast<uint32_t>(texOrder.size()) }
|
{ static_cast<uint32_t>(texOrder.size()) }
|
||||||
);
|
);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (auto set : texDescriptors->GetVkHandle())
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
|
||||||
|
#endif
|
||||||
texDescriptors->ModifyWriteDescImage
|
texDescriptors->ModifyWriteDescImage
|
||||||
(
|
(
|
||||||
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||||
|
|
|
@ -59,7 +59,8 @@ namespace SHADE
|
||||||
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
|
auto resource = resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
|
||||||
|
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -353,7 +354,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept
|
void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept
|
||||||
{
|
{
|
||||||
resourceManager = std::make_shared<SHResourceHub>();
|
resourceManager = std::make_shared<SHResourceHub>();
|
||||||
|
|
||||||
|
@ -365,6 +366,8 @@ namespace SHADE
|
||||||
|
|
||||||
renderGraphStorage->resourceManager = resourceManager;
|
renderGraphStorage->resourceManager = resourceManager;
|
||||||
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
|
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
|
||||||
|
|
||||||
|
name = std::move(graphName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -390,6 +393,7 @@ namespace SHADE
|
||||||
, nodeIndexing{ std::move(rhs.nodeIndexing) }
|
, nodeIndexing{ std::move(rhs.nodeIndexing) }
|
||||||
, nodes{ std::move(rhs.nodes) }
|
, nodes{ std::move(rhs.nodes) }
|
||||||
, resourceManager{ std::move(rhs.resourceManager) }
|
, resourceManager{ std::move(rhs.resourceManager) }
|
||||||
|
, name { std::move(rhs.name) }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -403,6 +407,7 @@ namespace SHADE
|
||||||
nodeIndexing = std::move(rhs.nodeIndexing);
|
nodeIndexing = std::move(rhs.nodeIndexing);
|
||||||
nodes = std::move(rhs.nodes);
|
nodes = std::move(rhs.nodes);
|
||||||
resourceManager = std::move(rhs.resourceManager);
|
resourceManager = std::move(rhs.resourceManager);
|
||||||
|
name = std::move(rhs.name);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -467,9 +472,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
|
auto node = nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
|
||||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
|
||||||
return nodes.at(nodeIndexing[nodeName]);
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -516,8 +521,10 @@ namespace SHADE
|
||||||
// better way to manage these
|
// better way to manage these
|
||||||
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
{
|
{
|
||||||
|
cmdBuffer->BeginLabeledSegment(name);
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
node->Execute(cmdBuffer, descPool, frameIndex);
|
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||||
|
cmdBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
|
|
|
@ -69,6 +69,9 @@ namespace SHADE
|
||||||
//! Resource library for graph handles
|
//! Resource library for graph handles
|
||||||
std::shared_ptr<SHResourceHub> resourceManager;
|
std::shared_ptr<SHResourceHub> resourceManager;
|
||||||
|
|
||||||
|
//! Name of the RenderGraph
|
||||||
|
std::string name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
|
@ -81,7 +84,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept;
|
void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept;
|
||||||
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
||||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
|
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace SHADE
|
||||||
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
||||||
{
|
{
|
||||||
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -57,6 +58,7 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +118,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
|
SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
|
||||||
: graphStorage{ renderGraphStorage}
|
: graphStorage{ renderGraphStorage}
|
||||||
, renderpass{}
|
, renderpass{}
|
||||||
, framebuffers{}
|
, framebuffers{}
|
||||||
|
@ -128,6 +130,7 @@ namespace SHADE
|
||||||
, executed{ false }
|
, executed{ false }
|
||||||
, configured{ false }
|
, configured{ false }
|
||||||
, nodeComputes{}
|
, nodeComputes{}
|
||||||
|
, name { std::move(nodeName) }
|
||||||
{
|
{
|
||||||
// pipeline library initialization
|
// pipeline library initialization
|
||||||
pipelineLibrary.Init(graphStorage->logicalDevice);
|
pipelineLibrary.Init(graphStorage->logicalDevice);
|
||||||
|
@ -189,6 +192,7 @@ namespace SHADE
|
||||||
, spDescs{ std::move(rhs.spDescs) }
|
, spDescs{ std::move(rhs.spDescs) }
|
||||||
, spDeps{ std::move(rhs.spDeps) }
|
, spDeps{ std::move(rhs.spDeps) }
|
||||||
, nodeComputes{ std::move(rhs.nodeComputes) }
|
, nodeComputes{ std::move(rhs.nodeComputes) }
|
||||||
|
, name { std::move(rhs.name) }
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -213,7 +217,7 @@ namespace SHADE
|
||||||
spDescs = std::move(rhs.spDescs);
|
spDescs = std::move(rhs.spDescs);
|
||||||
spDeps = std::move(rhs.spDeps);
|
spDeps = std::move(rhs.spDeps);
|
||||||
nodeComputes = std::move(rhs.nodeComputes);
|
nodeComputes = std::move(rhs.nodeComputes);
|
||||||
|
name = std::move(rhs.name);
|
||||||
|
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
|
||||||
|
@ -263,7 +267,7 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, 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
|
// Look for the required resources in the graph
|
||||||
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||||
|
@ -276,7 +280,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the subpass compute with the resources
|
// Create the subpass compute with the resources
|
||||||
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
||||||
nodeComputes.push_back(nodeCompute);
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
return nodeCompute;
|
return nodeCompute;
|
||||||
|
|
|
@ -78,8 +78,11 @@ namespace SHADE
|
||||||
//! Whether or not the node has been configured already or not
|
//! Whether or not the node has been configured already or not
|
||||||
bool configured;
|
bool configured;
|
||||||
|
|
||||||
|
//! Manages batching for this RenderPass
|
||||||
SHBatcher batcher;
|
SHBatcher batcher;
|
||||||
|
|
||||||
|
//! Name of this node
|
||||||
|
std::string name;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
@ -92,7 +95,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept;
|
SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept;
|
||||||
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
||||||
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
@ -100,7 +103,7 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
||||||
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
|
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
void AddDummySubpassIfNeeded (void) noexcept;
|
void AddDummySubpassIfNeeded (void) noexcept;
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
// TODO: RemoveSubpass()
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
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
|
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
: computePipeline{}
|
: computePipeline{}
|
||||||
, pipelineLayout{}
|
, pipelineLayout{}
|
||||||
, resources{}
|
, resources{}
|
||||||
|
@ -22,6 +22,7 @@ namespace SHADE
|
||||||
, followingEndRenderpass {followingEndRP}
|
, followingEndRenderpass {followingEndRP}
|
||||||
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
||||||
, computeResource{}
|
, computeResource{}
|
||||||
|
, name { std::move(nodeName) }
|
||||||
{
|
{
|
||||||
SHPipelineLayoutParams pipelineLayoutParams
|
SHPipelineLayoutParams pipelineLayoutParams
|
||||||
{
|
{
|
||||||
|
@ -31,13 +32,15 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create pipeline layout from parameters
|
// Create pipeline layout from parameters
|
||||||
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams);
|
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout(pipelineLayoutParams);
|
||||||
|
|
||||||
// Create the compute pipeline
|
// Create the compute pipeline
|
||||||
computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
|
computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
|
||||||
|
|
||||||
// and construct it
|
// and construct it
|
||||||
computePipeline->ConstructPipeline();
|
computePipeline->ConstructPipeline();
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + name);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + name);
|
||||||
|
|
||||||
// save the resources
|
// save the resources
|
||||||
resources = std::move (subpassComputeResources);
|
resources = std::move (subpassComputeResources);
|
||||||
|
@ -50,6 +53,10 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
{
|
{
|
||||||
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
|
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (auto set : graphResourceDescSets[i]->GetVkHandle())
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " #" + std::to_string(i));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +68,10 @@ namespace SHADE
|
||||||
computeResource = graphStorage->resourceManager->Create<ComputeResource>();
|
computeResource = graphStorage->resourceManager->Create<ComputeResource>();
|
||||||
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
|
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
|
||||||
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (auto set : computeResource->descSet->GetVkHandle())
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Allocate for descriptor offsets
|
// Allocate for descriptor offsets
|
||||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
|
|
|
@ -65,8 +65,11 @@ namespace SHADE
|
||||||
|
|
||||||
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
|
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
|
||||||
|
|
||||||
|
//! Name of this node
|
||||||
|
std::string name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
SHRenderGraphNodeCompute(std::string nodeName, 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 Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
images[i] = graphStorage->swapchain->GetSwapchainImage(i);
|
images[i] = graphStorage->swapchain->GetSwapchainImage(i);
|
||||||
imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails);
|
imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageViews[i]->GetImageView(), "[Image View] " + resourceName + " #" + std::to_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // if swapchain image resource
|
else // if swapchain image resource
|
||||||
|
@ -129,7 +130,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// The resource is not a swapchain image, just use the first slot of the vector
|
// The resource is not a swapchain image, just use the first slot of the vector
|
||||||
images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
auto image = graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImage, image->GetVkImage(), "[Image] " + resourceName);
|
||||||
|
images.push_back(image);
|
||||||
|
|
||||||
// prepare image view details
|
// prepare image view details
|
||||||
SHImageViewDetails viewDetails
|
SHImageViewDetails viewDetails
|
||||||
|
@ -144,7 +147,9 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// just 1 image view created
|
// just 1 image view created
|
||||||
imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails));
|
auto imageView = images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails);
|
||||||
|
imageViews.push_back(imageView);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageView->GetImageView(), "[Image View] " + resourceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
|
commandBuffer->BeginLabeledSegment(name);
|
||||||
// Ensure correct transforms are provided
|
// Ensure correct transforms are provided
|
||||||
superBatch->UpdateBuffers(frameIndex, descPool);
|
superBatch->UpdateBuffers(frameIndex, descPool);
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
drawCall(commandBuffer);
|
drawCall(commandBuffer);
|
||||||
}
|
}
|
||||||
|
commandBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSubpass::HandleResize(void) noexcept
|
void SHSubpass::HandleResize(void) noexcept
|
||||||
|
@ -301,6 +302,11 @@ namespace SHADE
|
||||||
group.Free();
|
group.Free();
|
||||||
|
|
||||||
group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
|
group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
const auto& GROUP_HANDLES = group->GetVkHandle();
|
||||||
|
for (int i = 0; i < static_cast<int>(GROUP_HANDLES.size()); ++i)
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, GROUP_HANDLES[i], "[Descriptor Set] " + name + " #" + std::to_string(i));
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (auto& binding : bindings)
|
for (auto& binding : bindings)
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage)
|
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name)
|
||||||
{
|
{
|
||||||
if (bufferHandle)
|
if (bufferHandle)
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,8 @@ namespace SHADE
|
||||||
size,
|
size,
|
||||||
usage | BuffUsage::eTransferDst,
|
usage | BuffUsage::eTransferDst,
|
||||||
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
|
||||||
|
name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@ namespace SHADE
|
||||||
bufferHandle->TransferToDeviceResource(cmdBuffer);
|
bufferHandle->TransferToDeviceResource(cmdBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage)
|
void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name)
|
||||||
{
|
{
|
||||||
if (bufferHandle)
|
if (bufferHandle)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +127,8 @@ namespace SHADE
|
||||||
size,
|
size,
|
||||||
usage,
|
usage,
|
||||||
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage);
|
static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage);
|
static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
|
||||||
|
|
||||||
static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept;
|
static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,11 +25,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox() noexcept
|
SHBoundingBox::SHBoundingBox() noexcept
|
||||||
|
: RelativeExtents { SHVec3::One }
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
|
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
|
||||||
|
: RelativeExtents { SHVec3::One }
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
|
@ -45,16 +47,18 @@ namespace SHADE
|
||||||
|
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
|
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -69,8 +73,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if (this != &rhs)
|
else if (this != &rhs)
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -84,8 +89,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,11 +106,16 @@ namespace SHADE
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept
|
SHVec3 SHBoundingBox::GetWorldExtents() const noexcept
|
||||||
{
|
{
|
||||||
return Extents;
|
return Extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept
|
||||||
|
{
|
||||||
|
return RelativeExtents;
|
||||||
|
}
|
||||||
|
|
||||||
SHVec3 SHBoundingBox::GetMin() const noexcept
|
SHVec3 SHBoundingBox::GetMin() const noexcept
|
||||||
{
|
{
|
||||||
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
|
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
|
||||||
|
@ -124,9 +135,14 @@ namespace SHADE
|
||||||
Center = newCenter;
|
Center = newCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept
|
void SHBoundingBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
||||||
{
|
{
|
||||||
Extents = newHalfExtents;
|
Extents = newWorldExtents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoundingBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
|
||||||
|
{
|
||||||
|
RelativeExtents = newRelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingBox::SetMin(const SHVec3& min) noexcept
|
void SHBoundingBox::SetMin(const SHVec3& min) noexcept
|
||||||
|
|
|
@ -54,21 +54,23 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept;
|
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||||
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||||
void SetHalfExtents (const SHVec3& newHalfExtents) noexcept;
|
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
||||||
void SetMin (const SHVec3& min) noexcept;
|
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
||||||
void SetMax (const SHVec3& max) noexcept;
|
void SetMin (const SHVec3& min) noexcept;
|
||||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
void SetMax (const SHVec3& max) noexcept;
|
||||||
|
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -89,6 +91,13 @@ namespace SHADE
|
||||||
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
|
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
|
||||||
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
||||||
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHVec3 RelativeExtents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere() noexcept
|
SHBoundingSphere::SHBoundingSphere() noexcept
|
||||||
|
: RelativeRadius { 1.0f }
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
|
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
|
||||||
|
: RelativeRadius { 1.0f }
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
|
@ -44,16 +46,18 @@ namespace SHADE
|
||||||
|
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
|
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -68,8 +72,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if (this != &rhs)
|
else if (this != &rhs)
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -83,8 +88,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -99,11 +105,16 @@ namespace SHADE
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHBoundingSphere::GetRadius() const noexcept
|
float SHBoundingSphere::GetWorldRadius() const noexcept
|
||||||
{
|
{
|
||||||
return Radius;
|
return Radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float SHBoundingSphere::GetRelativeRadius() const noexcept
|
||||||
|
{
|
||||||
|
return RelativeRadius;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -113,9 +124,14 @@ namespace SHADE
|
||||||
Center = center;
|
Center = center;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingSphere::SetRadius(float radius) noexcept
|
void SHBoundingSphere::SetWorldRadius(float newWorldRadius) noexcept
|
||||||
{
|
{
|
||||||
Radius = radius;
|
Radius = newWorldRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoundingSphere::SetRelativeRadius(float newRelativeRadius) noexcept
|
||||||
|
{
|
||||||
|
RelativeRadius = newRelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -48,15 +48,17 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] float GetRadius () const noexcept;
|
[[nodiscard]] float GetWorldRadius () const noexcept;
|
||||||
|
[[nodiscard]] float GetRelativeRadius () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetCenter (const SHVec3& center) noexcept;
|
void SetCenter (const SHVec3& center) noexcept;
|
||||||
void SetRadius (float radius) noexcept;
|
void SetWorldRadius (float newWorldRadius) noexcept;
|
||||||
|
void SetRelativeRadius (float newRelativeRadius) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -79,5 +81,12 @@ namespace SHADE
|
||||||
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
|
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
|
||||||
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
float RelativeRadius;
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
|
@ -231,12 +231,12 @@ namespace SHADE
|
||||||
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
||||||
|
|
||||||
// Set the orientation
|
// Set the orientation
|
||||||
// Wrap rotations between -360 and 360 and convert to radians
|
// Wrap rotations between -720 and 720 and convert to radians
|
||||||
SHVec3 worldRotRad, localRotRad;
|
SHVec3 worldRotRad, localRotRad;
|
||||||
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||||
{
|
{
|
||||||
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI);
|
||||||
localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
|
tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
|
||||||
|
|
|
@ -48,17 +48,22 @@ namespace SHADE
|
||||||
return orientation.ToEuler();
|
return orientation.ToEuler();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept
|
const SHVec3& SHColliderComponent::GetScale() const noexcept
|
||||||
{
|
{
|
||||||
return colliders;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider& SHColliderComponent::GetCollider(int index)
|
const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept
|
||||||
{
|
{
|
||||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
return collisionShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHCollisionShape& SHColliderComponent::GetCollisionShape(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
throw std::invalid_argument("Out-of-range access!");
|
||||||
|
|
||||||
return colliders[index];
|
return collisionShapes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -75,39 +80,74 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept
|
void SHColliderComponent::RecomputeCollisionShapes() noexcept
|
||||||
|
{
|
||||||
|
for (auto& collisionShape : collisionShapes)
|
||||||
|
{
|
||||||
|
switch (collisionShape.GetType())
|
||||||
|
{
|
||||||
|
case SHCollisionShape::Type::BOX:
|
||||||
|
{
|
||||||
|
auto* box = reinterpret_cast<SHBoundingBox*>(collisionShape.GetShape());
|
||||||
|
const SHVec3& RELATIVE_EXTENTS = box->GetRelativeExtents();
|
||||||
|
|
||||||
|
// Recompute world extents based on new scale and fixed relative extents
|
||||||
|
const SHVec3 WORLD_EXTENTS = RELATIVE_EXTENTS * (scale * 0.5f);
|
||||||
|
box->SetWorldExtents(WORLD_EXTENTS);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case SHCollisionShape::Type::SPHERE:
|
||||||
|
{
|
||||||
|
auto* sphere = reinterpret_cast<SHBoundingSphere*>(collisionShape.GetShape());
|
||||||
|
const float RELATIVE_RADIUS = sphere->GetRelativeRadius();
|
||||||
|
|
||||||
|
// Recompute world radius based on new scale and fixed radius
|
||||||
|
const float MAX_SCALE = SHMath::Max({ scale.x, scale.y, scale.z });
|
||||||
|
const float WORLD_RADIUS = RELATIVE_RADIUS * MAX_SCALE * 0.5f;
|
||||||
|
sphere->SetWorldRadius(WORLD_RADIUS);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset, const SHVec3& rotOffset) noexcept
|
||||||
{
|
{
|
||||||
if (!system)
|
if (!system)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
|
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
|
||||||
return nullptr;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto TYPE = SHCollider::Type::BOX;
|
static constexpr auto TYPE = SHCollisionShape::Type::BOX;
|
||||||
|
|
||||||
auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
|
auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE });
|
||||||
|
|
||||||
collider.entityID = GetEID();
|
collider.entityID = GetEID();
|
||||||
collider.SetPositionOffset(posOffset);
|
collider.SetPositionOffset(posOffset);
|
||||||
|
collider.SetRotationOffset(rotOffset);
|
||||||
collider.SetBoundingBox(halfExtents);
|
collider.SetBoundingBox(halfExtents);
|
||||||
|
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
system->AddCollisionShape(GetEID(), &collider);
|
system->AddCollisionShape(GetEID(), &collider);
|
||||||
|
|
||||||
return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
return static_cast<int>(collisionShapes.size()) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
|
int SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
|
||||||
{
|
{
|
||||||
if (!system)
|
if (!system)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
|
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
|
||||||
return nullptr;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto TYPE = SHCollider::Type::SPHERE;
|
static constexpr auto TYPE = SHCollisionShape::Type::SPHERE;
|
||||||
|
|
||||||
auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
|
auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE });
|
||||||
|
|
||||||
collider.entityID = GetEID();
|
collider.entityID = GetEID();
|
||||||
collider.SetPositionOffset(posOffset);
|
collider.SetPositionOffset(posOffset);
|
||||||
|
@ -116,17 +156,17 @@ namespace SHADE
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
system->AddCollisionShape(GetEID(), &collider);
|
system->AddCollisionShape(GetEID(), &collider);
|
||||||
|
|
||||||
return reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
return static_cast<int>(collisionShapes.size()) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHColliderComponent::RemoveCollider(int index)
|
void SHColliderComponent::RemoveCollider(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
throw std::invalid_argument("Out-of-range access!");
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
auto it = colliders.begin();
|
auto it = collisionShapes.begin();
|
||||||
for (; it != colliders.end(); ++it)
|
for (; it != collisionShapes.end(); ++it)
|
||||||
{
|
{
|
||||||
if (idx == index)
|
if (idx == index)
|
||||||
break;
|
break;
|
||||||
|
@ -134,7 +174,7 @@ namespace SHADE
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
it = colliders.erase(it);
|
it = collisionShapes.erase(it);
|
||||||
|
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
if (!system)
|
if (!system)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Physics/SHCollider.h"
|
#include "Physics/SHCollisionShape.h"
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
using Colliders = std::vector<SHCollider>;
|
using CollisionShapes = std::vector<SHCollisionShape>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -67,26 +67,29 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] bool HasChanged () const noexcept;
|
[[nodiscard]] bool HasChanged () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
||||||
|
[[nodiscard]] const SHVec3& GetScale () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const Colliders& GetColliders () const noexcept;
|
[[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept;
|
||||||
[[nodiscard]] SHCollider& GetCollider (int index);
|
[[nodiscard]] SHCollisionShape& GetCollisionShape (int index);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void OnCreate () override;
|
void OnCreate () override;
|
||||||
void OnDestroy () override;
|
void OnDestroy () override;
|
||||||
|
|
||||||
void RemoveCollider (int index);
|
void RecomputeCollisionShapes () noexcept;
|
||||||
|
|
||||||
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
void RemoveCollider (int index);
|
||||||
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
|
||||||
|
int AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero) noexcept;
|
||||||
|
int AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -98,7 +101,8 @@ namespace SHADE
|
||||||
|
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
Colliders colliders;
|
SHVec3 scale;
|
||||||
|
CollisionShapes collisionShapes;
|
||||||
|
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
|
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHCollider.h"
|
#include "SHCollisionShape.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -25,7 +25,7 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
||||||
: type { colliderType }
|
: type { colliderType }
|
||||||
, entityID { eid }
|
, entityID { eid }
|
||||||
, isTrigger { false }
|
, isTrigger { false }
|
||||||
|
@ -49,7 +49,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(const SHCollider& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(const SHCollisionShape& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -61,7 +61,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(SHCollider&& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(SHCollisionShape&& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -73,7 +73,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::~SHCollider() noexcept
|
SHCollisionShape::~SHCollisionShape() noexcept
|
||||||
{
|
{
|
||||||
shape = nullptr;
|
shape = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace SHADE
|
||||||
/* Operator Overload Definitions */
|
/* Operator Overload Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(const SHCollisionShape& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,7 +100,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(SHCollisionShape&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = rhs.type;
|
type = rhs.type;
|
||||||
entityID = rhs.entityID;
|
entityID = rhs.entityID;
|
||||||
|
@ -119,52 +119,52 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHCollider::HasChanged() const noexcept
|
bool SHCollisionShape::HasChanged() const noexcept
|
||||||
{
|
{
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHCollider::IsTrigger() const noexcept
|
bool SHCollisionShape::IsTrigger() const noexcept
|
||||||
{
|
{
|
||||||
return isTrigger;
|
return isTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::Type SHCollider::GetType() const noexcept
|
SHCollisionShape::Type SHCollisionShape::GetType() const noexcept
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetFriction() const noexcept
|
float SHCollisionShape::GetFriction() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetFriction();
|
return material.GetFriction();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetBounciness() const noexcept
|
float SHCollisionShape::GetBounciness() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetBounciness();
|
return material.GetBounciness();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetDensity() const noexcept
|
float SHCollisionShape::GetDensity() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetDensity();
|
return material.GetDensity();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept
|
const SHPhysicsMaterial& SHCollisionShape::GetMaterial() const noexcept
|
||||||
{
|
{
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetPositionOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept
|
||||||
{
|
{
|
||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetRotationOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept
|
||||||
{
|
{
|
||||||
return rotationOffset;
|
return rotationOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHShape* SHCollider::GetShape() noexcept
|
SHShape* SHCollisionShape::GetShape() noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
return shape;
|
return shape;
|
||||||
|
@ -174,93 +174,80 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::SetBoundingBox(const SHVec3& halfExtents)
|
void SHCollisionShape::SetBoundingBox(const SHVec3& halfExtents)
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
// Set the half extents relative to transform
|
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
|
||||||
SHVec3 worldHalfExtents = halfExtents;
|
// Set the half extents relative to world scale
|
||||||
|
const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
if (type != Type::BOX)
|
||||||
if (transformComponent != nullptr)
|
|
||||||
worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f);
|
|
||||||
|
|
||||||
if (type == Type::BOX)
|
|
||||||
{
|
|
||||||
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
|
||||||
box->SetHalfExtents(worldHalfExtents);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
delete shape;
|
delete shape;
|
||||||
shape = new SHBoundingBox{ positionOffset, worldHalfExtents };
|
shape = new SHBoundingBox{ positionOffset, WORLD_EXTENTS };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
||||||
|
box->SetWorldExtents(WORLD_EXTENTS);
|
||||||
|
box->SetRelativeExtents(halfExtents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBoundingSphere(float radius)
|
void SHCollisionShape::SetBoundingSphere(float radius)
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
// Set the radius relative to transform
|
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
|
||||||
float worldRadius = radius;
|
// Set the radius relative to world scale
|
||||||
|
const SHVec3 WORLD_SCALE = colliderComponent->GetScale();
|
||||||
|
const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z });
|
||||||
|
const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
if (type != Type::SPHERE)
|
||||||
if (transformComponent != nullptr)
|
|
||||||
{
|
|
||||||
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 * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type::SPHERE)
|
|
||||||
{
|
|
||||||
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
|
|
||||||
sphere->SetRadius(worldRadius);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
delete shape;
|
delete shape;
|
||||||
shape = new SHBoundingSphere{ positionOffset, worldRadius };
|
shape = new SHBoundingSphere{ positionOffset, WORLD_RADIUS };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
|
||||||
|
sphere->SetWorldRadius(WORLD_RADIUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetIsTrigger(bool trigger) noexcept
|
void SHCollisionShape::SetIsTrigger(bool trigger) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
isTrigger = trigger;
|
isTrigger = trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetFriction(float friction) noexcept
|
void SHCollisionShape::SetFriction(float friction) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetFriction(friction);
|
material.SetFriction(friction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBounciness(float bounciness) noexcept
|
void SHCollisionShape::SetBounciness(float bounciness) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetBounciness(bounciness);
|
material.SetBounciness(bounciness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetDensity(float density) noexcept
|
void SHCollisionShape::SetDensity(float density) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetDensity(density);
|
material.SetDensity(density);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material = newMaterial;
|
material = newMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
|
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
positionOffset = posOffset;
|
positionOffset = posOffset;
|
||||||
|
@ -281,7 +268,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
rotationOffset = rotOffset;
|
rotationOffset = rotOffset;
|
||||||
|
@ -291,7 +278,7 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::CopyShape(const SHShape* rhs)
|
void SHCollisionShape::CopyShape(const SHShape* rhs)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -299,14 +286,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
|
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
|
||||||
|
|
||||||
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() };
|
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetWorldExtents() };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::SPHERE:
|
case Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
|
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
|
||||||
|
|
||||||
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() };
|
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -320,14 +307,14 @@ RTTR_REGISTRATION
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
registration::enumeration<SHCollider::Type>("Collider Type")
|
registration::enumeration<SHCollisionShape::Type>("Collider Type")
|
||||||
(
|
(
|
||||||
value("Box", SHCollider::Type::BOX),
|
value("Box", SHCollisionShape::Type::BOX),
|
||||||
value("Sphere", SHCollider::Type::SPHERE)
|
value("Sphere", SHCollisionShape::Type::SPHERE)
|
||||||
// TODO(Diren): Add More Shapes
|
// TODO(Diren): Add More Shapes
|
||||||
);
|
);
|
||||||
|
|
||||||
registration::class_<SHCollider>("Collider")
|
registration::class_<SHCollisionShape>("Collider")
|
||||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
.property("Position Offset", &SHCollisionShape::GetPositionOffset, &SHCollisionShape::SetPositionOffset)
|
||||||
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
.property("Rotation Offset", &SHCollisionShape::GetRotationOffset, &SHCollisionShape::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHCollider
|
class SH_API SHCollisionShape
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -51,18 +51,18 @@ namespace SHADE
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
|
SHCollisionShape (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
|
||||||
|
|
||||||
SHCollider (const SHCollider& rhs) noexcept;
|
SHCollisionShape (const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider (SHCollider&& rhs) noexcept;
|
SHCollisionShape (SHCollisionShape&& rhs) noexcept;
|
||||||
~SHCollider () noexcept;
|
~SHCollisionShape () noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& operator=(const SHCollider& rhs) noexcept;
|
SHCollisionShape& operator=(const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider& operator=(SHCollider&& rhs) noexcept;
|
SHCollisionShape& operator=(SHCollisionShape&& rhs) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
|
@ -128,24 +128,24 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
int SHPhysicsObject::AddCollider(SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||||
|
|
||||||
switch (collider->GetType())
|
switch (collider->GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetWorldExtents());
|
||||||
|
|
||||||
rp3dBody->addCollider(newBox, OFFSETS);
|
rp3dBody->addCollider(newBox, OFFSETS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetWorldRadius());
|
||||||
|
|
||||||
rp3dBody->addCollider(newSphere, OFFSETS);
|
rp3dBody->addCollider(newSphere, OFFSETS);
|
||||||
break;
|
break;
|
||||||
|
@ -173,7 +173,7 @@ namespace SHADE
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto& collider : c->colliders)
|
for (auto& collider : c->collisionShapes)
|
||||||
{
|
{
|
||||||
if (!collider.dirty)
|
if (!collider.dirty)
|
||||||
continue;
|
continue;
|
||||||
|
@ -188,21 +188,21 @@ namespace SHADE
|
||||||
|
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||||
|
|
||||||
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
|
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
|
||||||
rp3dBoxShape->setHalfExtents(box->GetHalfExtents());
|
rp3dBoxShape->setHalfExtents(box->GetWorldExtents());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
||||||
|
|
||||||
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
|
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
|
||||||
rp3dSphereShape->setRadius(sphere->GetRadius());
|
rp3dSphereShape->setRadius(sphere->GetWorldRadius());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int AddCollider (SHCollider* collider);
|
int AddCollider (SHCollisionShape* collider);
|
||||||
void RemoveCollider (int index);
|
void RemoveCollider (int index);
|
||||||
|
|
||||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace SHADE
|
||||||
factory.destroyPhysicsWorld(world);
|
factory.destroyPhysicsWorld(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
|
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
auto* physicsObject = GetPhysicsObject(entityID);
|
auto* physicsObject = GetPhysicsObject(entityID);
|
||||||
|
|
||||||
|
@ -395,6 +395,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
const auto WORLD_ROT = transformComponent->GetWorldOrientation();
|
const auto WORLD_ROT = transformComponent->GetWorldOrientation();
|
||||||
|
const auto WORLD_SCL = transformComponent->GetWorldScale();
|
||||||
|
|
||||||
physicsObject.SetPosition(WORLD_POS);
|
physicsObject.SetPosition(WORLD_POS);
|
||||||
physicsObject.SetOrientation(WORLD_ROT);
|
physicsObject.SetOrientation(WORLD_ROT);
|
||||||
|
@ -409,8 +410,11 @@ namespace SHADE
|
||||||
|
|
||||||
if (colliderComponent)
|
if (colliderComponent)
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
colliderComponent->position = WORLD_POS;
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
colliderComponent->scale = WORLD_SCL;
|
||||||
|
|
||||||
|
colliderComponent->RecomputeCollisionShapes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,7 +609,6 @@ namespace SHADE
|
||||||
|
|
||||||
if (rigidBodyComponent != nullptr)
|
if (rigidBodyComponent != nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -658,8 +661,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
||||||
{
|
{
|
||||||
const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0];
|
const bool ENTITY_MATCH = (e.ids[0] == collisionEvent.ids[0] && e.ids[1] == collisionEvent.ids[1])
|
||||||
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1];
|
|| (e.ids[0] == collisionEvent.ids[1] && e.ids[1] == collisionEvent.ids[0]);
|
||||||
|
const bool COLLIDERS_MATCH = (e.ids[2] == collisionEvent.ids[2] && e.ids[3] == collisionEvent.ids[3])
|
||||||
|
|| (e.ids[2] == collisionEvent.ids[3] && e.ids[3] == collisionEvent.ids[2]);
|
||||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -734,7 +739,7 @@ namespace SHADE
|
||||||
// Add collision shapes back into the body
|
// Add collision shapes back into the body
|
||||||
if (colliderComponent != nullptr)
|
if (colliderComponent != nullptr)
|
||||||
{
|
{
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,8 +748,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
|
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
|
||||||
|
|
||||||
colliderComponent->position = transformComponent->GetWorldPosition();
|
colliderComponent->position = transformComponent->GetWorldPosition();
|
||||||
colliderComponent->orientation = transformComponent->GetWorldOrientation();
|
colliderComponent->orientation = transformComponent->GetWorldOrientation();
|
||||||
|
colliderComponent->scale = transformComponent->GetWorldScale();
|
||||||
|
|
||||||
if (physicsObject->rp3dBody == nullptr)
|
if (physicsObject->rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -755,7 +761,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Collision Shapes
|
// Add Collision Shapes
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,7 +806,7 @@ namespace SHADE
|
||||||
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
||||||
);
|
);
|
||||||
|
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace SHADE
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () override;
|
void Exit () override;
|
||||||
|
|
||||||
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
void AddCollisionShape (EntityID entityID, SHCollisionShape* collider);
|
||||||
void RemoveCollisionShape (EntityID entityID, int index);
|
void RemoveCollisionShape (EntityID entityID, int index);
|
||||||
|
|
||||||
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||||
|
@ -183,24 +183,24 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||||
|
|
||||||
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||||
void SyncTransforms () noexcept;
|
void SyncTransforms () noexcept;
|
||||||
|
|
||||||
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||||
void ClearInvalidCollisions () noexcept;
|
void ClearInvalidCollisions () noexcept;
|
||||||
|
|
||||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||||
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
||||||
|
|
||||||
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||||
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||||
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
||||||
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,14 @@ namespace SHADE
|
||||||
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderA() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderA() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollisionShape(ids[COLLIDER_A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderB() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderB() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollisionShape(ids[COLLIDER_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
struct SHPhysicsColliderAddedEvent
|
struct SHPhysicsColliderAddedEvent
|
||||||
{
|
{
|
||||||
EntityID entityID;
|
EntityID entityID;
|
||||||
SHCollider::Type colliderType;
|
SHCollisionShape::Type colliderType;
|
||||||
int colliderIndex;
|
int colliderIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ namespace SHADE
|
||||||
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderA () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderA () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderB () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderB () const noexcept;
|
||||||
[[nodiscard]] State GetCollisionState () const noexcept;
|
[[nodiscard]] State GetCollisionState () const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHSceneGraph.cpp
|
* \file SHSceneGraph.cpp
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Implementation for a Scene Graph & Scene Nodes.
|
* \brief Implementation for a Scene Graph.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -16,8 +16,6 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Tools/SHLogger.h"
|
|
||||||
#include "Tools/SHException.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -25,56 +23,6 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
|
|
||||||
: active { true }
|
|
||||||
, entityID { eid }
|
|
||||||
, parent { parent }
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
|
|
||||||
: active { rhs.active }
|
|
||||||
, entityID { rhs.entityID }
|
|
||||||
, parent { rhs.parent }
|
|
||||||
{
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
|
|
||||||
: active { rhs.active }
|
|
||||||
, entityID { rhs.entityID }
|
|
||||||
, parent { rhs.parent }
|
|
||||||
{
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (this == &rhs)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
active = rhs.active;
|
|
||||||
entityID = rhs.entityID;
|
|
||||||
parent = rhs.parent;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
|
|
||||||
{
|
|
||||||
active = rhs.active;
|
|
||||||
entityID = rhs.entityID;
|
|
||||||
parent = rhs.parent;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneGraph::SHSceneGraph() noexcept
|
SHSceneGraph::SHSceneGraph() noexcept
|
||||||
: root { nullptr }
|
: root { nullptr }
|
||||||
{
|
{
|
||||||
|
@ -110,56 +58,6 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHSceneNode::IsActive() const noexcept
|
|
||||||
{
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityID SHSceneNode::GetEntityID() const noexcept
|
|
||||||
{
|
|
||||||
return entityID;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
|
||||||
{
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
|
||||||
{
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error handling
|
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (children.empty())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Entity {} has no children!", entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
// Find child
|
|
||||||
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
|
||||||
|
|
||||||
const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH);
|
|
||||||
if (CHILD_ITER == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *CHILD_ITER;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
||||||
{
|
{
|
||||||
if (root != nullptr)
|
if (root != nullptr)
|
||||||
|
@ -313,41 +211,7 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* newParent) noexcept
|
||||||
{
|
|
||||||
if (parentNode == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
parent->RemoveChild(this);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle self assignment
|
|
||||||
if (parent && parentNode->entityID == parent->entityID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
parent->RemoveChild(this);
|
|
||||||
|
|
||||||
parent = parentNode;
|
|
||||||
// Update parent's children
|
|
||||||
parent->AddChild(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneNode::SetActive(bool newActiveState) noexcept
|
|
||||||
{
|
|
||||||
active = newActiveState;
|
|
||||||
|
|
||||||
for (auto* child : children)
|
|
||||||
{
|
|
||||||
SetActive(newActiveState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Error Handling
|
// Error Handling
|
||||||
|
@ -369,30 +233,31 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
.node = NODE_ITER->second
|
.node = NODE_ITER->second
|
||||||
, .oldParent = NODE_ITER->second->GetParent()
|
, .oldParent = NODE_ITER->second->GetParent()
|
||||||
, .newParent = parent ? parent : root
|
, .newParent = newParent ? newParent : root
|
||||||
};
|
};
|
||||||
|
|
||||||
if (parent == nullptr)
|
if (newParent == nullptr)
|
||||||
parent = root;
|
newParent = root;
|
||||||
|
|
||||||
NODE_ITER->second->SetParent(parent);
|
ChangeParent(NODE_ITER->second, newParent);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, EntityID newParent) noexcept
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Error Handling
|
// Error Handling
|
||||||
|
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SHEntityManager::IsValidEID(parent))
|
if (!SHEntityManager::IsValidEID(newParent))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID)
|
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,10 +268,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PARENT_ITER = entityNodeMap.find(parent);
|
auto PARENT_ITER = entityNodeMap.find(newParent);
|
||||||
if (PARENT_ITER == entityNodeMap.end())
|
if (PARENT_ITER == entityNodeMap.end())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
@ -419,7 +284,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
currentNode->SetParent(PARENT_ITER->second);
|
ChangeParent(currentNode, PARENT_ITER->second);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
@ -428,84 +293,6 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (newChild == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
if (newChild->parent)
|
|
||||||
newChild->parent->RemoveChild(newChild);
|
|
||||||
|
|
||||||
newChild->parent = this;
|
|
||||||
children.emplace_back(newChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Entity {} is invalid!", childID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node)
|
|
||||||
{
|
|
||||||
return node->GetEntityID() == childID;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (childIter == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*childIter)->parent = nullptr;
|
|
||||||
childIter = children.erase(childIter);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (childToRemove == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
auto childIter = std::find(children.begin(), children.end(), childToRemove);
|
|
||||||
if (childIter == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childToRemove->entityID, entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
childIter = children.erase(childIter);
|
|
||||||
childToRemove->parent = nullptr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneNode::RemoveAllChildren() noexcept
|
|
||||||
{
|
|
||||||
for (const auto child : children)
|
|
||||||
child->parent = nullptr;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
@ -528,13 +315,12 @@ namespace SHADE
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
{
|
{
|
||||||
// Specific handling for root to avoid a warning when removing a non-existent child
|
// Specific handling for root to avoid a warning when removing a non-existent child
|
||||||
parent = root;
|
|
||||||
newNode->parent = root;
|
newNode->parent = root;
|
||||||
root->children.emplace_back(newNode);
|
root->children.emplace_back(newNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newNode->SetParent(parent);
|
ChangeParent(newNode, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
@ -542,6 +328,8 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
|
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -554,12 +342,12 @@ namespace SHADE
|
||||||
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
|
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
SHSceneNode* parent = currentNode->GetParent();
|
if (currentNode->parent != nullptr)
|
||||||
if (parent != nullptr)
|
RemoveChild(currentNode->parent, currentNode);
|
||||||
parent->RemoveChild(currentNode);
|
|
||||||
|
|
||||||
ReleaseNode(currentNode);
|
ReleaseNode(currentNode);
|
||||||
return true;
|
return true;
|
||||||
|
@ -568,9 +356,8 @@ namespace SHADE
|
||||||
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
|
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
|
||||||
{
|
{
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
SHSceneNode* parent = nodeToRemove->GetParent();
|
if (nodeToRemove->parent != nullptr)
|
||||||
if (parent != nullptr)
|
RemoveChild(nodeToRemove->parent, nodeToRemove);
|
||||||
parent->RemoveChild(nodeToRemove);
|
|
||||||
|
|
||||||
ReleaseNode(nodeToRemove);
|
ReleaseNode(nodeToRemove);
|
||||||
return true;
|
return true;
|
||||||
|
@ -582,6 +369,91 @@ namespace SHADE
|
||||||
ReleaseNode(node);
|
ReleaseNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||||
|
if (NODE_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
// Handle self-checks
|
||||||
|
if (NODE_ITER->second == targetNode)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} cannot be a child of itself!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for a matching target until the root
|
||||||
|
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
|
||||||
|
while (CURRENT_TARGET != root)
|
||||||
|
{
|
||||||
|
if (CURRENT_TARGET == targetNode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CURRENT_TARGET = CURRENT_TARGET->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHSceneGraph::IsChildOf(EntityID entityID, EntityID targetID) noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(targetID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", targetID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||||
|
if (NODE_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TARGET_ITER = entityNodeMap.find(targetID);
|
||||||
|
if (TARGET_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
|
||||||
|
while (CURRENT_TARGET != root)
|
||||||
|
{
|
||||||
|
if (CURRENT_TARGET == TARGET_ITER->second)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CURRENT_TARGET = CURRENT_TARGET->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
||||||
{
|
{
|
||||||
TraverseAndInvokeFunction(root, function);
|
TraverseAndInvokeFunction(root, function);
|
||||||
|
@ -594,11 +466,6 @@ namespace SHADE
|
||||||
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
||||||
{
|
{
|
||||||
SHSceneNode* newNode = new SHSceneNode{entityID};
|
SHSceneNode* newNode = new SHSceneNode{entityID};
|
||||||
|
|
||||||
//#ifdef _DEBUG
|
|
||||||
// SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
entityNodeMap.emplace(entityID, newNode);
|
entityNodeMap.emplace(entityID, newNode);
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
@ -608,19 +475,81 @@ namespace SHADE
|
||||||
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
|
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
|
||||||
|
|
||||||
// Remove parent's reference to this node if there is a parent
|
// Remove parent's reference to this node if there is a parent
|
||||||
if (node->GetParent() != nullptr)
|
if (node->parent != nullptr)
|
||||||
node->GetParent()->RemoveChild(node);
|
RemoveChild(node->parent, node);
|
||||||
|
|
||||||
// Remove child's references to this node. Children end up as floating nodes.
|
// Remove child's references to this node. Children end up as floating nodes.
|
||||||
for (auto* child : node->GetChildren())
|
for (auto* child : node->GetChildren())
|
||||||
{
|
{
|
||||||
child->SetParent(nullptr);
|
ChangeParent(child, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityNodeMap.erase(node->GetEntityID());
|
entityNodeMap.erase(node->GetEntityID());
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent)
|
||||||
|
{
|
||||||
|
// Handle self assignment
|
||||||
|
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove child
|
||||||
|
if (node->parent)
|
||||||
|
RemoveChild(node->parent, node);
|
||||||
|
|
||||||
|
if (newParent == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Removing Entity {}'s parent", node->entityID)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->parent = newParent;
|
||||||
|
// Update parent's children
|
||||||
|
AddChild(newParent, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::AddChild(SHSceneNode* node, SHSceneNode* newChild)
|
||||||
|
{
|
||||||
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
|
SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
|
||||||
|
|
||||||
|
if (newChild->parent)
|
||||||
|
RemoveChild(newChild->parent, newChild);
|
||||||
|
|
||||||
|
newChild->parent = node;
|
||||||
|
node->children.emplace_back(newChild);
|
||||||
|
|
||||||
|
const SHSceneGraphAddChildEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.parent = node
|
||||||
|
, .childAdded = newChild
|
||||||
|
};
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphAddChildEvent>(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove)
|
||||||
|
{
|
||||||
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
|
SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!")
|
||||||
|
|
||||||
|
auto childIter = std::find(node->children.begin(), node->children.end(), childToRemove);
|
||||||
|
if (childIter == node->children.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
childIter = node->children.erase(childIter);
|
||||||
|
childToRemove->parent = nullptr;
|
||||||
|
|
||||||
|
const SHSceneGraphRemoveChildEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.parent = node
|
||||||
|
, .childRemoved = childToRemove
|
||||||
|
};
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphRemoveChildEvent>(EVENT_DATA, SH_SCENEGRAPH_REMOVE_CHILD_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
||||||
{
|
{
|
||||||
for (auto* child : node->children)
|
for (auto* child : node->children)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHSceneGraph.h
|
* \file SHSceneGraph.h
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Interface for a Scene Graph & Scene Nodes.
|
* \brief Interface for a Scene Graph.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -15,81 +15,15 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Entity/SHEntity.h"
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "SHSceneNode.h"
|
||||||
|
#include "SHSceneGraphEvents.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Forward Declarations */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SHSceneGraph;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHSceneNode
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Friends */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
friend class SHSceneGraph;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
~SHSceneNode () = default;
|
|
||||||
|
|
||||||
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
|
|
||||||
SHSceneNode (const SHSceneNode& rhs) noexcept;
|
|
||||||
SHSceneNode (SHSceneNode&& rhs) noexcept;
|
|
||||||
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
|
|
||||||
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Getter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsActive () const noexcept;
|
|
||||||
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
|
||||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
|
||||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Setter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void SetParent (SHSceneNode* parentNode) noexcept;
|
|
||||||
void SetActive (bool newActiveState) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void AddChild (SHSceneNode* newChild) noexcept;
|
|
||||||
|
|
||||||
bool RemoveChild (EntityID childID) noexcept;
|
|
||||||
bool RemoveChild (SHSceneNode* childToRemove) noexcept;
|
|
||||||
|
|
||||||
void RemoveAllChildren () noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Data Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
bool active;
|
|
||||||
EntityID entityID;
|
|
||||||
SHSceneNode* parent;
|
|
||||||
std::vector<SHSceneNode*> children;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SH_API SHSceneGraph
|
class SH_API SHSceneGraph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -130,19 +64,22 @@ namespace SHADE
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept;
|
void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
|
||||||
void SetParent (EntityID entityID, EntityID parent) const noexcept;
|
void SetParent (EntityID entityID, EntityID newParent) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
||||||
bool RemoveNode (EntityID entityID) noexcept;
|
bool RemoveNode (EntityID entityID) noexcept;
|
||||||
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
||||||
void Reset () noexcept;
|
void Reset () noexcept;
|
||||||
|
|
||||||
void Traverse (const UnaryFunction& function) const;
|
bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept;
|
||||||
|
bool IsChildOf (EntityID entityID, EntityID targetID) noexcept;
|
||||||
|
|
||||||
|
void Traverse (const UnaryFunction& function) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -156,20 +93,14 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode* AllocateNode (EntityID entityID);
|
SHSceneNode* AllocateNode (EntityID entityID);
|
||||||
void ReleaseNode (SHSceneNode* node) noexcept;
|
void ReleaseNode (SHSceneNode* node) noexcept;
|
||||||
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
void ChangeParent (SHSceneNode* node, SHSceneNode* newParent);
|
||||||
/* Event Data Definitions */
|
void AddChild (SHSceneNode* node, SHSceneNode* newChild);
|
||||||
/*-----------------------------------------------------------------------------------*/
|
void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove);
|
||||||
|
|
||||||
struct SHSceneGraphChangeParentEvent
|
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
||||||
{
|
|
||||||
SHSceneNode* node;
|
|
||||||
SHSceneNode* oldParent;
|
|
||||||
SHSceneNode* newParent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -0,0 +1,41 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneGraphEvents.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for Scene Graph Events.
|
||||||
|
*
|
||||||
|
* \copyright 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 Headers
|
||||||
|
#include "SHSceneNode.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Event Data Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct SHSceneGraphChangeParentEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* node;
|
||||||
|
SHSceneNode* oldParent;
|
||||||
|
SHSceneNode* newParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHSceneGraphAddChildEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* parent;
|
||||||
|
SHSceneNode* childAdded;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHSceneGraphRemoveChildEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* parent;
|
||||||
|
SHSceneNode* childRemoved;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,143 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneNode.c[[
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for a Scene Node.
|
||||||
|
*
|
||||||
|
* \copyright 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>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHSceneNode.h"
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
|
||||||
|
: active { true }
|
||||||
|
, entityID { eid }
|
||||||
|
, parent { parent }
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
|
||||||
|
: active { rhs.active }
|
||||||
|
, entityID { rhs.entityID }
|
||||||
|
, parent { rhs.parent }
|
||||||
|
{
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
|
||||||
|
: active { rhs.active }
|
||||||
|
, entityID { rhs.entityID }
|
||||||
|
, parent { rhs.parent }
|
||||||
|
{
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
active = rhs.active;
|
||||||
|
entityID = rhs.entityID;
|
||||||
|
parent = rhs.parent;
|
||||||
|
|
||||||
|
children.clear();
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
|
||||||
|
{
|
||||||
|
active = rhs.active;
|
||||||
|
entityID = rhs.entityID;
|
||||||
|
parent = rhs.parent;
|
||||||
|
|
||||||
|
children.clear();
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHSceneNode::IsActive() const noexcept
|
||||||
|
{
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityID SHSceneNode::GetEntityID() const noexcept
|
||||||
|
{
|
||||||
|
return entityID;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
||||||
|
{
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
|
if (!SHEntityManager::IsValidEID(childID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.empty())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} has no children!", entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
// Find child
|
||||||
|
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
||||||
|
|
||||||
|
const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH);
|
||||||
|
if (CHILD_ITER == children.end())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *CHILD_ITER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHSceneNode::SetActive(bool newActiveState) noexcept
|
||||||
|
{
|
||||||
|
active = newActiveState;
|
||||||
|
|
||||||
|
for (auto* child : children)
|
||||||
|
{
|
||||||
|
child->SetActive(newActiveState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,82 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneNode.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a Scene Node.
|
||||||
|
*
|
||||||
|
* \copyright 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 <vector>
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "SHSceneGraph.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class SHSceneGraph;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class SH_API SHSceneNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Friends */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
friend class SHSceneGraph;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
~SHSceneNode () = default;
|
||||||
|
|
||||||
|
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
|
||||||
|
SHSceneNode (const SHSceneNode& rhs) noexcept;
|
||||||
|
SHSceneNode (SHSceneNode&& rhs) noexcept;
|
||||||
|
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
|
||||||
|
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsActive () const noexcept;
|
||||||
|
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
||||||
|
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
||||||
|
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetActive (bool newActiveState) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
EntityID entityID;
|
||||||
|
SHSceneNode* parent;
|
||||||
|
std::vector<SHSceneNode*> children;
|
||||||
|
};
|
||||||
|
} // namespace SHADE
|
||||||
|
|
|
@ -26,13 +26,15 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Physics/SHPhysicsSystem.h"
|
#include "Physics/SHPhysicsSystem.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Static Definitions */
|
/* Static Definitions */
|
||||||
/*----------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------*/
|
||||||
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
||||||
const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder";
|
const std::string SHScriptEngine::CSPROJ_DIR = std::string(ASSET_ROOT) + "/Scripts";
|
||||||
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
|
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -262,18 +264,18 @@ namespace SHADE
|
||||||
</ItemGroup>\n\
|
</ItemGroup>\n\
|
||||||
<ItemGroup>\n\
|
<ItemGroup>\n\
|
||||||
<Reference Include=\"SHADE_Managed\">\n\
|
<Reference Include=\"SHADE_Managed\">\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
|
||||||
</Reference>\n\
|
</Reference>\n\
|
||||||
<Reference Include=\"SHADE_CSharp\">\n\
|
<Reference Include=\"SHADE_CSharp\">\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\
|
||||||
</Reference>\n\
|
</Reference>\n\
|
||||||
</ItemGroup>\n\
|
</ItemGroup>\n\
|
||||||
</Project>";
|
</Project>";
|
||||||
|
|
||||||
// Attempt to create the file
|
// Attempt to create the file
|
||||||
std::ofstream file(path);
|
std::ofstream file(path, std::ios::out | std::ios::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw std::runtime_error("Unable to create CsProj file!");
|
throw std::runtime_error("Unable to create CsProj file!");
|
||||||
|
|
||||||
|
@ -316,6 +318,20 @@ namespace SHADE
|
||||||
return eventData->handle;
|
return eventData->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHScriptEngine::onSceneNodeChildrenAdded(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphAddChildEvent>*>(eventPtr.get());
|
||||||
|
csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID());
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHScriptEngine::onSceneNodeChildrenRemoved(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphRemoveChildEvent>*>(eventPtr.get());
|
||||||
|
csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID());
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -380,6 +396,12 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
"ExecuteLateUpdate"
|
"ExecuteLateUpdate"
|
||||||
);
|
);
|
||||||
|
csScriptsExecuteDrawGizmos = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteOnDrawGizmos"
|
||||||
|
);
|
||||||
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
(
|
(
|
||||||
DEFAULT_CSHARP_LIB_NAME,
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
@ -434,6 +456,12 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".Collider",
|
DEFAULT_CSHARP_NAMESPACE + ".Collider",
|
||||||
"OnCollisionShapeRemoved"
|
"OnCollisionShapeRemoved"
|
||||||
);
|
);
|
||||||
|
csSceneNodeChildrenChanged = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ChildListCache",
|
||||||
|
"OnChildrenChanged"
|
||||||
|
);
|
||||||
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
||||||
(
|
(
|
||||||
DEFAULT_CSHARP_LIB_NAME,
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
@ -456,6 +484,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHScriptEngine::registerEvents()
|
void SHScriptEngine::registerEvents()
|
||||||
{
|
{
|
||||||
|
/* Entity */
|
||||||
// Register for entity destroyed event
|
// Register for entity destroyed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedEventReceiver
|
||||||
{
|
{
|
||||||
|
@ -463,26 +492,39 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
|
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
|
||||||
|
|
||||||
|
/* Colliders */
|
||||||
// Register for collider added event
|
// Register for collider added event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderAdded)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderAdded)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addedColliderEventReceiver));
|
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addedColliderEventReceiver));
|
||||||
|
|
||||||
// Register for collider removed event
|
// Register for collider removed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderRemoved)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderRemoved)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderEventReceiver));
|
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderEventReceiver));
|
||||||
|
|
||||||
// Register for collider component removed event
|
// Register for collider component removed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderComponentEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderComponentEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderComponentRemoved)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderComponentRemoved)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver));
|
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver));
|
||||||
|
|
||||||
|
/* SceneGraph */
|
||||||
|
// Register for SceneNode child added event
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addChildEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneNodeChildrenAdded)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_ADD_CHILD_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addChildEventReceiver));
|
||||||
|
// Register for SceneNode child removed event
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removeChildEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneNodeChildrenRemoved)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_REMOVE_CHILD_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removeChildEventReceiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
||||||
|
|
|
@ -55,6 +55,12 @@ namespace SHADE
|
||||||
LateUpdateRoutine();
|
LateUpdateRoutine();
|
||||||
void Execute(double dt) noexcept override final;
|
void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
|
class SH_API GizmosDrawRoutine final : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GizmosDrawRoutine();
|
||||||
|
void Execute(double dt) noexcept override final;
|
||||||
|
};
|
||||||
class SH_API FrameCleanUpRoutine final : public SHSystemRoutine
|
class SH_API FrameCleanUpRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -250,6 +256,7 @@ namespace SHADE
|
||||||
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
|
||||||
CsFuncPtr csScriptsExecuteUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteUpdate = nullptr;
|
||||||
CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
|
||||||
|
CsFuncPtr csScriptsExecuteDrawGizmos = nullptr;
|
||||||
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
|
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
|
||||||
CsFuncPtr csScriptsFrameCleanUp = nullptr;
|
CsFuncPtr csScriptsFrameCleanUp = nullptr;
|
||||||
CsScriptManipFuncPtr csScriptsAdd = nullptr;
|
CsScriptManipFuncPtr csScriptsAdd = nullptr;
|
||||||
|
@ -260,6 +267,7 @@ namespace SHADE
|
||||||
// - Events
|
// - Events
|
||||||
CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
|
CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
|
||||||
CsEventRelayFuncPtr csColliderOnRemoved = nullptr;
|
CsEventRelayFuncPtr csColliderOnRemoved = nullptr;
|
||||||
|
CsEventRelayFuncPtr csSceneNodeChildrenChanged = nullptr;
|
||||||
// - Editor
|
// - Editor
|
||||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||||
CsFuncPtr csEditorUndo = nullptr;
|
CsFuncPtr csEditorUndo = nullptr;
|
||||||
|
@ -272,6 +280,8 @@ namespace SHADE
|
||||||
SHEventHandle onColliderAdded(SHEventPtr eventPtr);
|
SHEventHandle onColliderAdded(SHEventPtr eventPtr);
|
||||||
SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
|
SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
|
||||||
SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr);
|
SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr);
|
||||||
|
SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr);
|
||||||
|
SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue