Animation WIP merge #321
|
@ -1,4 +1,4 @@
|
||||||
Start in Fullscreen: false
|
Start in Fullscreen: false
|
||||||
Starting Scene ID: 97158628
|
Starting Scene ID: 97402985
|
||||||
Window Size: {x: 1920, y: 1080}
|
Window Size: {x: 1920, y: 1080}
|
||||||
Window Title: SHADE Engine
|
Window Title: SHADE Engine
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -1,16 +1,16 @@
|
||||||
0 1
|
0 1 3
|
||||||
1 2
|
1 2 3
|
||||||
2 3
|
2 3 65535
|
||||||
3 4
|
3 4 65535
|
||||||
4 5
|
4 5 65535
|
||||||
5 6
|
5 6 65535
|
||||||
6 7
|
6 7 65535
|
||||||
7 8
|
7 8 65535
|
||||||
8 9
|
8 9 65535
|
||||||
9 10
|
9 10 65535
|
||||||
10 11
|
10 11 65535
|
||||||
11 12
|
11 12 65535
|
||||||
12 13
|
12 13 65535
|
||||||
13 14
|
13 14 65535
|
||||||
14 15
|
14 15 65535
|
||||||
15 16
|
15 16 65535
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Start Maximized: true
|
||||||
|
Working Scene ID: 97402985
|
||||||
|
Window Size: {x: 1920, y: 1080}
|
||||||
|
Style: 0
|
|
@ -0,0 +1,247 @@
|
||||||
|
- EID: 0
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 2.72256827, y: 0.501797795, z: -0.0273017883}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0.436332315}
|
||||||
|
Scale: {x: 4.61070776, y: 0.99999392, z: 0.999996722}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 1
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Camera Component:
|
||||||
|
Position: {x: 0, y: 2, z: 10}
|
||||||
|
Pitch: 0
|
||||||
|
Yaw: 0
|
||||||
|
Roll: 0
|
||||||
|
Width: 1920
|
||||||
|
Height: 1080
|
||||||
|
Near: 0.00999999978
|
||||||
|
Far: 10000
|
||||||
|
Perspective: true
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 3
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 2, y: 7.5, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: 0.785398185}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Auto Mass: false
|
||||||
|
Mass: 0.52359879
|
||||||
|
Drag: 0.00999999978
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Gravity Scale: 1
|
||||||
|
Interpolate: true
|
||||||
|
Sleeping Enabled: true
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: true
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: false
|
||||||
|
Freeze Rotation Y: false
|
||||||
|
Freeze Rotation Z: false
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Sphere
|
||||||
|
Radius: 1
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 2
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 4, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0.436332315}
|
||||||
|
Scale: {x: 4.61071014, y: 0.999995887, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 2
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 4
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -3, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 10, y: 3, z: 10}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -4.80025721, y: 3, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: 1.57079601}
|
||||||
|
Scale: {x: 9.99975109, y: 0.499992192, z: 10}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 6
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 4.80000019, y: 3, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: 1.57079601}
|
||||||
|
Scale: {x: 9.99975109, y: 0.499992192, z: 10}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 7
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 7, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0.785398185}
|
||||||
|
Scale: {x: 0.999990404, y: 0.999994457, z: 0.999985337}
|
||||||
|
IsActive: true
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Auto Mass: false
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0.00999999978
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Gravity Scale: 1
|
||||||
|
Interpolate: true
|
||||||
|
Sleeping Enabled: true
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: false
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: false
|
||||||
|
Freeze Rotation Y: false
|
||||||
|
Freeze Rotation Z: false
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts:
|
||||||
|
- Type: PhysicsTestObj
|
||||||
|
Enabled: true
|
||||||
|
forceAmount: 50
|
||||||
|
torqueAmount: 5
|
||||||
|
- EID: 8
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 3}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Collider Component:
|
||||||
|
DrawColliders: false
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Collision Tag: 1
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: PhysicsSandbox
|
||||||
|
ID: 97402985
|
||||||
|
Type: 5
|
|
@ -7,6 +7,7 @@
|
||||||
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
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}
|
||||||
|
IsActive: true
|
||||||
Camera Component:
|
Camera Component:
|
||||||
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
Pitch: 0
|
Pitch: 0
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
Near: 0.00999999978
|
Near: 0.00999999978
|
||||||
Far: 10000
|
Far: 10000
|
||||||
Perspective: true
|
Perspective: true
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Raccoon
|
Name: Raccoon
|
||||||
|
@ -24,12 +26,14 @@
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 1
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 0, z: 0}
|
Translate: {x: -1.86388135, y: 0.0544953719, z: 0}
|
||||||
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}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 3
|
- EID: 3
|
||||||
Name: Bag
|
Name: Bag
|
||||||
|
@ -40,9 +44,11 @@
|
||||||
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
||||||
Rotate: {x: -0, y: 2.79945588, z: 0}
|
Rotate: {x: -0, y: 2.79945588, z: 0}
|
||||||
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 144838771
|
Mesh: 144838771
|
||||||
Material: 123745521
|
Material: 123745521
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 2
|
- EID: 2
|
||||||
Name: DirectionalLight
|
Name: DirectionalLight
|
||||||
|
@ -50,12 +56,13 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Light Component:
|
Light Component:
|
||||||
Position: {x: 0, y: 0, z: 0}
|
Position: {x: 3, y: 4.5, z: 7}
|
||||||
Type: Directional
|
Type: Directional
|
||||||
Direction: {x: 0, y: 0, z: 1}
|
Direction: {x: -0.298000008, y: 0.522498012, z: 0.798600018}
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0
|
Strength: 0
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 4
|
- EID: 4
|
||||||
Name: AmbientLight
|
Name: AmbientLight
|
||||||
|
@ -69,4 +76,20 @@
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0.600000024
|
Strength: 0.600000024
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Floor
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0.0810000002, z: 0}
|
||||||
|
Rotate: {x: -1.57079637, y: 0, z: 0}
|
||||||
|
Scale: {x: 50, y: 50, z: 50}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 141771688
|
||||||
|
Material: 124370424
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
|
@ -1,7 +1,7 @@
|
||||||
- EID: 0
|
- EID: 0
|
||||||
Name: Canvas
|
Name: Canvas
|
||||||
IsActive: true
|
IsActive: true
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 2
|
||||||
Components:
|
Components:
|
||||||
Canvas Component:
|
Canvas Component:
|
||||||
Canvas Width: 10
|
Canvas Width: 10
|
||||||
|
@ -28,6 +28,26 @@
|
||||||
Clicked Texture: 0
|
Clicked Texture: 0
|
||||||
IsActive: true
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -3.9000001, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 141771688
|
||||||
|
Material: 129340704
|
||||||
|
IsActive: true
|
||||||
|
Toggle Button Component:
|
||||||
|
Non Toggled Texture: 0
|
||||||
|
Toggled Texture: 0
|
||||||
|
Value: true
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Camera
|
Name: Camera
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Name: UI_Test
|
Name: UI_Test
|
||||||
ID: 87707373
|
ID: 87244611
|
||||||
Type: 5
|
Type: 5
|
||||||
|
|
|
@ -159,7 +159,7 @@ public partial class LeafSearch : BehaviourTreeNode
|
||||||
//Since transform position is often the raccoon's base and the ray needs to hit somewhere higher to be more reliable
|
//Since transform position is often the raccoon's base and the ray needs to hit somewhere higher to be more reliable
|
||||||
Vector3 rayDestination = plrT.GlobalPosition + plrT.GlobalScale * playerCollider.PositionOffset;
|
Vector3 rayDestination = plrT.GlobalPosition + plrT.GlobalScale * playerCollider.PositionOffset;
|
||||||
Ray sightRay = new Ray(eyePosition, rayDestination - eyePosition);
|
Ray sightRay = new Ray(eyePosition, rayDestination - eyePosition);
|
||||||
RaycastHit sightRayHit = Physics.Raycast(sightRay);
|
RaycastHit sightRayHit = Physics.Raycast(sightRay, false)[0];
|
||||||
//As of November 2022, RaycastHit contains only the FIRST object hit by
|
//As of November 2022, RaycastHit contains only the FIRST object hit by
|
||||||
//the ray in the Other GameObject data member
|
//the ray in the Other GameObject data member
|
||||||
//Diren may likely add ALL objects hit by the ray over December
|
//Diren may likely add ALL objects hit by the ray over December
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using SHADE;
|
using SHADE;
|
||||||
using SHADE_Scripting;
|
using SHADE_Scripting;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using static PlayerController;
|
using static PlayerController;
|
||||||
using static Item;
|
using static Item;
|
||||||
|
|
||||||
|
@ -203,9 +204,13 @@ public class PickAndThrow : Script
|
||||||
Vector3 playerRayPos = pc.tranform.GlobalPosition;
|
Vector3 playerRayPos = pc.tranform.GlobalPosition;
|
||||||
playerRayPos.y += 0.05f;
|
playerRayPos.y += 0.05f;
|
||||||
dirNor.Normalise();
|
dirNor.Normalise();
|
||||||
RaycastHit ray1 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(22.5f))), rayDistance);
|
List<RaycastHit> rayList1 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(22.5f))), rayDistance, false);
|
||||||
RaycastHit ray2 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-22.5f))), rayDistance);
|
List<RaycastHit> rayList2 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-22.5f))), rayDistance, false);
|
||||||
RaycastHit ray3 = Physics.Raycast(new Ray(playerRayPos, dirNor), rayDistance * 0.75f);
|
List<RaycastHit> rayList3 = Physics.Raycast(new Ray(playerRayPos, dirNor), rayDistance * 0.75f, false);
|
||||||
|
|
||||||
|
RaycastHit ray1 = rayList1[0];
|
||||||
|
RaycastHit ray2 = rayList2[0];
|
||||||
|
RaycastHit ray3 = rayList3[0];
|
||||||
inRange = CheckForItem(ray1) || CheckForItem(ray2) || CheckForItem(ray3);
|
inRange = CheckForItem(ray1) || CheckForItem(ray2) || CheckForItem(ray3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using static Item;
|
||||||
|
|
||||||
|
|
||||||
|
public class PhysicsTestObj : Script
|
||||||
|
{
|
||||||
|
public RigidBody body { get; set; }
|
||||||
|
public Collider collider { get; set; }
|
||||||
|
|
||||||
|
// Movement input booleans
|
||||||
|
public enum Direction
|
||||||
|
{
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
FORWARD,
|
||||||
|
BACK,
|
||||||
|
LEFT,
|
||||||
|
RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
internal bool[] move = new bool[6];
|
||||||
|
internal bool[] rotate = new bool[6];
|
||||||
|
|
||||||
|
internal Vector3[] moveVec = new Vector3[6]
|
||||||
|
{
|
||||||
|
Vector3.Up,
|
||||||
|
Vector3.Down,
|
||||||
|
Vector3.Back,
|
||||||
|
Vector3.Forward,
|
||||||
|
Vector3.Left,
|
||||||
|
Vector3.Right
|
||||||
|
};
|
||||||
|
|
||||||
|
internal Vector3[] rotateVec = new Vector3[6]
|
||||||
|
{
|
||||||
|
Vector3.Right,
|
||||||
|
Vector3.Left,
|
||||||
|
Vector3.Forward,
|
||||||
|
Vector3.Down,
|
||||||
|
Vector3.Up,
|
||||||
|
Vector3.Down
|
||||||
|
};
|
||||||
|
|
||||||
|
internal Input.KeyCode[] moveInputKeys = new Input.KeyCode[6]
|
||||||
|
{
|
||||||
|
Input.KeyCode.Space,
|
||||||
|
Input.KeyCode.LeftControl,
|
||||||
|
Input.KeyCode.W,
|
||||||
|
Input.KeyCode.S,
|
||||||
|
Input.KeyCode.A,
|
||||||
|
Input.KeyCode.D
|
||||||
|
};
|
||||||
|
|
||||||
|
internal Input.KeyCode[] rotateInputKeys = new Input.KeyCode[6]
|
||||||
|
{
|
||||||
|
Input.KeyCode.I,
|
||||||
|
Input.KeyCode.K,
|
||||||
|
Input.KeyCode.U,
|
||||||
|
Input.KeyCode.O,
|
||||||
|
Input.KeyCode.J,
|
||||||
|
Input.KeyCode.L
|
||||||
|
};
|
||||||
|
|
||||||
|
public float forceAmount = 50.0f;
|
||||||
|
public float torqueAmount = 500.0f;
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
body = GetComponent<RigidBody>();
|
||||||
|
collider = GetComponent<Collider>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
move[i] = false;
|
||||||
|
rotate[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
Ray colliderRay = new Ray();
|
||||||
|
colliderRay.Direction = Vector3.Right;
|
||||||
|
Physics.ColliderRaycast(collider.Owner, colliderRay, false);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(moveInputKeys[i]))
|
||||||
|
move[i] = true;
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(rotateInputKeys[i]))
|
||||||
|
rotate[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void fixedUpdate()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; ++i)
|
||||||
|
{
|
||||||
|
bool shouldMove = move[i];
|
||||||
|
bool shouldRotate = rotate[i];
|
||||||
|
|
||||||
|
if (shouldMove)
|
||||||
|
{
|
||||||
|
//Vector3 offset = new Vector3(0.25f, 0.0f, 0.0f);
|
||||||
|
//rb.AddForceAtLocalPos(moveVec[i] * forceAmount, offset);
|
||||||
|
body.AddForce(moveVec[i] * forceAmount);
|
||||||
|
move[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldRotate)
|
||||||
|
{
|
||||||
|
body.AddTorque(rotateVec[i] * torqueAmount);
|
||||||
|
rotate[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: PhysicsTestObj
|
||||||
|
ID: 159293012
|
||||||
|
Type: 9
|
|
@ -19,11 +19,11 @@ layout(location = 0) out struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) out struct
|
layout(location = 4) out struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -56,6 +56,8 @@ void main()
|
||||||
// gBuffer position will be in view space
|
// gBuffer position will be in view space
|
||||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
|
||||||
// uvs for texturing in fragment shader
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ struct DirectionalLightStruct
|
||||||
uint isActive;
|
uint isActive;
|
||||||
uint cullingMask;
|
uint cullingMask;
|
||||||
vec4 diffuseColor;
|
vec4 diffuseColor;
|
||||||
|
mat4 pvMatrix;
|
||||||
|
uint shadowData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AmbientLightStruct
|
struct AmbientLightStruct
|
||||||
|
@ -22,7 +24,10 @@ layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
|
||||||
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
||||||
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||||
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||||
layout(set = 3, binding = 5, rgba8) uniform image2D targetImage;
|
layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace;
|
||||||
|
layout(set = 3, binding = 6, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
|
layout (set = 4, binding = 0) uniform sampler2D shadowMaps[]; // for textures (global)
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform LightCounts
|
layout(set = 1, binding = 0) uniform LightCounts
|
||||||
{
|
{
|
||||||
|
@ -43,6 +48,25 @@ layout(std430, set = 1, binding = 4) buffer AmbientLightData
|
||||||
AmbientLightStruct aLightData[];
|
AmbientLightStruct aLightData[];
|
||||||
} AmbLightData;
|
} AmbLightData;
|
||||||
|
|
||||||
|
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
|
||||||
|
{
|
||||||
|
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
|
||||||
|
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
|
||||||
|
|
||||||
|
float sampledDepth = texture(shadowMap, converted.xy).r;
|
||||||
|
|
||||||
|
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (fragPosLightPOV.z > sampledDepth && fragPosLightPOV.w > 0.0f)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1.0f;
|
||||||
|
// return step (fragPosLightPOV.z, );
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// convenient variables
|
// convenient variables
|
||||||
|
@ -52,6 +76,9 @@ void main()
|
||||||
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
||||||
|
|
||||||
// Get position of fragment in world space
|
// Get position of fragment in world space
|
||||||
|
vec4 positionWorld = vec4 (imageLoad (positionWorldSpace, globalThread).rgb, 1.0f);
|
||||||
|
|
||||||
|
// Get position of fragment in view spacee
|
||||||
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||||
|
|
||||||
// normal of fragment
|
// normal of fragment
|
||||||
|
@ -62,6 +89,18 @@ void main()
|
||||||
|
|
||||||
vec3 fragColor = vec3 (0.0f);
|
vec3 fragColor = vec3 (0.0f);
|
||||||
|
|
||||||
|
vec4 shadowMapColor = vec4 (1.0f);
|
||||||
|
|
||||||
|
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
||||||
|
{
|
||||||
|
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
||||||
|
{
|
||||||
|
// Just do some add
|
||||||
|
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
||||||
|
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
||||||
{
|
{
|
||||||
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||||
|
@ -74,16 +113,13 @@ void main()
|
||||||
|
|
||||||
// Calculate the fragment color
|
// Calculate the fragment color
|
||||||
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
// If the shadow map is enabled (test the bit)
|
||||||
|
if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1)
|
||||||
{
|
{
|
||||||
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
// calculate shadow map here
|
||||||
{
|
fragColor *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix).xxx;
|
||||||
// Just do some add
|
}
|
||||||
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
|
||||||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +128,12 @@ void main()
|
||||||
|
|
||||||
// store result into result image
|
// store result into result image
|
||||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
|
||||||
|
// vec2 normTexCoords = vec2 (gl_GlobalInvocationID.xy) / vec2 (1024.0f);
|
||||||
|
// vec4 shadowMapVal = texture(shadowMaps[0], normTexCoords);
|
||||||
|
// if (normTexCoords.x > 1.0f || normTexCoords.y > 1.0f)
|
||||||
|
// shadowMapVal = vec4(0.0f);
|
||||||
|
|
||||||
|
// imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), shadowMapVal.xxxx);
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_KHR_vulkan_glsl : enable
|
||||||
|
|
||||||
|
//#include "ShaderDescriptorDefinitions.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 aVertexPos;
|
||||||
|
layout(location = 4) in mat4 worldTransform;
|
||||||
|
|
||||||
|
layout(set = 1, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// clip space for rendering
|
||||||
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: ShadowMap_VS
|
||||||
|
ID: 44646107
|
||||||
|
Type: 2
|
|
@ -16,11 +16,11 @@ layout(location = 0) in struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
} In;
|
} In;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) flat in struct
|
layout(location = 4) flat in struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -38,12 +38,14 @@ layout(location = 1) out uint outEntityID;
|
||||||
layout(location = 2) out uint lightLayerIndices;
|
layout(location = 2) out uint lightLayerIndices;
|
||||||
layout(location = 3) out vec4 normals;
|
layout(location = 3) out vec4 normals;
|
||||||
layout(location = 4) out vec4 albedo;
|
layout(location = 4) out vec4 albedo;
|
||||||
|
layout(location = 5) out vec4 worldSpacePosition;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
position = In.vertPos;
|
position = In.vertPos;
|
||||||
normals = In.normal;
|
normals = In.normal;
|
||||||
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
||||||
|
worldSpacePosition = In.worldPos;
|
||||||
|
|
||||||
outEntityID = In2.eid;
|
outEntityID = In2.eid;
|
||||||
lightLayerIndices = In2.lightLayerIndex;
|
lightLayerIndices = In2.lightLayerIndex;
|
||||||
|
|
Binary file not shown.
|
@ -12,17 +12,19 @@ layout(location = 4) in mat4 worldTransform;
|
||||||
layout(location = 8) in uvec2 integerData;
|
layout(location = 8) in uvec2 integerData;
|
||||||
layout(location = 9) in uvec4 aBoneIndices;
|
layout(location = 9) in uvec4 aBoneIndices;
|
||||||
layout(location = 10) in vec4 aBoneWeights;
|
layout(location = 10) in vec4 aBoneWeights;
|
||||||
|
layout(location = 11) in uint firstBoneIndex;
|
||||||
|
|
||||||
layout(location = 0) out struct
|
layout(location = 0) out struct
|
||||||
{
|
{
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
|
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) out struct
|
layout(location = 4) out struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -50,6 +52,8 @@ void main()
|
||||||
// gBuffer position will be in view space
|
// gBuffer position will be in view space
|
||||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
|
||||||
// uvs for texturing in fragment shader
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -79,9 +79,6 @@ namespace Sandbox
|
||||||
SHSystemManager::CreateSystem<SHScriptEngine>();
|
SHSystemManager::CreateSystem<SHScriptEngine>();
|
||||||
SHSystemManager::CreateSystem<SHTransformSystem>();
|
SHSystemManager::CreateSystem<SHTransformSystem>();
|
||||||
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
||||||
#ifndef _PUBLISH
|
|
||||||
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
|
@ -92,7 +89,6 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||||
SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
|
||||||
|
|
||||||
// Link up SHDebugDraw
|
// Link up SHDebugDraw
|
||||||
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||||
|
@ -108,6 +104,8 @@ namespace Sandbox
|
||||||
editor->SetSDLWindow(sdlWindow);
|
editor->SetSDLWindow(sdlWindow);
|
||||||
editor->SetSHWindow(&window);
|
editor->SetSHWindow(&window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create Routines
|
// Create Routines
|
||||||
|
@ -119,11 +117,11 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostLogicUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostLogicUpdate>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
|
||||||
#ifndef _PUBLISH
|
#ifdef SHEDITOR
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
|
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDraw>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
|
@ -201,32 +199,12 @@ namespace Sandbox
|
||||||
#endif
|
#endif
|
||||||
SHSceneManager::SceneUpdate(0.016f);
|
SHSceneManager::SceneUpdate(0.016f);
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
|
||||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime());
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime());
|
||||||
editor->PollPicking();
|
editor->PollPicking();
|
||||||
#else
|
#else
|
||||||
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
||||||
#endif
|
#endif
|
||||||
// TODO: Move into an Editor menu
|
|
||||||
static bool drawContacts = false;
|
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
|
|
||||||
{
|
|
||||||
drawContacts = !drawContacts;
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
|
|
||||||
}
|
|
||||||
static bool drawColliders = false;
|
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
|
||||||
{
|
|
||||||
drawColliders = !drawColliders;
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders);
|
|
||||||
}
|
|
||||||
static bool drawRays = false;
|
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F11))
|
|
||||||
{
|
|
||||||
drawRays = !drawRays;
|
|
||||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
|
|
|
@ -44,23 +44,6 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
||||||
|
|
||||||
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
|
||||||
if (!physicsSystem)
|
|
||||||
{
|
|
||||||
SHLOGV_CRITICAL("Failed to get the physics system for building the scene!")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
|
||||||
|
|
||||||
physicsSystem->ForceBuild(SHSceneManager::GetCurrentSceneGraph());
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph());
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* TESTING CODE */
|
/* TESTING CODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Sandbox
|
||||||
|
|
||||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
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>();
|
||||||
|
@ -113,9 +113,9 @@ namespace Sandbox
|
||||||
racoonTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
racoonTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
racoonCollider.AddBoundingBox();
|
//racoonCollider.AddBoundingBox();
|
||||||
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
//racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
racoonCollider.GetCollisionShape(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);
|
||||||
|
@ -138,15 +138,15 @@ namespace Sandbox
|
||||||
itemTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
itemTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
itemTransform.SetWorldPosition({ 0.0f, -2.0f, -5.0f });
|
itemTransform.SetWorldPosition({ 0.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
itemCollider.AddBoundingBox();
|
//itemCollider.AddBoundingBox();
|
||||||
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
//itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||||
itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
//itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||||
|
|
||||||
itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
//itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
//itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
//itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollisionShape(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);
|
||||||
|
@ -167,9 +167,9 @@ namespace Sandbox
|
||||||
AITransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
AITransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||||
|
|
||||||
AICollider.AddBoundingBox();
|
//AICollider.AddBoundingBox();
|
||||||
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
//AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
AICollider.GetCollisionShape(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);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
class SHBox;
|
class SHAABB;
|
||||||
class SHRay;
|
class SHRay;
|
||||||
|
|
||||||
class SH_API SHCameraArmComponent final: public SHComponent
|
class SH_API SHCameraArmComponent final: public SHComponent
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Math/Geometry/SHBox.h"
|
#include "Math/Geometry/SHAABB.h"
|
||||||
#include "Math/SHRay.h"
|
#include "Math/SHRay.h"
|
||||||
#include "Physics/System/SHPhysicsSystem.h"
|
#include "Physics/System/SHPhysicsSystem.h"
|
||||||
|
|
||||||
|
@ -186,20 +186,20 @@ namespace SHADE
|
||||||
|
|
||||||
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
|
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
|
||||||
|
|
||||||
auto result = physicsSystem->Raycast(pivot.ray );
|
//auto result = physicsSystem->Raycast(pivot.ray );
|
||||||
if (result && result.distance < pivot.GetArmLength())
|
//if (result && result.distance < pivot.GetArmLength())
|
||||||
{
|
//{
|
||||||
|
//
|
||||||
SHVec3 newOffset = SHVec3{ 0.0f,0.0f, result.distance * 0.8f };
|
// SHVec3 newOffset = SHVec3{ 0.0f,0.0f, result.distance * 0.8f };
|
||||||
newOffset = SHVec3::RotateX(newOffset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
|
// newOffset = SHVec3::RotateX(newOffset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
|
||||||
newOffset = SHVec3::RotateY(newOffset, (SHMath::DegreesToRadians(pivot.GetYaw())));
|
// newOffset = SHVec3::RotateY(newOffset, (SHMath::DegreesToRadians(pivot.GetYaw())));
|
||||||
pivot.offset = newOffset;
|
// pivot.offset = newOffset;
|
||||||
//SHLOG_INFO("CAMERA COLLISION HIT, {}", result.distance);
|
// //SHLOG_INFO("CAMERA COLLISION HIT, {}", result.distance);
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
//SHLOG_INFO("CAMERA COLLISION CANT HIT CAMERA");
|
// //SHLOG_INFO("CAMERA COLLISION CANT HIT CAMERA");
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,8 +270,12 @@ namespace SHADE
|
||||||
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
|
||||||
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
||||||
|
|
||||||
|
//SHVec3 target{ 0.0f,0.0f,-1.0f };
|
||||||
|
//target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||||
|
//target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||||
|
//target += camera.position;
|
||||||
|
|
||||||
|
//camera.viewMatrix = SHMatrix::Transpose(SHMatrix::LookAtLH(camera.position, target, SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
|
||||||
camera.dirtyView = false;
|
camera.dirtyView = false;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +313,9 @@ namespace SHADE
|
||||||
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
||||||
camera.orthoProjMatrix(3, 3) = 1.0f;
|
camera.orthoProjMatrix(3, 3) = 1.0f;
|
||||||
|
|
||||||
//camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(9.0f, 9.0f, 0.1f, 20.0f);
|
||||||
|
camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
||||||
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(5.0f, 5.0f, 0.1f, 20.0f);
|
||||||
//camera.projMatrix.Transpose();
|
//camera.projMatrix.Transpose();
|
||||||
|
|
||||||
camera.dirtyProj = false;
|
camera.dirtyProj = false;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Camera/SHCameraArmComponent.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Physics/Interface/SHRigidBodyComponent.h"
|
||||||
|
#include "UI/SHCanvasComponent.h"
|
||||||
|
#include "UI/SHButtonComponent.h"
|
||||||
|
#include "UI/SHUIComponent.h"
|
||||||
|
#include "UI/SHToggleButtonComponent.h"
|
||||||
|
#include "UI/SHSliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
|
@ -23,7 +23,7 @@
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -151,6 +151,32 @@ namespace SHADE
|
||||||
return (componentSet.GetSparseSet<T>()->GetElement_s(EntityHandleGenerator::GetIndex(entityID)));
|
return (componentSet.GetSparseSet<T>()->GetElement_s(EntityHandleGenerator::GetIndex(entityID)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!*************************************************************************
|
||||||
|
* \brief
|
||||||
|
* Gets the Component of the entity with the specified entityID
|
||||||
|
*
|
||||||
|
* This is the safe version of GetComponent_s which does a HasComponent to make
|
||||||
|
* sure that the entity has such a component and returns nullptr if it doesn't
|
||||||
|
*
|
||||||
|
* This safe version also checks if the sparse set of this component type
|
||||||
|
* has been created in SHComponentManager and creates one if it doesn't
|
||||||
|
*
|
||||||
|
* @tparam T...
|
||||||
|
* Pack of Types for all the Components to get.
|
||||||
|
* \param entityID
|
||||||
|
* EntityID of the entity that we are trying to get the component of.
|
||||||
|
* \return
|
||||||
|
* A tuple of pointers to all the components specified.
|
||||||
|
* Returns nullptr if the entity does not contain such a component.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
template<typename ...T>
|
||||||
|
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, T>), std::tuple<T*...>> GetComponents(EntityID entityID) noexcept
|
||||||
|
{
|
||||||
|
return std::make_tuple<T*...>(GetComponent_s<T>(entityID)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
* Gets the Component of the entity with the specified entityID
|
* Gets the Component of the entity with the specified entityID
|
||||||
|
|
|
@ -162,7 +162,7 @@ namespace SHADE
|
||||||
|
|
||||||
//SHSceneNode* parentNode = entityVec[eIndex]->GetSceneNode()->GetParent();
|
//SHSceneNode* parentNode = entityVec[eIndex]->GetSceneNode()->GetParent();
|
||||||
|
|
||||||
//SHSceneGraph::RemoveChild(parentNode,entityVec[eIndex].get());
|
//SHSceneGraph::removeChild(parentNode,entityVec[eIndex].get());
|
||||||
|
|
||||||
//TODO remove from parent and recursively delete child.
|
//TODO remove from parent and recursively delete child.
|
||||||
|
|
||||||
|
|
|
@ -239,10 +239,7 @@ namespace SHADE
|
||||||
case AssetType::TEXTURE: break;
|
case AssetType::TEXTURE: break;
|
||||||
case AssetType::MESH: break;
|
case AssetType::MESH: break;
|
||||||
case AssetType::SCENE:
|
case AssetType::SCENE:
|
||||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
{
|
|
||||||
editor->LoadScene(asset->id);
|
editor->LoadScene(asset->id);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AssetType::PREFAB: break;
|
case AssetType::PREFAB: break;
|
||||||
case AssetType::MATERIAL:
|
case AssetType::MATERIAL:
|
||||||
|
@ -262,6 +259,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("AssetID: %zu | Path: %s", asset->id, asset->path.c_str());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
||||||
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
const float horizontalOffset = 0.0f;
|
const float horizontalOffset = 0.0f;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHColliderTagPanel.h"
|
#include "SHColliderTagPanel.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -15,7 +15,7 @@ namespace SHADE
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::PushID("CollisionTagNames");
|
ImGui::PushID("CollisionTagNames");
|
||||||
|
|
||||||
for (int i = SHCollisionTag::NUM_LAYERS; i >= 0; --i)
|
for (int i = SHCollisionTag::NUM_LAYERS; i >= 1; --i)
|
||||||
{
|
{
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if(i == SHCollisionTag::NUM_LAYERS) continue;
|
if(i == SHCollisionTag::NUM_LAYERS) continue;
|
||||||
|
@ -29,7 +29,7 @@ namespace SHADE
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
|
for (int i = 0; i < SHCollisionTag::NUM_LAYERS - 1; ++i)
|
||||||
{
|
{
|
||||||
std::string tagName = SHCollisionTagMatrix::GetTagName(i);
|
std::string tagName = SHCollisionTagMatrix::GetTagName(i);
|
||||||
auto tag = SHCollisionTagMatrix::GetTag(i);
|
auto tag = SHCollisionTagMatrix::GetTag(i);
|
||||||
|
@ -53,8 +53,8 @@ namespace SHADE
|
||||||
tagName2 = std::to_string(idx);
|
tagName2 = std::to_string(idx);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
//if(i == idx)
|
if(i == idx)
|
||||||
// continue;
|
continue;
|
||||||
std::string label = std::format("##{} vs {}", tagName, tagName2);
|
std::string label = std::format("##{} vs {}", tagName, tagName2);
|
||||||
SHEditorWidgets::CheckBox(label, [tag, &idx]{return tag->GetLayerState(idx);}, [tag, i, idx](bool const& value){tag->SetLayerState(idx, value); SHCollisionTagMatrix::GetTag(idx)->SetLayerState(i, value);}, label.substr(2));
|
SHEditorWidgets::CheckBox(label, [tag, &idx]{return tag->GetLayerState(idx);}, [tag, i, idx](bool const& value){tag->SetLayerState(idx, value); SHCollisionTagMatrix::GetTag(idx)->SetLayerState(i, value);}, label.substr(2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEditorPopups.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHSceneSavePrompt::Draw()
|
||||||
|
{
|
||||||
|
if(Begin())
|
||||||
|
{
|
||||||
|
static std::string newSceneName{};
|
||||||
|
ImGui::Text("Enter new scene name");
|
||||||
|
ImGui::InputText("##name", &newSceneName);
|
||||||
|
ImGui::BeginDisabled(newSceneName.empty());
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
editor->SaveScene(newSceneName);
|
||||||
|
newSceneName.clear();
|
||||||
|
isOpen = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
isOpen = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Editor/EditorWindow/SHPopUpWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHSceneSavePrompt : public SHPopUpWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHSceneSavePrompt():SHPopUpWindow("Save Scene As", true, 0, 0){}
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,11 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -16,14 +21,11 @@
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "SHHierarchyPanelCommands.h"
|
#include "SHHierarchyPanelCommands.h"
|
||||||
|
#include "Common/SHAllComponents.h"
|
||||||
//#==============================================================#
|
|
||||||
//|| Library Includes ||
|
|
||||||
//#==============================================================#
|
|
||||||
#include <imgui.h>
|
|
||||||
|
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Tools/Utilities/SHClipboardUtilities.h"
|
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||||
|
#include "Tools/Utilities/SHStringUtilities.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -80,7 +82,6 @@ namespace SHADE
|
||||||
|
|
||||||
if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
@ -99,7 +100,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (editor->selectedEntities.size() == 1)
|
if (editor->selectedEntities.size() == 1)
|
||||||
{
|
{
|
||||||
PasteEntities(editor->selectedEntities.back());
|
PasteEntities(editor->selectedEntities.back());
|
||||||
|
@ -141,16 +141,18 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Private Member Functions ||
|
//|| Private Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHHierarchyPanel::DrawMenuBar() const noexcept
|
void SHHierarchyPanel::DrawMenuBar() noexcept
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
auto size = ImGui::GetWindowSize();
|
auto size = ImGui::GetWindowSize();
|
||||||
auto g = ImGui::GetCurrentContext();
|
auto g = ImGui::GetCurrentContext();
|
||||||
|
|
||||||
|
DrawHierarchyPanelFilter();
|
||||||
|
|
||||||
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
||||||
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
|
@ -173,6 +175,56 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::DrawHierarchyPanelFilter() noexcept
|
||||||
|
{
|
||||||
|
if(ImGui::InputTextWithHint("##hierarchyPanelFilter", "Filter", &filter))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Button("x"))
|
||||||
|
{
|
||||||
|
filter.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHHierarchyPanel::EntityFilterCheck(SHSceneNode* entityNode) noexcept
|
||||||
|
{
|
||||||
|
if(!entityNode || filter.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EntityID const eid = entityNode->GetEntityID();
|
||||||
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
result |= SHStringUtilities::StringFindInsensitive(entity->name, filter) != std::string::npos;
|
||||||
|
|
||||||
|
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTransformComponent>().get_name().data(), filter) != std::string::npos)
|
||||||
|
{
|
||||||
|
result |= SHComponentManager::HasComponent<SHTransformComponent>(eid);
|
||||||
|
}
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHColliderComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRigidBodyComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraArmComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRenderable>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHLightComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTextRenderableComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHUIComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHButtonComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCanvasComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
|
||||||
|
//std::vector<SHSceneNode*> const& children = entityNode->GetChildren();
|
||||||
|
|
||||||
|
//for (auto const& child : children)
|
||||||
|
//{
|
||||||
|
// result |= EntityFilterCheck(child);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||||
{
|
{
|
||||||
if (currentNode == nullptr)
|
if (currentNode == nullptr)
|
||||||
|
@ -189,21 +241,39 @@ namespace SHADE
|
||||||
scrollTo = MAX_EID;
|
scrollTo = MAX_EID;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
auto* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
||||||
|
|
||||||
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
bool highlighted = false;
|
||||||
|
//if(!filter.empty())
|
||||||
//bool highlighted = false;
|
|
||||||
//if(highlighted)
|
|
||||||
//{
|
//{
|
||||||
|
// highlighted = EntityFilterCheck(currentNode);
|
||||||
|
// if (highlighted)
|
||||||
|
// {
|
||||||
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||||
|
//
|
||||||
|
// ImGui::SetNextItemOpen(true);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
|
|
||||||
|
|
||||||
//Draw Node
|
//Draw Node
|
||||||
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(eid), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
||||||
|
|
||||||
|
if (highlighted)
|
||||||
|
{
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
//Check For Begin Drag
|
//Check For Begin Drag
|
||||||
|
@ -336,6 +406,7 @@ namespace SHADE
|
||||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +421,6 @@ namespace SHADE
|
||||||
|
|
||||||
std::vector<EntityID> entitiesToParent = CleanUpEIDList(entities);
|
std::vector<EntityID> entitiesToParent = CleanUpEIDList(entities);
|
||||||
|
|
||||||
//auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
SHEntityParentCommand::EntityParentData entityParentData;
|
SHEntityParentCommand::EntityParentData entityParentData;
|
||||||
std::vector<EntityID> parentedEIDS;
|
std::vector<EntityID> parentedEIDS;
|
||||||
for (auto const& eid : entitiesToParent)
|
for (auto const& eid : entitiesToParent)
|
||||||
|
@ -371,7 +441,7 @@ namespace SHADE
|
||||||
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
|
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
|
||||||
{
|
{
|
||||||
bool startSelecting = false; bool endSelecting = false;
|
bool startSelecting = false; bool endSelecting = false;
|
||||||
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
@ -403,7 +473,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::SelectAllEntities()
|
void SHHierarchyPanel::SelectAllEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
@ -415,7 +484,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::CopySelectedEntities()
|
void SHHierarchyPanel::CopySelectedEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
std::vector<EntityID> entitiesToCopy = CleanUpEIDList(editor->selectedEntities);
|
std::vector<EntityID> entitiesToCopy = CleanUpEIDList(editor->selectedEntities);
|
||||||
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
|
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
|
||||||
}
|
}
|
||||||
|
@ -428,7 +496,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::DeleteSelectedEntities()
|
void SHHierarchyPanel::DeleteSelectedEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
std::vector<EntityID> entitiesToDelete = CleanUpEIDList(editor->selectedEntities);
|
std::vector<EntityID> entitiesToDelete = CleanUpEIDList(editor->selectedEntities);
|
||||||
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
|
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHSceneNode;
|
class SHSceneNode;
|
||||||
|
@ -24,7 +26,11 @@ namespace SHADE
|
||||||
void Exit() override;
|
void Exit() override;
|
||||||
void SetScrollTo(EntityID eid);
|
void SetScrollTo(EntityID eid);
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() noexcept;
|
||||||
|
void DrawHierarchyPanelFilter() noexcept;
|
||||||
|
|
||||||
|
bool EntityFilterCheck(SHSceneNode* entityNode) noexcept;
|
||||||
|
|
||||||
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept;
|
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept;
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
#include "Physics/Interface/SHColliderComponent.h"
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
|
||||||
#include "Serialization/SHSerializationHelper.hpp"
|
#include "Serialization/SHSerializationHelper.hpp"
|
||||||
#include "Tools/Utilities/SHClipboardUtilities.h"
|
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||||
#include "SHInspectorCommands.h"
|
#include "SHInspectorCommands.h"
|
||||||
|
#include "Physics/Collision/SHCompositeCollider.h"
|
||||||
|
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||||
#include "Animation/SHAnimatorComponent.h"
|
#include "Animation/SHAnimatorComponent.h"
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -78,7 +79,7 @@ namespace SHADE
|
||||||
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
auto const& properties = componentType.get_properties();
|
auto const& properties = componentType.get_properties();
|
||||||
|
@ -235,7 +236,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get<SHRigidBodyComponent>();
|
const auto componentType = rttr::type::get<SHRigidBodyComponent>();
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
@ -256,31 +257,34 @@ namespace SHADE
|
||||||
|
|
||||||
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity");
|
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetIsGravityEnabled(value);}, "Whether Gravity is enabled for this body");
|
||||||
//SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
SHEditorWidgets::DragFloat("Gravity Scale", [component] { return component->GetGravityScale(); }, [component](float const& value) { component->SetGravityScale(value); }, "Per-object Gravity Scale", 0.1f, 0.0f);
|
||||||
|
|
||||||
|
SHEditorWidgets::CheckBox("Auto Mass", [component]{return component->GetAutoMass();}, [component](bool const& value){component->SetAutoMass(value);}, "If mass should be automatically computed. Setting mass will turn this off.");
|
||||||
|
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
||||||
}
|
}
|
||||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag");
|
SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag", 0.1f, 0.0f);
|
||||||
SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag");
|
SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag", 0.1f, 0.0f);
|
||||||
|
|
||||||
SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "Interpolate");
|
SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "If the position between frames should be interpolated.");
|
||||||
|
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
|
|
||||||
SHEditorWidgets::TextLabel("Freeze Position");
|
SHEditorWidgets::TextLabel("Freeze Position");
|
||||||
ImGui::PushID("FreezePos");
|
ImGui::PushID("FreezePos");
|
||||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Freeze Position - X"); ImGui::SameLine();
|
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Stops any displacement along the X-axis."); ImGui::SameLine();
|
||||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Freeze Position - Y"); ImGui::SameLine();
|
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Stops any displacement along the Y-axis."); ImGui::SameLine();
|
||||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Freeze Position - Z");
|
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Stops any displacement along the Z-axis.");
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
|
|
||||||
SHEditorWidgets::TextLabel("Freeze Rotation");
|
SHEditorWidgets::TextLabel("Freeze Rotation");
|
||||||
ImGui::PushID("FreezeRot");
|
ImGui::PushID("FreezeRot");
|
||||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Freeze Rotation - X"); ImGui::SameLine();
|
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Stops any rotation about the X-axis."); ImGui::SameLine();
|
||||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Freeze Rotation - Y"); ImGui::SameLine();
|
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Stops any rotation about the Y-axis."); ImGui::SameLine();
|
||||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Freeze Rotation - Z");
|
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Stops any rotation about the Z-axis.");
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
|
@ -289,9 +293,15 @@ namespace SHADE
|
||||||
//Debug Info (Read-Only)
|
//Debug Info (Read-Only)
|
||||||
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
|
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragFloat("Mass", [component] { return component->GetMass(); }, [](float value){}, "Mass", 0.1f, 0.0f, std::numeric_limits<float>::infinity(), "%.3f", ImGuiSliderFlags_ReadOnly);
|
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component]
|
||||||
|
{
|
||||||
|
// Convert it to degrees...
|
||||||
|
auto rot = component->GetRotation();
|
||||||
|
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||||
|
rot[i] = SHMath::RadiansToDegrees(rot[i]);
|
||||||
|
return rot;
|
||||||
|
}, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec3("Velocity", { "X", "Y", "Z" }, [component] {return component->GetLinearVelocity(); }, [](SHVec3 const& value) {}, false, "Linear Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Velocity", { "X", "Y", "Z" }, [component] {return component->GetLinearVelocity(); }, [](SHVec3 const& value) {}, false, "Linear Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
|
@ -301,7 +311,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||||
SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep");
|
SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->IsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,68 +339,71 @@ namespace SHADE
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
auto& colliders = component->GetCollisionShapes();
|
SHEditorWidgets::CheckBox("Draw Colliders", [component] { return component->GetDebugDrawState(); }, [component](bool value) { component->SetDebugDrawState(value); });
|
||||||
int const size = static_cast<int>(colliders.size());
|
|
||||||
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
auto* collisionShapes = component->GetCollisionShapes();
|
||||||
|
int const size = collisionShapes ? static_cast<int>(collisionShapes->size()) : 0;
|
||||||
|
ImGui::BeginChild("Collision Shapes", { 0.0f, collisionShapes->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);
|
||||||
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
SHCollisionShape* shape = component->GetCollisionShape(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
//collider->IsTrigger
|
||||||
if (collider->GetType() == SHCollisionShape::Type::BOX)
|
if (shape->GetType() == SHCollisionShape::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", 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 });
|
||||||
|
|
||||||
const auto* BOX = reinterpret_cast<const SHBox*>(collider->GetShape());
|
auto* box = reinterpret_cast<SHBox*>(shape);
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[BOX] { return BOX->GetRelativeExtents(); },
|
[box] { return box->GetRelativeExtents(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[box](SHVec3 const& vec) { box->SetRelativeExtents(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
|
else if (shape->GetType() == SHCollisionShape::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", 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 });
|
||||||
const auto* SPHERE = reinterpret_cast<const SHSphere*>(collider->GetShape());
|
auto* sphere = reinterpret_cast<SHSphere*>(shape);
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[SPHERE] { return SPHERE->GetRelativeRadius(); },
|
[sphere] { return sphere->GetRelativeRadius(); },
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
[sphere](float const& value) { sphere->SetRelativeRadius(value); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
else if (shape->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
|
SHEditorWidgets::CheckBox("Is Trigger", [shape] { return shape->IsTrigger(); }, [shape](bool value) { shape->SetIsTrigger(value); });
|
||||||
SHEditorWidgets::ComboBox("Tag", collisionTagNames, [collider]{return SHCollisionTagMatrix::GetTagIndex(collider->GetCollisionTag().GetName());}, [collider](int const& value){collider->SetCollisionTag(SHCollisionTagMatrix::GetTag(value));});
|
SHEditorWidgets::ComboBox("Tag", collisionTagNames, [shape]{return SHCollisionTagMatrix::GetTagIndex(shape->GetCollisionTag().GetName());}, [shape](int const& value){shape->SetCollisionTag(SHCollisionTagMatrix::GetTag(value));});
|
||||||
|
|
||||||
if(ImGui::CollapsingHeader("Physics Material"))
|
if(ImGui::CollapsingHeader("Physics Material"))
|
||||||
{
|
{
|
||||||
SHEditorWidgets::DragFloat("Friction", [collider] { return collider->GetFriction(); }, [collider](float value) { collider->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
|
SHEditorWidgets::DragFloat("Friction", [shape] { return shape->GetFriction(); }, [shape](float value) { shape->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
|
||||||
SHEditorWidgets::DragFloat("Bounciness", [collider] { return collider->GetBounciness(); }, [collider](float value) { collider->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
|
SHEditorWidgets::DragFloat("Bounciness", [shape] { return shape->GetBounciness(); }, [shape](float value) { shape->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
|
||||||
SHEditorWidgets::DragFloat("Mass Density", [collider] { return collider->GetDensity(); }, [collider](float value) { collider->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
|
SHEditorWidgets::DragFloat("Mass Density", [shape] { return shape->GetDensity(); }, [shape](float value) { shape->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&shape] {return shape->GetPositionOffset(); }, [&shape](SHVec3 const& vec) {shape->SetPositionOffset(vec); });
|
||||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
|
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
|
||||||
[&collider]
|
[&shape]
|
||||||
{
|
{
|
||||||
auto offset = collider->GetRotationOffset();
|
auto offset = shape->GetRotationOffset();
|
||||||
return offset;
|
return offset;
|
||||||
},
|
},
|
||||||
[&collider](SHVec3 const& vec)
|
[&shape](SHVec3 const& vec)
|
||||||
{
|
{
|
||||||
collider->SetRotationOffset(vec);
|
shape->SetRotationOffset(vec);
|
||||||
}, true);
|
}, true);
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
}
|
}
|
||||||
|
@ -405,21 +418,24 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (colliderToDelete.has_value())
|
if (colliderToDelete.has_value())
|
||||||
{
|
{
|
||||||
component->RemoveCollider(colliderToDelete.value());
|
component->GetCollider()->RemoveCollisionShape(colliderToDelete.value());
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
// TODO: Handle differences between composite & hull collider
|
||||||
if (ImGui::BeginMenu("Add Collider"))
|
if (ImGui::BeginMenu("Add Collider"))
|
||||||
{
|
{
|
||||||
int newColl = -1;
|
int newColl = -1;
|
||||||
|
|
||||||
if (ImGui::Selectable("Box Collider"))
|
if (ImGui::Selectable("Box Collider"))
|
||||||
{
|
{
|
||||||
newColl = component->AddBoundingBox();
|
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
|
||||||
|
compositeCollider->AddBoxCollisionShape(SHVec3::One);
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Sphere Collider"))
|
if (ImGui::Selectable("Sphere Collider"))
|
||||||
{
|
{
|
||||||
newColl = component->AddBoundingSphere();
|
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
|
||||||
|
compositeCollider->AddSphereCollisionShape(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
//No idea why this doesn't work
|
//No idea why this doesn't work
|
||||||
|
@ -447,7 +463,7 @@ namespace SHADE
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
@ -479,7 +495,7 @@ namespace SHADE
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
Handle<SHMesh> const& mesh = component->GetMesh();
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
@ -537,7 +553,7 @@ namespace SHADE
|
||||||
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();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
Handle<SHFont> const& font = component->GetFont();
|
Handle<SHFont> const& font = component->GetFont();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "UI/SHUIComponent.h"
|
#include "UI/SHUIComponent.h"
|
||||||
#include "UI/SHCanvasComponent.h"
|
#include "UI/SHCanvasComponent.h"
|
||||||
#include "UI/SHButtonComponent.h"
|
#include "UI/SHButtonComponent.h"
|
||||||
|
#include "UI/SHToggleButtonComponent.h"
|
||||||
#include "SHEditorComponentView.h"
|
#include "SHEditorComponentView.h"
|
||||||
#include "AudioSystem/SHAudioListenerComponent.h"
|
#include "AudioSystem/SHAudioListenerComponent.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
||||||
|
@ -102,7 +103,6 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (editor && !editor->selectedEntities.empty())
|
if (editor && !editor->selectedEntities.empty())
|
||||||
{
|
{
|
||||||
EntityID const& eid = editor->selectedEntities[0];
|
EntityID const& eid = editor->selectedEntities[0];
|
||||||
|
@ -167,6 +167,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(buttonComponent);
|
DrawComponent(buttonComponent);
|
||||||
}
|
}
|
||||||
|
if (auto toggleButton = SHComponentManager::GetComponent_s<SHToggleButtonComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(toggleButton);
|
||||||
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
// Render Scripts
|
// Render Scripts
|
||||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
@ -180,6 +184,7 @@ namespace SHADE
|
||||||
DrawAddComponentButton<SHLightComponent>(eid);
|
DrawAddComponentButton<SHLightComponent>(eid);
|
||||||
DrawAddComponentButton<SHCanvasComponent>(eid);
|
DrawAddComponentButton<SHCanvasComponent>(eid);
|
||||||
DrawAddComponentButton<SHButtonComponent>(eid);
|
DrawAddComponentButton<SHButtonComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHToggleButtonComponent>(eid);
|
||||||
|
|
||||||
// Components that require Transforms
|
// Components that require Transforms
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||||
|
#include "Physics/System/SHPhysicsDebugDrawSystem.h"
|
||||||
|
|
||||||
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||||
|
|
||||||
|
@ -88,6 +89,7 @@ namespace SHADE
|
||||||
DrawThemeMenu();
|
DrawThemeMenu();
|
||||||
DrawLayoutMenu();
|
DrawLayoutMenu();
|
||||||
DrawApplicationConfig();
|
DrawApplicationConfig();
|
||||||
|
DrawPhysicsSettings();
|
||||||
|
|
||||||
std::string const sceneName{std::format("Current Scene: {}",SHSceneManager::GetSceneName().data())};
|
std::string const sceneName{std::format("Current Scene: {}",SHSceneManager::GetSceneName().data())};
|
||||||
auto const size = ImGui::CalcTextSize(sceneName.data());
|
auto const size = ImGui::CalcTextSize(sceneName.data());
|
||||||
|
@ -110,7 +112,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
ImGui::BeginMenuBar();
|
ImGui::BeginMenuBar();
|
||||||
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
|
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||||
{
|
{
|
||||||
|
@ -165,16 +167,18 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable("New Scene"))
|
if (ImGui::Selectable("New Scene"))
|
||||||
{
|
{
|
||||||
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
editor->NewScene();
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Save"))
|
if (ImGui::Selectable("Save"))
|
||||||
{
|
{
|
||||||
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
editor->SaveScene();
|
||||||
}
|
}
|
||||||
|
ImGui::BeginDisabled(true);
|
||||||
if (ImGui::Selectable("Load"))
|
if (ImGui::Selectable("Load"))
|
||||||
{
|
{
|
||||||
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
||||||
}
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +215,7 @@ namespace SHADE
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->OpenSolution();
|
scriptEngine->OpenSolution();
|
||||||
}
|
}
|
||||||
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
ImGui::BeginDisabled(editor->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>());
|
||||||
|
@ -252,7 +256,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable(style.to_string().c_str()))
|
if (ImGui::Selectable(style.to_string().c_str()))
|
||||||
{
|
{
|
||||||
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
editor->SetStyle(style.convert<SHEditor::Style>());
|
editor->SetStyle(style.convert<SHEditor::Style>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,4 +306,32 @@ namespace SHADE
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawPhysicsSettings() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Physics Settings"))
|
||||||
|
{
|
||||||
|
if (auto* physicsDebugDraw = SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>())
|
||||||
|
{
|
||||||
|
bool drawColliders = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS);
|
||||||
|
if (ImGui::Checkbox("Draw Colliders", &drawColliders))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS, drawColliders);
|
||||||
|
|
||||||
|
bool drawContactPoints = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS);
|
||||||
|
if (ImGui::Checkbox("Draw Contact Points", &drawContactPoints))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS, drawContactPoints);
|
||||||
|
|
||||||
|
bool drawRays = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS);
|
||||||
|
if (ImGui::Checkbox("Draw Rays", &drawRays))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||||
|
|
||||||
|
bool drawBroadphase = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE);
|
||||||
|
if (ImGui::Checkbox("Draw Broadphase", &drawBroadphase))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE, drawBroadphase);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace SHADE
|
||||||
void DrawThemeMenu() noexcept;
|
void DrawThemeMenu() noexcept;
|
||||||
void DrawLayoutMenu() noexcept;
|
void DrawLayoutMenu() noexcept;
|
||||||
void DrawApplicationConfig() noexcept;
|
void DrawApplicationConfig() noexcept;
|
||||||
|
void DrawPhysicsSettings() noexcept;
|
||||||
|
|
||||||
float menuBarHeight = 20.0f;
|
float menuBarHeight = 20.0f;
|
||||||
std::vector<std::filesystem::path> layoutPaths;
|
std::vector<std::filesystem::path> layoutPaths;
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHEditorWindow.h"
|
#include "SHEditorWindow.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -21,6 +23,7 @@ namespace SHADE
|
||||||
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||||
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||||
{
|
{
|
||||||
|
editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorWindow::Init()
|
void SHEditorWindow::Init()
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
struct ImGuiIO;
|
struct ImGuiIO;
|
||||||
typedef int ImGuiWindowFlags;
|
typedef int ImGuiWindowFlags;
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SHEditor;
|
||||||
class SHEditorWindow
|
class SHEditorWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -38,6 +38,6 @@ namespace SHADE
|
||||||
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
ImGuiIO& io;
|
ImGuiIO& io;
|
||||||
|
SHEditor* editor;
|
||||||
};//class SHEditorWindow
|
};//class SHEditorWindow
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -4,5 +4,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
||||||
|
SHEditorWindowManager::PopupWindowMap SHEditorWindowManager::popupWindows{};
|
||||||
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
||||||
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::popupWindowCount{};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "SHEditorWindow.h"
|
#include "SHEditorWindow.h"
|
||||||
|
#include "SHPopUpWindow.h"
|
||||||
#include "Tools/Logger/SHLog.h"
|
#include "Tools/Logger/SHLog.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -16,6 +17,10 @@ namespace SHADE
|
||||||
using EditorWindowID = uint8_t;
|
using EditorWindowID = uint8_t;
|
||||||
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||||
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||||
|
|
||||||
|
using PopupWindowPtr = std::unique_ptr<SHPopUpWindow>;
|
||||||
|
using PopupWindowMap = std::unordered_map<EditorWindowID, PopupWindowPtr>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get ID for the Editor Window Type
|
* @brief Get ID for the Editor Window Type
|
||||||
*
|
*
|
||||||
|
@ -67,10 +72,63 @@ namespace SHADE
|
||||||
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ID for the Popup Window Type
|
||||||
|
*
|
||||||
|
* @tparam T Type of Popup Window
|
||||||
|
* @return EditorWindowID ID of Popup Window Type
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static EditorWindowID GetPopupWindowID()
|
||||||
|
{
|
||||||
|
static EditorWindowID id;
|
||||||
|
static bool idCreated = false;
|
||||||
|
if (!idCreated)
|
||||||
|
{
|
||||||
|
id = popupWindowCount++;
|
||||||
|
idCreated = true;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an Popup Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of Popup Window to create
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static void CreatePopupWindow()
|
||||||
|
{
|
||||||
|
static bool isCreated = false;
|
||||||
|
if (!isCreated)
|
||||||
|
{
|
||||||
|
popupWindows[GetPopupWindowID<T>()] = std::make_unique<T>();
|
||||||
|
isCreated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLog::Warning("Attempt to create duplicate of Popup window type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get pointer to the Editor Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of editor window to retrieve
|
||||||
|
* @return T* Pointer to the editor window
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static T* GetPopupWindow()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(popupWindows[GetPopupWindowID<T>()].get());
|
||||||
|
}
|
||||||
|
|
||||||
static EditorWindowMap editorWindows;
|
static EditorWindowMap editorWindows;
|
||||||
|
static PopupWindowMap popupWindows;
|
||||||
private:
|
private:
|
||||||
// Number of windows; used for Editor Window ID Generation
|
// Number of windows; used for Editor Window ID Generation
|
||||||
static EditorWindowID windowCount;
|
static EditorWindowID windowCount;
|
||||||
|
static EditorWindowID popupWindowCount;
|
||||||
// Map of Editor Windows
|
// Map of Editor Windows
|
||||||
friend class SHEditor;
|
friend class SHEditor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHPopUpWindow.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHPopUpWindow::SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags)
|
||||||
|
:editor(nullptr), windowName(name), popupFlags(inPopupFlags), windowFlags(inWindowFlags), isOpen(false), isModal(modal)
|
||||||
|
{
|
||||||
|
editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPopUpWindow::Begin()
|
||||||
|
{
|
||||||
|
if (isOpen)
|
||||||
|
ImGui::OpenPopup(windowName.data(), popupFlags);
|
||||||
|
|
||||||
|
return isModal ? ImGui::BeginPopupModal(windowName.data(), &isOpen, windowFlags) : ImGui::BeginPopup(windowName.data(), windowFlags);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditor;
|
||||||
|
class SHPopUpWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags);
|
||||||
|
virtual ~SHPopUpWindow() = default;
|
||||||
|
virtual void Draw(){};
|
||||||
|
|
||||||
|
bool isOpen;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool Begin();
|
||||||
|
|
||||||
|
SHEditor* editor;
|
||||||
|
std::string_view windowName;
|
||||||
|
ImGuiPopupFlags popupFlags;
|
||||||
|
ImGuiWindowFlags windowFlags;
|
||||||
|
bool isModal;
|
||||||
|
};
|
||||||
|
}
|
|
@ -35,7 +35,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
|
|
||||||
if (!editor->selectedEntities.empty())
|
if (!editor->selectedEntities.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include "EditorWindow/SHEditorWindowManager.h"
|
#include "EditorWindow/SHEditorWindowManager.h"
|
||||||
#include "EditorWindow/SHEditorWindowIncludes.h"
|
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||||
|
|
||||||
|
#include "EditorWindow/SHPopUpWindow.h"
|
||||||
|
#include "EditorWindow/EditorPopups/SHEditorPopups.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -98,15 +101,18 @@ namespace SHADE
|
||||||
|
|
||||||
//Add editor windows
|
//Add editor windows
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||||
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
|
||||||
|
//Add popup windows
|
||||||
|
SHEditorWindowManager::CreatePopupWindow<SHSceneSavePrompt>();
|
||||||
|
|
||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
|
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
|
@ -150,7 +156,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
(void)dt;
|
(void)dt;
|
||||||
NewFrame();
|
NewFrame();
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (auto const& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
{
|
{
|
||||||
if(window->isOpen)
|
if(window->isOpen)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +164,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSceneNamePrompt();
|
for(auto const& popupWindow : SHEditorWindowManager::popupWindows | std::views::values)
|
||||||
|
{
|
||||||
|
popupWindow->Draw();
|
||||||
|
}
|
||||||
|
|
||||||
RenderUnsavedChangesPrompt();
|
RenderUnsavedChangesPrompt();
|
||||||
//PollPicking();
|
//PollPicking();
|
||||||
|
|
||||||
|
@ -177,37 +187,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::RenderSceneNamePrompt() noexcept
|
|
||||||
{
|
|
||||||
if(isSceneNamePromptOpen)
|
|
||||||
{
|
|
||||||
ImGui::OpenPopup(sceneNamePromptName.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ImGui::BeginPopupModal(sceneNamePromptName.data(), &isSceneNamePromptOpen))
|
|
||||||
{
|
|
||||||
static std::string newSceneName{};
|
|
||||||
ImGui::Text("Enter new scene name");
|
|
||||||
ImGui::InputText("##name", &newSceneName);
|
|
||||||
ImGui::BeginDisabled(newSceneName.empty());
|
|
||||||
if(ImGui::Button("Save"))
|
|
||||||
{
|
|
||||||
SaveScene(newSceneName);
|
|
||||||
newSceneName.clear();
|
|
||||||
isSceneNamePromptOpen = false;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::SameLine();
|
|
||||||
if(ImGui::Button("Cancel"))
|
|
||||||
{
|
|
||||||
isSceneNamePromptOpen = false;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHEditor::RenderUnsavedChangesPrompt() noexcept
|
void SHEditor::RenderUnsavedChangesPrompt() noexcept
|
||||||
{
|
{
|
||||||
if(isUnsavedChangesPromptOpen)
|
if(isUnsavedChangesPromptOpen)
|
||||||
|
@ -220,12 +199,12 @@ namespace SHADE
|
||||||
ImGui::Text("You have unsaved changes!");
|
ImGui::Text("You have unsaved changes!");
|
||||||
if(ImGui::Button("Save"))
|
if(ImGui::Button("Save"))
|
||||||
{
|
{
|
||||||
isSceneNamePromptOpen = true;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Cancel"))
|
if(ImGui::Button("Cancel"))
|
||||||
{
|
{
|
||||||
isUnsavedChangesPromptOpen = false;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +468,7 @@ namespace SHADE
|
||||||
|
|
||||||
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
auto renderPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->GetRenderpass();
|
||||||
|
|
||||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
{
|
{
|
||||||
|
@ -508,7 +487,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
cmd->BeginLabeledSegment("ImGui Draw");
|
cmd->BeginLabeledSegment("ImGui Draw");
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
|
@ -563,7 +542,7 @@ namespace SHADE
|
||||||
if (newSceneName.empty())
|
if (newSceneName.empty())
|
||||||
{
|
{
|
||||||
//Prompt for scene name
|
//Prompt for scene name
|
||||||
isSceneNamePromptOpen = true;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//Else We have a new name
|
//Else We have a new name
|
||||||
|
@ -644,7 +623,7 @@ namespace SHADE
|
||||||
editorState = SHEditor::State::STOP;
|
editorState = SHEditor::State::STOP;
|
||||||
SHCommandManager::SwapStacks();
|
SHCommandManager::SwapStacks();
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
LoadScene(editorConfig->workingSceneID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::ProcessShortcuts()
|
void SHEditor::ProcessShortcuts()
|
||||||
|
|
|
@ -37,8 +37,6 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkCommandPool;
|
class SHVkCommandPool;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
*
|
*
|
||||||
|
@ -144,8 +142,6 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
void RenderSceneNamePrompt() noexcept;
|
|
||||||
|
|
||||||
void RenderUnsavedChangesPrompt() noexcept;
|
void RenderUnsavedChangesPrompt() noexcept;
|
||||||
|
|
||||||
void InitLayout() noexcept;
|
void InitLayout() noexcept;
|
||||||
|
@ -156,8 +152,6 @@ namespace SHADE
|
||||||
|
|
||||||
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||||
|
|
||||||
bool isSceneNamePromptOpen = false;
|
|
||||||
|
|
||||||
bool isUnsavedChangesPromptOpen = false;
|
bool isUnsavedChangesPromptOpen = false;
|
||||||
|
|
||||||
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
|
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "Command/SHCommandManager.h"
|
#include "Command/SHCommandManager.h"
|
||||||
#include "SHImGuiHelpers.hpp"
|
#include "SHImGuiHelpers.hpp"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -454,7 +456,33 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
const bool hasChange = ImGui::InputScalar("##dragScalar", data_type, &value);
|
bool hasChange = ImGui::DragScalar("##dragScalar", data_type, &value);
|
||||||
|
if constexpr(std::is_same_v<T, uint32_t>) //EID or Resource
|
||||||
|
{
|
||||||
|
if (SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if(AssetID * payload = SHDragDrop::AcceptPayload<T>(SHDragDrop::DRAG_RESOURCE))
|
||||||
|
{
|
||||||
|
value = *payload;
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
hasChange = true;
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
else if (std::vector<EntityID>* payload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID))
|
||||||
|
{
|
||||||
|
value = payload->back();
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
hasChange = true;
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
if(hasChange)
|
||||||
|
{
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (hasChange)
|
if (hasChange)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,4 +23,7 @@ constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 };
|
||||||
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
|
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
|
||||||
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
|
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
|
||||||
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
|
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
|
||||||
|
constexpr SHEventIdentifier SH_BUTTON_CLICK_EVENT { 18 };
|
||||||
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 19 };
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,27 @@ namespace SHADE
|
||||||
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
writeInfo.descImageInfos[i].imageLayout = layout;
|
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rest is not used, so it doesn't matter what's in them, we just want to pacify Vulkan
|
||||||
|
for (uint32_t i = imageViewsAndSamplers.size(); i < writeInfo.descImageInfos.size(); ++i)
|
||||||
|
{
|
||||||
|
writeInfo.descImageInfos[i].sampler = std::get<Handle<SHVkSampler>>(imageViewsAndSamplers.back())->GetVkSampler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept
|
||||||
|
{
|
||||||
|
// Find the target writeDescSet
|
||||||
|
BindingAndSetHash writeHash = binding;
|
||||||
|
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||||
|
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||||
|
|
||||||
|
// write sampler and image view
|
||||||
|
auto& [view, sampler, layout] = imageViewAndSampler;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageView = view->GetImageView();
|
||||||
|
writeInfo.descImageInfos[descIndex].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageLayout = layout;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||||
|
@ -200,6 +221,28 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImage(uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
||||||
|
// Get binding + set hash
|
||||||
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
|
// to index a write for a binding
|
||||||
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
||||||
|
// Initialize info for write
|
||||||
|
writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
|
||||||
|
writeDescSet.dstArrayElement = descArrayIndex;
|
||||||
|
writeDescSet.dstSet = descSets[set];
|
||||||
|
writeDescSet.dstBinding = binding;
|
||||||
|
|
||||||
|
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data() + descArrayIndex;
|
||||||
|
writeDescSet.descriptorCount = 1u;
|
||||||
|
|
||||||
|
device->UpdateDescriptorSet(writeDescSet);
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
||||||
{
|
{
|
||||||
vk::WriteDescriptorSet writeDescSet{};
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
|
@ -63,10 +63,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Public member functions */
|
/* Public member functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void UpdateDescriptorSetImage (uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept;
|
||||||
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
||||||
|
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
||||||
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept;
|
||||||
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,33 +183,43 @@ namespace SHADE
|
||||||
/*if (!extensionsSupported)
|
/*if (!extensionsSupported)
|
||||||
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
||||||
|
|
||||||
vk::PhysicalDeviceFeatures features{}; // ADD MORE FEATURES HERE IF NEEDED
|
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature
|
||||||
|
{
|
||||||
|
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.descriptorBindingPartiallyBound = VK_TRUE,
|
||||||
|
.descriptorBindingVariableDescriptorCount = VK_TRUE,
|
||||||
|
.runtimeDescriptorArray = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PhysicalDeviceRobustness2FeaturesEXT robustFeatures
|
||||||
|
{
|
||||||
|
.nullDescriptor = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
robustFeatures.pNext = &descIndexingFeature;
|
||||||
|
|
||||||
|
vk::PhysicalDeviceFeatures2 features{}; // ADD MORE FEATURES HERE IF NEEDED
|
||||||
|
|
||||||
// point and lines fill mode
|
// point and lines fill mode
|
||||||
features.fillModeNonSolid = VK_TRUE;
|
features.features.fillModeNonSolid = VK_TRUE;
|
||||||
features.samplerAnisotropy = VK_TRUE;
|
features.features.samplerAnisotropy = VK_TRUE;
|
||||||
features.multiDrawIndirect = VK_TRUE;
|
features.features.multiDrawIndirect = VK_TRUE;
|
||||||
features.independentBlend = VK_TRUE;
|
features.features.independentBlend = VK_TRUE;
|
||||||
|
features.features.wideLines = VK_TRUE;
|
||||||
|
|
||||||
// for wide lines
|
features.pNext = &robustFeatures;
|
||||||
features.wideLines = true;
|
|
||||||
|
|
||||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
|
||||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
|
||||||
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
|
||||||
descIndexingFeature.runtimeDescriptorArray = true;
|
|
||||||
|
|
||||||
// Prepare to create the device
|
// Prepare to create the device
|
||||||
vk::DeviceCreateInfo deviceCreateInfo
|
vk::DeviceCreateInfo deviceCreateInfo
|
||||||
{
|
{
|
||||||
.pNext = &descIndexingFeature,
|
.pNext = &features,
|
||||||
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
||||||
.pQueueCreateInfos = queueCreateInfos.data(),
|
.pQueueCreateInfos = queueCreateInfos.data(),
|
||||||
.enabledLayerCount = 0, // deprecated and ignored
|
.enabledLayerCount = 0, // deprecated and ignored
|
||||||
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
||||||
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
||||||
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
||||||
.pEnabledFeatures = &features
|
//.pEnabledFeatures = &features
|
||||||
};
|
};
|
||||||
|
|
||||||
// Actually create the device
|
// Actually create the device
|
||||||
|
|
|
@ -10,5 +10,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
//! We need to get the light component and initialize the relevant variables.
|
//! We need to get the light component and initialize the relevant variables.
|
||||||
EntityID lightEntity;
|
EntityID lightEntity;
|
||||||
|
|
||||||
|
//! Generate a renderer for the light component
|
||||||
|
bool generateRenderer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace SHADE
|
||||||
.maxAnisotropy = 1.0f,
|
.maxAnisotropy = 1.0f,
|
||||||
.minLod = params.minLod,
|
.minLod = params.minLod,
|
||||||
.maxLod = params.maxLod,
|
.maxLod = params.maxLod,
|
||||||
|
.borderColor = vk::BorderColor::eFloatOpaqueWhite
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the sampler
|
// Create the sampler
|
||||||
|
|
|
@ -684,7 +684,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* SHBatch - Usage Functions */
|
/* SHBatch - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -703,7 +703,10 @@ namespace SHADE
|
||||||
dynamicOffset.emplace_back(0);
|
dynamicOffset.emplace_back(0);
|
||||||
}
|
}
|
||||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||||
|
|
||||||
|
if (bindBatchPipeline)
|
||||||
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);
|
||||||
if (isAnimated && boneMatrixFirstIndexBuffer[frameIndex])
|
if (isAnimated && boneMatrixFirstIndexBuffer[frameIndex])
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace SHADE
|
||||||
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
||||||
void UpdateAnimationBuffer(uint32_t frameIndex);
|
void UpdateAnimationBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex);
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex);
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -108,12 +108,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Draw(cmdBuffer, frameIndex);
|
batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace SHADE
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
||||||
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
||||||
|
SHVertexInputState SHGraphicsPredefinedData::shadowMapVertexInputState;
|
||||||
|
|
||||||
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
||||||
|
|
||||||
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
||||||
|
@ -160,6 +162,20 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
||||||
|
|
||||||
|
// descriptor binding for storing shadow maps
|
||||||
|
SHVkDescriptorSetLayout::Binding shadowMapBinding
|
||||||
|
{
|
||||||
|
.Type = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
|
||||||
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
|
||||||
|
.DescriptorCount = 200, // we can have up to 200 textures for now
|
||||||
|
.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For global data (generic data and textures)
|
||||||
|
Handle<SHVkDescriptorSetLayout> shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps");
|
||||||
|
|
||||||
// For per instance data (transforms, materials, etc.)
|
// For per instance data (transforms, materials, etc.)
|
||||||
SHVkDescriptorSetLayout::Binding boneDataBinding
|
SHVkDescriptorSetLayout::Binding boneDataBinding
|
||||||
{
|
{
|
||||||
|
@ -176,7 +192,7 @@ namespace SHADE
|
||||||
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
||||||
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
||||||
predefinedLayouts.push_back(fontDataDescSetLayout);
|
predefinedLayouts.push_back(fontDataDescSetLayout);
|
||||||
predefinedLayouts.push_back({});
|
predefinedLayouts.push_back(shadowMapDescLayout);
|
||||||
predefinedLayouts.push_back(materialBoneDataPerInstanceLayout);
|
predefinedLayouts.push_back(materialBoneDataPerInstanceLayout);
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
|
@ -208,7 +224,7 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept
|
void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept
|
||||||
{
|
{
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute positions at binding 0
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute positions at binding 0
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // Attribute UVs at binding 1
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // Attribute UVs at binding 1
|
||||||
|
@ -219,13 +235,16 @@ namespace SHADE
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_4D) }); // Attribute bone indices at index 9
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_4D) }); // Attribute bone indices at index 9
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Attribute bone weights at index 10
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Attribute bone weights at index 10
|
||||||
defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // Instance bone matrix first index at index 11
|
defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // Instance bone matrix first index at index 11
|
||||||
|
|
||||||
|
shadowMapVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D)});
|
||||||
|
shadowMapVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }, 4, 4); // Transform at binding 4 - 7 (4 slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||||
{
|
{
|
||||||
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
||||||
InitDescSetLayouts(logicalDevice);
|
InitDescSetLayouts(logicalDevice);
|
||||||
InitDefaultVertexInputState();
|
InitPredefinedVertexInputState();
|
||||||
InitDescMappings();
|
InitDescMappings();
|
||||||
InitDummyPipelineLayouts (logicalDevice);
|
InitDummyPipelineLayouts (logicalDevice);
|
||||||
}
|
}
|
||||||
|
@ -249,6 +268,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVertexInputState const& SHGraphicsPredefinedData::GetShadowMapViState(void) noexcept
|
||||||
|
{
|
||||||
|
return shadowMapVertexInputState;
|
||||||
|
}
|
||||||
|
|
||||||
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
||||||
{
|
{
|
||||||
return perSystemData[static_cast<uint32_t>(systemType)];
|
return perSystemData[static_cast<uint32_t>(systemType)];
|
||||||
|
|
|
@ -61,6 +61,9 @@ namespace SHADE
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
static SHVertexInputState defaultVertexInputState;
|
static SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
|
//! vertex input state for shadow mapping
|
||||||
|
static SHVertexInputState shadowMapVertexInputState;
|
||||||
|
|
||||||
//! Predefined data for each type of system
|
//! Predefined data for each type of system
|
||||||
static std::vector<PerSystem> perSystemData;
|
static std::vector<PerSystem> perSystemData;
|
||||||
|
|
||||||
|
@ -76,7 +79,7 @@ namespace SHADE
|
||||||
static void InitDescMappings (void) noexcept;
|
static void InitDescMappings (void) noexcept;
|
||||||
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDefaultVertexInputState (void) noexcept;
|
static void InitPredefinedVertexInputState (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -94,6 +97,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
||||||
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
||||||
|
static SHVertexInputState const& GetShadowMapViState (void) noexcept;
|
||||||
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
||||||
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
||||||
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace SHADE
|
||||||
PER_INSTANCE_BATCH,
|
PER_INSTANCE_BATCH,
|
||||||
PER_INSTANCE_ANIM_BATCH,
|
PER_INSTANCE_ANIM_BATCH,
|
||||||
FONT,
|
FONT,
|
||||||
RENDER_GRAPH_RESOURCE,
|
|
||||||
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
||||||
|
RENDER_GRAPH_RESOURCE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,13 @@ namespace SHADE
|
||||||
// Register function for subpass
|
// Register function for subpass
|
||||||
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
|
auto subPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data())->GetSubpass("Debug Draw");
|
||||||
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
// Set line width first
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
|
||||||
|
// Draw
|
||||||
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
||||||
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
|
||||||
{
|
{
|
||||||
|
@ -125,9 +129,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
});
|
});
|
||||||
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
|
auto subPassWithDepth = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data())->GetSubpass("Debug Draw with Depth");
|
||||||
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
// Set line width first
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
|
||||||
|
// Draw
|
||||||
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
||||||
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
|
||||||
{
|
{
|
||||||
|
@ -207,6 +215,11 @@ namespace SHADE
|
||||||
drawSphere(getMeshBatch(true, depthTested), matrix, color);
|
drawSphere(getMeshBatch(true, depthTested), matrix, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
|
||||||
|
{
|
||||||
|
drawWireCapsule(getLineBatch(depthTested), getMeshBatch(false, depthTested), position, rotation, height, radius, color);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Persistent Draw Functions */
|
/* Persistent Draw Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -264,6 +277,12 @@ namespace SHADE
|
||||||
markPersistentDrawsDirty();
|
markPersistentDrawsDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
|
||||||
|
{
|
||||||
|
drawWireCapsule(getPersistentLineBatch(depthTested), getPersistentMeshBatch(false, depthTested), position, rotation, height, radius, color);
|
||||||
|
markPersistentDrawsDirty();
|
||||||
|
}
|
||||||
|
|
||||||
void SHDebugDrawSystem::ClearPersistentDraws()
|
void SHDebugDrawSystem::ClearPersistentDraws()
|
||||||
{
|
{
|
||||||
for (auto& batch : persistentLineBatches)
|
for (auto& batch : persistentLineBatches)
|
||||||
|
@ -348,6 +367,53 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::drawWireCapsule(LinesBatch& lineBatch, MeshBatch& meshBatch, const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color)
|
||||||
|
{
|
||||||
|
// Get local axis vectors
|
||||||
|
const SHVec3 LOCAL_UP = SHVec3::Rotate(SHVec3::Up, rotation);
|
||||||
|
const SHVec3 LOCAL_RIGHT = SHVec3::Rotate(SHVec3::Right, rotation);
|
||||||
|
const SHVec3 LOCAL_FORWARD = SHVec3::Rotate(SHVec3::Forward, rotation);
|
||||||
|
|
||||||
|
// Rotate the circle
|
||||||
|
SHQuaternion circleOrientation = SHQuaternion::FromEuler(SHVec3(SHMath::DegreesToRadians(90.0), 0.0f, 0.0f)) * rotation;
|
||||||
|
|
||||||
|
// Compute top and bottom of the cylinder
|
||||||
|
const SHVec3 HALF_UP = LOCAL_UP * (height * 0.5f - radius);
|
||||||
|
const SHVec3 TOP_POS = position + HALF_UP;
|
||||||
|
const SHVec3 BOT_POS = position - HALF_UP;
|
||||||
|
|
||||||
|
// Render circles
|
||||||
|
const SHVec3 CIRCLE_SCALE = SHVec3(radius * 2.0f, radius * 2.0, radius * 2.0);
|
||||||
|
drawCircle(meshBatch, SHMatrix::Transform(TOP_POS, circleOrientation, CIRCLE_SCALE), color);
|
||||||
|
drawCircle(meshBatch, SHMatrix::Transform(BOT_POS, circleOrientation, CIRCLE_SCALE), color);
|
||||||
|
|
||||||
|
// Render connecting lines
|
||||||
|
drawLine(lineBatch, TOP_POS + LOCAL_RIGHT * radius, BOT_POS + LOCAL_RIGHT * radius, color);
|
||||||
|
drawLine(lineBatch, TOP_POS - LOCAL_RIGHT * radius, BOT_POS - LOCAL_RIGHT * radius, color);
|
||||||
|
drawLine(lineBatch, TOP_POS + LOCAL_FORWARD * radius, BOT_POS + LOCAL_FORWARD * radius, color);
|
||||||
|
drawLine(lineBatch, TOP_POS - LOCAL_FORWARD * radius, BOT_POS - LOCAL_FORWARD * radius, color);
|
||||||
|
|
||||||
|
// Render caps
|
||||||
|
const SHVec3 RADIUS_SCALE = SHVec3(radius * 2.0, radius * 2.0f, radius * 2.0);
|
||||||
|
const SHMatrix TOP_CAP_MAT = SHMatrix::Transform(TOP_POS, rotation, RADIUS_SCALE);
|
||||||
|
drawMesh
|
||||||
|
(
|
||||||
|
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCapsuleCap),
|
||||||
|
meshBatch, TOP_CAP_MAT, color
|
||||||
|
);
|
||||||
|
const SHMatrix BOT_CAP_MAT = SHMatrix::Transform
|
||||||
|
(
|
||||||
|
BOT_POS,
|
||||||
|
SHQuaternion::FromEuler(SHVec3(SHMath::DegreesToRadians(180.0), 0.0f, 0.0f)) * rotation,
|
||||||
|
RADIUS_SCALE
|
||||||
|
);
|
||||||
|
drawMesh
|
||||||
|
(
|
||||||
|
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCapsuleCap),
|
||||||
|
meshBatch, BOT_CAP_MAT, color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Batch Functions - Lines */
|
/* Helper Batch Functions - Lines */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -448,7 +514,6 @@ namespace SHADE
|
||||||
if (batch.NumPoints[frameIndex] > 0)
|
if (batch.NumPoints[frameIndex] > 0)
|
||||||
{
|
{
|
||||||
cmdBuffer->BindPipeline(batch.Pipeline);
|
cmdBuffer->BindPipeline(batch.Pipeline);
|
||||||
cmdBuffer->SetLineWidth(LineWidth);
|
|
||||||
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
|
||||||
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
|
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,17 @@ namespace SHADE
|
||||||
/// <param name="color">Colour to draw with.</param>
|
/// <param name="color">Colour to draw with.</param>
|
||||||
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
|
/// <summary>
|
||||||
|
/// Draws the outline of a capsule.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">Position of the wireframe capsule.</param>
|
||||||
|
/// <param name="rotation">Rotation of the capsule.</param>
|
||||||
|
/// <param name="height">Height of the overall capsule.</param>
|
||||||
|
/// <param name="radius">Radius of the capsule.</param>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
/// <param name="color">Colour to draw with.</param>
|
||||||
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
|
void DrawWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Persistent Draw Functions */
|
/* Persistent Draw Functions */
|
||||||
|
@ -269,6 +280,17 @@ namespace SHADE
|
||||||
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Draws a persistent outline of a capsule.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">Position of the wireframe capsule.</param>
|
||||||
|
/// <param name="rotation">Rotation of the capsule.</param>
|
||||||
|
/// <param name="height">Height of the overall capsule.</param>
|
||||||
|
/// <param name="radius">Radius of the capsule.</param>
|
||||||
|
/// <param name="color"></param>
|
||||||
|
/// <param name="color">Colour to draw with.</param>
|
||||||
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
|
void DrawPersistentWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
|
/// <summary>
|
||||||
/// Clears any persistent drawn debug primitives.
|
/// Clears any persistent drawn debug primitives.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void ClearPersistentDraws();
|
void ClearPersistentDraws();
|
||||||
|
@ -386,6 +408,7 @@ namespace SHADE
|
||||||
void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
||||||
void drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
void drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
||||||
void drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
void drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
|
||||||
|
void drawWireCapsule(LinesBatch& lineBatch, MeshBatch& meshBatch, const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Batch Functions - Lines */
|
/* Helper Batch Functions - Lines */
|
||||||
|
|
|
@ -31,68 +31,91 @@ namespace SHADE
|
||||||
static constexpr uint32_t EDITOR = 0;
|
static constexpr uint32_t EDITOR = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct DescriptorSetIndex
|
struct RenderGraphEntityNames
|
||||||
//{
|
{
|
||||||
// /***************************************************************************/
|
/***************************************************************************/
|
||||||
// /*!
|
/*!
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for static global values like generic data, and
|
|
||||||
// texture samplers
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t STATIC_GLOBALS = 0;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for dynamic global values like lights.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t DYNAMIC_GLOBALS = 1;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for high frequency changing global values like
|
|
||||||
// camera matrices.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for per-instance/material changing values.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t PER_INSTANCE = 3;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for render graph resources. Unlike the sets from
|
|
||||||
// 1 to 3 and 6, this set index does not have hard coded bindings and is
|
|
||||||
// NOT part of the layouts included in the global data.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for render graph node compute resources. For data
|
|
||||||
// that we wish to pass to compute shaders in the render graph, this is
|
|
||||||
// the set to use. Unlike the sets from 1 to 3 and 6, this set index does not have
|
|
||||||
// hard coded bindings and is NOT part of the layouts included in the global
|
|
||||||
// data.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
|
|
||||||
|
|
||||||
// /***************************************************************************/
|
\brief
|
||||||
// /*!
|
Name of G-Buffer render graph node.
|
||||||
// \brief
|
|
||||||
// To store font data.
|
*/
|
||||||
//
|
/***************************************************************************/
|
||||||
// */
|
static constexpr std::string_view GBUFFER_PASS = "G-Buffer";
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t FONT_DATA = 4;
|
/***************************************************************************/
|
||||||
//};
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of shadow map render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SHADOW_MAP_PASS = "Shadow Map Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_PASS = "Deferred Comp Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw with Depth render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW_DEPTH_PASS = "Debug Draw with Depth Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW = "Debug Draw Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of screen space pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SCREEN_SPACE_PASS = "Screen Space Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of ImGui pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view IMGUI_PASS = "ImGui Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite compute.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_COMPUTE = "Deferred Composite";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct DescriptorSetBindings
|
struct DescriptorSetBindings
|
||||||
{
|
{
|
||||||
|
@ -166,6 +189,16 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Descriptor set binding for shadow map images.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t SHADOW_MAP_IMAGE_SAMPLER_DATA = 0;
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
\brief
|
\brief
|
||||||
|
|
|
@ -44,6 +44,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
||||||
|
#include "Events/SHEvent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -124,6 +127,13 @@ namespace SHADE
|
||||||
|
|
||||||
SHFreetypeInstance::Init();
|
SHFreetypeInstance::Init();
|
||||||
|
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl", false);
|
||||||
|
|
||||||
// Load Built In Shaders
|
// Load Built In Shaders
|
||||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||||
static constexpr AssetID VS_ANIM = 47911992; animtVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_ANIM);
|
static constexpr AssetID VS_ANIM = 47911992; animtVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_ANIM);
|
||||||
|
@ -138,6 +148,8 @@ namespace SHADE
|
||||||
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
||||||
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
||||||
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
||||||
|
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
||||||
|
@ -170,6 +182,8 @@ namespace SHADE
|
||||||
// Create Default Viewport
|
// Create Default Viewport
|
||||||
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||||
|
|
||||||
|
shadowMapViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(SHLightingSubSystem::SHADOW_MAP_WIDTH), static_cast<float>(SHLightingSubSystem::SHADOW_MAP_HEIGHT), 0.0f, 1.0f));
|
||||||
|
|
||||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
||||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -184,22 +198,24 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
||||||
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
renderGraph->AddResource("Position World Space", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
|
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, 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);
|
||||||
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, true, windowDims.first, windowDims.second);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* MAIN NODE */
|
/* MAIN NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto gBufferNode = renderGraph->AddNode("G-Buffer",
|
auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(),
|
||||||
|
//auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS.data()
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Entity ID",
|
"Entity ID",
|
||||||
|
@ -208,7 +224,8 @@ namespace SHADE
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Depth Buffer",
|
"Depth Buffer",
|
||||||
"SSAO",
|
"SSAO",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{}); // no predecessors
|
{}); // no predecessors
|
||||||
|
|
||||||
|
@ -221,6 +238,7 @@ namespace SHADE
|
||||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||||
gBufferSubpass->AddColorOutput("Normals");
|
gBufferSubpass->AddColorOutput("Normals");
|
||||||
gBufferSubpass->AddColorOutput("Albedo");
|
gBufferSubpass->AddColorOutput("Albedo");
|
||||||
|
gBufferSubpass->AddColorOutput("Position World Space");
|
||||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
|
|
||||||
|
@ -255,53 +273,52 @@ namespace SHADE
|
||||||
// Add another pass to blur SSAO
|
// Add another pass to blur SSAO
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
|
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* SHADOW MAP PASS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
// Shadow map pass will have no resources bound at first. Lighting system will add resources to the node.
|
|
||||||
// It will initially also not have any subpasses since they will be added for each light that casts shadows.
|
|
||||||
//auto shadowMapPass = renderGraph->AddNode("Shadow Map Pass", {}, {});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE NODE */
|
/* DEFERRED COMPOSITE NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// This pass will facilitate both lighting and shadows in 1 single pass.
|
// This pass will facilitate both lighting and shadows in 1 single pass.
|
||||||
auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass",
|
auto deferredCompositeNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(),
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Light Layer Indices",
|
"Light Layer Indices",
|
||||||
"Normals",
|
"Normals",
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Scene",
|
"Scene",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{"G-Buffer"});
|
{ SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS .data()});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Position World Space", "Scene"}, {}, SHLightingSubSystem::MAX_SHADOWS);
|
||||||
|
deferredCompositeCompute->AddPreComputeFunction([=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEBUG DRAW PASS INIT */
|
/* DEBUG DRAW PASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Set up Debug Draw Passes
|
// Set up Debug Draw Passes
|
||||||
// - Depth Tested
|
// - Depth Tested
|
||||||
auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"});
|
auto debugDrawNodeDepth = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data(), {"Scene", "Depth Buffer"}, {SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data()});
|
||||||
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
||||||
debugDrawDepthSubpass->AddColorOutput("Scene");
|
debugDrawDepthSubpass->AddColorOutput("Scene");
|
||||||
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
||||||
// - No Depth Test
|
// - No Depth Test
|
||||||
auto debugDrawNode = renderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
|
auto debugDrawNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data(), {"Scene"}, {SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data()});
|
||||||
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
||||||
debugDrawSubpass->AddColorOutput("Scene");
|
debugDrawSubpass->AddColorOutput("Scene");
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SCREEN SPACE PASS */
|
/* SCREEN SPACE PASS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" });
|
auto screenSpaceNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data(), {"Scene", "Entity ID"}, {SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data()});
|
||||||
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
||||||
uiSubpass->AddColorOutput("Scene");
|
uiSubpass->AddColorOutput("Scene");
|
||||||
uiSubpass->AddColorOutput("Entity ID");
|
uiSubpass->AddColorOutput("Entity ID");
|
||||||
|
@ -316,16 +333,16 @@ namespace SHADE
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
{
|
{
|
||||||
// Dummy Node to transition scene render graph resource
|
// Dummy Node to transition scene render graph resource
|
||||||
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" });
|
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()});
|
||||||
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
|
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
|
||||||
dummySubpass->AddInput("Scene");
|
dummySubpass->AddInput("Scene");
|
||||||
|
|
||||||
auto imGuiNode = renderGraph->AddNode("ImGui Node", { "Present" }, {});
|
auto imGuiNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data(), {"Present"}, {});
|
||||||
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
||||||
imGuiSubpass->AddColorOutput("Present");
|
imGuiSubpass->AddColorOutput("Present");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS });
|
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()}, {renderToSwapchainVS, renderToSwapchainFS});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,12 +411,16 @@ namespace SHADE
|
||||||
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
|
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
|
||||||
|
|
||||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||||
lightingSubSystem->Init(device, descPool);
|
lightingSubSystem->Init(device, descPool, &resourceManager, samplerCache.GetSampler (device, SHVkSamplerParams
|
||||||
|
{
|
||||||
|
.addressMode = vk::SamplerAddressMode::eClampToBorder,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
||||||
|
|
||||||
// initialize the text renderer
|
// initialize the text renderer
|
||||||
auto uiNode = renderGraph->GetNode("Screen Space Pass");
|
auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data());
|
||||||
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
||||||
|
|
||||||
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
||||||
|
@ -420,13 +441,14 @@ namespace SHADE
|
||||||
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
|
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
|
||||||
primitiveMeshes[static_cast<int>(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary);
|
primitiveMeshes[static_cast<int>(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary);
|
||||||
primitiveMeshes[static_cast<int>(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary);
|
primitiveMeshes[static_cast<int>(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary);
|
||||||
|
primitiveMeshes[static_cast<int>(PrimitiveType::LineCapsuleCap)] = SHPrimitiveGenerator::LineCapsuleCap(meshLibrary);
|
||||||
BuildMeshBuffers();
|
BuildMeshBuffers();
|
||||||
|
|
||||||
// Create default materials
|
// Create default materials
|
||||||
defaultMaterial = AddMaterial
|
defaultMaterial = AddMaterial
|
||||||
(
|
(
|
||||||
defaultVertShader, defaultFragShader,
|
defaultVertShader, defaultFragShader,
|
||||||
renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write")
|
||||||
);
|
);
|
||||||
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||||
defaultAnimMaterial = AddMaterial
|
defaultAnimMaterial = AddMaterial
|
||||||
|
@ -457,6 +479,7 @@ namespace SHADE
|
||||||
InitMiddleEnd();
|
InitMiddleEnd();
|
||||||
InitSubsystems();
|
InitSubsystems();
|
||||||
InitBuiltInResources();
|
InitBuiltInResources();
|
||||||
|
InitEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
|
@ -554,6 +577,15 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
|
||||||
|
{
|
||||||
|
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||||
|
for (auto& comp : lightComps)
|
||||||
|
{
|
||||||
|
comp.SetEnableShadow(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderGraph->Begin(frameIndex);
|
renderGraph->Begin(frameIndex);
|
||||||
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
||||||
|
|
||||||
|
@ -734,16 +766,66 @@ namespace SHADE
|
||||||
renderers.erase(iter);
|
renderers.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept
|
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept
|
||||||
{
|
{
|
||||||
|
// we need to wait for the device to finish using the graph first
|
||||||
|
device->WaitIdle();
|
||||||
|
|
||||||
|
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
|
||||||
|
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
|
||||||
|
std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
|
||||||
|
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write");
|
||||||
|
|
||||||
|
if (EVENT_DATA->generateRenderer)
|
||||||
|
{
|
||||||
|
// Create new renderer for the light component and give it to the light component
|
||||||
|
Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
|
||||||
|
lightComp->SetRenderer (newRenderer);
|
||||||
|
|
||||||
|
// assign shadow map index to light component
|
||||||
|
lightComp->SetShadowMapIndex (lightingSubSystem->GetNumShadowMaps());
|
||||||
|
}
|
||||||
|
|
||||||
// Add the shadow map resource to the graph
|
// Add the shadow map resource to the graph
|
||||||
|
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
|
||||||
|
|
||||||
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
||||||
|
auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
|
|
||||||
// Add a subpass to render to that shadow map
|
// Add a subpass to render to that shadow map
|
||||||
|
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer());
|
||||||
|
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
|
||||||
|
|
||||||
//renderGraph->GetNode ();
|
// regenerate the node
|
||||||
return event->handle;
|
shadowMapNode->RuntimeStandaloneRegenerate();
|
||||||
|
|
||||||
|
// Create pipeline from new renderpass and subpass if it's not created yet
|
||||||
|
if (!shadowMapPipeline)
|
||||||
|
{
|
||||||
|
SHPipelineLibrary tempLibrary{};
|
||||||
|
Handle<SHRenderGraphNode> rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data());
|
||||||
|
|
||||||
|
SHRasterizationState rasterState{};
|
||||||
|
rasterState.cull_mode = vk::CullModeFlagBits::eBack;
|
||||||
|
|
||||||
|
tempLibrary.Init(device);
|
||||||
|
tempLibrary.CreateGraphicsPipelines
|
||||||
|
(
|
||||||
|
{ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass,
|
||||||
|
SHGraphicsPredefinedData::SystemType::BATCHING,
|
||||||
|
SHGraphicsPredefinedData::GetShadowMapViState(), rasterState
|
||||||
|
);
|
||||||
|
shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} });
|
||||||
|
}
|
||||||
|
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||||
|
|
||||||
|
// add the shadow map to the lighting system
|
||||||
|
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(resourceName), EVENT_DATA->lightEntity);
|
||||||
|
|
||||||
|
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
|
||||||
|
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);
|
||||||
|
|
||||||
|
return eventPtr->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
|
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
|
||||||
|
@ -828,6 +910,7 @@ namespace SHADE
|
||||||
case PrimitiveType::Sphere:
|
case PrimitiveType::Sphere:
|
||||||
case PrimitiveType::LineCube:
|
case PrimitiveType::LineCube:
|
||||||
case PrimitiveType::LineCircle:
|
case PrimitiveType::LineCircle:
|
||||||
|
case PrimitiveType::LineCapsuleCap:
|
||||||
return primitiveMeshes[static_cast<int>(type)];
|
return primitiveMeshes[static_cast<int>(type)];
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
|
@ -1054,6 +1137,7 @@ namespace SHADE
|
||||||
|
|
||||||
mousePickSubSystem->HandleResize();
|
mousePickSubSystem->HandleResize();
|
||||||
postOffscreenRenderSubSystem->HandleResize();
|
postOffscreenRenderSubSystem->HandleResize();
|
||||||
|
//lightingSubSystem->HandleResize(renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()));
|
||||||
|
|
||||||
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
||||||
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
||||||
|
@ -1086,7 +1170,7 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
||||||
{
|
{
|
||||||
return renderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
return renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
||||||
|
|
|
@ -72,9 +72,10 @@ namespace SHADE
|
||||||
Cube,
|
Cube,
|
||||||
Sphere,
|
Sphere,
|
||||||
LineCube,
|
LineCube,
|
||||||
LineCircle
|
LineCircle,
|
||||||
|
LineCapsuleCap
|
||||||
};
|
};
|
||||||
static constexpr int MAX_PRIMITIVE_TYPES = 4;
|
static constexpr int MAX_PRIMITIVE_TYPES = 5;
|
||||||
enum class DebugDrawPipelineType
|
enum class DebugDrawPipelineType
|
||||||
{
|
{
|
||||||
LineNoDepthTest,
|
LineNoDepthTest,
|
||||||
|
@ -177,7 +178,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Light functions */
|
/* Light functions */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept;
|
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Material Functions */
|
/* Material Functions */
|
||||||
|
@ -405,10 +406,6 @@ namespace SHADE
|
||||||
SHWindow* GetWindow() noexcept { return window; }
|
SHWindow* GetWindow() noexcept { return window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
/* Constants */
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
static constexpr std::string_view G_BUFFER_RENDER_GRAPH_NODE_NAME = "G-Buffer";
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
|
@ -445,6 +442,7 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Handle<SHViewport> worldViewport; // Whole screen
|
Handle<SHViewport> worldViewport; // Whole screen
|
||||||
|
Handle<SHViewport> shadowMapViewport;
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
||||||
// Renderers
|
// Renderers
|
||||||
|
@ -469,6 +467,7 @@ namespace SHADE
|
||||||
Handle<SHVkShaderModule> textFS;
|
Handle<SHVkShaderModule> textFS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainVS;
|
Handle<SHVkShaderModule> renderToSwapchainVS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainFS;
|
Handle<SHVkShaderModule> renderToSwapchainFS;
|
||||||
|
Handle<SHVkShaderModule> shadowMapVS;
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
Handle<SHFont> testFont;
|
Handle<SHFont> testFont;
|
||||||
|
@ -484,6 +483,7 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
||||||
|
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
|
||||||
|
|
||||||
// Built-In Textures
|
// Built-In Textures
|
||||||
Handle<SHTexture> defaultTexture;
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
|
@ -122,4 +122,9 @@ namespace SHADE
|
||||||
return cameraDirector;
|
return cameraDirector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHShaderCameraData SHRenderer::GetCPUCameraData(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuCameraData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "SHCamera.h"
|
#include "SHCamera.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -93,6 +93,7 @@ namespace SHADE
|
||||||
/* Setters and Getters */
|
/* Setters and Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
||||||
|
SHShaderCameraData GetCPUCameraData (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Graphics/Events/SHGraphicsEvents.h"
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ namespace SHADE
|
||||||
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||||
isActive = true;
|
isActive = true;
|
||||||
//Unbind();
|
//Unbind();
|
||||||
|
renderer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,11 +118,22 @@ namespace SHADE
|
||||||
// Create new event and broadcast it
|
// Create new event and broadcast it
|
||||||
SHLightEnableShadowEvent newEvent;
|
SHLightEnableShadowEvent newEvent;
|
||||||
newEvent.lightEntity = GetEID();
|
newEvent.lightEntity = GetEID();
|
||||||
|
newEvent.generateRenderer = static_cast<bool>(!renderer);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept
|
||||||
|
{
|
||||||
|
renderer = newRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetShadowMapIndex(uint32_t index) noexcept
|
||||||
|
{
|
||||||
|
lightData.shadowMapIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightData;
|
return lightData;
|
||||||
|
@ -172,6 +185,11 @@ namespace SHADE
|
||||||
return lightData.strength;
|
return lightData.strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderer> SHLightComponent::GetRenderer(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
#include <rttr/registration>
|
#include <rttr/registration>
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SHRenderer;
|
||||||
|
|
||||||
class SH_API SHLightComponent final : public SHComponent
|
class SH_API SHLightComponent final : public SHComponent
|
||||||
{
|
{
|
||||||
|
@ -14,6 +16,9 @@ namespace SHADE
|
||||||
//! GPU depends on the type of the light.
|
//! GPU depends on the type of the light.
|
||||||
SHLightData lightData;
|
SHLightData lightData;
|
||||||
|
|
||||||
|
//! Renderer to calculate light world to projection matrix
|
||||||
|
Handle<SHRenderer> renderer;
|
||||||
|
|
||||||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||||
|
@ -49,6 +54,8 @@ namespace SHADE
|
||||||
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
||||||
void SetStrength (float value) noexcept; // serialized
|
void SetStrength (float value) noexcept; // serialized
|
||||||
void SetEnableShadow (bool flag) noexcept;
|
void SetEnableShadow (bool flag) noexcept;
|
||||||
|
void SetRenderer (Handle<SHRenderer> newRenderer) noexcept;
|
||||||
|
void SetShadowMapIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
|
|
||||||
SHLightData const& GetLightData (void) const noexcept;
|
SHLightData const& GetLightData (void) const noexcept;
|
||||||
|
@ -61,6 +68,7 @@ namespace SHADE
|
||||||
//bool GetBound (void) const noexcept;
|
//bool GetBound (void) const noexcept;
|
||||||
//uint32_t GetIndexInBuffer (void) const noexcept;
|
//uint32_t GetIndexInBuffer (void) const noexcept;
|
||||||
float GetStrength (void) const noexcept;
|
float GetStrength (void) const noexcept;
|
||||||
|
Handle<SHRenderer> GetRenderer (void) const noexcept;
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -50,6 +57,19 @@ namespace SHADE
|
||||||
//lightPtr->direction = lightData.direction;
|
//lightPtr->direction = lightData.direction;
|
||||||
lightPtr->diffuseColor = lightData.color;
|
lightPtr->diffuseColor = lightData.color;
|
||||||
lightPtr->active = lightComp->isActive;
|
lightPtr->active = lightComp->isActive;
|
||||||
|
|
||||||
|
// write view projection matrix if renderer is available
|
||||||
|
auto lightRenderer = lightComp->GetRenderer();
|
||||||
|
if (lightRenderer)
|
||||||
|
{
|
||||||
|
lightPtr->pvMatrix = lightRenderer->GetCPUCameraData().viewProjectionMatrix;
|
||||||
|
|
||||||
|
// Boolean to cast shadows in first 8 bits (1 byte)
|
||||||
|
lightPtr->shadowData = lightData.castShadows;
|
||||||
|
|
||||||
|
// Next 24 bits for shadow map index
|
||||||
|
lightPtr->shadowData |= (lightData.shadowMapIndex << 8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SH_LIGHT_TYPE::POINT:
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
@ -365,6 +385,32 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::UpdateShadowMapDesc(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
|
||||||
|
{
|
||||||
|
switch (lightComp->GetLightData().type)
|
||||||
|
{
|
||||||
|
case SH_LIGHT_TYPE::DIRECTIONAL:
|
||||||
|
return SHMatrix::Transpose(SHMatrix::LookAtLH(lightComp->GetLightData().position, SHVec3::Normalise (lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
//return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::SPOT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::AMBIENT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::NUM_TYPES:
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -375,13 +421,15 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept
|
||||||
{
|
{
|
||||||
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
||||||
|
|
||||||
logicalDevice = device;
|
logicalDevice = device;
|
||||||
|
resourceHub = rh;
|
||||||
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
||||||
|
|
||||||
|
#pragma region LIGHTING
|
||||||
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
||||||
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
||||||
|
|
||||||
|
@ -418,7 +466,22 @@ namespace SHADE
|
||||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region SHADOWS
|
||||||
|
//std::vector<uint32_t> shadowDescVariableSizes{ MAX_SHADOWS };
|
||||||
|
//shadowMapDescriptorSet = descPool->Allocate({SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::SHADOW)}, shadowDescVariableSizes);
|
||||||
|
|
||||||
|
//#ifdef _DEBUG
|
||||||
|
// const auto& SHADOW_MAP_DESC_SETS = shadowMapDescriptorSet->GetVkHandle();
|
||||||
|
// for (int i = 0; i < static_cast<int>(SHADOW_MAP_DESC_SETS.size()); ++i)
|
||||||
|
// SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, SHADOW_MAP_DESC_SETS[i], "[Descriptor Set] Shadow Map Data Frame #" + std::to_string(i));
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
shadowMapSampler = inShadowMapSampler;
|
||||||
|
shadowMaps.clear();
|
||||||
//numLightComponents = 0;
|
//numLightComponents = 0;
|
||||||
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -452,6 +515,12 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& light : lightComps)
|
for (auto& light : lightComps)
|
||||||
{
|
{
|
||||||
|
if (auto renderer = light.GetRenderer())
|
||||||
|
{
|
||||||
|
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
|
||||||
|
renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(10.0f, 10.0f, 1.0f, 50.0f));
|
||||||
|
}
|
||||||
|
|
||||||
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
||||||
|
|
||||||
// First we want to make sure the light is already bound to the system. if it
|
// First we want to make sure the light is already bound to the system. if it
|
||||||
|
@ -503,7 +572,6 @@ namespace SHADE
|
||||||
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
||||||
ComputeDynamicOffsets();
|
ComputeDynamicOffsets();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -526,9 +594,101 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept
|
||||||
|
{
|
||||||
|
// Add to container of shadow maps
|
||||||
|
shadowMapIndexing.emplace(lightEntity, static_cast<uint32_t> (shadowMaps.size()));
|
||||||
|
shadowMaps.emplace_back(newShadowMap);
|
||||||
|
|
||||||
|
// Just use the image view stored in the resource
|
||||||
|
Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMap->GetImageView();
|
||||||
|
|
||||||
|
// Prepare to write to descriptor
|
||||||
|
shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
|
||||||
|
// Update descriptor set
|
||||||
|
//static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0;
|
||||||
|
//uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
//shadowMapDescriptorSet->ModifyWriteDescImage
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA,
|
||||||
|
// shadowMapImageSamplers[SHADOW_MAP_DESC_ARRAY_INDEX],
|
||||||
|
// SHADOW_MAP_DESC_ARRAY_INDEX
|
||||||
|
//);
|
||||||
|
|
||||||
|
//// TODO: Definitely can be optimized by writing a function that modifies a specific descriptor in the array
|
||||||
|
//shadowMapDescriptorSet->UpdateDescriptorSetImages
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA
|
||||||
|
//);
|
||||||
|
|
||||||
|
// add to barriers
|
||||||
|
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
|
||||||
|
.oldLayout = vk::ImageLayout::eDepthAttachmentOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = newShadowMap->GetImage()->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eDepth,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// return new index of shadow map
|
||||||
|
return static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||||
|
{
|
||||||
|
// Issue barrier to transition shadow maps for reading in compute shader
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept
|
||||||
|
//{
|
||||||
|
// uint32_t const NUM_SHADOW_MAPS = static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
// for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i)
|
||||||
|
// {
|
||||||
|
// // Just use the image view stored in the resource
|
||||||
|
// Handle<SHVkImageView> const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView();
|
||||||
|
|
||||||
|
// // set new image view
|
||||||
|
// std::get<Handle<SHVkImageView>>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW;
|
||||||
|
|
||||||
|
// // Set image for barrier
|
||||||
|
// shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (NUM_SHADOW_MAPS > 0)
|
||||||
|
// {
|
||||||
|
// // modify descriptors in render graph node compute
|
||||||
|
// compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightingDataDescSet;
|
return lightingDataDescSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& SHLightingSubSystem::GetViewSamplerLayout(uint32_t index) const noexcept
|
||||||
|
{
|
||||||
|
return shadowMapImageSamplers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::GetNumShadowMaps(void) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,6 +20,10 @@ namespace SHADE
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
class SHLightComponent;
|
class SHLightComponent;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHSamplerCache;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkSampler;
|
||||||
|
class SHRenderGraphNodeCompute;
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
struct SHDirectionalLightData
|
struct SHDirectionalLightData
|
||||||
|
@ -34,6 +42,12 @@ namespace SHADE
|
||||||
//! Diffuse color emitted by the light
|
//! Diffuse color emitted by the light
|
||||||
alignas (16) SHVec4 diffuseColor;
|
alignas (16) SHVec4 diffuseColor;
|
||||||
|
|
||||||
|
//! Matrix for world to projection from light's perspective
|
||||||
|
SHMatrix pvMatrix;
|
||||||
|
|
||||||
|
//! Represents boolean for casting shadows in first byte and shadow map index in the other 3.
|
||||||
|
uint32_t shadowData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
|
@ -52,19 +66,22 @@ namespace SHADE
|
||||||
//! when a fragment is being evaluated, the shader will use the fragment's
|
//! when a fragment is being evaluated, the shader will use the fragment's
|
||||||
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
||||||
uint32_t cullingMask;
|
uint32_t cullingMask;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API SHLightingSubSystem
|
class SH_API SHLightingSubSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
||||||
|
static constexpr uint32_t MAX_SHADOWS = 200;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_WIDTH = 1024;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_HEIGHT = 1024;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PerTypeData
|
class PerTypeData
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* STATIC MEMBER VARIABLES */
|
/* STATIC MEMBER VARIABLES */
|
||||||
|
@ -123,6 +140,10 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* STATIC MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
//! logical device used for creation
|
//! logical device used for creation
|
||||||
Handle<SHVkLogicalDevice> logicalDevice;
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
@ -150,24 +171,59 @@ namespace SHADE
|
||||||
//! don't do anything.
|
//! don't do anything.
|
||||||
//uint32_t numLightComponents;
|
//uint32_t numLightComponents;
|
||||||
|
|
||||||
|
//! Handle to sampler that all shadow map descriptors will use
|
||||||
|
Handle<SHVkSampler> shadowMapSampler;
|
||||||
|
|
||||||
|
//! For indexing shadow maps
|
||||||
|
std::unordered_map<EntityID, uint32_t> shadowMapIndexing;
|
||||||
|
|
||||||
|
//! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> shadowMaps;
|
||||||
|
|
||||||
|
//! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array.
|
||||||
|
//! It will also be preallocated.
|
||||||
|
//Handle<SHVkDescriptorSetGroup> shadowMapDescriptorSet;
|
||||||
|
|
||||||
|
//! Combined image samplers for the texture descriptors
|
||||||
|
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> shadowMapImageSamplers;
|
||||||
|
|
||||||
|
//! Barriers required to transition the resources from whatever layout they are in (probably from VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||||
|
//! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||||
|
std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers;
|
||||||
|
|
||||||
|
//! Resource hub from Graphics System
|
||||||
|
SHResourceHub* resourceHub;
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void UpdateDescSet (uint32_t binding) noexcept;
|
void UpdateDescSet (uint32_t binding) noexcept;
|
||||||
void ComputeDynamicOffsets (void) noexcept;
|
void ComputeDynamicOffsets (void) noexcept;
|
||||||
void ResetNumLights (void) noexcept;
|
void ResetNumLights (void) noexcept;
|
||||||
|
void UpdateShadowMapDesc (void) noexcept;
|
||||||
|
SHMatrix GetViewMatrix (SHLightComponent* lightComp) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept;
|
||||||
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
||||||
void Exit (void) noexcept;
|
void Exit (void) noexcept;
|
||||||
|
|
||||||
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
||||||
|
uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept;
|
||||||
|
void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||||
|
//void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept;
|
||||||
|
//void RemoveShadowMap (uint32_t index) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& GetViewSamplerLayout (uint32_t index) const noexcept;
|
||||||
|
uint32_t GetNumShadowMaps (void) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace SHADE
|
||||||
SHMeshAsset SHPrimitiveGenerator::sphereMesh;
|
SHMeshAsset SHPrimitiveGenerator::sphereMesh;
|
||||||
SHMeshAsset SHPrimitiveGenerator::lineCubeMesh;
|
SHMeshAsset SHPrimitiveGenerator::lineCubeMesh;
|
||||||
SHMeshAsset SHPrimitiveGenerator::lineCircleMesh;
|
SHMeshAsset SHPrimitiveGenerator::lineCircleMesh;
|
||||||
|
SHMeshAsset SHPrimitiveGenerator::lineCapsuleCapMesh;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Primitive Generation Functions */
|
/* Primitive Generation Functions */
|
||||||
|
@ -392,6 +393,64 @@ namespace SHADE
|
||||||
return addMeshDataTo(lineCircleMesh, gfxSystem);
|
return addMeshDataTo(lineCircleMesh, gfxSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHMeshAsset SHPrimitiveGenerator::LineCapsuleCap() noexcept
|
||||||
|
{
|
||||||
|
SHMeshAsset mesh;
|
||||||
|
|
||||||
|
// Have multiple semi-circles for the cap
|
||||||
|
static constexpr int SPLITS = 36;
|
||||||
|
static constexpr float ANGLE_INCREMENTS = (std::numbers::pi_v<float> * 2.0f) / static_cast<float>(SPLITS);
|
||||||
|
|
||||||
|
/* X-Axis */
|
||||||
|
// Generate points of the circle
|
||||||
|
for (int i = 0; i <= SPLITS / 2; ++i)
|
||||||
|
{
|
||||||
|
const float ANGLE = ANGLE_INCREMENTS * i;
|
||||||
|
mesh.VertexPositions.emplace_back(cos(ANGLE) * 0.5f, sin(ANGLE) * 0.5f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate lines of the circle
|
||||||
|
for (int i = 1; i <= SPLITS / 2; ++i)
|
||||||
|
{
|
||||||
|
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
|
||||||
|
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Z-Axis */
|
||||||
|
// Generate points of the circle
|
||||||
|
for (int i = 0; i <= SPLITS / 2; ++i)
|
||||||
|
{
|
||||||
|
const float ANGLE = ANGLE_INCREMENTS * i;
|
||||||
|
mesh.VertexPositions.emplace_back(0.0f, sin(ANGLE) * 0.5f, cos(ANGLE) * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate lines of the circle
|
||||||
|
for (int i = 2 + SPLITS / 2; i <= SPLITS + 1; ++i)
|
||||||
|
{
|
||||||
|
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
|
||||||
|
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh.VertexNormals.resize(mesh.VertexPositions.size());
|
||||||
|
mesh.VertexTangents.resize(mesh.VertexPositions.size());
|
||||||
|
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
Handle<SHADE::SHMesh> SHPrimitiveGenerator::LineCapsuleCap(SHMeshLibrary& meshLibrary) noexcept
|
||||||
|
{
|
||||||
|
if (lineCapsuleCapMesh.VertexPositions.empty())
|
||||||
|
lineCapsuleCapMesh = LineCapsuleCap();
|
||||||
|
|
||||||
|
return addMeshDataTo(lineCapsuleCapMesh, meshLibrary);
|
||||||
|
}
|
||||||
|
Handle<SHADE::SHMesh> SHPrimitiveGenerator::LineCapsuleCap(SHGraphicsSystem& gfxSystem) noexcept
|
||||||
|
{
|
||||||
|
if (lineCapsuleCapMesh.VertexPositions.empty())
|
||||||
|
lineCapsuleCapMesh = LineCapsuleCap();
|
||||||
|
|
||||||
|
return addMeshDataTo(lineCapsuleCapMesh, gfxSystem);
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -195,6 +195,46 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
[[nodiscard]] static Handle<SHMesh> LineCircle(SHGraphicsSystem& gfxSystem) noexcept;
|
[[nodiscard]] static Handle<SHMesh> LineCircle(SHGraphicsSystem& gfxSystem) noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a cap of a wireframe capsule that is comprised only of lines and
|
||||||
|
store the data in a SHMeshData object.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMeshData object containing vertex data for the line circle.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static SHMeshAsset LineCapsuleCap() noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a cap of a wireframe capsule that is comprised only of lines and
|
||||||
|
constructs a SHMesh using the SHGraphicsSystem provided.
|
||||||
|
|
||||||
|
\param meshLibrary
|
||||||
|
Reference to the SHMeshLibrary to produce and store a line circle mesh in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMesh object that points to the generated line circle mesh in the SHMeshLibrary.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static Handle<SHMesh> LineCapsuleCap(SHMeshLibrary& meshLibrary) noexcept;
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Produces a cap of a wireframe capsule that is comprised only of lines and
|
||||||
|
constructs a SHMesh using the SHGraphicsSystem provided.
|
||||||
|
|
||||||
|
\param gfxSystem
|
||||||
|
Reference to the SHGraphicsSystem to produce and store a line circle mesh in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
SHMesh object that points to the generated line circle mesh in the
|
||||||
|
SHGraphicsSystem.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
[[nodiscard]] static Handle<SHMesh> LineCapsuleCap(SHGraphicsSystem& gfxSystem) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -210,5 +250,6 @@ namespace SHADE
|
||||||
static SHMeshAsset sphereMesh;
|
static SHMeshAsset sphereMesh;
|
||||||
static SHMeshAsset lineCubeMesh;
|
static SHMeshAsset lineCubeMesh;
|
||||||
static SHMeshAsset lineCircleMesh;
|
static SHMeshAsset lineCircleMesh;
|
||||||
|
static SHMeshAsset lineCapsuleCapMesh;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,15 +1,20 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHPipelineLibrary.h"
|
#include "SHPipelineLibrary.h"
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
|
||||||
#include "Graphics/RenderGraph/SHSubpass.h"
|
#include "Graphics/RenderGraph/SHSubpass.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHGraphicsPredefinedData::SystemType systemType) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHGraphicsPredefinedData::SystemType systemType, SHVertexInputState const& viState, SHRasterizationState const& rasterState) noexcept
|
||||||
{
|
{
|
||||||
|
std::vector<Handle<SHVkShaderModule>> modules{};
|
||||||
|
if (vsFsPair.first)
|
||||||
|
modules.push_back(vsFsPair.first);
|
||||||
|
if (vsFsPair.second)
|
||||||
|
modules.push_back(vsFsPair.second);
|
||||||
|
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
||||||
|
@ -21,7 +26,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Create the pipeline and configure the default vertex input state
|
// Create the pipeline and configure the default vertex input state
|
||||||
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
||||||
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState());
|
newPipeline->GetPipelineState().SetVertexInputState(viState);
|
||||||
|
|
||||||
SHColorBlendState colorBlendState{};
|
SHColorBlendState colorBlendState{};
|
||||||
colorBlendState.logic_op_enable = VK_FALSE;
|
colorBlendState.logic_op_enable = VK_FALSE;
|
||||||
|
@ -30,6 +35,7 @@ namespace SHADE
|
||||||
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
||||||
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||||
|
|
||||||
|
|
||||||
for (auto& att : subpassColorReferences)
|
for (auto& att : subpassColorReferences)
|
||||||
{
|
{
|
||||||
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||||
|
@ -48,6 +54,8 @@ namespace SHADE
|
||||||
|
|
||||||
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
||||||
|
|
||||||
|
newPipeline->GetPipelineState().SetRasterizationState(rasterState);
|
||||||
|
|
||||||
// Actually construct the pipeline
|
// Actually construct the pipeline
|
||||||
newPipeline->ConstructPipeline();
|
newPipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,9 @@ namespace SHADE
|
||||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||||
Handle<SHVkRenderpass> renderpass,
|
Handle<SHVkRenderpass> renderpass,
|
||||||
Handle<SHSubpass> subpass,
|
Handle<SHSubpass> subpass,
|
||||||
SHGraphicsPredefinedData::SystemType systemType
|
SHGraphicsPredefinedData::SystemType systemType,
|
||||||
|
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState(),
|
||||||
|
SHRasterizationState const& rasterState = SHRasterizationState{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
|
|
|
@ -195,7 +195,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept
|
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding /*= static_cast<uint32_t>(-1)*/, uint32_t fixedAttributeLocation/* = static_cast<uint32_t>(-1)*/) noexcept
|
||||||
{
|
{
|
||||||
// add a binding and get ref to it
|
// add a binding and get ref to it
|
||||||
bindings.emplace_back();
|
bindings.emplace_back();
|
||||||
|
@ -210,7 +210,7 @@ namespace SHADE
|
||||||
// Offset is 0 at first (for first element)
|
// Offset is 0 at first (for first element)
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
binding.binding = static_cast<uint32_t>(bindings.size() - 1);
|
binding.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
// for every attribute passed in
|
// for every attribute passed in
|
||||||
for (auto const& attrib : inAttribs)
|
for (auto const& attrib : inAttribs)
|
||||||
|
@ -226,10 +226,11 @@ namespace SHADE
|
||||||
auto& vertexAttrib = attributes.back();
|
auto& vertexAttrib = attributes.back();
|
||||||
|
|
||||||
// The binding for that attribute description is index of the new binding created earlier in this function
|
// The binding for that attribute description is index of the new binding created earlier in this function
|
||||||
vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1);
|
vertexAttrib.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
// Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
||||||
vertexAttrib.location = static_cast<uint32_t>(attributes.size () - 1);
|
vertexAttrib.location = (fixedAttributeLocation != static_cast<uint32_t>(-1)) ? fixedAttributeLocation + i : static_cast<uint32_t>(attributes.size () - 1);
|
||||||
|
//vertexAttrib.location = static_cast<uint32_t>(attributes.size() - 1);
|
||||||
|
|
||||||
// Get the vkFormat associated with the SHAttribFormat
|
// Get the vkFormat associated with the SHAttribFormat
|
||||||
vertexAttrib.format = format;
|
vertexAttrib.format = format;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SHADE
|
||||||
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
||||||
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
||||||
|
|
||||||
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept;
|
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding = static_cast<uint32_t>(-1), uint32_t fixedAttributeLocation = static_cast<uint32_t>(-1)) noexcept;
|
||||||
|
|
||||||
friend class SHVkPipelineState;
|
friend class SHVkPipelineState;
|
||||||
friend class SHVkPipeline;
|
friend class SHVkPipeline;
|
||||||
|
|
|
@ -18,6 +18,8 @@ namespace SHADE
|
||||||
vk::ShaderStageFlags stageFlags;
|
vk::ShaderStageFlags stageFlags;
|
||||||
|
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
|
{
|
||||||
|
if (shaderModule)
|
||||||
{
|
{
|
||||||
// References for convenience
|
// References for convenience
|
||||||
auto const& reflectedData = shaderModule->GetReflectedData();
|
auto const& reflectedData = shaderModule->GetReflectedData();
|
||||||
|
@ -81,7 +83,7 @@ namespace SHADE
|
||||||
|
|
||||||
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
||||||
|
@ -132,6 +134,9 @@ namespace SHADE
|
||||||
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
|
if (!shaderModule)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
||||||
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
||||||
|
|
||||||
|
@ -200,11 +205,13 @@ namespace SHADE
|
||||||
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
||||||
|
|
||||||
// Set the flags for variable bindings
|
// Set the flags for variable bindings
|
||||||
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount;
|
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount | vk::DescriptorBindingFlagBits::ePartiallyBound;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
||||||
}
|
}
|
||||||
|
@ -326,11 +333,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
{
|
{
|
||||||
mod->AddCallback([this]()
|
if (mod)
|
||||||
{
|
{
|
||||||
RecreateIfNeeded();
|
mod->AddCallback([this]() { RecreateIfNeeded(); });
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecreateIfNeeded ();
|
RecreateIfNeeded ();
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_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 SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, bool resizeWithWindow, 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 /*= {}*/)
|
||||||
{
|
{
|
||||||
// If we set to
|
// If we set to
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
|
@ -64,7 +64,7 @@ namespace SHADE
|
||||||
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
|
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags, resizeWithWindow);
|
||||||
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,9 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& affectedNode : affectedNodes)
|
for (auto& affectedNode : affectedNodes)
|
||||||
nodes[affectedNode]->CreateFramebuffer();
|
nodes[affectedNode]->CreateFramebuffer();
|
||||||
|
|
||||||
|
renderGraphStorage->graphResources->at(resourceName).Free();
|
||||||
|
renderGraphStorage->graphResources->erase (resourceName);
|
||||||
/*
|
/*
|
||||||
* IMPORTANT NOTES
|
* IMPORTANT NOTES
|
||||||
*
|
*
|
||||||
|
@ -166,68 +169,7 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is final layout.
|
node->StandaloneConfigureAttDesc(i == nodes.size() - 1);
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
|
||||||
if (node->subpasses.empty())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
|
||||||
auto const resources = node->GetResources();
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, vk::ImageLayout::eUndefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to get all final layouts for all resources
|
|
||||||
for (auto& subpass : node->subpasses)
|
|
||||||
{
|
|
||||||
for (auto& color : subpass->colorReferences)
|
|
||||||
{
|
|
||||||
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
|
||||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
|
||||||
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
|
||||||
else
|
|
||||||
resourceAttFinalLayouts[color.attachment] = color.layout;
|
|
||||||
|
|
||||||
node->attResources[color.attachment]->infoTracker->TrackLayout(node, subpass, color.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& depth : subpass->depthReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
|
||||||
node->attResources[depth.attachment]->infoTracker->TrackLayout(node, subpass, depth.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& input : subpass->inputReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[input.attachment] = input.layout;
|
|
||||||
node->attResources[input.attachment]->infoTracker->TrackLayout(node, subpass, input.layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
|
||||||
{
|
|
||||||
auto& att = node->attachmentDescriptions[j];
|
|
||||||
auto& resource = node->attResources[j];
|
|
||||||
|
|
||||||
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
|
||||||
// We also want to load the attachment, not "don't care".
|
|
||||||
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
|
||||||
renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
|
||||||
{
|
|
||||||
att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw);
|
|
||||||
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
|
||||||
|
|
||||||
att.finalLayout = resourceAttFinalLayouts[j];
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, att.finalLayout);
|
|
||||||
}
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +275,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraph::ReindexNodes(void) noexcept
|
||||||
|
{
|
||||||
|
nodeIndexing.clear();
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
nodeIndexing.emplace (node->name, i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -473,6 +426,65 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function is purely used for dynamic nodes (if such a thing were to
|
||||||
|
exist in our architecture). In other words, don't use this function unless
|
||||||
|
the new node is fully standalone and does not rely or is a prereq of
|
||||||
|
other nodes.
|
||||||
|
|
||||||
|
\param nodeName
|
||||||
|
Name of new node
|
||||||
|
|
||||||
|
\param resourceInstruction
|
||||||
|
Resources for the node
|
||||||
|
|
||||||
|
\param nodeToAddAfter
|
||||||
|
The node to add the new node after.
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHRenderGraphNode> SHRenderGraph::AddNodeAfter(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::string nodeToAddAfter) noexcept
|
||||||
|
{
|
||||||
|
if (nodeIndexing.contains(nodeName))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Node already exists, cannot add node. ");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHAttachmentDescInitParams> descInitParams;
|
||||||
|
for (auto const& instruction : resourceInstruction)
|
||||||
|
{
|
||||||
|
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
||||||
|
if (renderGraphStorage->graphResources->contains(instruction.resourceName))
|
||||||
|
{
|
||||||
|
descInitParams.push_back(
|
||||||
|
{
|
||||||
|
.resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName),
|
||||||
|
.dontClearOnLoad = instruction.dontClearOnLoad,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get target node
|
||||||
|
auto targetNode = nodes.begin() + nodeIndexing.at(nodeToAddAfter);
|
||||||
|
|
||||||
|
auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::vector<Handle<SHRenderGraphNode>>()));
|
||||||
|
ReindexNodes ();
|
||||||
|
return *node;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
||||||
{
|
{
|
||||||
for (auto& node : predecessorNodes)
|
for (auto& node : predecessorNodes)
|
||||||
|
@ -532,10 +544,6 @@ namespace SHADE
|
||||||
ConfigureSubSystems();
|
ConfigureSubSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraph::Regenerate(void) noexcept
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -571,12 +579,15 @@ namespace SHADE
|
||||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
if (node->renderpass)
|
||||||
{
|
{
|
||||||
// bind static global data
|
// bind static global data
|
||||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
||||||
|
|
||||||
node->Execute(cmdBuffer, descPool, frameIndex);
|
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
}
|
}
|
||||||
|
@ -604,10 +615,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// resize resources
|
// resize resources
|
||||||
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
||||||
|
{
|
||||||
|
if (resource->resizeWithWindow)
|
||||||
{
|
{
|
||||||
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
||||||
resource->HandleResize(newWidth, newHeight);
|
resource->HandleResize(newWidth, newHeight);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace SHADE
|
||||||
void ConfigureRenderpasses (void) noexcept;
|
void ConfigureRenderpasses (void) noexcept;
|
||||||
void ConfigureSubSystems (void) noexcept;
|
void ConfigureSubSystems (void) noexcept;
|
||||||
void ConfigureFramebuffers (void) noexcept;
|
void ConfigureFramebuffers (void) noexcept;
|
||||||
|
void ReindexNodes (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -101,6 +102,7 @@ namespace SHADE
|
||||||
(
|
(
|
||||||
std::string resourceName,
|
std::string resourceName,
|
||||||
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
||||||
|
bool resizeWithWindow = true,
|
||||||
uint32_t w = static_cast<uint32_t>(-1),
|
uint32_t w = static_cast<uint32_t>(-1),
|
||||||
uint32_t h = static_cast<uint32_t>(-1),
|
uint32_t h = static_cast<uint32_t>(-1),
|
||||||
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
||||||
|
@ -123,6 +125,12 @@ namespace SHADE
|
||||||
std::initializer_list<ResourceInstruction> resourceInstruction,
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
std::initializer_list<std::string> predecessorNodes
|
std::initializer_list<std::string> predecessorNodes
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
Handle<SHRenderGraphNode> AddNodeAfter
|
||||||
|
(
|
||||||
|
std::string nodeName,
|
||||||
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
|
std::string nodeToAddAfter
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
void AddRenderToSwapchainNode
|
void AddRenderToSwapchainNode
|
||||||
(
|
(
|
||||||
|
@ -134,7 +142,6 @@ namespace SHADE
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
void Regenerate (void) noexcept;
|
|
||||||
void CheckForNodeComputes (void) noexcept;
|
void CheckForNodeComputes (void) noexcept;
|
||||||
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void Begin (uint32_t frameIndex) noexcept;
|
void Begin (uint32_t frameIndex) noexcept;
|
||||||
|
@ -165,7 +172,14 @@ namespace SHADE
|
||||||
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
||||||
* but different matrices (SHRenderer) can be used in different nodes.
|
* but different matrices (SHRenderer) can be used in different nodes.
|
||||||
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
||||||
* -
|
* - In hindsight there should have been a distinction between static and dynamic nodes. Static nodes are the ones that are accounted
|
||||||
|
* for in the generation of the render graph. Dynamic nodes begin with nothing at first, but allows for linking of resources and subpasses
|
||||||
|
* while the render graph is executing. The resources here should also be dynamic, which means it should never be used in anywhere else other
|
||||||
|
* than in the node that is using it. This would mean its initial layouts are always specified as undefined and final layouts specified as
|
||||||
|
* whatever the last subpass that is using that resource specifies in the node. Dynamic nodes are meant to render to resources that would later
|
||||||
|
* be used externally, as descriptors for example (the descriptors can be used in a render graph node compute for example). Dynamic nodes run as
|
||||||
|
* if they are the only nodes in the graph, because their resources are not used in other nodes and are thus not predecessors or successors of any
|
||||||
|
* other node.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,12 @@ namespace SHADE
|
||||||
renderpass.Free();
|
renderpass.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!spDescs.empty())
|
||||||
|
{
|
||||||
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);
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -45,6 +48,8 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
if (!framebuffers.empty())
|
if (!framebuffers.empty())
|
||||||
{
|
{
|
||||||
|
@ -78,8 +83,11 @@ namespace SHADE
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::HandleResize(void) noexcept
|
void SHRenderGraphNode::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
renderpass->HandleResize();
|
renderpass->HandleResize();
|
||||||
|
|
||||||
|
@ -114,23 +122,32 @@ namespace SHADE
|
||||||
nodeCompute->HandleResize();
|
nodeCompute->HandleResize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
||||||
{
|
{
|
||||||
|
if (subpasses.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t numValidSubpasses = std::count_if(subpasses.begin(), subpasses.end(), [](Handle<SHSubpass> subpass) {return !subpass->HasNoAttachments();});
|
||||||
|
|
||||||
// Create subpass description and dependencies based on number of subpasses
|
// Create subpass description and dependencies based on number of subpasses
|
||||||
spDescs.resize(subpasses.size());
|
spDescs.resize(numValidSubpasses);
|
||||||
spDeps.resize(subpasses.size());
|
spDeps.resize(numValidSubpasses);
|
||||||
|
|
||||||
// Now we want to loop through all attachments in all subpasses in the node and query
|
// Now we want to loop through all attachments in all subpasses in the node and query
|
||||||
// the resources being used. For each resource we want to query the type and record it
|
// the resources being used. For each resource we want to query the type and record it
|
||||||
// in bit fields (1 bit for each subpass).
|
// in bit fields (1 bit for each subpass).
|
||||||
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
// For all subpasses (see above description about bit field for this).
|
// For all subpasses (see above description about bit field for this).
|
||||||
for (auto& subpass : subpasses)
|
for (uint32_t i = 0; auto& subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
// skip if subpass is not valid
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Configure subpass description
|
// Configure subpass description
|
||||||
auto& desc = spDescs[i];
|
auto& desc = spDescs[i];
|
||||||
desc.pColorAttachments = subpass->colorReferences.data();
|
desc.pColorAttachments = subpass->colorReferences.data();
|
||||||
|
@ -186,8 +203,11 @@ namespace SHADE
|
||||||
|
|
||||||
// Loop through all subpasses again but this time we use the bit field to initialize
|
// Loop through all subpasses again but this time we use the bit field to initialize
|
||||||
// the dependencies.
|
// the dependencies.
|
||||||
for (i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; auto & subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
vk::PipelineStageFlags srcStage;
|
vk::PipelineStageFlags srcStage;
|
||||||
vk::PipelineStageFlags dstStage;
|
vk::PipelineStageFlags dstStage;
|
||||||
vk::AccessFlags srcAccess;
|
vk::AccessFlags srcAccess;
|
||||||
|
@ -245,6 +265,8 @@ namespace SHADE
|
||||||
|
|
||||||
// initialize input descriptors
|
// initialize input descriptors
|
||||||
subpasses[i]->CreateInputDescriptors();
|
subpasses[i]->CreateInputDescriptors();
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +365,7 @@ namespace SHADE
|
||||||
, 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) }
|
, name { std::move(rhs.name) }
|
||||||
|
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -419,7 +442,7 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, uint32_t variableDescCount/* = 0*/, 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{};
|
||||||
|
@ -435,7 +458,7 @@ namespace SHADE
|
||||||
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
||||||
|
|
||||||
// Create the subpass compute with the resources
|
// Create the subpass compute with the resources
|
||||||
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty(), variableDescCount);
|
||||||
nodeComputes.push_back(nodeCompute);
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
for (auto& resource : temp)
|
for (auto& resource : temp)
|
||||||
|
@ -483,6 +506,68 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::StandaloneConfigureAttDesc(bool isLastNode) noexcept
|
||||||
|
{
|
||||||
|
// key is handle ID, value is final layout.
|
||||||
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
||||||
|
if (!subpasses.empty())
|
||||||
|
{
|
||||||
|
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
||||||
|
for (auto& resource : attResources)
|
||||||
|
{
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, vk::ImageLayout::eUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to get all final layouts for all resources
|
||||||
|
for (auto& subpass : subpasses)
|
||||||
|
{
|
||||||
|
for (auto& color : subpass->colorReferences)
|
||||||
|
{
|
||||||
|
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
||||||
|
if (isLastNode && (attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
||||||
|
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
|
else
|
||||||
|
resourceAttFinalLayouts[color.attachment] = color.layout;
|
||||||
|
|
||||||
|
attResources[color.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, color.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& depth : subpass->depthReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
||||||
|
attResources[depth.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, depth.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& input : subpass->inputReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[input.attachment] = input.layout;
|
||||||
|
attResources[input.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, input.layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachmentDescriptions.size(); ++j)
|
||||||
|
{
|
||||||
|
auto& att = attachmentDescriptions[j];
|
||||||
|
auto& resource = attResources[j];
|
||||||
|
|
||||||
|
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
||||||
|
// We also want to load the attachment, not "don't care".
|
||||||
|
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
||||||
|
graphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
||||||
|
{
|
||||||
|
att.initialLayout = graphStorage->nonOwningResourceInitialLayouts.at(resource.GetId().Raw);
|
||||||
|
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
|
||||||
|
att.finalLayout = resourceAttFinalLayouts[j];
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, att.finalLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -509,14 +594,14 @@ namespace SHADE
|
||||||
// remove attachment reference
|
// remove attachment reference
|
||||||
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
||||||
|
|
||||||
|
// erase from mapping as well
|
||||||
|
resourceAttachmentMapping->erase(resourceHandleID);
|
||||||
|
|
||||||
// Remove footprint of attachment from all subpasses as well
|
// Remove footprint of attachment from all subpasses as well
|
||||||
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
||||||
{
|
{
|
||||||
// attempt to detach resource from subpass
|
// If the subpass uses the resource, just remove the subpass since the subpass will be invalid
|
||||||
(*it)->DetachResource(resourceName, index);
|
if ((*it)->UsesResource(index))
|
||||||
|
|
||||||
// If the subpass ends up having no attachments after, erase it from the node
|
|
||||||
if ((*it)->HasNoAttachments())
|
|
||||||
{
|
{
|
||||||
// erase from indexing
|
// erase from indexing
|
||||||
subpassIndexing.erase((*it)->GetName());
|
subpassIndexing.erase((*it)->GetName());
|
||||||
|
@ -530,12 +615,32 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
subpasses[i]->SetIndex(i);
|
subpasses[i]->SetIndex(i);
|
||||||
|
|
||||||
|
// remove node computes using the resource
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->UsesResource(resourceHandleID))
|
||||||
|
{
|
||||||
|
it = nodeComputes.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recompute the barriers for the other computes
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it == nodeComputes.begin())
|
||||||
|
(*it)->SetFollowingEndRenderpass(true);
|
||||||
|
|
||||||
|
(*it)->InitializeBarriers();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
if (renderpass)
|
||||||
{
|
{
|
||||||
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
||||||
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
|
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
|
||||||
|
@ -545,7 +650,7 @@ namespace SHADE
|
||||||
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
||||||
|
|
||||||
// Go to next subpass if not last subpass
|
// Go to next subpass if not last subpass
|
||||||
if (i != static_cast<uint32_t>(subpasses.size()) - 1u)
|
if (i != static_cast<uint32_t>(subpasses.size()) - 1u && !subpasses[i]->HasNoAttachments())
|
||||||
commandBuffer->NextSubpass();
|
commandBuffer->NextSubpass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,6 +674,7 @@ namespace SHADE
|
||||||
for (auto& sbCompute : nodeComputes)
|
for (auto& sbCompute : nodeComputes)
|
||||||
sbCompute->Execute(commandBuffer, frameIndex);
|
sbCompute->Execute(commandBuffer, frameIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
||||||
{
|
{
|
||||||
|
@ -625,6 +731,77 @@ namespace SHADE
|
||||||
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function simply appends to the container of VkAttachmentDescription
|
||||||
|
and attResources. It will assume the resource is used standalone in the
|
||||||
|
node and will not account for its usage in other nodes. As such its
|
||||||
|
initialLayout will always be UNDEFINED and its finalLayout will be
|
||||||
|
whatever is calculated if the node is regenerated using
|
||||||
|
StandaloneRegnerate. This function also does not affect the render graph
|
||||||
|
while its running since the 2 containers above have already been copied
|
||||||
|
to the GPU.
|
||||||
|
|
||||||
|
\param resourceName
|
||||||
|
The name of the resource for getting the resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeLinkResource(std::string resourceName) noexcept
|
||||||
|
{
|
||||||
|
// Get new resource
|
||||||
|
Handle<SHRenderGraphResource> newResource = graphStorage->graphResources->at(resourceName);
|
||||||
|
|
||||||
|
// append new resource to container
|
||||||
|
attResources.push_back(newResource);
|
||||||
|
|
||||||
|
attachmentDescriptions.push_back(vk::AttachmentDescription
|
||||||
|
{
|
||||||
|
.format = newResource->GetResourceFormat(),
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
.stencilLoadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.stencilStoreOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceAttachmentMapping->try_emplace(newResource.GetId().Raw, attachmentDescriptions.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHSubpass> SHRenderGraphNode::RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept
|
||||||
|
{
|
||||||
|
return AddSubpass(std::move (subpassName), viewport, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
USE WITH CAUTION because the function does not reevaluate resource
|
||||||
|
layouts in attachment descriptions. All resources here will start at
|
||||||
|
UNDEFINED and end at whatever the last subpass using the attachment
|
||||||
|
specifies. It will also not support render graph node computes given its
|
||||||
|
complexity if it has to be accounted for.
|
||||||
|
|
||||||
|
IN SHORT, IT GENERATES A RENDERPASS AS IF ITS THE ONLY NODE
|
||||||
|
IN THE RENDER GRAPH. SEE NOTES IN SHRenderGraph.h
|
||||||
|
|
||||||
|
This function is mainly meant for nodes that are dynamic (in hindsight,
|
||||||
|
there really should have been a distinction between static and dynamic
|
||||||
|
nodes).
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeStandaloneRegenerate(void) noexcept
|
||||||
|
{
|
||||||
|
StandaloneConfigureAttDesc(false);
|
||||||
|
ConfigureSubpasses();
|
||||||
|
CreateRenderpass();
|
||||||
|
CreateFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -659,4 +836,15 @@ namespace SHADE
|
||||||
return attResources;
|
return attResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::GetNodeCompute(std::string nodeComputeName) const noexcept
|
||||||
|
{
|
||||||
|
for (auto nc : nodeComputes)
|
||||||
|
{
|
||||||
|
if (nc->name == nodeComputeName)
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -93,6 +93,9 @@ namespace SHADE
|
||||||
void CreateFramebuffer(void) noexcept;
|
void CreateFramebuffer(void) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
void ConfigureSubpasses (void) noexcept;
|
void ConfigureSubpasses (void) noexcept;
|
||||||
|
bool DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
||||||
|
void AddDummySubpassIfNeeded(void) noexcept;
|
||||||
|
void StandaloneConfigureAttDesc (bool isLastNode) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -106,15 +109,17 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) 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;
|
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
void AddDummySubpassIfNeeded (void) noexcept;
|
|
||||||
bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
|
||||||
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
||||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
|
||||||
|
// Runtime functions that don't affect the renderpass
|
||||||
|
void RuntimeLinkResource(std::string resourceName) noexcept;
|
||||||
|
Handle<SHSubpass> RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
||||||
|
void RuntimeStandaloneRegenerate (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -122,6 +127,7 @@ namespace SHADE
|
||||||
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
||||||
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
||||||
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
||||||
|
Handle<SHRenderGraphNodeCompute> GetNodeCompute (std::string nodeComputeName) const noexcept;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,56 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
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
|
|
||||||
|
bool SHRenderGraphNodeCompute::UsesResource(uint64_t resourceHandleID) const noexcept
|
||||||
|
{
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
if (resource.GetId().Raw == resourceHandleID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::InitializeBarriers(void) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; auto & barriers : memoryBarriers)
|
||||||
|
{
|
||||||
|
barriers.clear();
|
||||||
|
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
||||||
|
barriers.push_back(vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = srcAccessMask,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = resource->imageAspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = resource->mipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::SetFollowingEndRenderpass(uint32_t flag) noexcept
|
||||||
|
{
|
||||||
|
followingEndRenderpass = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
: computePipeline{}
|
: computePipeline{}
|
||||||
, pipelineLayout{}
|
, pipelineLayout{}
|
||||||
, resources{}
|
, resources{}
|
||||||
|
@ -68,10 +117,12 @@ namespace SHADE
|
||||||
// check if all layouts are there
|
// check if all layouts are there
|
||||||
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
||||||
{
|
{
|
||||||
|
Handle<SHVkDescriptorSetLayout> computeResourceLayout = {};
|
||||||
|
computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
||||||
|
|
||||||
// create compute resources
|
// create compute resources
|
||||||
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
||||||
auto computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, {variableDescCount});
|
||||||
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
for (auto set : computeResource->descSet->GetVkHandle())
|
for (auto set : computeResource->descSet->GetVkHandle())
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
||||||
|
@ -91,6 +142,11 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
|
for (auto& fn : preComputeFunctions)
|
||||||
|
{
|
||||||
|
fn (cmdBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// bind the compute pipeline
|
// bind the compute pipeline
|
||||||
cmdBuffer->BindPipeline(computePipeline);
|
cmdBuffer->BindPipeline(computePipeline);
|
||||||
|
|
||||||
|
@ -157,35 +213,7 @@ namespace SHADE
|
||||||
groupSizeX = maxWidth / workGroupSizeX;
|
groupSizeX = maxWidth / workGroupSizeX;
|
||||||
groupSizeY = maxHeight / workGroupSizeY;
|
groupSizeY = maxHeight / workGroupSizeY;
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& barriers : memoryBarriers)
|
InitializeBarriers();
|
||||||
{
|
|
||||||
barriers.clear();
|
|
||||||
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
|
||||||
barriers.push_back(vk::ImageMemoryBarrier
|
|
||||||
{
|
|
||||||
.srcAccessMask = srcAccessMask,
|
|
||||||
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
|
||||||
.oldLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
|
||||||
.subresourceRange = vk::ImageSubresourceRange
|
|
||||||
{
|
|
||||||
.aspectMask = resource->imageAspectFlags,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = resource->mipLevels,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
||||||
|
@ -219,4 +247,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
|
||||||
|
computeResource->descSet->ModifyWriteDescImage(COMPUTE_RESOURCE_SET_INDEX, binding, viewSamplerLayout, descArrayIndex);
|
||||||
|
computeResource->descSet->UpdateDescriptorSetImage(COMPUTE_RESOURCE_SET_INDEX, binding, descArrayIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::AddPreComputeFunction(PreComputeFunction const& fn) noexcept
|
||||||
|
{
|
||||||
|
preComputeFunctions.push_back(fn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace SHADE
|
||||||
|
|
||||||
class SHRenderGraphNodeCompute
|
class SHRenderGraphNodeCompute
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using PreComputeFunction = std::function<void(Handle<SHVkCommandBuffer>, uint32_t)>;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
||||||
struct ComputeResource
|
struct ComputeResource
|
||||||
|
@ -73,8 +77,23 @@ namespace SHADE
|
||||||
//! Name of this node
|
//! Name of this node
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<PreComputeFunction> preComputeFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource (uint64_t resourceHandleID) const noexcept;
|
||||||
|
void InitializeBarriers (void) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetFollowingEndRenderpass (uint32_t flag) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
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;
|
SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, 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;
|
||||||
|
@ -84,7 +103,9 @@ namespace SHADE
|
||||||
|
|
||||||
void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||||
|
void ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept;
|
||||||
|
|
||||||
|
void AddPreComputeFunction (PreComputeFunction const& fn) noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept
|
||||||
: graphStorage{renderGraphStorage}
|
: graphStorage{renderGraphStorage}
|
||||||
, resourceTypeFlags{ }
|
, resourceTypeFlags{ }
|
||||||
, resourceFormat{ format }
|
, resourceFormat{ format }
|
||||||
|
@ -88,6 +88,7 @@ namespace SHADE
|
||||||
, height{ h }
|
, height{ h }
|
||||||
, mipLevels{ levels }
|
, mipLevels{ levels }
|
||||||
, resourceName{ name }
|
, resourceName{ name }
|
||||||
|
, resizeWithWindow { inResizeWithWindow }
|
||||||
{
|
{
|
||||||
// If the resource type is an arbitrary image and not swapchain image
|
// If the resource type is an arbitrary image and not swapchain image
|
||||||
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
||||||
|
@ -210,6 +211,7 @@ namespace SHADE
|
||||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||||
, graphStorage{rhs.graphStorage}
|
, graphStorage{rhs.graphStorage}
|
||||||
, infoTracker {std::move (rhs.infoTracker)}
|
, infoTracker {std::move (rhs.infoTracker)}
|
||||||
|
, resizeWithWindow{rhs.resizeWithWindow}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -242,7 +244,8 @@ namespace SHADE
|
||||||
mipLevels = rhs.mipLevels;
|
mipLevels = rhs.mipLevels;
|
||||||
imageAspectFlags = rhs.imageAspectFlags;
|
imageAspectFlags = rhs.imageAspectFlags;
|
||||||
graphStorage = rhs.graphStorage;
|
graphStorage = rhs.graphStorage;
|
||||||
infoTracker = std::move(infoTracker);
|
infoTracker = std::move(rhs.infoTracker);
|
||||||
|
resizeWithWindow = rhs.resizeWithWindow;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,11 +96,14 @@ namespace SHADE
|
||||||
//! For tracking resource states in stages of the render graphs
|
//! For tracking resource states in stages of the render graphs
|
||||||
Handle<InfoTracker> infoTracker;
|
Handle<InfoTracker> infoTracker;
|
||||||
|
|
||||||
|
//! Whether or not to resize (recreate vulkan image) when window resizes
|
||||||
|
bool resizeWithWindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept;
|
||||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
~SHRenderGraphResource(void) noexcept;
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace SHADE
|
||||||
, name { rhs.name }
|
, name { rhs.name }
|
||||||
, viewport {rhs.viewport}
|
, viewport {rhs.viewport}
|
||||||
, renderer {rhs.renderer}
|
, renderer {rhs.renderer}
|
||||||
|
, companionSubpass {rhs.companionSubpass}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -113,6 +114,7 @@ namespace SHADE
|
||||||
name = std::move(rhs.name);
|
name = std::move(rhs.name);
|
||||||
renderer = rhs.renderer;
|
renderer = rhs.renderer;
|
||||||
viewport = rhs.viewport;
|
viewport = rhs.viewport;
|
||||||
|
companionSubpass = rhs.companionSubpass;
|
||||||
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -162,7 +164,7 @@ namespace SHADE
|
||||||
switch (attachmentDescriptionType)
|
switch (attachmentDescriptionType)
|
||||||
{
|
{
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
||||||
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||||
break;
|
break;
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
||||||
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
||||||
|
@ -211,6 +213,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
commandBuffer->BeginLabeledSegment(name);
|
commandBuffer->BeginLabeledSegment(name);
|
||||||
|
|
||||||
|
if (!HasNoAttachments())
|
||||||
|
{
|
||||||
// Ensure correct transforms are provided
|
// Ensure correct transforms are provided
|
||||||
superBatch->UpdateBuffers(frameIndex, descPool);
|
superBatch->UpdateBuffers(frameIndex, descPool);
|
||||||
|
|
||||||
|
@ -227,8 +231,19 @@ namespace SHADE
|
||||||
if (renderer)
|
if (renderer)
|
||||||
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
||||||
|
|
||||||
|
// If companion subpass is not a valid handle, render super batch normally
|
||||||
|
if (!companionSubpass.companion)
|
||||||
|
{
|
||||||
// Draw all the batches
|
// Draw all the batches
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if not bind pipeline for companion and and execute draw command
|
||||||
|
commandBuffer->BindPipeline(companionSubpass.pipeline);
|
||||||
|
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw all the exterior draw calls
|
// Draw all the exterior draw calls
|
||||||
for (auto& drawCall : exteriorDrawCalls)
|
for (auto& drawCall : exteriorDrawCalls)
|
||||||
|
@ -265,43 +280,27 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept
|
bool SHSubpass::UsesResource(uint32_t attachmentIndex) noexcept
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (colorReferences[i].attachment == attachmentIndex)
|
if (colorReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
colorReferences.erase (colorReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (depthReferences[i].attachment == attachmentIndex)
|
if (depthReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
depthReferences.erase(depthReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (inputReferences[i].attachment == attachmentIndex)
|
if (inputReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
inputReferences.erase(inputReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputNames.size(); ++i)
|
return false;
|
||||||
{
|
|
||||||
if (inputNames[i] == resourceName)
|
|
||||||
{
|
|
||||||
inputNames.erase(inputNames.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSubpass::HasNoAttachments(void) const noexcept
|
bool SHSubpass::HasNoAttachments(void) const noexcept
|
||||||
|
@ -458,6 +457,12 @@ namespace SHADE
|
||||||
subpassIndex = index;
|
subpassIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::SetCompanionSubpass(Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept
|
||||||
|
{
|
||||||
|
companionSubpass.companion = companion;
|
||||||
|
companionSubpass.pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,23 @@ namespace SHADE
|
||||||
class SHVkSampler;
|
class SHVkSampler;
|
||||||
class SHRenderer;
|
class SHRenderer;
|
||||||
class SHViewport;
|
class SHViewport;
|
||||||
|
class SHVkPipeline;
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
||||||
|
|
||||||
|
// Allows for subpasses to run using a companions data
|
||||||
|
struct CompanionSubpass
|
||||||
|
{
|
||||||
|
// subpass whose data will be borrowed to draw
|
||||||
|
Handle<SHSubpass> companion;
|
||||||
|
|
||||||
|
// Pipeline that will be used for all the draw calls from all batches of the companion subpass
|
||||||
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -94,6 +105,15 @@ namespace SHADE
|
||||||
// For identifying subpasses
|
// For identifying subpasses
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
//! Optional component to a companion subpass. If the subpass handle of this object
|
||||||
|
//! is valid, the subpass will be drawn using this companion's data.
|
||||||
|
CompanionSubpass companionSubpass;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource(uint32_t attachmentIndex) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -119,7 +139,6 @@ namespace SHADE
|
||||||
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
void BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept;
|
void BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept;
|
||||||
void DetachResource (std::string const& resourceName, uint32_t attachmentIndex) noexcept;
|
|
||||||
bool HasNoAttachments (void) const noexcept;
|
bool HasNoAttachments (void) const noexcept;
|
||||||
|
|
||||||
void Init(SHResourceHub& resourceManager) noexcept;
|
void Init(SHResourceHub& resourceManager) noexcept;
|
||||||
|
@ -128,13 +147,18 @@ namespace SHADE
|
||||||
void CreateInputDescriptors (void) noexcept;
|
void CreateInputDescriptors (void) noexcept;
|
||||||
void UpdateWriteDescriptors (void) noexcept;
|
void UpdateWriteDescriptors (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* GETTERS AND SETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE GETTERS AND SETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
void SetIndex (uint32_t index) noexcept;
|
void SetIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PUBLIC SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetCompanionSubpass (Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept;
|
||||||
|
|
||||||
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
||||||
SHSubPassIndex GetIndex() const noexcept;
|
SHSubPassIndex GetIndex() const noexcept;
|
||||||
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
|
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
|
#include <fstream>
|
||||||
#include "SHInputManager.h"
|
#include "SHInputManager.h"
|
||||||
#include "../Tools/SHException.h"
|
#include "../Tools/SHException.h"
|
||||||
|
|
||||||
|
@ -99,6 +100,161 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The Binding File format presently goes as such:
|
||||||
|
/*
|
||||||
|
* Binding count
|
||||||
|
* (For each binding:)
|
||||||
|
* Name
|
||||||
|
Binding Type Enum
|
||||||
|
Inverted Bool
|
||||||
|
Gravity Double
|
||||||
|
Dead Double
|
||||||
|
Sensitivity Double
|
||||||
|
Snap Bool
|
||||||
|
PositiveKeyCode count
|
||||||
|
PositiveKeyCodes
|
||||||
|
NegativeKeyCode count
|
||||||
|
NegativeKeyCodes
|
||||||
|
PositiveControllerCode Count
|
||||||
|
PositiveControllerCodes
|
||||||
|
NegativeControllerCode Count
|
||||||
|
NegativeControllerCodes
|
||||||
|
*/
|
||||||
|
void SHInputManager::SaveBindings(std::string const& targetFile) noexcept
|
||||||
|
{
|
||||||
|
std::ofstream file;
|
||||||
|
file.open(targetFile);
|
||||||
|
|
||||||
|
//File cannot be written to
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
//First write the number of bindings
|
||||||
|
file << bindings.size() << std::endl;
|
||||||
|
|
||||||
|
for (auto& b : bindings)
|
||||||
|
{
|
||||||
|
//Name
|
||||||
|
file << b.first << std::endl;
|
||||||
|
|
||||||
|
//Data
|
||||||
|
auto& lbd = b.second;
|
||||||
|
|
||||||
|
file << static_cast<int>(lbd.bindingType) << std::endl;
|
||||||
|
file << static_cast<int>(lbd.inverted) << std::endl;
|
||||||
|
file << lbd.gravity << std::endl;
|
||||||
|
file << lbd.dead << std::endl;
|
||||||
|
file << lbd.sensitivity << std::endl;
|
||||||
|
file << static_cast<int>(lbd.snap) << std::endl;
|
||||||
|
|
||||||
|
//Bindings
|
||||||
|
file << lbd.positiveKeyCodes.size() << std::endl;
|
||||||
|
for (auto kc : lbd.positiveKeyCodes)
|
||||||
|
file << static_cast<int>(kc) << std::endl;
|
||||||
|
file << lbd.negativeKeyCodes.size() << std::endl;
|
||||||
|
for (auto kc : lbd.negativeKeyCodes)
|
||||||
|
file << static_cast<int>(kc) << std::endl;
|
||||||
|
file << lbd.positiveControllerCodes.size() << std::endl;
|
||||||
|
for (auto cc : lbd.positiveControllerCodes)
|
||||||
|
file << static_cast<int>(cc) << std::endl;
|
||||||
|
file << lbd.negativeControllerCodes.size() << std::endl;
|
||||||
|
for (auto cc : lbd.negativeControllerCodes)
|
||||||
|
file << static_cast<int>(cc) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHInputManager::LoadBindings(std::string const& sourceFile) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream file;
|
||||||
|
file.open(sourceFile);
|
||||||
|
|
||||||
|
//Check
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
//Erase
|
||||||
|
ClearBindings();
|
||||||
|
|
||||||
|
//Read
|
||||||
|
std::string read;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
std::getline(file, read);
|
||||||
|
count = std::stoi(read);
|
||||||
|
|
||||||
|
std::string bindingName;
|
||||||
|
for (int b = 0; b < count; ++b)
|
||||||
|
{
|
||||||
|
//Name
|
||||||
|
std::getline(file, read);
|
||||||
|
bindingName = read;
|
||||||
|
AddBinding(bindingName);
|
||||||
|
|
||||||
|
//Type
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingType(bindingName, static_cast<SH_BINDINGTYPE>(std::stoi(read)));
|
||||||
|
|
||||||
|
//Inversion
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingInverted(bindingName, static_cast<bool>(std::stoi(read)));
|
||||||
|
|
||||||
|
//Gravity
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingGravity(bindingName, std::stod(read));
|
||||||
|
|
||||||
|
//Dead
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingDead(bindingName, std::stod(read));
|
||||||
|
|
||||||
|
//Sensitivity
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingSensitivity(bindingName, std::stod(read));
|
||||||
|
|
||||||
|
//Snap
|
||||||
|
std::getline(file, read);
|
||||||
|
SetBindingSnap(bindingName, static_cast<bool>(std::stoi(read)));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
//Positive Key Codes
|
||||||
|
std::getline(file, read);
|
||||||
|
count = std::stoi(read);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
std::getline(file, read);
|
||||||
|
AddBindingPositiveKeyCode(bindingName, static_cast<SH_KEYCODE>(std::stoi(read)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Negative Key Codes
|
||||||
|
std::getline(file, read);
|
||||||
|
count = std::stoi(read);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
std::getline(file, read);
|
||||||
|
AddBindingNegativeKeyCode(bindingName, static_cast<SH_KEYCODE>(std::stoi(read)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Positive Controller Codes
|
||||||
|
std::getline(file, read);
|
||||||
|
count = std::stoi(read);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
std::getline(file, read);
|
||||||
|
AddBindingPositiveControllerCode(bindingName, static_cast<SH_CONTROLLERCODE>(std::stoi(read)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Negative Controller Codes
|
||||||
|
std::getline(file, read);
|
||||||
|
count = std::stoi(read);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
std::getline(file, read);
|
||||||
|
AddBindingNegativeControllerCode(bindingName, static_cast<SH_CONTROLLERCODE>(std::stoi(read)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
void SHInputManager::UpdateInput(double dt) noexcept
|
void SHInputManager::UpdateInput(double dt) noexcept
|
||||||
{
|
{
|
||||||
//Keyboard and Mouse Buttons////////////////////////////////////////////////
|
//Keyboard and Mouse Buttons////////////////////////////////////////////////
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "../../SHADE_Managed/src/SHpch.h"
|
#include "../../SHADE_Managed/src/SHpch.h"
|
||||||
|
#include "../../SHADE_Engine/src/Assets/SHAssetMacros.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#pragma comment(lib, "xinput.lib")
|
#pragma comment(lib, "xinput.lib")
|
||||||
|
|
||||||
|
@ -681,6 +682,17 @@ namespace SHADE
|
||||||
return controllersReleasedTime[controllerNum][static_cast<size_t>(code)];
|
return controllersReleasedTime[controllerNum][static_cast<size_t>(code)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Binding I/O */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//Save bindings registered into a file
|
||||||
|
static void SaveBindings(std::string const& targetFile = std::string(ASSET_ROOT) + "/Bindings.SHConfig") noexcept;
|
||||||
|
|
||||||
|
//Load and register bindings from a file
|
||||||
|
//If specified file exists, the current list of bindings will be overwritten, so save them somewhere else before loading
|
||||||
|
static void LoadBindings(std::string const& sourceFile = std::string(ASSET_ROOT) + "/Bindings.SHConfig") noexcept;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
/* Binding Functions */
|
/* Binding Functions */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHBox.cpp
|
* \file SHAABB.cpp
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
|
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
|
||||||
*
|
*
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
|
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHBox.h"
|
#include "SHAABB.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Math/SHRay.h"
|
#include "Math/SHRay.h"
|
||||||
|
@ -24,75 +24,52 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBox::SHBox() noexcept
|
SHAABB::SHAABB() noexcept
|
||||||
: RelativeExtents { SHVec3::One }
|
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
Extents = SHVec3::One * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBox::SHBox(const SHVec3& c, const SHVec3& hE) noexcept
|
SHAABB::SHAABB(const SHVec3& c, const SHVec3& hE) noexcept
|
||||||
: RelativeExtents { SHVec3::One }
|
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
|
||||||
|
|
||||||
Center = c;
|
Center = c;
|
||||||
Extents = hE;
|
Extents = hE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SHBox::SHBox(const SHBox& rhs) noexcept
|
SHAABB::SHAABB(const SHAABB& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type = Type::BOX;
|
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
RelativeExtents = rhs.RelativeExtents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBox::SHBox(SHBox&& rhs) noexcept
|
SHAABB::SHAABB(SHAABB&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
RelativeExtents = rhs.RelativeExtents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Operator Overload Definitions */
|
/* Operator Overload Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBox& SHBox::operator=(const SHBox& rhs) noexcept
|
SHAABB& SHAABB::operator=(const SHAABB& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (rhs.type != Type::BOX)
|
if (this != &rhs)
|
||||||
{
|
|
||||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
|
||||||
}
|
|
||||||
else if (this != &rhs)
|
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
RelativeExtents = rhs.RelativeExtents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBox& SHBox::operator=(SHBox&& rhs) noexcept
|
SHAABB& SHAABB::operator=(SHAABB&& rhs) noexcept
|
||||||
{
|
|
||||||
if (rhs.type != Type::BOX)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
RelativeExtents = rhs.RelativeExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -101,27 +78,22 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHVec3 SHBox::GetCenter() const noexcept
|
SHVec3 SHAABB::GetCenter() const noexcept
|
||||||
{
|
{
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHBox::GetWorldExtents() const noexcept
|
SHVec3 SHAABB::GetExtents() const noexcept
|
||||||
{
|
{
|
||||||
return Extents;
|
return Extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHBox::GetRelativeExtents() const noexcept
|
SHVec3 SHAABB::GetMin() const noexcept
|
||||||
{
|
|
||||||
return RelativeExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHVec3 SHBox::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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHBox::GetMax() const noexcept
|
SHVec3 SHAABB::GetMax() 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 };
|
||||||
}
|
}
|
||||||
|
@ -130,22 +102,17 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHBox::SetCenter(const SHVec3& newCenter) noexcept
|
void SHAABB::SetCenter(const SHVec3& newCenter) noexcept
|
||||||
{
|
{
|
||||||
Center = newCenter;
|
Center = newCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
void SHAABB::SetExtents(const SHVec3& newHalfExtents) noexcept
|
||||||
{
|
{
|
||||||
Extents = newWorldExtents;
|
Extents = newHalfExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
|
void SHAABB::SetMin(const SHVec3& min) noexcept
|
||||||
{
|
|
||||||
RelativeExtents = newRelativeExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHBox::SetMin(const SHVec3& min) noexcept
|
|
||||||
{
|
{
|
||||||
const SHVec3 MAX = GetMax();
|
const SHVec3 MAX = GetMax();
|
||||||
|
|
||||||
|
@ -153,7 +120,7 @@ namespace SHADE
|
||||||
Extents = SHVec3::Abs((MAX - min) * 0.5f);
|
Extents = SHVec3::Abs((MAX - min) * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBox::SetMax(const SHVec3& max) noexcept
|
void SHAABB::SetMax(const SHVec3& max) noexcept
|
||||||
{
|
{
|
||||||
const SHVec3 MIN = GetMin();
|
const SHVec3 MIN = GetMin();
|
||||||
|
|
||||||
|
@ -161,13 +128,13 @@ namespace SHADE
|
||||||
Extents = SHVec3::Abs((max - MIN) * 0.5f);
|
Extents = SHVec3::Abs((max - MIN) * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
|
void SHAABB::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
|
||||||
{
|
{
|
||||||
Center = SHVec3::Lerp(min, max, 0.5f);
|
Center = SHVec3::Lerp(min, max, 0.5f);
|
||||||
Extents = SHVec3::Abs((max - min) * 0.5f);
|
Extents = SHVec3::Abs((max - min) * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SHVec3> SHBox::GetVertices() const noexcept
|
std::vector<SHVec3> SHAABB::GetVertices() const noexcept
|
||||||
{
|
{
|
||||||
std::vector<SHVec3> vertices{ 8 };
|
std::vector<SHVec3> vertices{ 8 };
|
||||||
GetCorners(vertices.data());
|
GetCorners(vertices.data());
|
||||||
|
@ -178,12 +145,12 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHBox::TestPoint(const SHVec3& point) const noexcept
|
bool SHAABB::TestPoint(const SHVec3& point) const noexcept
|
||||||
{
|
{
|
||||||
return BoundingBox::Contains(point);
|
return BoundingBox::Contains(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHRaycastResult SHBox::Raycast(const SHRay& ray) const noexcept
|
SHRaycastResult SHAABB::Raycast(const SHRay& ray) const noexcept
|
||||||
{
|
{
|
||||||
SHRaycastResult result;
|
SHRaycastResult result;
|
||||||
|
|
||||||
|
@ -192,22 +159,24 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
result.position = ray.position + ray.direction * result.distance;
|
result.position = ray.position + ray.direction * result.distance;
|
||||||
result.angle = SHVec3::Angle(ray.position, result.position);
|
result.angle = SHVec3::Angle(ray.position, result.position);
|
||||||
|
|
||||||
|
// TODO: Compute normal
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHBox::Contains(const SHBox& rhs) const noexcept
|
bool SHAABB::Contains(const SHAABB& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return BoundingBox::Contains(rhs);
|
return BoundingBox::Contains(rhs) == CONTAINS;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHBox::Volume() const noexcept
|
float SHAABB::Volume() const noexcept
|
||||||
{
|
{
|
||||||
return 8.0f * (Extents.x * Extents.y * Extents.z);
|
return 8.0f * (Extents.x * Extents.y * Extents.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHBox::SurfaceArea() const noexcept
|
float SHAABB::SurfaceArea() const noexcept
|
||||||
{
|
{
|
||||||
return 8.0f * ((Extents.x * Extents.y)
|
return 8.0f * ((Extents.x * Extents.y)
|
||||||
+ (Extents.x * Extents.z)
|
+ (Extents.x * Extents.z)
|
||||||
|
@ -218,21 +187,21 @@ namespace SHADE
|
||||||
/* Static Function Member Definitions */
|
/* Static Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBox SHBox::Combine(const SHBox& lhs, const SHBox& rhs) noexcept
|
SHAABB SHAABB::Combine(const SHAABB& lhs, const SHAABB& rhs) noexcept
|
||||||
{
|
{
|
||||||
SHBox result;
|
SHAABB result;
|
||||||
CreateMerged(result, lhs, rhs);
|
CreateMerged(result, lhs, rhs);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHBox::Intersect(const SHBox& lhs, const SHBox& rhs) noexcept
|
bool SHAABB::Intersect(const SHAABB& lhs, const SHAABB& rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs.Intersects(rhs);
|
return lhs.Intersects(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBox SHBox::BuildFromBoxes(const SHBox* boxes, size_t numBoxes) noexcept
|
SHAABB SHAABB::BuildFromBoxes(const SHAABB* boxes, size_t numBoxes) noexcept
|
||||||
{
|
{
|
||||||
SHBox result;
|
SHAABB result;
|
||||||
|
|
||||||
for (size_t i = 1; i < numBoxes; ++i)
|
for (size_t i = 1; i < numBoxes; ++i)
|
||||||
CreateMerged(result, boxes[i - 1], boxes[i]);
|
CreateMerged(result, boxes[i - 1], boxes[i]);
|
||||||
|
@ -240,9 +209,9 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBox SHBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
SHAABB SHAABB::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
||||||
{
|
{
|
||||||
SHBox result;
|
SHAABB result;
|
||||||
CreateFromPoints(result, numVertices, vertices, stride);
|
CreateFromPoints(result, numVertices, vertices, stride);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHAABB.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
||||||
|
*
|
||||||
|
* \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 <DirectXCollision.h>
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "Math/SHRay.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulates a 3D Axis-Aligned Bounding Box.
|
||||||
|
*/
|
||||||
|
class SH_API SHAABB : private DirectX::BoundingBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static constexpr size_t NUM_VERTICES = 8;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
~SHAABB () noexcept = default;
|
||||||
|
|
||||||
|
SHAABB () noexcept;
|
||||||
|
SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept;
|
||||||
|
SHAABB (const SHAABB& rhs) noexcept;
|
||||||
|
SHAABB (SHAABB&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHAABB& operator= (const SHAABB& rhs) noexcept;
|
||||||
|
SHAABB& operator= (SHAABB&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
|
[[nodiscard]] SHVec3 GetExtents () const noexcept;
|
||||||
|
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||||
|
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||||
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||||
|
void SetExtents (const SHVec3& newHalfExtents) noexcept;
|
||||||
|
void SetMin (const SHVec3& min) noexcept;
|
||||||
|
void SetMax (const SHVec3& max) noexcept;
|
||||||
|
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Member Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if a point is inside the aabb.
|
||||||
|
* @param point
|
||||||
|
* The point to check.
|
||||||
|
* @return
|
||||||
|
* True if the point is inside the aabb.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Casts a ray against the aabb.
|
||||||
|
* @param ray
|
||||||
|
* The ray to cast.
|
||||||
|
* @return
|
||||||
|
* The result of the raycast. <br/>
|
||||||
|
* See the corresponding header for the contents of the raycast result object.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if an entire other aabb is contained by this aabb.
|
||||||
|
* @param rhs
|
||||||
|
* The aabb to check.
|
||||||
|
* @return
|
||||||
|
* True if the other sphere is completely contained by this aabb.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool Contains (const SHAABB& rhs) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Calculates the volume of the aabb.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] float Volume () const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Calculates the surface area of the aabb.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] float SurfaceArea () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Member Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Combines two aabbs to form a larger aabb.
|
||||||
|
* If one aabb is completely contained by the other, the result is the larger aabb.
|
||||||
|
* @return
|
||||||
|
* The combined aabb.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static SHAABB Combine (const SHAABB& lhs, const SHAABB& rhs) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if two aabbs are intersecting.
|
||||||
|
* @return
|
||||||
|
* True if they are intersecting.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static bool Intersect (const SHAABB& lhs, const SHAABB& rhs) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Builds a single aabb from multiple aabbs.
|
||||||
|
* @param spheres
|
||||||
|
* The set of aabbs to build from.
|
||||||
|
* @param numSpheres
|
||||||
|
* The number of aabbs in the set to build from.
|
||||||
|
* @return
|
||||||
|
* An aabb that contains all the spheres in the set.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static SHAABB BuildFromBoxes (const SHAABB* boxes, size_t numBoxes) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Builds a aabb from a set of vertices.
|
||||||
|
* @param vertices
|
||||||
|
* The vertices to build a aabb from.
|
||||||
|
* @param numVertices
|
||||||
|
* The number of vertices in the set to build from.
|
||||||
|
* @param stride
|
||||||
|
* The stride between each vertex, in the instance there is data in between each
|
||||||
|
* vertex that does not define the geometry of the object.
|
||||||
|
* @return
|
||||||
|
* An aabb that contains all the vertices in the set.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static SHAABB BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace SHADE
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
/****************************************************************************************
|
|
||||||
* \file SHBox.h
|
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
|
||||||
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
|
||||||
*
|
|
||||||
* \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 <DirectXCollision.h>
|
|
||||||
|
|
||||||
// Project Headers
|
|
||||||
#include "SHShape.h"
|
|
||||||
#include "SH_API.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Type Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SH_API SHBox : public SHShape,
|
|
||||||
private DirectX::BoundingBox
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Static Data Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static constexpr size_t NUM_VERTICES = 8;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
~SHBox () override = default;
|
|
||||||
|
|
||||||
SHBox () noexcept;
|
|
||||||
SHBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
|
|
||||||
SHBox (const SHBox& rhs) noexcept;
|
|
||||||
SHBox (SHBox&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Operator Overloads */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHBox& operator= (const SHBox& rhs) noexcept;
|
|
||||||
SHBox& operator= (SHBox&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Getter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
|
||||||
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
|
||||||
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
|
|
||||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
|
||||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
|
||||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Setter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
|
||||||
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
|
||||||
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
|
||||||
void SetMin (const SHVec3& min) noexcept;
|
|
||||||
void SetMax (const SHVec3& max) noexcept;
|
|
||||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
|
||||||
[[nodiscard]] SHRaycastResult Raycast(const SHRay& ray) const noexcept override;
|
|
||||||
|
|
||||||
[[nodiscard]] bool Contains (const SHBox& rhs) const noexcept;
|
|
||||||
[[nodiscard]] float Volume () const noexcept;
|
|
||||||
[[nodiscard]] float SurfaceArea () const noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Static Function Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
[[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept;
|
|
||||||
[[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept;
|
|
||||||
[[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept;
|
|
||||||
[[nodiscard]] static SHBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Data Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHVec3 RelativeExtents;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace SHADE
|
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPlane.cpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for a plane.
|
||||||
|
*
|
||||||
|
* \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>
|
||||||
|
|
||||||
|
#include <DirectXMath.h>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHPlane.h"
|
||||||
|
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
|
|
||||||
|
using namespace DirectX;
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHPlane::SHPlane() noexcept
|
||||||
|
: planeEquation { SHVec3::One }
|
||||||
|
{
|
||||||
|
planeEquation.w = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHPlane::SHPlane(const SHVec3& point, const SHVec3& normal) noexcept
|
||||||
|
{
|
||||||
|
XMStoreFloat4(&planeEquation, XMPlaneFromPointNormal(point, normal));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHPlane::SHPlane(float a, float b, float c, float d) noexcept
|
||||||
|
: planeEquation { a, b, c, d }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHPlane::SHPlane(const SHVec3& normal, float distance) noexcept
|
||||||
|
: planeEquation { normal }
|
||||||
|
{
|
||||||
|
planeEquation.w = distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overload Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHPlane::operator==(const SHPlane& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return XMPlaneEqual(planeEquation, rhs.planeEquation);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPlane::operator!=(const SHPlane& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return XMPlaneNotEqual(planeEquation, rhs.planeEquation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHVec3 SHPlane::GetNormal() const noexcept
|
||||||
|
{
|
||||||
|
return SHVec3{ planeEquation.x, planeEquation.y, planeEquation.z };
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHPlane::GetDistance() const noexcept
|
||||||
|
{
|
||||||
|
return planeEquation.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHPlane::SetNormal(const SHVec3& normal) noexcept
|
||||||
|
{
|
||||||
|
planeEquation.x = normal.x;
|
||||||
|
planeEquation.y = normal.y;
|
||||||
|
planeEquation.z = normal.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPlane::SetDistance(float distance) noexcept
|
||||||
|
{
|
||||||
|
planeEquation.w = distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Public Function Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHPlane::TestPoint(const SHVec3& point) const noexcept
|
||||||
|
{
|
||||||
|
const float DISTANCE = SignedDistance(point);
|
||||||
|
return SHMath::CompareFloat(DISTANCE, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRaycastResult SHPlane::Raycast(const SHRay& ray) const noexcept
|
||||||
|
{
|
||||||
|
SHRaycastResult result;
|
||||||
|
|
||||||
|
const SHVec3 N = GetNormal();
|
||||||
|
|
||||||
|
// Check if ray is parallel to plane
|
||||||
|
const float N_DOT_D = N.Dot(ray.direction);
|
||||||
|
if (SHMath::CompareFloat(N_DOT_D, 0.0f))
|
||||||
|
{
|
||||||
|
result.hit = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float DIST = (planeEquation.w - N.Dot(ray.position)) / N_DOT_D;
|
||||||
|
if (DIST < 0.0f || !SHMath::CompareFloat(DIST, 0.0f))
|
||||||
|
{
|
||||||
|
result.hit = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.hit = true;
|
||||||
|
result.distance = DIST;
|
||||||
|
result.position = ray.position + ray.direction * DIST;
|
||||||
|
result.angle = SHVec3::Angle(ray.position, result.position);
|
||||||
|
|
||||||
|
// The normal is either the plane's normal or the reverse if the ray came from below
|
||||||
|
result.normal = N_DOT_D < 0.0f ? -N : N;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHPlane::SignedDistance(const SHVec3& point) const noexcept
|
||||||
|
{
|
||||||
|
return XMVectorGetX(XMPlaneDotCoord(planeEquation, point));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,121 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHPlane.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a plane.
|
||||||
|
*
|
||||||
|
* \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 "Math/SHRay.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulates a 3D plane in point-normal form.
|
||||||
|
*/
|
||||||
|
class SH_API SHPlane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
~SHPlane () noexcept = default;
|
||||||
|
SHPlane (const SHPlane& rhs) noexcept = default;
|
||||||
|
SHPlane (SHPlane&& rhs) noexcept = default;
|
||||||
|
|
||||||
|
SHPlane () noexcept;
|
||||||
|
SHPlane (const SHVec3& point, const SHVec3& normal) noexcept;
|
||||||
|
SHPlane (float a, float b, float c, float d) noexcept;
|
||||||
|
SHPlane (const SHVec3& normal, float distance) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHPlane& operator= (const SHPlane& rhs) noexcept = default;
|
||||||
|
SHPlane& operator= (SHPlane&& rhs) noexcept = default;
|
||||||
|
|
||||||
|
bool operator== (const SHPlane& rhs) const noexcept;
|
||||||
|
bool operator!= (const SHPlane& rhs) const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] SHVec3 GetNormal () const noexcept;
|
||||||
|
[[nodiscard]] float GetDistance () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetNormal (const SHVec3& normal) noexcept;
|
||||||
|
void SetDistance (float distance) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Member Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if a point is on the plane.
|
||||||
|
* @param point
|
||||||
|
* The point to check.
|
||||||
|
* @return
|
||||||
|
* True if the point is on the plane.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Casts a ray against the plane.
|
||||||
|
* @param ray
|
||||||
|
* The ray to cast.
|
||||||
|
* @return
|
||||||
|
* The result of the raycast. <br/>
|
||||||
|
* See the corresponding header for the contents of the raycast result object.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Gets the signed distance from a point to the plane.
|
||||||
|
* @param point
|
||||||
|
* The point to check.
|
||||||
|
* @return
|
||||||
|
* The signed distance of the point to a plane. <br/>
|
||||||
|
* If the signed distance is negative, the point is behind the plane. <br/>
|
||||||
|
* If the signed distance is zero, the point is on the plane. <br/>
|
||||||
|
* If the signed distance is positive, the point is in front of the plane. <br/>
|
||||||
|
*/
|
||||||
|
[[nodiscard]] float SignedDistance (const SHVec3& point) const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Member Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* Transform plane
|
||||||
|
* Intersection Tests
|
||||||
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SHVec4 planeEquation;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -1,208 +0,0 @@
|
||||||
/****************************************************************************************
|
|
||||||
* \file SHBoundingSphere.cpp
|
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
|
||||||
* \brief Implementation for a Bounding Sphere
|
|
||||||
*
|
|
||||||
* \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 "SHSphere.h"
|
|
||||||
// Project Headers
|
|
||||||
#include "Math/SHMathHelpers.h"
|
|
||||||
#include "Math/SHRay.h"
|
|
||||||
|
|
||||||
using namespace DirectX;
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHSphere::SHSphere() noexcept
|
|
||||||
: RelativeRadius { 1.0f }
|
|
||||||
{
|
|
||||||
type = Type::SPHERE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere::SHSphere(const SHVec3& center, float radius) noexcept
|
|
||||||
: RelativeRadius { 1.0f }
|
|
||||||
{
|
|
||||||
type = Type::SPHERE;
|
|
||||||
|
|
||||||
Center = center;
|
|
||||||
Radius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere::SHSphere(const SHSphere& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (this == &rhs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
type = Type::SPHERE;
|
|
||||||
|
|
||||||
Center = rhs.Center;
|
|
||||||
Radius = rhs.Radius;
|
|
||||||
RelativeRadius = rhs.RelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere::SHSphere(SHSphere&& rhs) noexcept
|
|
||||||
{
|
|
||||||
type = Type::SPHERE;
|
|
||||||
|
|
||||||
Center = rhs.Center;
|
|
||||||
Radius = rhs.Radius;
|
|
||||||
RelativeRadius = rhs.RelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Operator Overload Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHSphere& SHSphere::operator=(const SHSphere& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (rhs.type != Type::SPHERE)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
|
|
||||||
}
|
|
||||||
else if (this != &rhs)
|
|
||||||
{
|
|
||||||
Center = rhs.Center;
|
|
||||||
Radius = rhs.Radius;
|
|
||||||
RelativeRadius = rhs.RelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere& SHSphere::operator=(SHSphere&& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (rhs.type != Type::SPHERE)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Center = rhs.Center;
|
|
||||||
Radius = rhs.Radius;
|
|
||||||
RelativeRadius = rhs.RelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Getter Function Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHVec3 SHSphere::GetCenter() const noexcept
|
|
||||||
{
|
|
||||||
return Center;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHSphere::GetWorldRadius() const noexcept
|
|
||||||
{
|
|
||||||
return Radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHSphere::GetRelativeRadius() const noexcept
|
|
||||||
{
|
|
||||||
return RelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Setter Function Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void SHSphere::SetCenter(const SHVec3& center) noexcept
|
|
||||||
{
|
|
||||||
Center = center;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSphere::SetWorldRadius(float newWorldRadius) noexcept
|
|
||||||
{
|
|
||||||
Radius = newWorldRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSphere::SetRelativeRadius(float newRelativeRadius) noexcept
|
|
||||||
{
|
|
||||||
RelativeRadius = newRelativeRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Public Function Member Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
bool SHSphere::TestPoint(const SHVec3& point) const noexcept
|
|
||||||
{
|
|
||||||
return BoundingSphere::Contains(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHRaycastResult SHSphere::Raycast(const SHRay& ray) const noexcept
|
|
||||||
{
|
|
||||||
SHRaycastResult result;
|
|
||||||
|
|
||||||
result.hit = Intersects(ray.position, ray.direction, result.distance);
|
|
||||||
if (result.hit)
|
|
||||||
{
|
|
||||||
result.position = ray.position + ray.direction * result.distance;
|
|
||||||
result.angle = SHVec3::Angle(ray.position, result.position);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSphere::Contains(const SHSphere& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return BoundingSphere::Contains(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHSphere::Volume() const noexcept
|
|
||||||
{
|
|
||||||
return (4.0f / 3.0f) * SHMath::PI * (Radius * Radius * Radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHSphere::SurfaceArea() const noexcept
|
|
||||||
{
|
|
||||||
return 4.0f * SHMath::PI * (Radius * Radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Static Function Member Definitions */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
SHSphere SHSphere::Combine(const SHSphere& lhs, const SHSphere& rhs) noexcept
|
|
||||||
{
|
|
||||||
SHSphere result;
|
|
||||||
CreateMerged(result, lhs, rhs);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSphere::Intersect(const SHSphere& lhs, const SHSphere& rhs) noexcept
|
|
||||||
{
|
|
||||||
return lhs.Intersects(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere SHSphere::BuildFromSpheres(const SHSphere* spheres, size_t numSpheres) noexcept
|
|
||||||
{
|
|
||||||
SHSphere result;
|
|
||||||
|
|
||||||
for (size_t i = 1; i < numSpheres; ++i)
|
|
||||||
CreateMerged(result, spheres[i - 1], spheres[i]);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSphere SHSphere::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
|
||||||
{
|
|
||||||
SHSphere result;
|
|
||||||
CreateFromPoints(result, numVertices, vertices, stride);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace SHADE
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue