Fixed Vector3.GetNormalised!!!!!!! #211
|
@ -0,0 +1,4 @@
|
||||||
|
Start in Fullscreen: false
|
||||||
|
Starting Scene ID: 94283040
|
||||||
|
Window Size: {x: 1920, y: 1080}
|
||||||
|
Window Title: SHADE Engine
|
Binary file not shown.
|
@ -1,3 +0,0 @@
|
||||||
Name: Cube.003
|
|
||||||
ID: 71245919
|
|
||||||
Type: 4
|
|
|
@ -1,3 +0,0 @@
|
||||||
Name: Cube.012
|
|
||||||
ID: 80365422
|
|
||||||
Type: 4
|
|
|
@ -1,16 +1,16 @@
|
||||||
[Window][MainStatusBar]
|
[Window][MainStatusBar]
|
||||||
Pos=0,1060
|
Pos=0,1007
|
||||||
Size=1920,20
|
Size=1920,20
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][SHEditorMenuBar]
|
[Window][SHEditorMenuBar]
|
||||||
Pos=0,48
|
Pos=0,48
|
||||||
Size=1920,1012
|
Size=1920,959
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Hierarchy Panel]
|
[Window][Hierarchy Panel]
|
||||||
Pos=0,197
|
Pos=0,189
|
||||||
Size=308,863
|
Size=308,818
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
|
@ -21,13 +21,13 @@ Collapsed=0
|
||||||
|
|
||||||
[Window][Inspector]
|
[Window][Inspector]
|
||||||
Pos=1528,48
|
Pos=1528,48
|
||||||
Size=392,1012
|
Size=392,959
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000006,0
|
DockId=0x00000006,0
|
||||||
|
|
||||||
[Window][Profiler]
|
[Window][Profiler]
|
||||||
Pos=0,48
|
Pos=0,48
|
||||||
Size=308,147
|
Size=308,139
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,0
|
DockId=0x00000003,0
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ DockId=0x0000000B,0
|
||||||
|
|
||||||
[Window][ Viewport]
|
[Window][ Viewport]
|
||||||
Pos=310,48
|
Pos=310,48
|
||||||
Size=1216,715
|
Size=1216,662
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000B,0
|
DockId=0x0000000B,0
|
||||||
|
|
||||||
|
@ -93,13 +93,19 @@ Collapsed=0
|
||||||
DockId=0x0000000A,0
|
DockId=0x0000000A,0
|
||||||
|
|
||||||
[Window][ Asset Browser]
|
[Window][ Asset Browser]
|
||||||
Pos=310,765
|
Pos=310,712
|
||||||
Size=1216,295
|
Size=1216,295
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000000C,0
|
DockId=0x0000000C,0
|
||||||
|
|
||||||
|
[Window][Material Inspector]
|
||||||
|
Pos=1528,48
|
||||||
|
Size=392,959
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000006,1
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
|
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=1920,959 Split=X
|
||||||
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X
|
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881
|
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881
|
||||||
|
@ -111,5 +117,5 @@ DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Spli
|
||||||
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A
|
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A
|
||||||
DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6
|
DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6
|
||||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532
|
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532
|
||||||
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xE7039252
|
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xD3697FB6
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
- VertexShader: 39210065
|
||||||
|
FragmentShader: 46377769
|
||||||
|
SubPass: G-Buffer Write
|
||||||
|
Properties:
|
||||||
|
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
data.textureIndex: 58303057
|
||||||
|
data.alpha: 0
|
||||||
|
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: BagMaterial
|
||||||
|
ID: 123745521
|
||||||
|
Type: 7
|
|
@ -0,0 +1,8 @@
|
||||||
|
- VertexShader: 39210065
|
||||||
|
FragmentShader: 46377769
|
||||||
|
SubPass: G-Buffer Write
|
||||||
|
Properties:
|
||||||
|
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
data.textureIndex: 64651793
|
||||||
|
data.alpha: 0
|
||||||
|
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: TestMat
|
||||||
|
ID: 126974645
|
||||||
|
Type: 7
|
|
@ -0,0 +1,8 @@
|
||||||
|
- VertexShader: 39210065
|
||||||
|
FragmentShader: 46377769
|
||||||
|
SubPass: G-Buffer Write
|
||||||
|
Properties:
|
||||||
|
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
data.textureIndex: 0
|
||||||
|
data.alpha: 0
|
||||||
|
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: WhiteMat
|
||||||
|
ID: 124370424
|
||||||
|
Type: 7
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
Name: racoon
|
||||||
|
ID: 77816045
|
||||||
|
Type: 4
|
||||||
|
Sub Assets:
|
||||||
|
Name: Bag
|
||||||
|
ID: 144838771
|
||||||
|
Type: 8
|
||||||
|
Name: Raccoon
|
||||||
|
ID: 149697411
|
||||||
|
Type: 8
|
|
@ -0,0 +1,229 @@
|
||||||
|
- EID: 0
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Camera Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Pitch: 0
|
||||||
|
Yaw: 0
|
||||||
|
Roll: 0
|
||||||
|
Width: 1920
|
||||||
|
Height: 1080
|
||||||
|
Near: 0.00999999978
|
||||||
|
Far: 10000
|
||||||
|
Perspective: true
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Directional
|
||||||
|
Direction: {x: 1.79999995, y: 0, z: 1}
|
||||||
|
Color: {x: 0.951541841, y: 0.921719015, z: 0.553319454, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 1
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -1.440328, y: -4.41369677, z: -5}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 49.4798889, y: 0.5, z: 17.5}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Static
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: 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
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0, z: 0}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 2
|
||||||
|
Name: Player
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 3
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -3.06177855, y: -2, z: -5}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 2, y: 2, z: 2}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: 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
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 3
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -0.0094268322, y: 0, z: 0}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 4
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 9
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 144838771
|
||||||
|
Material: 123745521
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 6
|
||||||
|
Name: AI
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -8, y: -2, z: 2.5}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: false
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: false
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: true
|
||||||
|
Freeze Rotation Y: true
|
||||||
|
Freeze Rotation Z: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 7
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -16.8647861, z: -14.039052}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 8
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Ambient
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0.25
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: item
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -2, z: -5}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 2, y: 2, z: 2}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 144838771
|
||||||
|
Material: 123745521
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: false
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: false
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: true
|
||||||
|
Freeze Rotation Y: true
|
||||||
|
Freeze Rotation Z: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
- Is Trigger: true
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 2, y: 2, z: 2}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: M2Scene
|
||||||
|
ID: 94283040
|
||||||
|
Type: 5
|
|
@ -0,0 +1,72 @@
|
||||||
|
- EID: 0
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Camera Component:
|
||||||
|
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
|
Pitch: 0
|
||||||
|
Yaw: 0
|
||||||
|
Roll: 0
|
||||||
|
Width: 1200
|
||||||
|
Height: 1080
|
||||||
|
Near: 0.00999999978
|
||||||
|
Far: 10000
|
||||||
|
Perspective: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 1
|
||||||
|
Name: Raccoon
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 1
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 3
|
||||||
|
Name: Bag
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
||||||
|
Rotate: {x: -0, y: 2.79945588, z: 0}
|
||||||
|
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 144838771
|
||||||
|
Material: 123745521
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 2
|
||||||
|
Name: DirectionalLight
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Directional
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 4
|
||||||
|
Name: AmbientLight
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Ambient
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0.600000024
|
||||||
|
Scripts: ~
|
|
@ -0,0 +1,3 @@
|
||||||
|
Name: Scene2
|
||||||
|
ID: 87285316
|
||||||
|
Type: 5
|
|
@ -0,0 +1,184 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SHADE;
|
||||||
|
|
||||||
|
public class AIPrototype : Script
|
||||||
|
{
|
||||||
|
//This object's relevant components
|
||||||
|
private Transform transform;
|
||||||
|
private RigidBody rb;
|
||||||
|
|
||||||
|
/*[SerializeField]
|
||||||
|
[Tooltip("The list of waypoints that the object will move around on")]
|
||||||
|
private Vector3[] waypoints;*/
|
||||||
|
|
||||||
|
private Vector3[] waypoints = { new Vector3(-8.0f, -2.0f, 3.5f), new Vector3(-8.0f, -2.0f, -13.0f), new Vector3(8.0f, -2.0f, -13.0f), new Vector3(8.0f, -2.0f, 3.5f) };
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How much force is applied in movement")]
|
||||||
|
private float movementForceMultiplier = 100.0f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How fast the object moves about waypoints")]
|
||||||
|
private float patrolSpeed = 0.4f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How fast the object moves while chasing")]
|
||||||
|
private float chaseSpeed = 0.8f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How near the player must be to the AI for capture")]
|
||||||
|
private float distanceToCapture = 1.2f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How near the player must be for the chase to begin. Should be less than distanceToEndChase")]
|
||||||
|
private float distanceToStartChase = 2.0f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("How far the player must be for the chase to end. Should be greater than distanceToStartChase")]
|
||||||
|
private float distanceToEndChase = 2.5f;
|
||||||
|
|
||||||
|
//Whether the AI is chasing or not
|
||||||
|
private bool chaseMode;
|
||||||
|
|
||||||
|
//To cycle depending on the length of waypoints
|
||||||
|
private int currentTargetWaypointIndex;
|
||||||
|
|
||||||
|
private GameObject? player;
|
||||||
|
|
||||||
|
public AIPrototype(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
transform = GetComponent<Transform>();
|
||||||
|
if (transform == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Transform is NULL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
rb = GetComponent<RigidBody>();
|
||||||
|
if (rb == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Rigidbody is NULL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTargetWaypointIndex = 0;
|
||||||
|
|
||||||
|
player = GameObject.Find("Player");
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Player is NULL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
chaseMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void fixedUpdate()
|
||||||
|
{
|
||||||
|
//Patrolling
|
||||||
|
if (!chaseMode)
|
||||||
|
{
|
||||||
|
//Head towards the next target
|
||||||
|
Vector3 normalisedDifference = waypoints[currentTargetWaypointIndex] - transform.GlobalPosition;
|
||||||
|
normalisedDifference /= normalisedDifference.GetMagnitude();
|
||||||
|
|
||||||
|
//transform.GlobalPosition += normalisedDifference * moveSpeed * (float)Time.DeltaTime;
|
||||||
|
//rb.LinearVelocity = normalisedDifference * patrolSpeed;
|
||||||
|
|
||||||
|
//ORIGINAL INTENDED CODE
|
||||||
|
/*rb.AddForce(new Vector3(normalisedDifference.x, 0.0f, normalisedDifference.z) * movementForceMultiplier);
|
||||||
|
float currentSpeed = MathF.Sqrt(rb.LinearVelocity.x * rb.LinearVelocity.x + rb.LinearVelocity.z * rb.LinearVelocity.z);
|
||||||
|
if (currentSpeed > patrolSpeed)
|
||||||
|
{
|
||||||
|
float adjustmentFactor = patrolSpeed / currentSpeed;
|
||||||
|
Vector3 adjustedVelocity = rb.LinearVelocity;
|
||||||
|
//adjustedVelocity *= adjustmentFactor;
|
||||||
|
adjustedVelocity.x = patrolSpeed;
|
||||||
|
adjustedVelocity.z = patrolSpeed;
|
||||||
|
rb.LinearVelocity = adjustedVelocity;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//TODO delete this when original intended code above works with velocity being limited correctly
|
||||||
|
rb.LinearVelocity = normalisedDifference * patrolSpeed;
|
||||||
|
|
||||||
|
//transform.GlobalRotation.SetLookRotation(waypoints[currentTargetWaypointIndex], Vector3.Up);
|
||||||
|
|
||||||
|
//Cycle to next waypoint if near enough current waypoint
|
||||||
|
if ((waypoints[currentTargetWaypointIndex] - transform.GlobalPosition).GetSqrMagnitude() <= 0.5f)
|
||||||
|
{
|
||||||
|
++currentTargetWaypointIndex;
|
||||||
|
if (currentTargetWaypointIndex >= waypoints.Length)
|
||||||
|
{
|
||||||
|
currentTargetWaypointIndex = 0; //Recycle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Go chase if near enough to player
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
Transform pTransform = player.GetValueOrDefault().GetComponent<Transform>();
|
||||||
|
if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() <= distanceToStartChase)
|
||||||
|
{
|
||||||
|
//Start the chase
|
||||||
|
chaseMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //Chasing
|
||||||
|
{
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
Transform pTransform = player.GetValueOrDefault().GetComponent<Transform>();
|
||||||
|
|
||||||
|
//Chase the player
|
||||||
|
Vector3 normalisedDifference = pTransform.GlobalPosition - transform.GlobalPosition;
|
||||||
|
normalisedDifference /= normalisedDifference.GetMagnitude();
|
||||||
|
|
||||||
|
//transform.GlobalPosition += normalisedDifference * moveSpeed * (float)Time.DeltaTime;
|
||||||
|
|
||||||
|
//ORIGINAL INTENDED CODE
|
||||||
|
/*rb.AddForce(new Vector3(normalisedDifference.x, 0.0f, normalisedDifference.z) * movementForceMultiplier);
|
||||||
|
float currentSpeed = MathF.Sqrt(rb.LinearVelocity.x * rb.LinearVelocity.x + rb.LinearVelocity.z * rb.LinearVelocity.z);
|
||||||
|
if (currentSpeed > chaseSpeed)
|
||||||
|
{
|
||||||
|
float adjustmentFactor = chaseSpeed / currentSpeed;
|
||||||
|
Vector3 adjustedVelocity = rb.LinearVelocity;
|
||||||
|
adjustedVelocity *= adjustmentFactor;
|
||||||
|
rb.LinearVelocity = adjustedVelocity;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//TODO delete this when original intended code above works with velocity being limited correctly
|
||||||
|
rb.LinearVelocity = normalisedDifference * chaseSpeed;
|
||||||
|
|
||||||
|
//Capture player if near enough
|
||||||
|
if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() <= distanceToCapture)
|
||||||
|
{
|
||||||
|
player.GetValueOrDefault().GetScript<PlayerController>().currentState = PlayerController.RaccoonStates.CAUGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//End chase if too far
|
||||||
|
if ((pTransform.GlobalPosition - transform.GlobalPosition).GetMagnitude() >= distanceToEndChase)
|
||||||
|
{
|
||||||
|
//Stop the chase
|
||||||
|
chaseMode = false;
|
||||||
|
|
||||||
|
//Find the nearest waypoint to go instead
|
||||||
|
float nearestWaypointDistance = 99999999999999.9f;
|
||||||
|
for (int i = 0; i < waypoints.Length; ++i)
|
||||||
|
{
|
||||||
|
if ((waypoints[i] - transform.GlobalPosition).GetSqrMagnitude() < nearestWaypointDistance)
|
||||||
|
{
|
||||||
|
nearestWaypointDistance = waypoints[i].GetSqrMagnitude();
|
||||||
|
currentTargetWaypointIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public class CameraFix : Script
|
||||||
|
{
|
||||||
|
public CameraFix(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
private Transform tranform;
|
||||||
|
public Vector3 pos = Vector3.Zero;
|
||||||
|
public Vector3 rot = Vector3.Zero;
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
tranform = GetComponent<Transform>();
|
||||||
|
if (tranform == null)
|
||||||
|
Debug.LogError("tranform is NULL!");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tranform.LocalPosition = pos;
|
||||||
|
tranform.LocalEulerAngles = rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
public class Item : Script
|
||||||
|
{
|
||||||
|
public enum ItemCategory
|
||||||
|
{
|
||||||
|
LIGHT,
|
||||||
|
MEDIUM,
|
||||||
|
HEAVY
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemCategory currCategory;
|
||||||
|
public Item(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using static PlayerController;
|
||||||
|
|
||||||
|
public class PickAndThrow : Script
|
||||||
|
{
|
||||||
|
public Vector3 throwForce = new Vector3(100.0f, 200.0f, 100.0f);
|
||||||
|
public GameObject item;
|
||||||
|
private PlayerController pc;
|
||||||
|
private Camera cam;
|
||||||
|
private Transform itemTransform;
|
||||||
|
private RigidBody itemRidibody;
|
||||||
|
private Transform raccoonHoldLocation;
|
||||||
|
private float lastXDir;
|
||||||
|
private float lastZDir;
|
||||||
|
private bool inRange = false;
|
||||||
|
public PickAndThrow(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
pc = GetScript<PlayerController>();
|
||||||
|
raccoonHoldLocation = GetComponentInChildren<Transform>();
|
||||||
|
if (raccoonHoldLocation == null)
|
||||||
|
Debug.Log("CHILD EMPTY");
|
||||||
|
else
|
||||||
|
raccoonHoldLocation.LocalPosition = new Vector3(0.0f, 1.0f, 0.0f);
|
||||||
|
}
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
if (cam == null)
|
||||||
|
cam = GetComponentInChildren<Camera>();
|
||||||
|
else if (cam != null)
|
||||||
|
{
|
||||||
|
Vector3 camerAixs = cam.GetForward();
|
||||||
|
camerAixs.y = 0;
|
||||||
|
camerAixs.Normalise();
|
||||||
|
lastXDir = camerAixs.x;
|
||||||
|
lastZDir = camerAixs.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.GetScript<Item>() != null && itemTransform == null && itemRidibody == null)
|
||||||
|
{
|
||||||
|
itemTransform = item.GetComponent<Transform>();
|
||||||
|
if (itemTransform == null)
|
||||||
|
Debug.Log("Item transform EMPTY");
|
||||||
|
|
||||||
|
itemRidibody = item.GetComponent<RigidBody>();
|
||||||
|
if (itemRidibody == null)
|
||||||
|
Debug.Log("Item rb EMPTY");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc != null && inRange && !pc.holdItem && Input.GetKey(Input.KeyCode.E))
|
||||||
|
pc.holdItem = true;
|
||||||
|
|
||||||
|
if (pc != null && itemRidibody != null && itemTransform != null && pc.holdItem)
|
||||||
|
{
|
||||||
|
itemTransform.LocalPosition = raccoonHoldLocation.GlobalPosition;
|
||||||
|
itemRidibody.IsGravityEnabled = false;
|
||||||
|
itemRidibody.LinearVelocity = Vector3.Zero;
|
||||||
|
itemRidibody.AngularVelocity = Vector3.Zero;
|
||||||
|
|
||||||
|
if (Input.GetMouseButtonDown(Input.MouseCode.LeftButton))
|
||||||
|
{
|
||||||
|
pc.holdItem = false;
|
||||||
|
inRange = false;
|
||||||
|
itemRidibody.IsGravityEnabled = true;
|
||||||
|
itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir));
|
||||||
|
itemRidibody.LinearVelocity += pc.rb.LinearVelocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!pc.holdItem && itemRidibody != null)
|
||||||
|
itemRidibody.IsGravityEnabled = true;
|
||||||
|
}
|
||||||
|
protected override void onCollisionEnter(CollisionInfo info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
protected override void onTriggerEnter(CollisionInfo info)
|
||||||
|
{
|
||||||
|
//Debug.Log("ENTER");
|
||||||
|
if (info.GameObject.GetScript<Item>() != null && !pc.holdItem)
|
||||||
|
{
|
||||||
|
item = info.GameObject;
|
||||||
|
inRange = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected override void onTriggerStay(CollisionInfo info)
|
||||||
|
{
|
||||||
|
//Debug.Log("STAY");
|
||||||
|
}
|
||||||
|
protected override void onTriggerExit(CollisionInfo info)
|
||||||
|
{
|
||||||
|
//Debug.Log("EXIT");
|
||||||
|
if (info.GameObject.GetScript<Item>() != null && !pc.holdItem)
|
||||||
|
{
|
||||||
|
inRange = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,360 @@
|
||||||
|
using SHADE;
|
||||||
|
using System;
|
||||||
|
using static Item;
|
||||||
|
|
||||||
|
public class PlayerController : Script
|
||||||
|
{
|
||||||
|
public enum RaccoonStates
|
||||||
|
{
|
||||||
|
IDILE,
|
||||||
|
WALKING,
|
||||||
|
RUNNING,
|
||||||
|
JUMP,
|
||||||
|
FALLING,
|
||||||
|
CAUGHT,
|
||||||
|
TOTAL
|
||||||
|
}
|
||||||
|
|
||||||
|
public RigidBody rb { get; set; }
|
||||||
|
private Transform tranform;
|
||||||
|
private Camera cam;
|
||||||
|
private PickAndThrow pat;
|
||||||
|
|
||||||
|
//to be remove
|
||||||
|
public float drag = 2.0f;
|
||||||
|
public bool holdItem { get; set; }
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The current state fo the raccoon")]
|
||||||
|
public RaccoonStates currentState = RaccoonStates.IDILE;
|
||||||
|
|
||||||
|
//Movement variables============================================================
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("Max vel for walking")]
|
||||||
|
public float maxMoveVel = 2.0f;
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("how much force is apply for walking")]
|
||||||
|
public float moveForce = 50.0f;
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("increase the moveForce and maxMoveVel by its amt")]
|
||||||
|
public float sprintMultiplier = 2.0f;
|
||||||
|
|
||||||
|
private float oldForce;
|
||||||
|
private float maxOldVel;
|
||||||
|
private bool sprintIncreaseOnce = false;
|
||||||
|
|
||||||
|
public float xAxisMove { get; set; }
|
||||||
|
public float zAxisMove { get; set; }
|
||||||
|
|
||||||
|
public Vector2 axisMove { get; set; }
|
||||||
|
|
||||||
|
public bool isMoveKeyPress { get; set; }
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("curr not working")]
|
||||||
|
public float rotationFactorPerFrame = 1.0f;
|
||||||
|
|
||||||
|
//Jumping vars==================================================================
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("max height of the jump")]
|
||||||
|
public float maxJumpHeight = 4.0f;
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("max amt of time it will take for the jump")]
|
||||||
|
public float maxJumpTime = 0.75f;
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("increase gravity when falling")]
|
||||||
|
public float fallMultipler = 2.0f;
|
||||||
|
private float initialJumpVel;
|
||||||
|
private bool isGrounded = true;
|
||||||
|
private float gravity = -9.8f;
|
||||||
|
private float groundGravity = -0.5f;
|
||||||
|
|
||||||
|
//ItemMultipler==================================================================
|
||||||
|
public float lightMultiper = 0.75f;
|
||||||
|
public float mediumMultiper = 0.5f;
|
||||||
|
public float heavyMultiper = 0.25f;
|
||||||
|
|
||||||
|
public PlayerController(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
protected override void awake()
|
||||||
|
{
|
||||||
|
//default setup
|
||||||
|
isMoveKeyPress = false;
|
||||||
|
holdItem = false;
|
||||||
|
|
||||||
|
//Jump setup
|
||||||
|
float timeToApex = maxJumpTime / 2;
|
||||||
|
gravity = (-2 * maxJumpHeight) / MathF.Pow(timeToApex, 2);
|
||||||
|
initialJumpVel = (2 * maxJumpHeight) / timeToApex;
|
||||||
|
|
||||||
|
//rigidbody check
|
||||||
|
rb = GetComponent<RigidBody>();
|
||||||
|
if (rb == null)
|
||||||
|
Debug.LogError("RigidBody is NULL!");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rb.IsGravityEnabled = false;
|
||||||
|
rb.FreezeRotationX = true;
|
||||||
|
rb.FreezeRotationY = true;
|
||||||
|
rb.FreezeRotationZ = true;
|
||||||
|
rb.Drag = drag;
|
||||||
|
rb.Interpolating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Transform check
|
||||||
|
tranform = GetComponent<Transform>();
|
||||||
|
if(tranform == null)
|
||||||
|
Debug.LogError("tranform is NULL!");
|
||||||
|
|
||||||
|
//PickAndThrow checl
|
||||||
|
pat = GetScript<PickAndThrow>();
|
||||||
|
if (pat == null)
|
||||||
|
Debug.LogError("PickAndThrow is NULL!");
|
||||||
|
|
||||||
|
//toRemove
|
||||||
|
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
|
||||||
|
tranform.LocalRotation = Quaternion.Euler(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void update()
|
||||||
|
{
|
||||||
|
if (cam == null)
|
||||||
|
cam = GetComponentInChildren<Camera>();
|
||||||
|
|
||||||
|
//toRemove
|
||||||
|
if (Input.GetKey(Input.KeyCode.G))
|
||||||
|
{
|
||||||
|
tranform.LocalRotation = Quaternion.Euler(0.0f, 0.0f, 0.0f);
|
||||||
|
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GotCaught();
|
||||||
|
MoveKey();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void fixedUpdate()
|
||||||
|
{
|
||||||
|
//Rotation();
|
||||||
|
Move();
|
||||||
|
Sprint();
|
||||||
|
Jump();
|
||||||
|
Gravity();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MoveKey()
|
||||||
|
{
|
||||||
|
/* if (Input.GetKey(Input.KeyCode.A))
|
||||||
|
xAxisMove = -1;
|
||||||
|
else if (Input.GetKey(Input.KeyCode.D))
|
||||||
|
xAxisMove = 1;
|
||||||
|
else
|
||||||
|
xAxisMove = 0;
|
||||||
|
|
||||||
|
if (Input.GetKey(Input.KeyCode.W))
|
||||||
|
zAxisMove = -1;
|
||||||
|
else if (Input.GetKey(Input.KeyCode.S))
|
||||||
|
zAxisMove = 1;
|
||||||
|
else
|
||||||
|
zAxisMove = 0;*/
|
||||||
|
|
||||||
|
|
||||||
|
xAxisMove = 0;
|
||||||
|
zAxisMove = 0;
|
||||||
|
axisMove = Vector2.Zero;
|
||||||
|
if (Input.GetKey(Input.KeyCode.W))
|
||||||
|
{
|
||||||
|
Vector3 camerAixs = cam.GetForward();
|
||||||
|
camerAixs.y = 0;
|
||||||
|
camerAixs.Normalise();
|
||||||
|
xAxisMove = camerAixs.x;
|
||||||
|
zAxisMove = camerAixs.z;
|
||||||
|
axisMove += new Vector2(camerAixs.x, camerAixs.z);
|
||||||
|
}
|
||||||
|
if (Input.GetKey(Input.KeyCode.S))
|
||||||
|
{
|
||||||
|
Vector3 camerAixs = cam.GetForward();
|
||||||
|
camerAixs.y = 0;
|
||||||
|
camerAixs.Normalise();
|
||||||
|
xAxisMove = -camerAixs.x;
|
||||||
|
zAxisMove = -camerAixs.z;
|
||||||
|
axisMove -= new Vector2(camerAixs.x, camerAixs.z);
|
||||||
|
}
|
||||||
|
if (Input.GetKey(Input.KeyCode.A))
|
||||||
|
{
|
||||||
|
Vector3 camerAixs = cam.GetRight();
|
||||||
|
camerAixs.y = 0;
|
||||||
|
camerAixs.Normalise();
|
||||||
|
xAxisMove = -camerAixs.x;
|
||||||
|
zAxisMove = -camerAixs.z;
|
||||||
|
axisMove -= new Vector2(camerAixs.x, camerAixs.z);
|
||||||
|
}
|
||||||
|
if (Input.GetKey(Input.KeyCode.D))
|
||||||
|
{
|
||||||
|
Vector3 camerAixs = cam.GetRight();
|
||||||
|
camerAixs.y = 0;
|
||||||
|
camerAixs.Normalise();
|
||||||
|
xAxisMove = camerAixs.x;
|
||||||
|
zAxisMove = camerAixs.z;
|
||||||
|
axisMove += new Vector2(camerAixs.x, camerAixs.z);
|
||||||
|
}
|
||||||
|
axisMove.Normalise();
|
||||||
|
isMoveKeyPress = xAxisMove != 0 || zAxisMove != 0;
|
||||||
|
|
||||||
|
if(isMoveKeyPress && currentState != RaccoonStates.RUNNING && isGrounded)
|
||||||
|
currentState = RaccoonStates.WALKING;
|
||||||
|
|
||||||
|
if (!isMoveKeyPress && isGrounded)
|
||||||
|
currentState = RaccoonStates.IDILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Move()
|
||||||
|
{
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
rb.AddForce(new Vector3(axisMove.x, 0.0f,axisMove.y) * moveForce);
|
||||||
|
|
||||||
|
if (isMoveKeyPress)
|
||||||
|
{
|
||||||
|
if (rb.LinearVelocity.x > maxMoveVel || rb.LinearVelocity.x < -maxMoveVel)
|
||||||
|
{
|
||||||
|
Vector3 v = rb.LinearVelocity;
|
||||||
|
v.x = System.Math.Clamp(v.x, -maxMoveVel, maxMoveVel);
|
||||||
|
rb.LinearVelocity = v;
|
||||||
|
}
|
||||||
|
if (rb.LinearVelocity.z > maxMoveVel || rb.LinearVelocity.z < -maxMoveVel)
|
||||||
|
{
|
||||||
|
Vector3 v = rb.LinearVelocity;
|
||||||
|
v.z = System.Math.Clamp(v.z, -maxMoveVel, maxMoveVel);
|
||||||
|
rb.LinearVelocity = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Sprint()
|
||||||
|
{
|
||||||
|
if (Input.GetKey(Input.KeyCode.LeftShift) && isMoveKeyPress && isGrounded)
|
||||||
|
{
|
||||||
|
currentState = RaccoonStates.RUNNING;
|
||||||
|
holdItem = false;
|
||||||
|
if (!sprintIncreaseOnce)
|
||||||
|
{
|
||||||
|
sprintIncreaseOnce = true;
|
||||||
|
oldForce = moveForce;
|
||||||
|
moveForce *= sprintMultiplier;
|
||||||
|
|
||||||
|
maxOldVel = maxMoveVel;
|
||||||
|
maxMoveVel *= sprintMultiplier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.GetKeyUp(Input.KeyCode.LeftShift))
|
||||||
|
{
|
||||||
|
if(isMoveKeyPress)
|
||||||
|
currentState = RaccoonStates.WALKING;
|
||||||
|
sprintIncreaseOnce = false;
|
||||||
|
moveForce = oldForce;
|
||||||
|
maxMoveVel = maxOldVel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//press and hold jump
|
||||||
|
private void Jump()
|
||||||
|
{
|
||||||
|
if (currentState == RaccoonStates.WALKING || currentState == RaccoonStates.RUNNING || currentState == RaccoonStates.IDILE)
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(Input.KeyCode.Space) && isGrounded && rb != null)
|
||||||
|
{
|
||||||
|
currentState = RaccoonStates.JUMP;
|
||||||
|
Vector3 v = rb.LinearVelocity;
|
||||||
|
v.y = initialJumpVel * 0.5f;
|
||||||
|
if (pat != null && pat.item.GetScript<Item>() != null && holdItem)
|
||||||
|
{
|
||||||
|
Item item = pat.item.GetScript<Item>();
|
||||||
|
if (item.currCategory == ItemCategory.LIGHT)
|
||||||
|
v.y *= lightMultiper;
|
||||||
|
if (item.currCategory == ItemCategory.MEDIUM)
|
||||||
|
v.y *= mediumMultiper;
|
||||||
|
if (item.currCategory == ItemCategory.HEAVY)
|
||||||
|
v.y *= heavyMultiper;
|
||||||
|
}
|
||||||
|
rb.LinearVelocity = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rb != null && !isGrounded && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space)))
|
||||||
|
currentState = RaccoonStates.FALLING;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Rotation()
|
||||||
|
{
|
||||||
|
Vector3 poitionToLookAt;
|
||||||
|
poitionToLookAt.x = xAxisMove;
|
||||||
|
poitionToLookAt.y = 0.0f;
|
||||||
|
poitionToLookAt.z = zAxisMove;
|
||||||
|
|
||||||
|
if (tranform != null)
|
||||||
|
{
|
||||||
|
Quaternion currentRotation = tranform.LocalRotation;
|
||||||
|
if (currentState == RaccoonStates.WALKING || currentState == RaccoonStates.RUNNING)
|
||||||
|
{
|
||||||
|
Quaternion targetRotation = Quaternion.LookRotation(poitionToLookAt, new Vector3(0.0f, 1.0f, 0.0f));
|
||||||
|
tranform.LocalRotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * (float)Time.DeltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Gravity()
|
||||||
|
{
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
//check player vel.y if its close to zero its on the ground
|
||||||
|
if (SHADE.Math.CompareFloat(rb.LinearVelocity.y, 0.0f))
|
||||||
|
isGrounded = true;
|
||||||
|
else
|
||||||
|
isGrounded = false;
|
||||||
|
|
||||||
|
Vector3 v = rb.LinearVelocity;
|
||||||
|
|
||||||
|
if (isGrounded)
|
||||||
|
v.y = groundGravity;
|
||||||
|
else if (currentState == RaccoonStates.FALLING)
|
||||||
|
{
|
||||||
|
float prevYVel = v.y;
|
||||||
|
float newYVel = v.y + (gravity * fallMultipler * (float)Time.DeltaTime);
|
||||||
|
float nextYVel = (prevYVel + newYVel) * 0.5f;
|
||||||
|
v.y = nextYVel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float prevYVel = v.y;
|
||||||
|
float newYVel = v.y + (gravity * (float)Time.DeltaTime);
|
||||||
|
float nextYVel = (prevYVel + newYVel) * 0.5f;
|
||||||
|
v.y = nextYVel;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb.LinearVelocity = v;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GotCaught()
|
||||||
|
{
|
||||||
|
if (currentState == RaccoonStates.CAUGHT && tranform != null)
|
||||||
|
{
|
||||||
|
currentState = RaccoonStates.IDILE;
|
||||||
|
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void onCollisionEnter(CollisionInfo info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -36,4 +36,10 @@ public class RaccoonShowcase : Script
|
||||||
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
||||||
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void onDrawGizmos()
|
||||||
|
{
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f));
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 0.0f), Color.Red);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -8,14 +8,23 @@ public class RaccoonSpin : Script
|
||||||
private float RotateSpeed = 1.0f;
|
private float RotateSpeed = 1.0f;
|
||||||
private float rotation = 0.0f;
|
private float rotation = 0.0f;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
private CallbackEvent emptyEvent;
|
||||||
|
[SerializeField]
|
||||||
private CallbackEvent<int> testEvent;
|
private CallbackEvent<int> testEvent;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
|
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
|
||||||
private Transform Transform;
|
private Transform Transform;
|
||||||
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
||||||
|
|
||||||
|
|
||||||
protected override void awake()
|
protected override void awake()
|
||||||
{
|
{
|
||||||
|
emptyEvent = new CallbackEvent();
|
||||||
|
emptyEvent.RegisterAction(() => Debug.Log("Empty event action!"));
|
||||||
|
testEvent = new CallbackEvent<int>();
|
||||||
|
Action<int> action = (x) => Debug.Log($"{x}");
|
||||||
|
testEvent.RegisterAction(action);
|
||||||
|
|
||||||
Transform = GetComponent<Transform>();
|
Transform = GetComponent<Transform>();
|
||||||
if (Transform == null)
|
if (Transform == null)
|
||||||
{
|
{
|
|
@ -11,7 +11,7 @@ namespace SHADE_Scripting
|
||||||
public class ThirdPersonCamera: Script
|
public class ThirdPersonCamera: Script
|
||||||
{
|
{
|
||||||
|
|
||||||
public float armLength = 4.0f;
|
public float armLength = 2.0f;
|
||||||
public float turnSpeedPitch = 0.3f;
|
public float turnSpeedPitch = 0.3f;
|
||||||
public float turnSpeedYaw = 0.5f;
|
public float turnSpeedYaw = 0.5f;
|
||||||
public float pitchClamp = 45.0f;
|
public float pitchClamp = 45.0f;
|
||||||
|
@ -19,10 +19,13 @@ namespace SHADE_Scripting
|
||||||
|
|
||||||
protected override void awake()
|
protected override void awake()
|
||||||
{
|
{
|
||||||
|
AddComponent<Transform>();
|
||||||
|
|
||||||
if(!GetComponent<Camera>())
|
if(!GetComponent<Camera>())
|
||||||
{
|
{
|
||||||
AddComponent<Camera>();
|
AddComponent<Camera>();
|
||||||
}
|
}
|
||||||
|
GetComponent<Camera>().SetMainCamera();
|
||||||
if (!GetComponent<CameraArm>())
|
if (!GetComponent<CameraArm>())
|
||||||
{
|
{
|
||||||
AddComponent<CameraArm>();
|
AddComponent<CameraArm>();
|
||||||
|
@ -30,26 +33,29 @@ namespace SHADE_Scripting
|
||||||
GetComponent<CameraArm>().ArmLength = armLength;
|
GetComponent<CameraArm>().ArmLength = armLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void update()
|
protected override void update()
|
||||||
{
|
{
|
||||||
CameraArm arm = GetComponent<CameraArm>();
|
if (Input.GetMouseButton(Input.MouseCode.RightButton))
|
||||||
if(arm)
|
{
|
||||||
|
CameraArm arm = GetComponent<CameraArm>();
|
||||||
|
if (arm)
|
||||||
|
{
|
||||||
|
Vector2 vel = Input.GetMouseVelocity();
|
||||||
|
arm.Pitch -= vel.y * turnSpeedPitch * Time.DeltaTimeF;
|
||||||
|
arm.Yaw += vel.x * turnSpeedYaw * Time.DeltaTimeF;
|
||||||
|
|
||||||
|
if (arm.Pitch > pitchClamp)
|
||||||
{
|
{
|
||||||
Vector2 vel = Input.GetMouseVelocity();
|
arm.Pitch = pitchClamp;
|
||||||
arm.Pitch -= vel.y * turnSpeedPitch * Time.DeltaTimeF;
|
|
||||||
arm.Yaw += vel.x * turnSpeedYaw * Time.DeltaTimeF;
|
|
||||||
|
|
||||||
if(arm.Pitch > pitchClamp)
|
|
||||||
{
|
|
||||||
arm.Pitch = pitchClamp;
|
|
||||||
}
|
|
||||||
else if(arm.Pitch < -pitchClamp)
|
|
||||||
{
|
|
||||||
arm.Pitch = -pitchClamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (arm.Pitch < 0)
|
||||||
|
{
|
||||||
|
arm.Pitch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : require
|
||||||
|
|
||||||
|
layout(location = 0) in struct
|
||||||
|
{
|
||||||
|
vec4 vertColor;
|
||||||
|
} In;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outColor = In.vertColor;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: DebugDraw_FS
|
||||||
|
ID: 36671027
|
||||||
|
Type: 2
|
|
@ -0,0 +1,24 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_KHR_vulkan_glsl : enable
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 aVertexPos;
|
||||||
|
layout(location = 1) in vec4 aVertColor;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) out struct
|
||||||
|
{
|
||||||
|
vec4 vertColor; // location 0
|
||||||
|
|
||||||
|
} Out;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f);
|
||||||
|
Out.vertColor = aVertColor;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: DebugDraw_VS
|
||||||
|
ID: 48002439
|
||||||
|
Type: 2
|
|
@ -21,7 +21,8 @@ layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
|
||||||
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
||||||
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
|
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
|
||||||
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||||
layout(set = 4, binding = 4, rgba8) uniform image2D targetImage;
|
layout(set = 4, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||||
|
layout(set = 4, binding = 5, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform LightCounts
|
layout(set = 1, binding = 0) uniform LightCounts
|
||||||
{
|
{
|
||||||
|
@ -51,33 +52,46 @@ 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
|
||||||
vec3 positionWorld = imageLoad (positions, globalThread).rgb;
|
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||||
|
|
||||||
// normal of fragment
|
// normal of fragment
|
||||||
vec3 normalWorld = imageLoad(normals, globalThread).rgb;
|
vec3 normalView = imageLoad(normals, globalThread).rgb;
|
||||||
|
|
||||||
|
// light layer index
|
||||||
|
uint lightLayer = imageLoad (lightLayerData, globalThread).r;
|
||||||
|
|
||||||
vec3 fragColor = vec3 (0.0f);
|
vec3 fragColor = vec3 (0.0f);
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
||||||
{
|
{
|
||||||
// get normalized direction of light
|
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||||
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
|
{
|
||||||
|
// get normalized direction of light
|
||||||
|
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
|
||||||
|
|
||||||
// Get diffuse strength
|
// Get diffuse strength
|
||||||
float diffuseStrength = max (0, dot (dLightNormalized, normalWorld));
|
float diffuseStrength = max (0, dot (dLightNormalized, normalView));
|
||||||
|
|
||||||
// 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)
|
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
||||||
{
|
{
|
||||||
// Just do some add
|
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
||||||
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
{
|
||||||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
// Just do some add
|
||||||
|
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
||||||
|
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
|
||||||
|
fragColor *= ssaoVal;
|
||||||
|
|
||||||
// store result into result image
|
// store result into result image
|
||||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor, 1.0f));
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||||
|
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -0,0 +1,58 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
#define BLUR_WIDTH 5
|
||||||
|
#define BLUR_HALF_WIDTH BLUR_WIDTH / 2
|
||||||
|
#define SHM_WIDTH BLUR_WIDTH + 16 - 1
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, r8) uniform image2D ssaoImage;
|
||||||
|
layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage;
|
||||||
|
|
||||||
|
|
||||||
|
float GetSSAOValue(ivec2 uv, ivec2 imageSize)
|
||||||
|
{
|
||||||
|
if (uv.x >= 0 && uv.y >= 0 && uv.x < imageSize.x && uv.y < imageSize.y)
|
||||||
|
{
|
||||||
|
return imageLoad (ssaoImage, uv).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared float sharedPixels[16 + BLUR_WIDTH - 1][16 + BLUR_WIDTH - 1];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||||
|
ivec2 localThread = ivec2 (gl_LocalInvocationID.xy);
|
||||||
|
ivec2 inputImageSize = imageSize(ssaoImage);
|
||||||
|
|
||||||
|
// Load color into shared memory
|
||||||
|
ivec2 start = ivec2 (gl_WorkGroupID) * ivec2 (gl_WorkGroupSize) - (BLUR_HALF_WIDTH);
|
||||||
|
for (int i = localThread.x; i < SHM_WIDTH; i += int (gl_WorkGroupSize.x))
|
||||||
|
{
|
||||||
|
for (int j = localThread.y; j < SHM_WIDTH; j += int (gl_WorkGroupSize.y))
|
||||||
|
{
|
||||||
|
float value = GetSSAOValue (start + ivec2 (i, j), inputImageSize);
|
||||||
|
sharedPixels[i][j] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for all shared memory to load
|
||||||
|
barrier();
|
||||||
|
|
||||||
|
ivec2 shmStart = ivec2 (localThread + (BLUR_HALF_WIDTH));
|
||||||
|
|
||||||
|
float sum = 0;
|
||||||
|
for (int i = -BLUR_HALF_WIDTH; i <= BLUR_HALF_WIDTH; ++i)
|
||||||
|
{
|
||||||
|
for (int j = -BLUR_HALF_WIDTH; j <= BLUR_HALF_WIDTH; ++j)
|
||||||
|
{
|
||||||
|
float sharedVal = sharedPixels[shmStart.x + i][shmStart.y + j];
|
||||||
|
sum += sharedVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum /= (BLUR_WIDTH * BLUR_WIDTH);
|
||||||
|
imageStore(ssaoBlurImage, globalThread, vec4(sum.rrr, 1.0f));
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: SSAOBlur_CS
|
||||||
|
ID: 39760835
|
||||||
|
Type: 2
|
|
@ -0,0 +1,104 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
const uint NUM_SAMPLES = 64;
|
||||||
|
const uint NUM_ROTATIONS = 16;
|
||||||
|
const int ROTATION_KERNEL_W = 4;
|
||||||
|
const int ROTATION_KERNEL_H = 4;
|
||||||
|
|
||||||
|
// can perhaps pass in as push constant.
|
||||||
|
const float RADIUS = 0.5f;
|
||||||
|
const float BIAS = 0.025f;
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
|
||||||
|
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
||||||
|
layout(set = 4, binding = 2, rgba32f) uniform image2D outputImage;
|
||||||
|
|
||||||
|
|
||||||
|
// SSAO data
|
||||||
|
layout(std430, set = 5, binding = 0) buffer SSAOData
|
||||||
|
{
|
||||||
|
vec4 samples[NUM_SAMPLES];
|
||||||
|
|
||||||
|
} ssaoData;
|
||||||
|
|
||||||
|
layout (set = 5, binding = 1) uniform sampler2D noiseTexture;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
|
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// image size of the SSAO image
|
||||||
|
ivec2 ssaoSize = imageSize (outputImage);
|
||||||
|
|
||||||
|
// global thread
|
||||||
|
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
// load all the necessary variables
|
||||||
|
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
|
||||||
|
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
|
||||||
|
|
||||||
|
// Get the noise dimension. This should be 4x4
|
||||||
|
vec2 noiseDim = vec2 (textureSize(noiseTexture, 0));
|
||||||
|
|
||||||
|
// Get normlized thread UV coordinates
|
||||||
|
vec2 threadUV = (vec2(globalThread)) / vec2(ssaoSize);
|
||||||
|
vec2 noiseUVMult = vec2 (vec2(ssaoSize) / noiseDim);
|
||||||
|
noiseUVMult *= threadUV;
|
||||||
|
|
||||||
|
// sample from the noise
|
||||||
|
vec3 randomVec = texture(noiseTexture, noiseUVMult).rgb;
|
||||||
|
|
||||||
|
// Gram schmidt
|
||||||
|
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
|
||||||
|
vec3 bitangent = normalize (cross (tangent, viewSpaceNormal));
|
||||||
|
|
||||||
|
// matrix for tangent space to view space
|
||||||
|
mat3 TBN = mat3(tangent, bitangent, viewSpaceNormal);
|
||||||
|
|
||||||
|
float occlusion = 0.0f;
|
||||||
|
for (int i = 0; i < NUM_SAMPLES; ++i)
|
||||||
|
{
|
||||||
|
// We want to get a position at an offset from the view space position. Offset scaled by radius.
|
||||||
|
vec3 displacementVector = TBN * ssaoData.samples[i].rgb;
|
||||||
|
|
||||||
|
// Why are we adding positions?
|
||||||
|
displacementVector = viewSpacePos + displacementVector * RADIUS;
|
||||||
|
|
||||||
|
// Now we take that offset position and bring it to clip space
|
||||||
|
vec4 offsetPos = vec4 (displacementVector, 1.0f);
|
||||||
|
offsetPos = cameraData.projMat * offsetPos;
|
||||||
|
|
||||||
|
// then we do perspective division
|
||||||
|
offsetPos.xyz /= offsetPos.w;
|
||||||
|
|
||||||
|
// and bring it from [-1, 1] to screen coordinates
|
||||||
|
offsetPos.xyz = ((offsetPos.xyz * 0.5f) + 0.5f);
|
||||||
|
offsetPos.xy *= vec2(ssaoSize.xy);
|
||||||
|
|
||||||
|
// Now we attempt to get a position at that point.
|
||||||
|
float sampleDepth = imageLoad (positions, ivec2 (offsetPos.xy)).z;
|
||||||
|
|
||||||
|
// skip checks
|
||||||
|
if (sampleDepth == 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if sampled fragment is in front of current fragment, just occlude
|
||||||
|
float rangeCheck = smoothstep (0.0f, 1.0f, RADIUS / abs (viewSpacePos.z - sampleDepth));
|
||||||
|
occlusion += (sampleDepth <= displacementVector.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
|
||||||
|
|
||||||
|
// store result into result image
|
||||||
|
imageStore(outputImage, globalThread, occlusion.rrrr);
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: SSAO_CS
|
||||||
|
ID: 38430899
|
||||||
|
Type: 2
|
|
@ -43,7 +43,7 @@ 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 / MatProp.data[In2.materialIndex].alpha;
|
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
||||||
|
|
||||||
outEntityID = In2.eid;
|
outEntityID = In2.eid;
|
||||||
lightLayerIndices = In2.lightLayerIndex;
|
lightLayerIndices = In2.lightLayerIndex;
|
||||||
|
|
Binary file not shown.
|
@ -33,18 +33,31 @@ layout(set = 2, binding = 0) uniform CameraData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
mat4 vpMat;
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
} cameraData;
|
} cameraData;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
Out2.materialIndex = gl_InstanceIndex;
|
Out2.materialIndex = gl_InstanceIndex;
|
||||||
Out2.eid = integerData[0];
|
Out2.eid = integerData[0];
|
||||||
Out2.lightLayerIndex = integerData[1];
|
Out2.lightLayerIndex = integerData[1];
|
||||||
|
|
||||||
Out.vertPos = worldTransform * vec4(aVertexPos, 1.0f);
|
// for transforming gBuffer position and normal data
|
||||||
|
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||||
|
|
||||||
|
// gBuffer position will be in view space
|
||||||
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
Out.normal.rgb = mat3(transpose(inverse(worldTransform))) * aNormal.rgb;
|
|
||||||
|
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||||
|
|
||||||
|
// normals are also in view space
|
||||||
|
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||||
|
|
||||||
|
// clip space for rendering
|
||||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
}
|
}
|
Binary file not shown.
|
@ -7,7 +7,7 @@ echo "SHADE DEPENDENCIES (Default - All in 10 Seconds)"
|
||||||
echo "A - All"
|
echo "A - All"
|
||||||
echo "B - VMA"
|
echo "B - VMA"
|
||||||
echo "C - msdf"
|
echo "C - msdf"
|
||||||
echo "D - assimp"
|
echo "D - ModelCompiler"
|
||||||
echo "E - spdlog"
|
echo "E - spdlog"
|
||||||
echo "F - reactphysics3d"
|
echo "F - reactphysics3d"
|
||||||
echo "G - imgui"
|
echo "G - imgui"
|
||||||
|
@ -29,7 +29,7 @@ set _e=%ERRORLEVEL%
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
if %_e%==2 goto VMA
|
if %_e%==2 goto VMA
|
||||||
if %_e%==3 goto MSDF
|
if %_e%==3 goto MSDF
|
||||||
if %_e%==4 goto assimp
|
if %_e%==4 goto ModelCompiler
|
||||||
if %_e%==5 goto spdlog
|
if %_e%==5 goto spdlog
|
||||||
if %_e%==6 goto reactphysics3d
|
if %_e%==6 goto reactphysics3d
|
||||||
if %_e%==7 goto imgui
|
if %_e%==7 goto imgui
|
||||||
|
@ -53,12 +53,13 @@ if %_e%==2 (goto :done) else (goto :MSDF)
|
||||||
echo -----------------------MSDF----------------------------
|
echo -----------------------MSDF----------------------------
|
||||||
rmdir "Dependencies/msdf" /S /Q
|
rmdir "Dependencies/msdf" /S /Q
|
||||||
git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen.git "Dependencies/msdf"
|
git clone --recurse-submodules https://github.com/SHADE-DP/msdf-atlas-gen.git "Dependencies/msdf"
|
||||||
if %_e%==3 (goto :done) else (goto :assimp)
|
if %_e%==3 (goto :done) else (goto :ModelCompiler)
|
||||||
|
|
||||||
:assimp
|
:ModelCompiler
|
||||||
echo -----------------------assimp----------------------------
|
echo -----------------------ModelCompiler----------------------------
|
||||||
rmdir "Dependencies/assimp" /S /Q
|
rmdir "Dependencies/ModelCompiler" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/assimp"
|
git clone https://github.com/SHADE-DP/ModelCompiler.git "Dependencies/ModelCompiler"
|
||||||
|
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/ModelCompiler/Dependencies/assimp"
|
||||||
if %_e%==4 (goto :done) else (goto :spdlog)
|
if %_e%==4 (goto :done) else (goto :spdlog)
|
||||||
|
|
||||||
@REM :ktx
|
@REM :ktx
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
IncludeDir = {}
|
IncludeDir = {}
|
||||||
IncludeDir["assimp"] = "%{wks.location}\\Dependencies\\assimp"
|
IncludeDir["ModelCompiler"] = "%{wks.location}\\Dependencies\\ModelCompiler"
|
||||||
IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui"
|
IncludeDir["imgui"] = "%{wks.location}\\Dependencies\\imgui"
|
||||||
IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo"
|
IncludeDir["imguizmo"] = "%{wks.location}\\Dependencies\\imguizmo"
|
||||||
IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes"
|
IncludeDir["imnodes"] = "%{wks.location}\\Dependencies\\imnodes"
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "FRC/SHFramerateController.h"
|
#include "FRC/SHFramerateController.h"
|
||||||
#include "AudioSystem/SHAudioSystem.h"
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
#include "Camera/SHCameraSystem.h"
|
#include "Camera/SHCameraSystem.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
@ -40,8 +41,11 @@
|
||||||
|
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Scenes/SBMainScene.h"
|
||||||
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -58,8 +62,9 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
// Set working directory
|
// Set working directory
|
||||||
SHFileUtilities::SetWorkDirToExecDir();
|
SHFileUtilities::SetWorkDirToExecDir();
|
||||||
|
WindowData wndData{};
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
auto& appConfig = SHConfigurationManager::LoadApplicationConfig(&wndData);
|
||||||
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
|
||||||
|
|
||||||
// Create Systems
|
// Create Systems
|
||||||
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||||
|
@ -69,12 +74,20 @@ namespace Sandbox
|
||||||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
|
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||||
|
|
||||||
|
// Link up SHDebugDraw
|
||||||
|
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||||
SHSystemManager::CreateSystem<SHEditor>();
|
SHSystemManager::CreateSystem<SHEditor>();
|
||||||
SHSystemManager::GetSystem<SHEditor>()->SetSDLWindow(sdlWindow);
|
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
|
{
|
||||||
|
editor->SetSDLWindow(sdlWindow);
|
||||||
|
editor->SetSHWindow(&window);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create Routines
|
// Create Routines
|
||||||
|
@ -88,9 +101,12 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
|
@ -120,9 +136,12 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSystemManager::Init();
|
SHSystemManager::Init();
|
||||||
|
|
||||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
SHSceneManager::InitSceneManager<SBMainScene>(appConfig.startingSceneID);
|
||||||
|
|
||||||
SHFrameRateController::UpdateFRC();
|
SHFrameRateController::UpdateFRC();
|
||||||
|
|
||||||
|
// Link up SHDebugDraw
|
||||||
|
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBApplication::Update(void)
|
void SBApplication::Update(void)
|
||||||
|
@ -141,6 +160,13 @@ namespace Sandbox
|
||||||
#endif
|
#endif
|
||||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||||
editor->PollPicking();
|
editor->PollPicking();
|
||||||
|
|
||||||
|
static bool drawColliders = false;
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
||||||
|
{
|
||||||
|
drawColliders = !drawColliders;
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "SBpch.h"
|
||||||
|
#include "SBMainScene.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
|
using namespace SHADE;
|
||||||
|
|
||||||
|
namespace Sandbox
|
||||||
|
{
|
||||||
|
|
||||||
|
void SBMainScene::WindowFocusFunc([[maybe_unused]] void* window, int focused)
|
||||||
|
{
|
||||||
|
if (focused)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Load()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Init()
|
||||||
|
{
|
||||||
|
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Update(float dt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Render()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Unload()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBMainScene::Free()
|
||||||
|
{
|
||||||
|
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Scene/SHScene.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
|
||||||
|
namespace Sandbox
|
||||||
|
{
|
||||||
|
class SBMainScene : public SHADE::SHScene
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EntityID camera;
|
||||||
|
EntityID testObj;
|
||||||
|
std::vector<EntityID> stressTestObjects;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Load();
|
||||||
|
virtual void Init();
|
||||||
|
virtual void Update(float dt);
|
||||||
|
virtual void Render();
|
||||||
|
virtual void Free();
|
||||||
|
virtual void Unload();
|
||||||
|
|
||||||
|
//TODO: Change to new window DO IT IN CPP TOO
|
||||||
|
void WindowFocusFunc(void* window, int focused);
|
||||||
|
|
||||||
|
SBMainScene(void) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Camera/SHCameraComponent.h"
|
||||||
#include "Math/SHColour.h"
|
#include "Math/SHColour.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ namespace Sandbox
|
||||||
switch (asset.type)
|
switch (asset.type)
|
||||||
{
|
{
|
||||||
case AssetType::MESH:
|
case AssetType::MESH:
|
||||||
if (asset.name == "Cube.012")
|
if (asset.name == "Raccoon")
|
||||||
handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
|
handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
|
||||||
break;
|
break;
|
||||||
case AssetType::TEXTURE:
|
case AssetType::TEXTURE:
|
||||||
|
@ -63,58 +65,20 @@ namespace Sandbox
|
||||||
SHResourceManager::FinaliseChanges();
|
SHResourceManager::FinaliseChanges();
|
||||||
|
|
||||||
// Create Materials
|
// Create Materials
|
||||||
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
auto baseRaccoonMat = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||||
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
|
auto baseRaccoonMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat);
|
||||||
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
|
baseRaccoonMatInstant->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
customMat->SetProperty("data.textureIndex", 0);
|
baseRaccoonMatInstant->SetProperty("data.textureIndex", 0);
|
||||||
customMat->SetProperty("data.alpha", 0.1f);
|
baseRaccoonMatInstant->SetProperty("data.alpha", 0.1f);
|
||||||
|
|
||||||
// Create Stress Test Objects
|
auto baseFloorMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat);
|
||||||
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
|
baseFloorMatInstant->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
constexpr int NUM_ROWS = 3;
|
baseFloorMatInstant->SetProperty("data.textureIndex", 0);
|
||||||
constexpr int NUM_COLS = 1;
|
baseFloorMatInstant->SetProperty("data.alpha", 0.1f);
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
|
|
||||||
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
|
|
||||||
|
|
||||||
for (int y = 0; y < NUM_ROWS; ++y)
|
auto dummy = SHEntityManager::CreateEntity<>();
|
||||||
for (int x = 0; x < NUM_COLS; ++x)
|
|
||||||
{
|
|
||||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
|
||||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
|
||||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
|
||||||
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
|
|
||||||
|
|
||||||
//renderable.Mesh = handles.front();
|
auto floor = SHEntityManager::CreateEntity<SHTransformComponent,SHRenderable, SHRigidBodyComponent, SHColliderComponent>();
|
||||||
renderable.SetMesh(CUBE_MESH);
|
|
||||||
renderable.SetMaterial(customMat);
|
|
||||||
|
|
||||||
if (y == 50)
|
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
//Set initial positions
|
|
||||||
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) });
|
|
||||||
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
|
|
||||||
transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
|
|
||||||
transform.SetWorldScale(TEST_OBJ_SCALE);
|
|
||||||
|
|
||||||
collider.AddBoundingBox(SHVec3::One, SHVec3::Zero);
|
|
||||||
stressTestObjects.emplace_back(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
|
||||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
|
|
||||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
|
|
||||||
|
|
||||||
renderable.SetMesh(handles.front());
|
|
||||||
renderable.SetMaterial(customMat);
|
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
|
||||||
|
|
||||||
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
|
|
||||||
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
|
||||||
|
|
||||||
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
|
||||||
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
|
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
|
||||||
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
|
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
|
||||||
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
|
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
|
||||||
|
@ -123,12 +87,12 @@ namespace Sandbox
|
||||||
floorRenderable.SetMesh(CUBE_MESH);
|
floorRenderable.SetMesh(CUBE_MESH);
|
||||||
floorRenderable.SetMaterial(graphicsSystem->GetDefaultMaterialInstance());
|
floorRenderable.SetMaterial(graphicsSystem->GetDefaultMaterialInstance());
|
||||||
|
|
||||||
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
|
floorTransform.SetWorldScale({ 17.5f, 0.5f, 17.5f });
|
||||||
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
|
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
|
||||||
|
|
||||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
auto* floorBox = floorCollider.AddBoundingBox();
|
floorCollider.AddBoundingBox();
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
@ -136,17 +100,97 @@ namespace Sandbox
|
||||||
//testObjRenderable.Mesh = CUBE_MESH;
|
//testObjRenderable.Mesh = CUBE_MESH;
|
||||||
//testObjRenderable.SetMaterial(matInst);
|
//testObjRenderable.SetMaterial(matInst);
|
||||||
|
|
||||||
|
//raccoon =======================================================================================================================
|
||||||
|
auto racoon = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "Player");
|
||||||
|
auto& racoonRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(racoon);
|
||||||
|
auto& racoonTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoon);
|
||||||
|
auto& racoonRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(racoon);
|
||||||
|
auto& racoonCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(racoon);
|
||||||
|
|
||||||
|
racoonRenderable.SetMesh(handles.front());
|
||||||
|
racoonRenderable.SetMaterial(baseRaccoonMatInstant);
|
||||||
|
|
||||||
|
racoonTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
|
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
|
racoonCollider.AddBoundingBox();
|
||||||
|
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
|
racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||||
|
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
||||||
|
SHSceneManager::GetCurrentSceneGraph().SetParent(racoonItemLocation, racoon);
|
||||||
|
|
||||||
|
auto racoonCamera = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||||
|
SHSceneManager::GetCurrentSceneGraph().SetParent(racoonCamera, racoon);
|
||||||
|
//================================================================================================================================
|
||||||
|
|
||||||
|
//item ===========================================================================================================================
|
||||||
|
auto item = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "item");
|
||||||
|
auto& itemRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(item);
|
||||||
|
auto& itemTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(item);
|
||||||
|
auto& itemRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(item);
|
||||||
|
auto& itemCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(item);
|
||||||
|
|
||||||
|
itemRenderable.SetMesh(handles.front());
|
||||||
|
itemRenderable.SetMaterial(baseRaccoonMatInstant);
|
||||||
|
|
||||||
|
itemTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
|
itemTransform.SetWorldPosition({ 0.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
|
itemCollider.AddBoundingBox();
|
||||||
|
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||||
|
itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||||
|
|
||||||
|
itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
|
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).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
itemRigidBody.SetInterpolate(false);
|
||||||
|
itemRigidBody.SetFreezeRotationX(true);
|
||||||
|
itemRigidBody.SetFreezeRotationY(true);
|
||||||
|
itemRigidBody.SetFreezeRotationZ(true);
|
||||||
|
//================================================================================================================================
|
||||||
|
|
||||||
|
//AI =============================================================================================================================
|
||||||
|
auto AI = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "AI");
|
||||||
|
auto& AIRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(AI);
|
||||||
|
auto& AITransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(AI);
|
||||||
|
auto& AIRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(AI);
|
||||||
|
auto& AICollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(AI);
|
||||||
|
|
||||||
|
AIRenderable.SetMesh(handles.front());
|
||||||
|
AIRenderable.SetMaterial(baseRaccoonMatInstant);
|
||||||
|
|
||||||
|
AITransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||||
|
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||||
|
|
||||||
|
AICollider.AddBoundingBox();
|
||||||
|
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
|
AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
AIRigidBody.SetInterpolate(false);
|
||||||
|
AIRigidBody.SetFreezeRotationX(true);
|
||||||
|
AIRigidBody.SetFreezeRotationY(true);
|
||||||
|
AIRigidBody.SetFreezeRotationZ(true);
|
||||||
|
//================================================================================================================================
|
||||||
|
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
|
scriptEngine->AddScript(racoon, "PlayerController");
|
||||||
|
scriptEngine->AddScript(racoon, "PickAndThrow");
|
||||||
|
scriptEngine->AddScript(racoonCamera, "ThirdPersonCamera");
|
||||||
|
scriptEngine->AddScript(AI, "AIPrototype");
|
||||||
|
scriptEngine->AddScript(item, "Item");
|
||||||
|
|
||||||
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
||||||
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
||||||
|
|
||||||
renderableShowcase.SetMesh(handles.front());
|
renderableShowcase.SetMesh(handles.front());
|
||||||
renderableShowcase.SetMaterial(customMat);
|
renderableShowcase.SetMaterial(baseRaccoonMatInstant);
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||||
|
|
||||||
|
@ -187,6 +231,8 @@ namespace Sandbox
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->RemoveAllScripts(testObj);
|
scriptEngine->RemoveAllScripts(testObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Render()
|
void SBTestScene::Render()
|
||||||
|
|
|
@ -34,6 +34,99 @@ namespace SHADE
|
||||||
Object TargetObject { get; }
|
Object TargetObject { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
|
/// This variant accepts functions with 0 parameter.
|
||||||
|
/// </summary>
|
||||||
|
public class CallbackAction : ICallbackAction
|
||||||
|
{
|
||||||
|
#region Properties ------------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public Object TargetObject { get; private set; }
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string TargetMethodName => targetMethod == null ? "" : targetMethod.Name;
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsRuntimeAction => targetAction != null;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields ------------------------------------------------------------------
|
||||||
|
private MethodInfo targetMethod;
|
||||||
|
private Action targetAction;
|
||||||
|
private Object[] parameters;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors ------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs an empty Callback action.
|
||||||
|
/// </summary>
|
||||||
|
public CallbackAction() {}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a CallbackAction that represents a call to the specified static
|
||||||
|
/// method.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if a method that is not compatible with the target is specified. The method's
|
||||||
|
/// source type must match the target's type.
|
||||||
|
/// </exception>
|
||||||
|
public CallbackAction(MethodInfo method)
|
||||||
|
{
|
||||||
|
// No errors, assign
|
||||||
|
targetMethod = method;
|
||||||
|
|
||||||
|
// Create storage for parameters for calling
|
||||||
|
parameters = new Object[0];
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a CallbackAction that represents a call to a specified member
|
||||||
|
/// method on the specified target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">Object to call the method on.</param>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// Thrown if a method that is not compatible with the target is specified. The method's
|
||||||
|
/// source type must match the target's type.
|
||||||
|
/// </exception>
|
||||||
|
public CallbackAction(Object target, MethodInfo method)
|
||||||
|
{
|
||||||
|
// Error Checks
|
||||||
|
if (method.DeclaringType != target.GetType())
|
||||||
|
throw new ArgumentException("[CallbackAction] Attempted register an action using an incompatible target object and method.");
|
||||||
|
|
||||||
|
// No errors, assign
|
||||||
|
TargetObject = target;
|
||||||
|
targetMethod = method;
|
||||||
|
|
||||||
|
// Create storage for parameters for calling
|
||||||
|
parameters = new Object[0];
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a Callback action based on an action.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">Action that wraps a function to be called.</param>
|
||||||
|
public CallbackAction(Action action)
|
||||||
|
{
|
||||||
|
targetAction = action;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usage Functions ---------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the CallbackAction's stored method/action with the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
if (targetAction != null)
|
||||||
|
{
|
||||||
|
targetAction.Invoke();
|
||||||
|
}
|
||||||
|
else if (targetMethod != null)
|
||||||
|
{
|
||||||
|
_ = targetMethod.Invoke(TargetObject, parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a function call that can be serialised and put togetheer with scripts.
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
/// This variant accepts functions with 1 parameter.
|
/// This variant accepts functions with 1 parameter.
|
||||||
|
|
|
@ -50,12 +50,12 @@ namespace SHADE
|
||||||
Object TargetObject { get; }
|
Object TargetObject { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<# for (int i = 1; i <= max; ++i) { #>
|
<# for (int i = 0; i <= max; ++i) { #>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a function call that can be serialised and put togetheer with scripts.
|
/// Represents a function call that can be serialised and put togetheer with scripts.
|
||||||
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
|
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackAction
|
public class CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackAction
|
||||||
{
|
{
|
||||||
#region Properties ------------------------------------------------------------
|
#region Properties ------------------------------------------------------------
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -68,7 +68,7 @@ namespace SHADE
|
||||||
|
|
||||||
#region Fields ------------------------------------------------------------------
|
#region Fields ------------------------------------------------------------------
|
||||||
private MethodInfo targetMethod;
|
private MethodInfo targetMethod;
|
||||||
private Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> targetAction;
|
private Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> targetAction;
|
||||||
private Object[] parameters;
|
private Object[] parameters;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ namespace SHADE
|
||||||
/// Constructs a Callback action based on an action.
|
/// Constructs a Callback action based on an action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">Action that wraps a function to be called.</param>
|
/// <param name="action">Action that wraps a function to be called.</param>
|
||||||
public CallbackAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public CallbackAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
targetAction = action;
|
targetAction = action;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,92 @@ namespace SHADE
|
||||||
IEnumerable<ICallbackAction> Actions { get; }
|
IEnumerable<ICallbackAction> Actions { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
|
/// specified by the user of this class.
|
||||||
|
/// This variant accepts CallbackEvents with 1 generic parameter.
|
||||||
|
/// </summary>
|
||||||
|
public class CallbackEvent : ICallbackEvent
|
||||||
|
{
|
||||||
|
#region Properties --------------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerable<ICallbackAction> Actions => actions;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Fields ------------------------------------------------------------------
|
||||||
|
private List<ICallbackAction> actions = new List<ICallbackAction>();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usage Functions ---------------------------------------------------------
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void RegisterAction()
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction());
|
||||||
|
}
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void RegisterAction(ICallbackAction action)
|
||||||
|
{
|
||||||
|
// Check if valid action
|
||||||
|
if (action.GetType() != typeof(CallbackAction))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.Add(action);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">CallbackAction to add.</param>
|
||||||
|
public void RegisterAction(CallbackAction action)
|
||||||
|
{
|
||||||
|
actions.Add(action);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
|
public void RegisterAction(Action action)
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction(action));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">Object to call the method on.</param>
|
||||||
|
/// <param name="method">Method to call.</param>
|
||||||
|
public void RegisterAction(Object target, MethodInfo method)
|
||||||
|
{
|
||||||
|
actions.Add(new CallbackAction(target, method));
|
||||||
|
}
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void DeregisterAction(ICallbackAction action)
|
||||||
|
{
|
||||||
|
if (!actions.Remove(action))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Attempted to deregister invalid action. Ignored.", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes all stored CallbackActions with the specified parameters.
|
||||||
|
/// </summary>
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
foreach (CallbackAction action in actions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container of CallbackActions that is correlated to a specific scenario as
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
/// specified by the user of this class.
|
/// specified by the user of this class.
|
||||||
|
@ -88,7 +174,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1> action)
|
public void RegisterAction(Action<T1> action)
|
||||||
|
@ -96,7 +182,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1>(action));
|
actions.Add(new CallbackAction<T1>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -174,7 +260,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2> action)
|
public void RegisterAction(Action<T1, T2> action)
|
||||||
|
@ -182,7 +268,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2>(action));
|
actions.Add(new CallbackAction<T1, T2>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -260,7 +346,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3> action)
|
public void RegisterAction(Action<T1, T2, T3> action)
|
||||||
|
@ -268,7 +354,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3>(action));
|
actions.Add(new CallbackAction<T1, T2, T3>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -346,7 +432,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
public void RegisterAction(Action<T1, T2, T3, T4> action)
|
||||||
|
@ -354,7 +440,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -432,7 +518,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
|
||||||
|
@ -440,7 +526,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -518,7 +604,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
|
||||||
|
@ -526,7 +612,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -604,7 +690,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
|
||||||
|
@ -612,7 +698,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -690,7 +776,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
|
||||||
|
@ -698,7 +784,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -776,7 +862,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
|
||||||
|
@ -784,7 +870,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
@ -862,7 +948,7 @@ namespace SHADE
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
|
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
|
||||||
|
@ -870,7 +956,7 @@ namespace SHADE
|
||||||
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
|
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
|
|
|
@ -61,13 +61,13 @@ namespace SHADE
|
||||||
IEnumerable<ICallbackAction> Actions { get; }
|
IEnumerable<ICallbackAction> Actions { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
<# for (int i = 1; i <= max; ++i) { #>
|
<# for (int i = 0; i <= max; ++i) { #>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A container of CallbackActions that is correlated to a specific scenario as
|
/// A container of CallbackActions that is correlated to a specific scenario as
|
||||||
/// specified by the user of this class.
|
/// specified by the user of this class.
|
||||||
/// This variant accepts CallbackEvents with 1 generic parameter.
|
/// This variant accepts CallbackEvents with 1 generic parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CallbackEvent<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackEvent
|
public class CallbackEvent<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackEvent
|
||||||
{
|
{
|
||||||
#region Properties --------------------------------------------------------------
|
#region Properties --------------------------------------------------------------
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -82,13 +82,13 @@ namespace SHADE
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RegisterAction()
|
public void RegisterAction()
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>());
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>());
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RegisterAction(ICallbackAction action)
|
public void RegisterAction(ICallbackAction action)
|
||||||
{
|
{
|
||||||
// Check if valid action
|
// Check if valid action
|
||||||
if (action.GetType() != typeof(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>))
|
if (action.GetType() != typeof(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>))
|
||||||
{
|
{
|
||||||
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
|
||||||
return;
|
return;
|
||||||
|
@ -100,26 +100,26 @@ namespace SHADE
|
||||||
/// Adds a CallbackAction into the event.
|
/// Adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">CallbackAction to add.</param>
|
/// <param name="action">CallbackAction to add.</param>
|
||||||
public void RegisterAction(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public void RegisterAction(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
actions.Add(action);
|
actions.Add(action);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
/// <param name="action">System.Action to add as a CallbackAction.</param>
|
||||||
public void RegisterAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
|
public void RegisterAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(action));
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(action));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs and adds a CallbackACtion into the event.
|
/// Constructs and adds a CallbackAction into the event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">Object to call the method on.</param>
|
/// <param name="target">Object to call the method on.</param>
|
||||||
/// <param name="method">Method to call.</param>
|
/// <param name="method">Method to call.</param>
|
||||||
public void RegisterAction(Object target, MethodInfo method)
|
public void RegisterAction(Object target, MethodInfo method)
|
||||||
{
|
{
|
||||||
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(target, method));
|
actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(target, method));
|
||||||
}
|
}
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void DeregisterAction(ICallbackAction action)
|
public void DeregisterAction(ICallbackAction action)
|
||||||
|
@ -132,9 +132,9 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invokes all stored CallbackActions with the specified parameters.
|
/// Invokes all stored CallbackActions with the specified parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Invoke(<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } #>)
|
public void Invoke(<# if (i != 0) { for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } } #>)
|
||||||
{
|
{
|
||||||
foreach (CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action in actions)
|
foreach (CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action in actions)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,6 @@ project "SHADE_Engine"
|
||||||
|
|
||||||
externalincludedirs
|
externalincludedirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.assimp}\\include",
|
|
||||||
"%{IncludeDir.imgui}",
|
"%{IncludeDir.imgui}",
|
||||||
"%{IncludeDir.imguizmo}",
|
"%{IncludeDir.imguizmo}",
|
||||||
"%{IncludeDir.imnodes}",
|
"%{IncludeDir.imnodes}",
|
||||||
|
@ -52,8 +51,6 @@ project "SHADE_Engine"
|
||||||
{
|
{
|
||||||
"%{prj.location}/libs",
|
"%{prj.location}/libs",
|
||||||
"%{IncludeDir.VULKAN}/Lib",
|
"%{IncludeDir.VULKAN}/Lib",
|
||||||
"%{IncludeDir.assimp}/lib/Debug",
|
|
||||||
"%{IncludeDir.assimp}/lib/Release",
|
|
||||||
"%{IncludeDir.RTTR}/lib",
|
"%{IncludeDir.RTTR}/lib",
|
||||||
"%{IncludeDir.SDL}/lib",
|
"%{IncludeDir.SDL}/lib",
|
||||||
"%{IncludeDir.spdlog}/lib",
|
"%{IncludeDir.spdlog}/lib",
|
||||||
|
@ -119,7 +116,8 @@ project "SHADE_Engine"
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
postbuildcommands
|
postbuildcommands
|
||||||
{
|
{
|
||||||
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
@ -127,7 +125,8 @@ project "SHADE_Engine"
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
postbuildcommands
|
postbuildcommands
|
||||||
{
|
{
|
||||||
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
@ -135,32 +134,35 @@ project "SHADE_Engine"
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
postbuildcommands
|
postbuildcommands
|
||||||
{
|
{
|
||||||
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
--"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
postbuildcommands
|
||||||
|
{
|
||||||
|
--"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""
|
||||||
|
}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG", "SHEDITOR"}
|
defines {"_DEBUG", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
links{"librttr_core_d.lib", "spdlogd.lib"}
|
||||||
links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE", "SHEDITOR"}
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"librttr_core.lib", "spdlog.lib"}
|
||||||
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE", "_PUBLISH"}
|
defines{"_RELEASE", "_PUBLISH"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"librttr_core.lib", "spdlog.lib"}
|
||||||
excludes
|
excludes
|
||||||
{
|
{
|
||||||
-- "%{prj.location}/src/Editor/**.cpp",
|
-- "%{prj.location}/src/Editor/**.cpp",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "SHMeshAsset.h"
|
#include "SHModelAsset.h"
|
||||||
#include "SHTextureAsset.h"
|
#include "SHTextureAsset.h"
|
|
@ -18,24 +18,31 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SH_API SHMeshAssetHeader
|
struct SHMeshAssetHeader
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SH_API SHMeshAsset : SHAssetData
|
struct SHModelAssetHeader
|
||||||
{
|
{
|
||||||
bool compiled;
|
size_t meshCount;
|
||||||
bool changed;
|
};
|
||||||
|
|
||||||
SHMeshAssetHeader header;
|
struct SH_API SHMeshData : SHAssetData
|
||||||
|
{
|
||||||
|
SHMeshAssetHeader header;
|
||||||
|
std::vector<SHVec3> VertexPositions;
|
||||||
|
std::vector<SHVec3> VertexTangents;
|
||||||
|
std::vector<SHVec3> VertexNormals;
|
||||||
|
std::vector<SHVec2> VertexTexCoords;
|
||||||
|
std::vector<uint32_t> Indices;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<SHVec3> vertexPosition;
|
struct SH_API SHModelAsset : SHAssetData
|
||||||
std::vector<SHVec3> vertexTangent;
|
{
|
||||||
std::vector<SHVec3> vertexNormal;
|
SHModelAssetHeader header;
|
||||||
std::vector<SHVec2> texCoords;
|
std::vector<SHMeshData*> subMeshes;
|
||||||
std::vector<uint32_t> indices;
|
};
|
||||||
};
|
|
||||||
}
|
}
|
|
@ -1,201 +0,0 @@
|
||||||
/*************************************************************************//**
|
|
||||||
* \file SHMeshCompiler.cpp
|
|
||||||
* \author Loh Xiao Qi
|
|
||||||
* \date 30 September 2022
|
|
||||||
* \brief Library to write data in SHMeshAsset into binary file for faster
|
|
||||||
* loading in the future
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 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 "SHMeshCompiler.h"
|
|
||||||
#include "Graphics/MiddleEnd/Meshes/SHMeshData.h"
|
|
||||||
#include <assimp/postprocess.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
|
|
||||||
Assimp::Importer SHMeshCompiler::aiImporter;
|
|
||||||
|
|
||||||
void SHMeshCompiler::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept
|
|
||||||
{
|
|
||||||
for (size_t i{ 0 }; i < node.mNumMeshes; ++i)
|
|
||||||
{
|
|
||||||
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
|
|
||||||
meshes.push_back(ProcessMesh(*mesh));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
|
|
||||||
{
|
|
||||||
ProcessNode(*node.mChildren[i], scene, meshes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHMeshCompiler::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept
|
|
||||||
{
|
|
||||||
if (scene.HasAnimations())
|
|
||||||
{
|
|
||||||
std::vector<SHAnimationAsset> anims(scene.mNumAnimations);
|
|
||||||
for (auto i{ 0 }; i < scene.mNumAnimations; ++i)
|
|
||||||
{
|
|
||||||
auto const& anim{ *scene.mAnimations[i] };
|
|
||||||
|
|
||||||
anims[i].name = anim.mName.C_Str();
|
|
||||||
|
|
||||||
anims[i].duration = anim.mDuration;
|
|
||||||
anims[i].ticksPerSecond = anim.mTicksPerSecond;
|
|
||||||
|
|
||||||
std::copy_n(anim.mChannels, anim.mNumChannels, anims[i].nodeChannels.data());
|
|
||||||
std::copy_n(anim.mMeshChannels, anim.mNumMeshChannels, anims[i].meshChannels.data());
|
|
||||||
std::copy_n(anim.mMorphMeshChannels, anim.mNumMorphMeshChannels, anims[i].morphMeshChannels.data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHMeshAsset* SHMeshCompiler::ProcessMesh(aiMesh const& mesh) noexcept
|
|
||||||
{
|
|
||||||
SHMeshAsset* result = new SHMeshAsset();
|
|
||||||
result->compiled = false;
|
|
||||||
result->changed = false;
|
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < mesh.mNumVertices; ++i)
|
|
||||||
{
|
|
||||||
// Vertex position
|
|
||||||
SHVec3 vertex;
|
|
||||||
vertex.x = mesh.mVertices[i].x;
|
|
||||||
vertex.y = mesh.mVertices[i].y;
|
|
||||||
vertex.z = mesh.mVertices[i].z;
|
|
||||||
result->vertexPosition.push_back(vertex);
|
|
||||||
|
|
||||||
// Tex coords
|
|
||||||
SHVec2 texCoord{ 0.f, 0.f };
|
|
||||||
if (mesh.mTextureCoords[0])
|
|
||||||
{
|
|
||||||
texCoord.x = mesh.mTextureCoords[0][i].x;
|
|
||||||
texCoord.y = mesh.mTextureCoords[0][i].y;
|
|
||||||
}
|
|
||||||
result->texCoords.push_back(texCoord);
|
|
||||||
|
|
||||||
// Normals
|
|
||||||
SHVec3 normal{ 0.f, 0.f, 0.f };
|
|
||||||
if (mesh.mNormals)
|
|
||||||
{
|
|
||||||
normal.x = mesh.mNormals[i].x;
|
|
||||||
normal.y = mesh.mNormals[i].y;
|
|
||||||
normal.z = mesh.mNormals[i].z;
|
|
||||||
}
|
|
||||||
result->vertexNormal.push_back(normal);
|
|
||||||
|
|
||||||
// Tangent
|
|
||||||
SHVec3 tangent{ 0.f, 0.f, 0.f };
|
|
||||||
if (mesh.mTangents)
|
|
||||||
{
|
|
||||||
tangent.x = mesh.mTangents[i].x;
|
|
||||||
tangent.y = mesh.mTangents[i].y;
|
|
||||||
tangent.z = mesh.mTangents[i].z;
|
|
||||||
}
|
|
||||||
result->vertexTangent.push_back(tangent);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i{ 0 }; i < mesh.mNumFaces; ++i)
|
|
||||||
{
|
|
||||||
aiFace face = mesh.mFaces[i];
|
|
||||||
for (size_t j{ 0 }; j < face.mNumIndices; ++j)
|
|
||||||
{
|
|
||||||
result->indices.push_back(face.mIndices[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result->header.vertexCount = static_cast<uint32_t>(result->vertexPosition.size());
|
|
||||||
result->header.indexCount = static_cast<uint32_t>(result->indices.size());
|
|
||||||
result->header.name = mesh.mName.C_Str();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHMeshCompiler::LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept
|
|
||||||
{
|
|
||||||
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
|
||||||
aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
|
|
||||||
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
|
|
||||||
| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
|
|
||||||
| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
|
|
||||||
| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
|
|
||||||
| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
|
|
||||||
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
|
||||||
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
|
|
||||||
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!scene || !scene->HasMeshes())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ExtractAnimations(*scene, anims);
|
|
||||||
|
|
||||||
ProcessNode(*scene->mRootNode, *scene, meshes);
|
|
||||||
|
|
||||||
aiImporter.FreeScene();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<AssetPath> SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
|
||||||
{
|
|
||||||
std::string newPath{ path.parent_path().string() + '/' };
|
|
||||||
newPath += asset.header.name + MESH_EXTENSION.data();
|
|
||||||
|
|
||||||
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount };
|
|
||||||
auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount };
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.texCoords.data()),
|
|
||||||
vertexVec2Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.indices.data()),
|
|
||||||
sizeof(uint32_t) * asset.header.indexCount
|
|
||||||
);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
return newPath;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*************************************************************************//**
|
|
||||||
* \file SHMeshCompiler.h
|
|
||||||
* \author Loh Xiao Qi
|
|
||||||
* \date 30 September 2022
|
|
||||||
* \brief Library to write data in SHMeshAsset into binary file for faster
|
|
||||||
* loading in the future
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 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 <assimp/Importer.hpp>
|
|
||||||
#include <assimp/scene.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Assets/Asset Types/SHAnimationAsset.h"
|
|
||||||
#include "Assets/Asset Types/SHMeshAsset.h"
|
|
||||||
#include "Assets/SHAssetMacros.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHMeshCompiler
|
|
||||||
{
|
|
||||||
|
|
||||||
using MeshVectorRef = std::vector<SHMeshAsset*>&;
|
|
||||||
using AnimVectorRef = std::vector<SHAnimationAsset*>&;
|
|
||||||
|
|
||||||
static Assimp::Importer aiImporter;
|
|
||||||
static void ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept;
|
|
||||||
static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
|
|
||||||
static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept;
|
|
||||||
static std::optional<AssetPath> CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*************************************************************************//**
|
|
||||||
* \file SHMeshLoader.cpp
|
|
||||||
* \author Loh Xiao Qi
|
|
||||||
* \date 30 September 2022
|
|
||||||
* \brief Implementation for Mesh loader. Accounts for custom binary format
|
|
||||||
* as well as GLTF file format.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 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 "SHMeshLoader.h"
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept
|
|
||||||
{
|
|
||||||
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string name{ path.stem().string() };
|
|
||||||
|
|
||||||
file.seekg(0);
|
|
||||||
|
|
||||||
uint32_t vertCount, indexCount;
|
|
||||||
std::vector<SHVec3> vertPos, vertTan, vertNorm;
|
|
||||||
std::vector<SHVec2> texCoord;
|
|
||||||
std::vector<uint32_t> indices;
|
|
||||||
|
|
||||||
file.read(reinterpret_cast<char*>(&vertCount), sizeof(uint32_t));
|
|
||||||
file.read(reinterpret_cast<char*>(&indexCount), sizeof(uint32_t));
|
|
||||||
|
|
||||||
auto const vertexVec3Byte{ sizeof(SHVec3) * vertCount };
|
|
||||||
auto const vertexVec2Byte{ sizeof(SHVec2) * vertCount };
|
|
||||||
|
|
||||||
vertPos.resize(vertCount);
|
|
||||||
vertTan.resize(vertCount);
|
|
||||||
vertNorm.resize(vertCount);
|
|
||||||
texCoord.resize(vertCount);
|
|
||||||
indices.resize(indexCount);
|
|
||||||
|
|
||||||
file.read(reinterpret_cast<char *>(vertPos.data()), vertexVec3Byte);
|
|
||||||
file.read(reinterpret_cast<char *>(vertTan.data()), vertexVec3Byte);
|
|
||||||
file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte);
|
|
||||||
file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte);
|
|
||||||
file.read(reinterpret_cast<char *>(indices.data()), sizeof(uint32_t) * indexCount);
|
|
||||||
|
|
||||||
mesh.compiled = true;
|
|
||||||
mesh.changed = false;
|
|
||||||
|
|
||||||
mesh.header.indexCount = indexCount;
|
|
||||||
mesh.header.vertexCount = vertCount;
|
|
||||||
mesh.header.name = name;
|
|
||||||
|
|
||||||
mesh.vertexPosition = std::move(vertPos);
|
|
||||||
mesh.vertexTangent = std::move(vertTan);
|
|
||||||
mesh.vertexNormal = std::move(vertNorm);
|
|
||||||
mesh.texCoords = std::move(texCoord);
|
|
||||||
mesh.indices = std::move(indices);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
SHAssetData* SHMeshLoader::Load(AssetPath path)
|
|
||||||
{
|
|
||||||
auto result = new SHMeshAsset();
|
|
||||||
|
|
||||||
LoadSHMesh(path, *result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHMeshLoader::Write(SHAssetData const* data, AssetPath path)
|
|
||||||
{
|
|
||||||
std::ofstream file{ path, std::ios::out | std::ios::binary | std::ios::trunc };
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto asset = *dynamic_cast<SHMeshAsset const*>(data);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount };
|
|
||||||
auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount };
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.texCoords.data()),
|
|
||||||
vertexVec2Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.indices.data()),
|
|
||||||
sizeof(uint32_t) * asset.header.indexCount
|
|
||||||
);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHModelLoader.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Implementation for Mesh loader. Accounts for custom binary format
|
||||||
|
* as well as GLTF file format.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "SHModelLoader.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHModelLoader::ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept
|
||||||
|
{
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&header),
|
||||||
|
sizeof(SHMeshLoaderHeader)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHModelLoader::ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept
|
||||||
|
{
|
||||||
|
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
|
||||||
|
auto const vertexVec2Byte{ sizeof(SHVec2) * header.vertexCount };
|
||||||
|
|
||||||
|
data.VertexPositions.resize(header.vertexCount);
|
||||||
|
data.VertexTangents.resize(header.vertexCount);
|
||||||
|
data.VertexNormals.resize(header.vertexCount);
|
||||||
|
data.VertexTexCoords.resize(header.vertexCount);
|
||||||
|
data.Indices.resize(header.indexCount);
|
||||||
|
data.header.name.resize(header.charCount);
|
||||||
|
|
||||||
|
file.read(data.header.name.data(), header.charCount);
|
||||||
|
file.read(reinterpret_cast<char*>(data.VertexPositions.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.VertexTangents.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.VertexNormals.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
|
||||||
|
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
|
||||||
|
|
||||||
|
data.header.vertexCount = header.vertexCount;
|
||||||
|
data.header.indexCount = header.indexCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHModelLoader::LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.seekg(0);
|
||||||
|
|
||||||
|
file.read(
|
||||||
|
reinterpret_cast<char*>(&model.header),
|
||||||
|
sizeof(SHModelAssetHeader)
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<SHMeshLoaderHeader> headers(model.header.meshCount);
|
||||||
|
model.subMeshes.resize(model.header.meshCount);
|
||||||
|
|
||||||
|
for (auto i{ 0 }; i < model.header.meshCount; ++i)
|
||||||
|
{
|
||||||
|
model.subMeshes[i] = new SHMeshData();
|
||||||
|
ReadHeader(file, headers[i]);
|
||||||
|
ReadData(file, headers[i], *model.subMeshes[i]);
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAssetData* SHModelLoader::Load(AssetPath path)
|
||||||
|
{
|
||||||
|
auto result = new SHModelAsset();
|
||||||
|
|
||||||
|
LoadSHMesh(path, *result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHModelLoader::Write(SHAssetData const* data, AssetPath path)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*************************************************************************//**
|
/*************************************************************************//**
|
||||||
* \file SHMeshLoader.h
|
* \file SHModelLoader.h
|
||||||
* \author Loh Xiao Qi
|
* \author Loh Xiao Qi
|
||||||
* \date 30 September 2022
|
* \date 30 September 2022
|
||||||
* \brief Library to load gltf mesh files and custom binary format
|
* \brief Library to load gltf mesh files and custom binary format
|
||||||
|
@ -10,14 +10,27 @@
|
||||||
* of DigiPen Institute of Technology is prohibited.
|
* of DigiPen Institute of Technology is prohibited.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Assets/Asset Types/SHMeshAsset.h"
|
#include "Assets/Asset Types/SHModelAsset.h"
|
||||||
#include "SHAssetLoader.h"
|
#include "SHAssetLoader.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHMeshLoader : SHAssetLoader
|
class SHModelLoader : public SHAssetLoader
|
||||||
{
|
{
|
||||||
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
|
struct SHMeshLoaderHeader
|
||||||
|
{
|
||||||
|
uint32_t vertexCount;
|
||||||
|
uint32_t indexCount;
|
||||||
|
uint32_t charCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept;
|
||||||
|
void ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept;
|
||||||
SHAssetData* Load(AssetPath path) override;
|
SHAssetData* Load(AssetPath path) override;
|
||||||
void Write(SHAssetData const* data, AssetPath path) override;
|
void Write(SHAssetData const* data, AssetPath path) override;
|
||||||
};
|
};
|
|
@ -21,6 +21,11 @@ namespace SHADE
|
||||||
AssetName name;
|
AssetName name;
|
||||||
AssetID id;
|
AssetID id;
|
||||||
AssetType type;
|
AssetType type;
|
||||||
AssetPath path;
|
AssetPath path;
|
||||||
|
bool isSubAsset;
|
||||||
|
|
||||||
|
std::vector<SHAsset*> subAssets;
|
||||||
|
|
||||||
|
AssetID parent;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -47,10 +47,11 @@ enum class AssetType : AssetTypeMeta
|
||||||
SHADER,
|
SHADER,
|
||||||
SHADER_BUILT_IN,
|
SHADER_BUILT_IN,
|
||||||
TEXTURE,
|
TEXTURE,
|
||||||
MESH,
|
MODEL,
|
||||||
SCENE,
|
SCENE,
|
||||||
PREFAB,
|
PREFAB,
|
||||||
MATERIAL,
|
MATERIAL,
|
||||||
|
MESH,
|
||||||
MAX_COUNT
|
MAX_COUNT
|
||||||
};
|
};
|
||||||
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
|
||||||
|
@ -64,6 +65,9 @@ constexpr std::string_view ASSET_ROOT {"../../Assets"};
|
||||||
constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" };
|
constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// COMPILER PATHS
|
||||||
|
constexpr std::string_view MODEL_COMPILER_EXE{ "ModelCompiler.exe" };
|
||||||
|
|
||||||
// INTERNAL ASSET PATHS
|
// INTERNAL ASSET PATHS
|
||||||
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
|
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
|
||||||
constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" };
|
constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" };
|
||||||
|
@ -81,7 +85,7 @@ constexpr std::string_view SCENE_EXTENSION {".shade"};
|
||||||
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
|
||||||
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
|
||||||
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
|
||||||
constexpr std::string_view MESH_EXTENSION {".shmesh"};
|
constexpr std::string_view MODEL_EXTENSION {".shmodel"};
|
||||||
|
|
||||||
constexpr std::string_view EXTENSIONS[] = {
|
constexpr std::string_view EXTENSIONS[] = {
|
||||||
AUDIO_EXTENSION,
|
AUDIO_EXTENSION,
|
||||||
|
@ -89,7 +93,7 @@ constexpr std::string_view EXTENSIONS[] = {
|
||||||
SHADER_BUILT_IN_EXTENSION,
|
SHADER_BUILT_IN_EXTENSION,
|
||||||
MATERIAL_EXTENSION,
|
MATERIAL_EXTENSION,
|
||||||
TEXTURE_EXTENSION,
|
TEXTURE_EXTENSION,
|
||||||
MESH_EXTENSION,
|
MODEL_EXTENSION,
|
||||||
SCRIPT_EXTENSION,
|
SCRIPT_EXTENSION,
|
||||||
SCENE_EXTENSION,
|
SCENE_EXTENSION,
|
||||||
PREFAB_EXTENSION,
|
PREFAB_EXTENSION,
|
||||||
|
|
|
@ -11,15 +11,17 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "SHAssetManager.h"
|
#include "SHAssetManager.h"
|
||||||
#include "SHAssetMetaHandler.h"
|
#include "SHAssetMetaHandler.h"
|
||||||
|
|
||||||
#include "Libraries/Loaders/SHMeshLoader.h"
|
#include "Libraries/Loaders/SHModelLoader.h"
|
||||||
#include "Libraries/Loaders/SHTextureLoader.h"
|
#include "Libraries/Loaders/SHTextureLoader.h"
|
||||||
#include "Libraries/Loaders/SHShaderSourceLoader.h"
|
#include "Libraries/Loaders/SHShaderSourceLoader.h"
|
||||||
#include "Libraries/Loaders/SHTextBasedLoader.h"
|
#include "Libraries/Loaders/SHTextBasedLoader.h"
|
||||||
|
|
||||||
#include "Libraries/Compilers/SHMeshCompiler.h"
|
//#include "Libraries/Compilers/SHMeshCompiler.h"
|
||||||
#include "Libraries/Compilers/SHTextureCompiler.h"
|
#include "Libraries/Compilers/SHTextureCompiler.h"
|
||||||
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
|
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
|
||||||
|
|
||||||
|
@ -157,16 +159,22 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
case AssetType::PREFAB:
|
case AssetType::PREFAB:
|
||||||
newPath += PREFAB_FOLDER;
|
newPath += PREFAB_FOLDER;
|
||||||
|
newPath += name;
|
||||||
|
newPath += PREFAB_EXTENSION;
|
||||||
data = new SHPrefabAsset();
|
data = new SHPrefabAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AssetType::SCENE:
|
case AssetType::SCENE:
|
||||||
newPath += SCENE_FOLDER;
|
newPath += SCENE_FOLDER;
|
||||||
|
newPath += name;
|
||||||
|
newPath += SCENE_EXTENSION;
|
||||||
data = new SHSceneAsset();
|
data = new SHSceneAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AssetType::MATERIAL:
|
case AssetType::MATERIAL:
|
||||||
newPath += MATERIAL_FOLDER;
|
newPath += MATERIAL_FOLDER;
|
||||||
|
newPath += name;
|
||||||
|
newPath += MATERIAL_EXTENSION;
|
||||||
data = new SHMaterialAsset();
|
data = new SHMaterialAsset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -180,7 +188,8 @@ namespace SHADE
|
||||||
name,
|
name,
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
newPath
|
newPath,
|
||||||
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
assetCollection.insert({
|
assetCollection.insert({
|
||||||
|
@ -189,7 +198,8 @@ namespace SHADE
|
||||||
name,
|
name,
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
newPath
|
newPath,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -328,25 +338,32 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetID SHAssetManager::CompileAsset(AssetPath const& path) noexcept
|
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
|
||||||
{
|
{
|
||||||
SHAsset newAsset
|
if (!std::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
.name = path.stem().string()
|
SHLOG_ERROR("Path provided does not point to a file: {}", path.string());
|
||||||
};
|
return;
|
||||||
|
}
|
||||||
|
AssetPath newPath;
|
||||||
auto const ext{ path.extension().string() };
|
auto const ext{ path.extension().string() };
|
||||||
if (ext == GLSL_EXTENSION.data())
|
if (ext == GLSL_EXTENSION.data())
|
||||||
{
|
{
|
||||||
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
||||||
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
|
|
||||||
newAsset.type = AssetType::SHADER_BUILT_IN;
|
|
||||||
}
|
}
|
||||||
|
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
|
||||||
|
{
|
||||||
|
std::string command = MODEL_COMPILER_EXE.data();
|
||||||
|
command += " " + path.string();
|
||||||
|
std::system(command.c_str());
|
||||||
|
|
||||||
assetCollection.insert({ newAsset.id, newAsset });
|
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
||||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
modelPath += MODEL_EXTENSION;
|
||||||
|
newPath = modelPath;
|
||||||
|
|
||||||
|
GenerateNewMeta(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
return newAsset.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
||||||
|
@ -399,46 +416,28 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto const& path : paths)
|
for (auto const& path : paths)
|
||||||
{
|
{
|
||||||
SHAsset newAsset
|
AssetPath newPath;
|
||||||
{
|
|
||||||
.name = path.stem().string()
|
|
||||||
};
|
|
||||||
|
|
||||||
auto const ext{ path.extension().string() };
|
auto const ext{ path.extension().string() };
|
||||||
if (ext == GLSL_EXTENSION.data())
|
if (ext == GLSL_EXTENSION.data())
|
||||||
{
|
{
|
||||||
newAsset.path = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
|
||||||
newAsset.id = GenerateAssetID(AssetType::SHADER_BUILT_IN);
|
|
||||||
newAsset.type = AssetType::SHADER_BUILT_IN;
|
|
||||||
}
|
}
|
||||||
else if (ext == DDS_EXTENSION.data())
|
else if (ext == DDS_EXTENSION.data())
|
||||||
{
|
{
|
||||||
newAsset.path = SHTextureCompiler::CompileTextureAsset(path).value();
|
newPath = SHTextureCompiler::CompileTextureAsset(path).value();
|
||||||
newAsset.id = GenerateAssetID(AssetType::TEXTURE);
|
|
||||||
newAsset.type = AssetType::TEXTURE;
|
|
||||||
}
|
}
|
||||||
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
|
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
|
||||||
{
|
{
|
||||||
std::vector<SHMeshAsset*> meshes;
|
std::string command = MODEL_COMPILER_EXE.data();
|
||||||
std::vector<SHAnimationAsset*> anims;
|
command += " " + path.string();
|
||||||
SHMeshCompiler::LoadFromFile(path, meshes, anims);
|
std::system(command.c_str());
|
||||||
|
|
||||||
for (auto const& mesh : meshes)
|
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
||||||
{
|
modelPath += MODEL_EXTENSION;
|
||||||
SHAsset meshAsset{
|
newPath = modelPath;
|
||||||
.name = mesh->header.name
|
|
||||||
};
|
|
||||||
meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value();
|
|
||||||
meshAsset.id = GenerateAssetID(AssetType::MESH);
|
|
||||||
meshAsset.type = AssetType::MESH;
|
|
||||||
assetCollection.insert({ meshAsset.id, meshAsset });
|
|
||||||
SHAssetMetaHandler::WriteMetaData(meshAsset);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assetCollection.insert({ newAsset.id, newAsset });
|
GenerateNewMeta(newPath);
|
||||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,10 +452,11 @@ namespace SHADE
|
||||||
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
|
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
|
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
|
||||||
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
|
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader());
|
loaders[static_cast<size_t>(AssetType::MODEL)] = dynamic_cast<SHAssetLoader*>(new SHModelLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
|
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
|
||||||
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
||||||
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
|
||||||
|
loaders[static_cast<size_t>(AssetType::MESH)] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -464,9 +464,9 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetManager::Load() noexcept
|
void SHAssetManager::Load() noexcept
|
||||||
{
|
{
|
||||||
//CompileAll();
|
|
||||||
BuildAssetCollection();
|
BuildAssetCollection();
|
||||||
InitLoaders();
|
InitLoaders();
|
||||||
|
//CompileAll();
|
||||||
//LoadAllData();
|
//LoadAllData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,8 +484,12 @@ namespace SHADE
|
||||||
|
|
||||||
SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept
|
SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept
|
||||||
{
|
{
|
||||||
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
|
if (asset.isSubAsset)
|
||||||
|
{
|
||||||
|
return LoadSubData(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
|
SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
|
||||||
|
@ -498,8 +502,120 @@ namespace SHADE
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHAssetData* SHAssetManager::LoadSubData(SHAsset const& asset) noexcept
|
||||||
|
{
|
||||||
|
auto const& parent = assetCollection[asset.parent];
|
||||||
|
auto parentData = loaders[static_cast<size_t>(parent.type)]->Load(parent.path);
|
||||||
|
|
||||||
|
if (parentData == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to load asset into memory: {}\n", parent.path.string());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assetData.emplace(parent.id, parentData);
|
||||||
|
if (parent.type == AssetType::MODEL)
|
||||||
|
{
|
||||||
|
auto parentModel = reinterpret_cast<SHModelAsset*>(parentData);
|
||||||
|
for (auto i {0}; i < parent.subAssets.size(); ++i)
|
||||||
|
{
|
||||||
|
assetData.emplace(
|
||||||
|
parent.subAssets[i]->id,
|
||||||
|
parentModel->subMeshes[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetData[asset.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return parentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadNewData(AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::GenerateNewMeta(AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
auto const ext = path.extension().string();
|
||||||
|
if (ext == SHADER_BUILT_IN_EXTENSION.data())
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::SHADER_BUILT_IN),
|
||||||
|
AssetType::SHADER_BUILT_IN,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
}
|
||||||
|
else if (ext == TEXTURE_EXTENSION.data())
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::SHADER_BUILT_IN),
|
||||||
|
AssetType::SHADER_BUILT_IN,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
}
|
||||||
|
else if (ext == MODEL_EXTENSION)
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::MODEL),
|
||||||
|
AssetType::MODEL,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
|
||||||
|
SHModelAsset* const data = reinterpret_cast<SHModelAsset*>(LoadData(newAsset));
|
||||||
|
assetData.emplace(newAsset.id, data);
|
||||||
|
for(auto const& subMesh : data->subMeshes)
|
||||||
|
{
|
||||||
|
SHAsset subAsset{
|
||||||
|
.name = subMesh->header.name,
|
||||||
|
.id = GenerateAssetID(AssetType::MESH),
|
||||||
|
.type = AssetType::MESH,
|
||||||
|
.isSubAsset = true,
|
||||||
|
.parent = newAsset.id
|
||||||
|
};
|
||||||
|
|
||||||
|
assetCollection.emplace(subAsset.id, subAsset);
|
||||||
|
assetCollection[newAsset.id].subAssets.push_back(&assetCollection[subAsset.id]);
|
||||||
|
|
||||||
|
assetData.emplace(subAsset.id, subMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHAssetManager::BuildAssetCollection() noexcept
|
void SHAssetManager::BuildAssetCollection() noexcept
|
||||||
{
|
{
|
||||||
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection);
|
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection);
|
||||||
|
|
||||||
|
for (auto& asset : std::ranges::views::values(assetCollection))
|
||||||
|
{
|
||||||
|
if (!asset.subAssets.empty())
|
||||||
|
{
|
||||||
|
// Add subasset data into map, replace pointer and free heap memory
|
||||||
|
for (auto i{ 0 }; i < asset.subAssets.size(); ++i)
|
||||||
|
{
|
||||||
|
auto const id = asset.subAssets[i]->id;
|
||||||
|
assetCollection[id] = *asset.subAssets[i];
|
||||||
|
delete asset.subAssets[i];
|
||||||
|
asset.subAssets[i] = &assetCollection[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace SHADE
|
||||||
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
||||||
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
||||||
|
|
||||||
static AssetID CompileAsset(AssetPath const& path) noexcept;
|
static void CompileAsset(AssetPath const& path) noexcept;
|
||||||
|
|
||||||
static FolderPointer GetRootFolder() noexcept;
|
static FolderPointer GetRootFolder() noexcept;
|
||||||
|
|
||||||
|
@ -95,7 +95,11 @@ namespace SHADE
|
||||||
|
|
||||||
static void InitLoaders() noexcept;
|
static void InitLoaders() noexcept;
|
||||||
static void LoadAllData() noexcept;
|
static void LoadAllData() noexcept;
|
||||||
static SHAssetData* LoadData(SHAsset const& asset) noexcept;
|
static SHAssetData* LoadData(SHAsset const& asset) noexcept;
|
||||||
|
static SHAssetData* LoadSubData(SHAsset const& asset) noexcept;
|
||||||
|
static void LoadNewData(AssetPath path) noexcept;
|
||||||
|
static void GenerateNewMeta(AssetPath path) noexcept;
|
||||||
|
|
||||||
inline static void BuildAssetCollection() noexcept;
|
inline static void BuildAssetCollection() noexcept;
|
||||||
|
|
||||||
static bool IsRecognised(char const*) noexcept;
|
static bool IsRecognised(char const*) noexcept;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHAssetMetaHandler.h"
|
#include "SHAssetMetaHandler.h"
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -21,11 +20,15 @@ namespace SHADE
|
||||||
* \brief Helper function to retrieve field value from meta data file
|
* \brief Helper function to retrieve field value from meta data file
|
||||||
* for processing
|
* for processing
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void GetFieldValue(std::ifstream& file, std::string& line) noexcept
|
bool GetFieldValue(std::ifstream& file, std::string& line) noexcept
|
||||||
{
|
{
|
||||||
line = "";
|
line = "";
|
||||||
std::getline(file, line);
|
if (std::getline(file, line))
|
||||||
line = line.substr(line.find_last_of(':') + 2, line.length());
|
{
|
||||||
|
line = line.substr(line.find_last_of(':') + 2, line.length());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -66,7 +69,8 @@ namespace SHADE
|
||||||
std::ifstream metaFile{ path.string(), std::ios_base::in };
|
std::ifstream metaFile{ path.string(), std::ios_base::in };
|
||||||
if (!metaFile.is_open())
|
if (!metaFile.is_open())
|
||||||
{
|
{
|
||||||
// Error unable to open
|
SHLOG_ERROR("Unable to open meta file: {}", path.string());
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
|
@ -92,6 +96,43 @@ namespace SHADE
|
||||||
AssetTypeMeta type;
|
AssetTypeMeta type;
|
||||||
typeStream >> type;
|
typeStream >> type;
|
||||||
meta.type = static_cast<AssetType>(type);
|
meta.type = static_cast<AssetType>(type);
|
||||||
|
|
||||||
|
meta.isSubAsset = false;
|
||||||
|
|
||||||
|
// Burn Line
|
||||||
|
if (std::getline(metaFile, line))
|
||||||
|
{
|
||||||
|
// Name Line
|
||||||
|
while(GetFieldValue(metaFile, line))
|
||||||
|
{
|
||||||
|
auto subAsset = new SHAsset();
|
||||||
|
|
||||||
|
// Get resource name
|
||||||
|
std::stringstream nameStream{ line };
|
||||||
|
AssetName name;
|
||||||
|
nameStream >> name;
|
||||||
|
subAsset->name = name;
|
||||||
|
|
||||||
|
// Get resource id
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream idStream{ line };
|
||||||
|
AssetID id;
|
||||||
|
idStream >> id;
|
||||||
|
subAsset->id = id;
|
||||||
|
|
||||||
|
// Get resource type
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream typeStream{ line };
|
||||||
|
AssetTypeMeta type;
|
||||||
|
typeStream >> type;
|
||||||
|
subAsset->type = static_cast<AssetType>(type);
|
||||||
|
|
||||||
|
subAsset->isSubAsset = true;
|
||||||
|
subAsset->parent = meta.id;
|
||||||
|
|
||||||
|
meta.subAssets.push_back(subAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
metaFile.close();
|
metaFile.close();
|
||||||
|
|
||||||
|
@ -108,6 +149,12 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
||||||
{
|
{
|
||||||
|
if (meta.isSubAsset)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Cannot write subasset meta: {}", meta.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Write into binary eventually
|
//TODO: Write into binary eventually
|
||||||
std::string path{ meta.path.string() };
|
std::string path{ meta.path.string() };
|
||||||
path.append(META_EXTENSION);
|
path.append(META_EXTENSION);
|
||||||
|
@ -124,7 +171,23 @@ namespace SHADE
|
||||||
metaFile << "ID: " << meta.id << "\n";
|
metaFile << "ID: " << meta.id << "\n";
|
||||||
metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
|
metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
|
||||||
|
|
||||||
|
if (!meta.subAssets.empty())
|
||||||
|
{
|
||||||
|
metaFile << "Sub Assets:\n";
|
||||||
|
|
||||||
|
for (auto const& subAsset : meta.subAssets)
|
||||||
|
{
|
||||||
|
WriteSubAssetMeta(metaFile, *subAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
metaFile.close();
|
metaFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAssetMetaHandler::WriteSubAssetMeta(std::ofstream& metaFile, SHAsset const& subAsset) noexcept
|
||||||
|
{
|
||||||
|
metaFile << "Name: " << subAsset.name << "\n";
|
||||||
|
metaFile << "ID: " << subAsset.id << "\n";
|
||||||
|
metaFile << "Type: " << static_cast<AssetTypeMeta>(subAsset.type) << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "SHAssetMacros.h"
|
#include "SHAssetMacros.h"
|
||||||
#include "SHAsset.h"
|
#include "SHAsset.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -45,6 +46,8 @@ namespace SHADE
|
||||||
* \brief Writes meta data into text file
|
* \brief Writes meta data into text file
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void WriteMetaData(SHAsset const&) noexcept;
|
static void WriteMetaData(SHAsset const&) noexcept;
|
||||||
|
|
||||||
|
static void WriteSubAssetMeta(std::ofstream&, SHAsset const&) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <FMOD/fmod_studio.hpp>
|
#include <FMOD/fmod_studio.hpp>
|
||||||
#include <SDL_keyboard.h>
|
#include <SDL_keyboard.h>
|
||||||
|
|
||||||
|
const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAudioSystem::SHAudioSystem()
|
SHAudioSystem::SHAudioSystem()
|
||||||
|
@ -79,10 +81,10 @@ namespace SHADE
|
||||||
//SHResourceManager::LoadAllAudio(system, soundList);
|
//SHResourceManager::LoadAllAudio(system, soundList);
|
||||||
|
|
||||||
|
|
||||||
LoadBank("../../Assets/Audio/Master.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
|
||||||
LoadBank("../../Assets/Audio/Master.strings.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
|
||||||
//LoadBank("../../Assets/Audio/Music.bank");
|
//LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data());
|
||||||
LoadBank("../../Assets/Audio/footsteps.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data());
|
||||||
|
|
||||||
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
||||||
//clip->Play();
|
//clip->Play();
|
||||||
|
|
|
@ -5,15 +5,19 @@
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/IconsFontAwesome6.h"
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
|
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAssetBrowser::SHAssetBrowser()
|
SHAssetBrowser::SHAssetBrowser()
|
||||||
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
|
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,14 +57,33 @@ namespace SHADE
|
||||||
flags |= ImGuiTreeNodeFlags_Selected;
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
if (folder == rootFolder)
|
if (folder == rootFolder)
|
||||||
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
flags |= ImGuiTreeNodeFlags_DefaultOpen;
|
||||||
|
|
||||||
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
|
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
|
||||||
|
ImGuiID folderID = ImGui::GetItemID();
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
if(ImGui::IsItemClicked())
|
|
||||||
|
if (ImGui::BeginPopupContextItem())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Create Asset"))
|
||||||
|
{
|
||||||
|
//TODO: Change to rttr type enum align
|
||||||
|
if (ImGui::Selectable("Material"))
|
||||||
|
{
|
||||||
|
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
|
||||||
|
ImGui::TreeNodeSetOpen(folderID, true);
|
||||||
|
isOpen = true;
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
selectedFolders.clear();
|
selectedFolders.clear();
|
||||||
selectedFolders.push_back(folder);
|
selectedFolders.push_back(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
{
|
{
|
||||||
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
@ -79,13 +102,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
for (auto const& file : files)
|
for (auto const& file : files)
|
||||||
{
|
{
|
||||||
|
if(file.assetMeta == nullptr)
|
||||||
|
continue;
|
||||||
const float horizontalLineSize = 25.0f;
|
const float horizontalLineSize = 25.0f;
|
||||||
const ImRect childRect = DrawFile(file);
|
const ImRect childRect = DrawFile(file.assetMeta);
|
||||||
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
vertLineEnd.y = midPoint;
|
vertLineEnd.y = midPoint;
|
||||||
}
|
}
|
||||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
|
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
|
||||||
|
DrawAssetBeingCreated();
|
||||||
|
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
|
@ -120,45 +148,111 @@ namespace SHADE
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept
|
ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept
|
||||||
{
|
{
|
||||||
if (file.assetMeta == nullptr)
|
if (asset == nullptr)
|
||||||
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end();
|
const bool isSelected = std::ranges::find(selectedAssets, asset->id) != selectedAssets.end();
|
||||||
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
|
ImGuiTreeNodeFlags flags = (!asset->subAssets.empty()) ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf;
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
flags |= ImGuiTreeNodeFlags_Selected;
|
flags |= ImGuiTreeNodeFlags_Selected;
|
||||||
std::string icon{};
|
std::string icon{};
|
||||||
|
|
||||||
switch(file.assetMeta->type)
|
switch (asset->type)
|
||||||
{
|
{
|
||||||
case AssetType::INVALID: break;
|
case AssetType::INVALID: break;
|
||||||
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
|
||||||
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
|
||||||
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
|
||||||
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
case AssetType::MODEL: icon = ICON_FA_CUBES_STACKED; break;
|
||||||
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
|
||||||
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
|
||||||
case AssetType::MATERIAL: break;
|
case AssetType::MATERIAL: break;
|
||||||
|
case AssetType::MESH: icon = ICON_FA_CUBES; break;
|
||||||
case AssetType::MAX_COUNT: break;
|
case AssetType::MAX_COUNT: break;
|
||||||
default: ;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
|
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data());
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
if(SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
auto id = file.assetMeta->id;
|
auto id = asset->id;
|
||||||
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
|
ImGui::Text("Moving Asset: %s [%zu]", asset->name.data(), asset->id);
|
||||||
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
if(ImGui::IsItemClicked())
|
if (ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
selectedAssets.clear();
|
selectedAssets.clear();
|
||||||
selectedAssets.push_back(file.assetMeta->id);
|
selectedAssets.push_back(asset->id);
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
switch (asset->type)
|
||||||
|
{
|
||||||
|
case AssetType::INVALID: break;
|
||||||
|
case AssetType::SHADER: break;
|
||||||
|
case AssetType::SHADER_BUILT_IN: break;
|
||||||
|
case AssetType::TEXTURE: break;
|
||||||
|
case AssetType::MESH: break;
|
||||||
|
case AssetType::SCENE:
|
||||||
|
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
|
{
|
||||||
|
editor->LoadScene(asset->id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AssetType::PREFAB: break;
|
||||||
|
case AssetType::MATERIAL:
|
||||||
|
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||||
|
{
|
||||||
|
matInspector->OpenMaterial(asset->id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AssetType::MAX_COUNT: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
if(isOpen)
|
||||||
|
{
|
||||||
|
for(auto const& subAsset : asset->subAssets)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 25.0f;
|
||||||
|
const ImRect childRect = DrawFile(subAsset);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
|
||||||
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
|
||||||
|
{
|
||||||
|
if (!assetBeingCreated.has_value())
|
||||||
|
return;
|
||||||
|
auto& path = std::get<0>(assetBeingCreated.value());
|
||||||
|
auto& type = std::get<1>(assetBeingCreated.value());
|
||||||
|
auto& assetName = std::get<2>(assetBeingCreated.value());
|
||||||
|
if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
|
||||||
|
{
|
||||||
|
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
|
||||||
|
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
|
||||||
|
{
|
||||||
|
matInspector->OpenMaterial(assetId, true);
|
||||||
|
}
|
||||||
|
assetBeingCreated.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace SHADE
|
||||||
class SHAssetBrowser final : public SHEditorWindow
|
class SHAssetBrowser final : public SHEditorWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
|
||||||
SHAssetBrowser();
|
SHAssetBrowser();
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
@ -20,12 +21,13 @@ namespace SHADE
|
||||||
void DrawMenuBar();
|
void DrawMenuBar();
|
||||||
ImRect RecursivelyDrawTree(FolderPointer folder);
|
ImRect RecursivelyDrawTree(FolderPointer folder);
|
||||||
void DrawCurrentFolder();
|
void DrawCurrentFolder();
|
||||||
ImRect DrawFile(SHFile const& file) noexcept;
|
ImRect DrawFile(SHAsset const* const asset) noexcept;
|
||||||
|
void DrawAssetBeingCreated() noexcept;
|
||||||
|
|
||||||
FolderPointer rootFolder, prevFolder, currentFolder;
|
FolderPointer rootFolder, prevFolder, currentFolder;
|
||||||
|
std::optional<AssetEntry> assetBeingCreated;
|
||||||
std::vector<FolderPointer> selectedFolders;
|
std::vector<FolderPointer> selectedFolders;
|
||||||
std::vector<AssetID> selectedAssets;
|
std::vector<AssetID> selectedAssets;
|
||||||
static constexpr float tileWidth = 50.0f;
|
static constexpr float tileWidth = 50.0f;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
|
|
||||||
isAnyNodeSelected = false;
|
isAnyNodeSelected = false;
|
||||||
|
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
if (skipFrame)
|
if (skipFrame)
|
||||||
|
@ -108,6 +108,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
ParentSelectedEntities(MAX_EID, draggingEntities);
|
||||||
|
draggingEntities.clear();
|
||||||
|
ImGui::ClearDragDrop();
|
||||||
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +201,7 @@ namespace SHADE
|
||||||
if (SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
std::string moveLabel = "Moving EID: ";
|
std::string moveLabel = "Moving EID: ";
|
||||||
static std::vector<EntityID> draggingEntities = editor->selectedEntities;
|
draggingEntities = editor->selectedEntities;
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
{
|
{
|
||||||
draggingEntities.clear();
|
draggingEntities.clear();
|
||||||
|
@ -217,7 +223,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
|
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(eid);
|
ParentSelectedEntities(eid, draggingEntities);
|
||||||
|
draggingEntities.clear();
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +262,7 @@ namespace SHADE
|
||||||
|
|
||||||
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||||
{
|
{
|
||||||
ParentSelectedEntities(MAX_EID);
|
ParentSelectedEntities(MAX_EID, editor->selectedEntities);
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
@ -323,14 +330,16 @@ namespace SHADE
|
||||||
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept
|
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
//auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
SHEntityParentCommand::EntityParentData entityParentData;
|
SHEntityParentCommand::EntityParentData entityParentData;
|
||||||
std::vector<EntityID> parentedEIDS;
|
std::vector<EntityID> parentedEIDS;
|
||||||
for (auto const& eid : editor->selectedEntities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
|
if(eid == parentEID)
|
||||||
|
continue;
|
||||||
if (sceneGraph.GetChild(eid, parentEID) == nullptr)
|
if (sceneGraph.GetChild(eid, parentEID) == nullptr)
|
||||||
{
|
{
|
||||||
parentedEIDS.push_back(eid);
|
parentedEIDS.push_back(eid);
|
||||||
|
@ -410,7 +419,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Execute()
|
void SHEntityParentCommand::Execute()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].newParentEID == MAX_EID)
|
if (entityParentData[eid].newParentEID == MAX_EID)
|
||||||
|
@ -422,7 +431,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Undo()
|
void SHEntityParentCommand::Undo()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].oldParentEID == MAX_EID)
|
if (entityParentData[eid].oldParentEID == MAX_EID)
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace SHADE
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() const 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) const noexcept;
|
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept;
|
||||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||||
void SelectAllEntities();
|
void SelectAllEntities();
|
||||||
void CopySelectedEntities();
|
void CopySelectedEntities();
|
||||||
|
@ -37,6 +37,8 @@ namespace SHADE
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
EntityID scrollTo = MAX_EID;
|
EntityID scrollTo = MAX_EID;
|
||||||
|
std::vector<EntityID> draggingEntities;
|
||||||
|
|
||||||
};//class SHHierarchyPanel
|
};//class SHHierarchyPanel
|
||||||
|
|
||||||
//Might move to a different file
|
//Might move to a different file
|
||||||
|
|
|
@ -224,9 +224,6 @@ namespace SHADE
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get transform component for extrapolating relative sizes
|
|
||||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
|
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -234,45 +231,43 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
auto& colliders = component->GetColliders();
|
auto& colliders = component->GetCollisionShapes();
|
||||||
int const size = static_cast<int>(colliders.size());
|
int const size = static_cast<int>(colliders.size());
|
||||||
ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
||||||
std::optional<int> colliderToDelete{ std::nullopt };
|
std::optional<int> colliderToDelete{ std::nullopt };
|
||||||
for (int i{}; i < size; ++i)
|
for (int i{}; i < size; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
SHCollider* collider = &component->GetCollider(i);
|
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
if (collider->GetType() == SHCollider::Type::BOX)
|
//collider->IsTrigger
|
||||||
|
|
||||||
|
if (collider->GetType() == SHCollisionShape::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
|
[box] { return box->GetRelativeExtents(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[sphere, transformComponent]
|
[sphere] { return sphere->GetRelativeRadius(); },
|
||||||
{
|
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||||
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
|
||||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
|
||||||
return sphere->GetRadius() / MAX_SCALE;
|
|
||||||
},
|
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
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" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||||
|
@ -297,6 +292,9 @@ namespace SHADE
|
||||||
});
|
});
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
|
||||||
|
|
||||||
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||||
{
|
{
|
||||||
colliderToDelete = i;
|
colliderToDelete = i;
|
||||||
|
@ -368,6 +366,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
Handle<SHMesh> const& mesh = component->GetMesh();
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
|
||||||
|
|
||||||
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
|
||||||
{
|
{
|
||||||
|
@ -379,6 +378,19 @@ namespace SHADE
|
||||||
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
|
||||||
SHResourceManager::FinaliseChanges();
|
SHResourceManager::FinaliseChanges();
|
||||||
}, SHDragDrop::DRAG_RESOURCE);
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
|
|
||||||
|
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]()
|
||||||
|
{
|
||||||
|
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
|
||||||
|
if(!mat)
|
||||||
|
return static_cast<AssetID>(0);
|
||||||
|
return SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0);
|
||||||
|
},
|
||||||
|
[component](AssetID const& id)
|
||||||
|
{
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id)));
|
||||||
|
}, SHDragDrop::DRAG_RESOURCE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "Serialization/SHSerializationHelper.hpp"
|
||||||
|
#include "SHMaterialInspector.h"
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHMaterialInspector::SHMaterialInspector()
|
||||||
|
:SHEditorWindow("Material Inspector", ImGuiWindowFlags_MenuBar), isDirty(false), isNewMaterial(false), currentViewedMaterial(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::OpenMaterial(AssetID const& assetId, bool isNew) noexcept
|
||||||
|
{
|
||||||
|
//Get mat data
|
||||||
|
if(isDirty)
|
||||||
|
return;
|
||||||
|
isDirty = isNew;
|
||||||
|
isOpen = true;
|
||||||
|
SetFocusToWindow();
|
||||||
|
currentViewedMaterial = assetId;
|
||||||
|
|
||||||
|
//currentMatSpec = //Get mat spec
|
||||||
|
|
||||||
|
currentMatSpec = SHResourceManager::LoadOrGet<SHMaterialSpec>(assetId);
|
||||||
|
currentMaterial = SHResourceManager::LoadOrGet<SHMaterial>(assetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
if(currentViewedMaterial)
|
||||||
|
{
|
||||||
|
DrawMenuBar();
|
||||||
|
|
||||||
|
//if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Vertex Shader", std::to_string(currentMatSpec->vertexShader), [&]() {return currentMatSpec->vertexShader; }, [&](AssetID const& id) {currentMatSpec->vertexShader = id; }, SHDragDrop::DRAG_RESOURCE))
|
||||||
|
//{
|
||||||
|
// isDirty = true;
|
||||||
|
// vertShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->vertexShader);
|
||||||
|
//}
|
||||||
|
//if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Fragment Shader", std::to_string(currentMatSpec->fragShader), [&]() {return currentMatSpec->fragShader; }, [&](AssetID const& id) {currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE))
|
||||||
|
//{
|
||||||
|
// isDirty = true;
|
||||||
|
// fragShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
|
||||||
|
//}
|
||||||
|
|
||||||
|
DrawShaderProperties(/*fragShaderHandle*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::DrawMenuBar()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled(!isDirty);
|
||||||
|
if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
|
||||||
|
{
|
||||||
|
//save
|
||||||
|
if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial))
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
out << YAML::convert<SHMaterialSpec>::encode(*currentMatSpec);
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
matAsset->data = out.c_str();
|
||||||
|
|
||||||
|
Handle<SHShaderBlockInterface> pipelineProperties = currentMaterial->GetShaderBlockInterface();
|
||||||
|
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||||
|
{
|
||||||
|
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
||||||
|
const YAML::Node& PROP_NODE = currentMatSpec->properties[PROP_NAME.data()];
|
||||||
|
if (PROP_NODE.IsDefined())
|
||||||
|
{
|
||||||
|
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||||
|
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||||
|
switch (VARIABLE->type)
|
||||||
|
{
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||||
|
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||||
|
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
|
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||||
|
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec3>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||||
|
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec4>());
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SHAssetManager::SaveAsset(currentViewedMaterial))
|
||||||
|
{
|
||||||
|
isDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInspector::DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/)
|
||||||
|
{
|
||||||
|
/*if(!shaderModule)
|
||||||
|
return;*/
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface();
|
||||||
|
//auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
|
||||||
|
|
||||||
|
int const varCount = static_cast<int>(interface->GetVariableCount());
|
||||||
|
|
||||||
|
for (int i = 0; i < varCount; ++i)
|
||||||
|
{
|
||||||
|
auto variable = interface->GetVariable(i);
|
||||||
|
const std::string& VAR_NAME = interface->GetVariableName(i);
|
||||||
|
if(VAR_NAME.empty())
|
||||||
|
continue;
|
||||||
|
switch (variable->type)
|
||||||
|
{
|
||||||
|
case SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||||
|
isDirty |= SHEditorWidgets::DragFloat(VAR_NAME,
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<float>();
|
||||||
|
else
|
||||||
|
return 0.0f;
|
||||||
|
},
|
||||||
|
[&](float const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHShaderBlockInterface::Variable::Type::INT:
|
||||||
|
isDirty |= SHEditorWidgets::DragInt(VAR_NAME,
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<int>();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
[&](int const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if(SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if(AssetID* payload = SHDragDrop::AcceptPayload<AssetID>(SHDragDrop::DRAG_RESOURCE))
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = *payload;
|
||||||
|
isDirty = true;
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
|
isDirty |= SHEditorWidgets::DragVec2(VAR_NAME, { "X", "Y" },
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<SHVec2>();
|
||||||
|
else
|
||||||
|
return SHVec2::Zero;
|
||||||
|
},
|
||||||
|
[&](SHVec2 const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||||
|
isDirty |= SHEditorWidgets::DragVec3(VAR_NAME, { "X", "Y", "Z" },
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<SHVec3>();
|
||||||
|
else
|
||||||
|
return SHVec3::Zero;
|
||||||
|
},
|
||||||
|
[&](SHVec3 const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||||
|
isDirty |= SHEditorWidgets::DragVec4(VAR_NAME, { "X", "Y", "Z", "W" },
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<SHVec4>();
|
||||||
|
else
|
||||||
|
return SHVec4::Zero;
|
||||||
|
},
|
||||||
|
[&](SHVec4 const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case SHShaderBlockInterface::Variable::Type::OTHER:
|
||||||
|
isDirty |= SHEditorWidgets::InputText(VAR_NAME,
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
if (currentMatSpec->properties[VAR_NAME].IsDefined())
|
||||||
|
return currentMatSpec->properties[VAR_NAME].as<std::string>();
|
||||||
|
else
|
||||||
|
return std::string();
|
||||||
|
},
|
||||||
|
[&](std::string const& value)
|
||||||
|
{
|
||||||
|
currentMatSpec->properties[VAR_NAME] = value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHMaterialInspector final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHMaterialInspector();
|
||||||
|
~SHMaterialInspector() = default;
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
|
||||||
|
void OpenMaterial(AssetID const& assetId, bool isNew = false) noexcept;
|
||||||
|
private:
|
||||||
|
void DrawMenuBar();
|
||||||
|
void DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/);
|
||||||
|
|
||||||
|
bool isDirty;
|
||||||
|
bool isNewMaterial;
|
||||||
|
AssetID currentViewedMaterial;
|
||||||
|
Handle<SHMaterialSpec> currentMatSpec;
|
||||||
|
Handle<SHMaterial> currentMaterial;
|
||||||
|
Handle<SHVkShaderModule> vertShaderHandle, fragShaderHandle;
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
#include "SHEditorMenuBar.h"
|
#include "SHEditorMenuBar.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
@ -17,7 +18,14 @@
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <rttr/type>
|
#include <rttr/type>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -38,8 +46,7 @@ namespace SHADE
|
||||||
void SHEditorMenuBar::Init()
|
void SHEditorMenuBar::Init()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Init();
|
SHEditorWindow::Init();
|
||||||
constexpr std::string_view path = "../../Assets/Editor/Layouts";
|
for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
|
||||||
for(auto const& entry : std::filesystem::directory_iterator(path))
|
|
||||||
{
|
{
|
||||||
layoutPaths.push_back(entry.path());
|
layoutPaths.push_back(entry.path());
|
||||||
}
|
}
|
||||||
|
@ -75,13 +82,17 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("File"))
|
if (ImGui::BeginMenu("File"))
|
||||||
{
|
{
|
||||||
|
if(ImGui::Selectable("New Scene"))
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
||||||
|
}
|
||||||
if(ImGui::Selectable("Save"))
|
if(ImGui::Selectable("Save"))
|
||||||
{
|
{
|
||||||
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
|
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Load"))
|
if(ImGui::Selectable("Load"))
|
||||||
{
|
{
|
||||||
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
|
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
@ -108,16 +119,22 @@ namespace SHADE
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->GenerateScriptsCsProjFile();
|
scriptEngine->GenerateScriptsCsProjFile();
|
||||||
}
|
}
|
||||||
|
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
||||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
{
|
{
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
scriptEngine->BuildScriptAssembly(true, true);
|
scriptEngine->BuildScriptAssembly(true, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Build Scripts - Release"))
|
if (ImGui::Selectable("Build Scripts - Release"))
|
||||||
{
|
{
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->BuildScriptAssembly(false, true);
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
scriptEngine->BuildScriptAssembly(false, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +172,35 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Application Config"))
|
||||||
|
{
|
||||||
|
auto& appConfig = SHConfigurationManager::applicationConfig;
|
||||||
|
ImGui::InputText("Window Title", &appConfig.windowTitle);
|
||||||
|
ImGui::Checkbox("Start in Fullscreen", &appConfig.startInFullScreen);
|
||||||
|
SHEditorWidgets::DragN<float, 2>("Window Size", { "Width", "Height" }, { &appConfig.windowSize.x, &appConfig.windowSize.y });
|
||||||
|
//ImGui::InputScalar("Starting Scene", ImGuiDataType_U32, &appConfig.startingSceneID);
|
||||||
|
auto sceneAsset = SHAssetManager::GetData<SHSceneAsset>(appConfig.startingSceneID);
|
||||||
|
|
||||||
|
if(ImGui::BeginCombo("Starting Scne", sceneAsset ? sceneAsset->name.data() : ""))
|
||||||
|
{
|
||||||
|
auto scenes = SHAssetManager::GetAllRecordOfType(AssetType::SCENE);
|
||||||
|
for(auto const& scene : scenes)
|
||||||
|
{
|
||||||
|
if(ImGui::Selectable(scene.name.data()))
|
||||||
|
{
|
||||||
|
appConfig.startingSceneID = scene.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
SHConfigurationManager::SaveApplicationConfig();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,13 +221,16 @@ namespace SHADE
|
||||||
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))
|
||||||
{
|
{
|
||||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
if(editor->SaveScene())
|
||||||
{
|
{
|
||||||
.previousState = editor->editorState
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
};
|
{
|
||||||
editor->editorState = SHEditor::State::PLAY;
|
.previousState = editor->editorState
|
||||||
|
};
|
||||||
|
editor->editorState = SHEditor::State::PLAY;
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
|
||||||
|
@ -206,6 +255,7 @@ namespace SHADE
|
||||||
editor->editorState = SHEditor::State::STOP;
|
editor->editorState = SHEditor::State::STOP;
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
|
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace SHADE
|
||||||
//|| Public Member Functions ||
|
//|| Public Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||||
: windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,5 +68,10 @@ namespace SHADE
|
||||||
void SHEditorWindow::OnPosChange()
|
void SHEditorWindow::OnPosChange()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::SetFocusToWindow()
|
||||||
|
{
|
||||||
|
ImGui::SetWindowFocus(windowName.data());
|
||||||
|
}
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
||||||
virtual bool Begin();
|
virtual bool Begin();
|
||||||
virtual void OnResize();
|
virtual void OnResize();
|
||||||
virtual void OnPosChange();
|
virtual void OnPosChange();
|
||||||
|
virtual void SetFocusToWindow();
|
||||||
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
ImGuiIO& io;
|
ImGuiIO& io;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||||
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||||
#include "Inspector/SHEditorInspector.h" //Inspector
|
#include "Inspector/SHEditorInspector.h" //Inspector
|
||||||
#include "Profiling/SHEditorProfiler.h" //Profiler
|
#include "Profiling/SHEditorProfiler.h" //Profiler
|
||||||
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
|
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
|
||||||
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
||||||
|
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
|
@ -45,7 +45,12 @@
|
||||||
#include <backends/imgui_impl_sdl.h>
|
#include <backends/imgui_impl_sdl.h>
|
||||||
#include <backends/imgui_impl_vulkan.h>
|
#include <backends/imgui_impl_vulkan.h>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
{
|
{
|
||||||
|
@ -60,6 +65,10 @@ RTTR_REGISTRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" };
|
||||||
|
const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" };
|
||||||
|
const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"};
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -77,7 +86,6 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::Init()
|
void SHEditor::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
if(auto context = ImGui::CreateContext())
|
if(auto context = ImGui::CreateContext())
|
||||||
{
|
{
|
||||||
|
@ -93,6 +101,8 @@ namespace SHADE
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||||
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
|
||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
|
@ -100,7 +110,7 @@ namespace SHADE
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
io->IniFilename = USER_LAYOUT_PATH.data();
|
||||||
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
InitLayout();
|
InitLayout();
|
||||||
|
|
||||||
|
@ -120,6 +130,17 @@ namespace SHADE
|
||||||
window->Init();
|
window->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Editor View Gridlines */
|
||||||
|
SetUpGridLines(true, true);
|
||||||
|
// Handle state changes so that we only show in edit mode
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHEditor>> stateChangeEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHEditor>>(this, &SHEditor::onEditorStateChanged)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_PLAY_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
|
||||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +155,9 @@ namespace SHADE
|
||||||
window->Update();
|
window->Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderSceneNamePrompt();
|
||||||
|
RenderUnsavedChangesPrompt();
|
||||||
//PollPicking();
|
//PollPicking();
|
||||||
|
|
||||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
@ -159,27 +182,172 @@ 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
|
||||||
|
{
|
||||||
|
if(isUnsavedChangesPromptOpen)
|
||||||
|
{
|
||||||
|
ImGui::OpenPopup(unsavedChangesPromptName.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ImGui::BeginPopupModal(unsavedChangesPromptName.data(), &isUnsavedChangesPromptOpen))
|
||||||
|
{
|
||||||
|
ImGui::Text("You have unsaved changes!");
|
||||||
|
if(ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
isSceneNamePromptOpen = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
isUnsavedChangesPromptOpen = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::InitLayout() noexcept
|
void SHEditor::InitLayout() noexcept
|
||||||
{
|
{
|
||||||
if(!std::filesystem::exists(io->IniFilename))
|
if(!std::filesystem::exists(io->IniFilename))
|
||||||
{
|
{
|
||||||
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename);
|
std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename);
|
||||||
}
|
}
|
||||||
//eventually load preferred layout here
|
//eventually load preferred layout here
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::InitFonts() noexcept
|
void SHEditor::InitFonts() noexcept
|
||||||
{
|
{
|
||||||
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path
|
||||||
|
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes)
|
||||||
|
{
|
||||||
|
// Clear existing lines
|
||||||
|
SHDebugDraw::ClearPersistentDraws();
|
||||||
|
|
||||||
|
static constexpr float DELTA = 1.0f;
|
||||||
|
static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA);
|
||||||
|
static constexpr float LINE_HALF_LENGTH = (DELTA * static_cast<float>(EXTENT_COUNT)) * 0.5f;
|
||||||
|
|
||||||
|
// Render Grid
|
||||||
|
static const SHColour GRID_COL = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||||
|
if (drawGrid)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < EXTENT_COUNT; ++i)
|
||||||
|
{
|
||||||
|
// X-Axis Lines
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA }
|
||||||
|
);
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA }
|
||||||
|
);
|
||||||
|
// Y-Axis Lines
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render World Axes
|
||||||
|
if (drawAxes || drawGrid)
|
||||||
|
{
|
||||||
|
const SHColour X_AXIS_COL = drawAxes ? SHColour::RED : GRID_COL;
|
||||||
|
const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL;
|
||||||
|
const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL;
|
||||||
|
// X
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
X_AXIS_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f }
|
||||||
|
);
|
||||||
|
// Y
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
Y_AXIS_COL,
|
||||||
|
SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f },
|
||||||
|
SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f }
|
||||||
|
);
|
||||||
|
// Z
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
Z_AXIS_COL,
|
||||||
|
SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHEditor::onEditorStateChanged(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get());
|
||||||
|
switch (editorState)
|
||||||
|
{
|
||||||
|
case State::PAUSE:
|
||||||
|
case State::STOP:
|
||||||
|
SetUpGridLines(true, true);
|
||||||
|
break;
|
||||||
|
case State::PLAY:
|
||||||
|
default:
|
||||||
|
SHDebugDraw::ClearPersistentDraws();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::Exit()
|
void SHEditor::Exit()
|
||||||
{
|
{
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
|
@ -337,9 +505,12 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd)
|
||||||
|
{
|
||||||
|
cmd->BeginLabeledSegment("ImGui Draw");
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
});
|
cmd->EndLabeledSegment();
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,6 +537,66 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::NewScene()
|
||||||
|
{
|
||||||
|
if(shWindow->IsUnsavedChanges())
|
||||||
|
{
|
||||||
|
//Unsaved changes prompt
|
||||||
|
sceneToLoad = 0;
|
||||||
|
isUnsavedChangesPromptOpen = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHSceneManager::RestartScene(0);
|
||||||
|
shWindow->ToggleUnsavedChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditor::SaveScene(std::string const& newSceneName)
|
||||||
|
{
|
||||||
|
auto const data = SHAssetManager::GetData<SHSceneAsset>(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
if (newSceneName.empty())
|
||||||
|
{
|
||||||
|
//Prompt for scene name
|
||||||
|
isSceneNamePromptOpen = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Else We have a new name
|
||||||
|
|
||||||
|
SHSceneManager::SetCurrentSceneName(newSceneName);
|
||||||
|
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName));
|
||||||
|
}
|
||||||
|
//Get data, if data is null, asset doesn't exist, prompt for a name and create a new asset with the name
|
||||||
|
|
||||||
|
//serialize the scene
|
||||||
|
if(SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID()))
|
||||||
|
{
|
||||||
|
if(shWindow->IsUnsavedChanges())
|
||||||
|
shWindow->ToggleUnsavedChanges();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditor::LoadScene(AssetID const& assetID) noexcept
|
||||||
|
{
|
||||||
|
if(shWindow->IsUnsavedChanges())
|
||||||
|
{
|
||||||
|
//Unsaved changes prompt
|
||||||
|
isUnsavedChangesPromptOpen = true;
|
||||||
|
sceneToLoad = assetID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Load the scene
|
||||||
|
sceneToLoad = 0;
|
||||||
|
SHSceneManager::RestartScene(assetID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::NewFrame()
|
void SHEditor::NewFrame()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
|
@ -17,13 +17,17 @@
|
||||||
#include "EditorWindow/SHEditorWindow.h"
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
#include "Gizmos/SHTransformGizmo.h"
|
#include "Gizmos/SHTransformGizmo.h"
|
||||||
|
#include "Events/SHEventDefines.h"
|
||||||
|
#include "Events/SHEvent.h"
|
||||||
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <SDL_video.h>
|
#include <SDL_video.h>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -170,9 +174,16 @@ namespace SHADE
|
||||||
void InitBackend();
|
void InitBackend();
|
||||||
|
|
||||||
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
||||||
|
void SetSHWindow(SHWindow* inWindow){shWindow = inWindow;}
|
||||||
|
|
||||||
void PollPicking();
|
void PollPicking();
|
||||||
|
|
||||||
|
void NewScene();
|
||||||
|
|
||||||
|
bool SaveScene(std::string const& newSceneName = {});
|
||||||
|
|
||||||
|
void LoadScene(AssetID const& assetID) noexcept;
|
||||||
|
|
||||||
// List of selected entities
|
// List of selected entities
|
||||||
std::vector<EntityID> selectedEntities;
|
std::vector<EntityID> selectedEntities;
|
||||||
|
|
||||||
|
@ -190,16 +201,34 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
|
void RenderSceneNamePrompt() noexcept;
|
||||||
|
|
||||||
|
void RenderUnsavedChangesPrompt() noexcept;
|
||||||
|
|
||||||
void InitLayout() noexcept;
|
void InitLayout() noexcept;
|
||||||
|
|
||||||
void InitFonts() noexcept;
|
void InitFonts() noexcept;
|
||||||
|
|
||||||
|
void SetUpGridLines(bool drawGrid, bool drawAxes);
|
||||||
|
|
||||||
|
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||||
|
|
||||||
|
bool isSceneNamePromptOpen = false;
|
||||||
|
|
||||||
|
bool isUnsavedChangesPromptOpen = false;
|
||||||
|
|
||||||
|
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
|
||||||
|
static constexpr std::string_view unsavedChangesPromptName = "Unsaved Changes";
|
||||||
|
|
||||||
|
AssetID sceneToLoad = 0;
|
||||||
|
|
||||||
// Handle to command pool used for ImGui Vulkan Backend
|
// Handle to command pool used for ImGui Vulkan Backend
|
||||||
Handle<SHVkCommandPool> imguiCommandPool;
|
Handle<SHVkCommandPool> imguiCommandPool;
|
||||||
// Handle to command buffer used for ImGui Vulkan Backend
|
// Handle to command buffer used for ImGui Vulkan Backend
|
||||||
Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||||
|
|
||||||
SDL_Window* sdlWindow {nullptr};
|
SDL_Window* sdlWindow {nullptr};
|
||||||
|
SHWindow* shWindow {nullptr};
|
||||||
|
|
||||||
ImGuiIO* io{nullptr};
|
ImGuiIO* io{nullptr};
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::Checkbox("#", &value);
|
return ImGui::Checkbox("##", &value);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputInt("#", &value,
|
return ImGui::InputInt("##", &value,
|
||||||
1, 10,
|
1, 10,
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = InputInt("#", signedVal);
|
const bool CHANGED = InputInt("##", signedVal);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||||
|
@ -190,7 +190,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputFloat("#", &value,
|
return ImGui::InputFloat("##", &value,
|
||||||
0.1f, 1.0f, "%.3f",
|
0.1f, 1.0f, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
0.1, 1.0, "%.3f",
|
0.1, 1.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
1.0, 45.0, "%.3f",
|
1.0, 45.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||||
|
@ -288,7 +288,7 @@ namespace SHADE
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
|
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
|
||||||
{
|
{
|
||||||
ImGui::Text(label.c_str());
|
ImGui::Text(label.c_str());
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
|
@ -296,7 +296,7 @@ namespace SHADE
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
if (entity)
|
if (!alwaysNull && entity)
|
||||||
{
|
{
|
||||||
oss << value << ": " << entity->name;
|
oss << value << ": " << entity->name;
|
||||||
}
|
}
|
||||||
|
@ -314,6 +314,13 @@ namespace SHADE
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Clear"))
|
||||||
|
{
|
||||||
|
value = MAX_EID;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +334,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < enumNames.size(); ++i)
|
for (int i = 0; i < enumNames.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -313,8 +313,12 @@ namespace SHADE
|
||||||
/// <param name="label">Label used to identify this widget.</param>
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
/// <param name="value">Reference to the variable to store the result.</param>
|
/// <param name="value">Reference to the variable to store the result.</param>
|
||||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <param name="alwaysNull>
|
||||||
|
/// If set, the field displayed will always be blank regardless of specified
|
||||||
|
/// GameObject.
|
||||||
|
/// </param>
|
||||||
/// <returns>True if the value was changed.</returns>
|
/// <returns>True if the value was changed.</returns>
|
||||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a combo box for enumeration input.
|
/// Creates a combo box for enumeration input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -422,12 +422,13 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
bool const changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
|
bool changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
|
||||||
if(SHDragDrop::BeginTarget())
|
if(SHDragDrop::BeginTarget())
|
||||||
{
|
{
|
||||||
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
|
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
|
||||||
{
|
{
|
||||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
|
||||||
|
changed = true;
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
||||||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,11 @@ namespace SHADE
|
||||||
return bufferUsageFlags;
|
return bufferUsageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkBuffer::GetSizeStored(void) const noexcept
|
||||||
|
{
|
||||||
|
return sizeStored;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -212,9 +217,11 @@ namespace SHADE
|
||||||
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
|
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &stagingAlloc, &allocInfo);
|
&tempBuffer, &stagingAlloc, &allocInfo);
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name);
|
||||||
|
|
||||||
// then assign it to the hpp version
|
// then assign it to the hpp version
|
||||||
stagingBuffer = tempBuffer;
|
stagingBuffer = tempBuffer;
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name);
|
||||||
|
|
||||||
// Just map, copy then unmap
|
// Just map, copy then unmap
|
||||||
void* stagingBufferMappedPtr = nullptr;
|
void* stagingBufferMappedPtr = nullptr;
|
||||||
|
@ -246,7 +253,11 @@ namespace SHADE
|
||||||
auto result = vmaCreateBuffer(vmaAllocator,
|
auto result = vmaCreateBuffer(vmaAllocator,
|
||||||
&bufferCreateInfo.operator VkBufferCreateInfo & (),
|
&bufferCreateInfo.operator VkBufferCreateInfo & (),
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &alloc, &allocInfo);
|
&tempBuffer, &alloc, &allocInfo);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (!name.empty())
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] " + name);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
|
||||||
|
@ -264,7 +275,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkBuffer::SHVkBuffer(std::reference_wrapper<VmaAllocator const> allocator) noexcept
|
SHVkBuffer::SHVkBuffer(Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept
|
||||||
: vkBuffer{}
|
: vkBuffer{}
|
||||||
, stagingBuffer{}
|
, stagingBuffer{}
|
||||||
, sizeStored{ 0 }
|
, sizeStored{ 0 }
|
||||||
|
@ -272,19 +283,23 @@ namespace SHADE
|
||||||
, alloc {nullptr}
|
, alloc {nullptr}
|
||||||
, randomAccessOptimized{false}
|
, randomAccessOptimized{false}
|
||||||
, vmaAllocator{allocator}
|
, vmaAllocator{allocator}
|
||||||
|
, device { logicalDevice }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHVkBuffer::SHVkBuffer(
|
SHVkBuffer::SHVkBuffer(
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice,
|
||||||
uint32_t inSize,
|
uint32_t inSize,
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
std::reference_wrapper<VmaAllocator const> allocator,
|
std::reference_wrapper<VmaAllocator const> allocator,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
|
const std::string& name,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept
|
) noexcept
|
||||||
: SHVkBuffer(allocator)
|
: SHVkBuffer(logicalDevice, allocator)
|
||||||
{
|
{
|
||||||
|
this->name = name;
|
||||||
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
|
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +314,8 @@ namespace SHADE
|
||||||
, bufferUsageFlags {rhs.bufferUsageFlags}
|
, bufferUsageFlags {rhs.bufferUsageFlags}
|
||||||
, bufferCreateInfo { rhs.bufferCreateInfo }
|
, bufferCreateInfo { rhs.bufferCreateInfo }
|
||||||
, allocCreateInfo { rhs.allocCreateInfo }
|
, allocCreateInfo { rhs.allocCreateInfo }
|
||||||
|
, name { std::move(rhs.name) }
|
||||||
|
, device { rhs.device }
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.vkBuffer = VK_NULL_HANDLE;
|
rhs.vkBuffer = VK_NULL_HANDLE;
|
||||||
|
@ -320,6 +337,8 @@ namespace SHADE
|
||||||
bufferCreateInfo = rhs.bufferCreateInfo;
|
bufferCreateInfo = rhs.bufferCreateInfo;
|
||||||
allocCreateInfo = rhs.allocCreateInfo;
|
allocCreateInfo = rhs.allocCreateInfo;
|
||||||
bufferUsageFlags = rhs.bufferUsageFlags;
|
bufferUsageFlags = rhs.bufferUsageFlags;
|
||||||
|
name = std::move(rhs.name);
|
||||||
|
device = rhs.device;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -397,6 +416,8 @@ namespace SHADE
|
||||||
|
|
||||||
auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
|
auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
|
||||||
vkBuffer = tempBuffer;
|
vkBuffer = tempBuffer;
|
||||||
|
if (!name.empty())
|
||||||
|
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, vkBuffer, "[Buffer] " + name);
|
||||||
|
|
||||||
// This probably means that a HOST_CACHED memory type is used on allocation
|
// This probably means that a HOST_CACHED memory type is used on allocation
|
||||||
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
|
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace SHADE
|
||||||
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
|
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
|
||||||
|
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
|
||||||
class SHVkBuffer
|
class SHVkBuffer
|
||||||
{
|
{
|
||||||
|
@ -51,6 +52,11 @@ namespace SHADE
|
||||||
//VmaAllocator const& vmaAllocator;
|
//VmaAllocator const& vmaAllocator;
|
||||||
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
||||||
|
|
||||||
|
//! Name of this buffer if any
|
||||||
|
std::string name;
|
||||||
|
//! Handle to the logical device that created this buffer
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -62,13 +68,15 @@ namespace SHADE
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHVkBuffer (void) noexcept = delete;
|
SHVkBuffer (void) noexcept = delete;
|
||||||
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept;
|
SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
|
||||||
SHVkBuffer (
|
SHVkBuffer (
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice,
|
||||||
uint32_t inSize,
|
uint32_t inSize,
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
std::reference_wrapper<VmaAllocator const> allocator,
|
std::reference_wrapper<VmaAllocator const> allocator,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
|
const std::string& name = "",
|
||||||
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlags allocFlags = {}
|
VmaAllocationCreateFlags allocFlags = {}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
@ -84,7 +92,7 @@ namespace SHADE
|
||||||
uint32_t inSize,
|
uint32_t inSize,
|
||||||
void* data,
|
void* data,
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
@ -102,8 +110,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
vk::Buffer GetVkBuffer (void) const noexcept;
|
vk::Buffer GetVkBuffer (void) const noexcept;
|
||||||
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
||||||
|
uint32_t GetSizeStored (void) const noexcept;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
||||||
|
|
|
@ -105,6 +105,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Set the state to recording if the call above succeeded.
|
// Set the state to recording if the call above succeeded.
|
||||||
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
|
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
|
||||||
|
|
||||||
|
// Reset segment count
|
||||||
|
segmentDepth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -282,6 +285,11 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::SetLineWidth(float lineWidth) noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.setLineWidth(lineWidth);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -502,6 +510,41 @@ namespace SHADE
|
||||||
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::BeginLabeledSegment(const std::string& label) noexcept
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
static const std::array SEGMENT_COLOURS =
|
||||||
|
{
|
||||||
|
SHColour::LIGHTPINK,
|
||||||
|
SHColour::LIGHTBLUE,
|
||||||
|
SHColour::LIGHTGREEN,
|
||||||
|
SHColour::YELLOW,
|
||||||
|
SHColour::PINK,
|
||||||
|
SHColour::TEAL,
|
||||||
|
SHColour::LIME,
|
||||||
|
SHColour::ORANGE,
|
||||||
|
SHColour::VIOLET,
|
||||||
|
SHColour::MAROON,
|
||||||
|
SHColour::DARKGREEN,
|
||||||
|
SHColour::SANDYBROWN
|
||||||
|
};
|
||||||
|
|
||||||
|
const SHColour COLOR = SEGMENT_COLOURS[segmentDepth];
|
||||||
|
++segmentDepth;
|
||||||
|
if (segmentDepth >= static_cast<int>(SEGMENT_COLOURS.size()))
|
||||||
|
segmentDepth = 0;
|
||||||
|
vkCommandBuffer.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT().setPLabelName(label.data()).setColor({ COLOR.x, COLOR.y, COLOR.z, COLOR.w }));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::EndLabeledSegment() noexcept
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
vkCommandBuffer.endDebugUtilsLabelEXT();
|
||||||
|
segmentDepth = std::max(segmentDepth - 1, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
||||||
//{
|
//{
|
||||||
// //vkCommandBuffer.pipelineBarrier()
|
// //vkCommandBuffer.pipelineBarrier()
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Resource/SHResourceLibrary.h"
|
#include "Resource/SHResourceLibrary.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
||||||
#include "Graphics/Pipeline/SHPipelineType.h"
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -78,7 +79,10 @@ namespace SHADE
|
||||||
std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData;
|
std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData;
|
||||||
|
|
||||||
//! The push constant data for the command buffer
|
//! The push constant data for the command buffer
|
||||||
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
||||||
|
|
||||||
|
//! Depth of segmenting of the command buffer (used for debug data)
|
||||||
|
int segmentDepth;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
@ -107,7 +111,7 @@ namespace SHADE
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
// Begins and Ends
|
// Begins and Ends
|
||||||
void BeginRecording (void) noexcept;
|
void BeginRecording () noexcept;
|
||||||
void EndRecording (void) noexcept;
|
void EndRecording (void) noexcept;
|
||||||
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
||||||
void EndRenderpass (void) noexcept;
|
void EndRenderpass (void) noexcept;
|
||||||
|
@ -115,6 +119,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Dynamic State
|
// Dynamic State
|
||||||
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
||||||
|
void SetLineWidth (float lineWidth) noexcept;
|
||||||
|
|
||||||
// Binding Commands
|
// Binding Commands
|
||||||
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
||||||
|
@ -147,6 +152,10 @@ namespace SHADE
|
||||||
bool IsReadyToSubmit (void) const noexcept;
|
bool IsReadyToSubmit (void) const noexcept;
|
||||||
void HandlePostSubmit (void) noexcept;
|
void HandlePostSubmit (void) noexcept;
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
void BeginLabeledSegment(const std::string& label) noexcept;
|
||||||
|
void EndLabeledSegment() noexcept;
|
||||||
|
|
||||||
// Push Constant variable setting
|
// Push Constant variable setting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
|
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
|
||||||
|
|
|
@ -119,6 +119,18 @@ namespace SHADE
|
||||||
return setIndex;
|
return setIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
|
||||||
|
{
|
||||||
|
uint32_t numDynamicBindings = 0;
|
||||||
|
for (auto& binding : layoutDesc)
|
||||||
|
{
|
||||||
|
if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic)
|
||||||
|
++numDynamicBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numDynamicBindings;
|
||||||
|
}
|
||||||
|
|
||||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace SHADE
|
||||||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||||
std::vector<Binding> const& GetBindings (void) const noexcept;
|
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||||
SetIndex GetSetIndex (void) const noexcept;
|
SetIndex GetSetIndex (void) const noexcept;
|
||||||
|
uint32_t GetNumDynamicOffsetsRequired (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -220,6 +220,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
|
||||||
|
SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device");
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVMA();
|
InitializeVMA();
|
||||||
|
@ -419,9 +420,9 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept
|
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags, const std::string& name) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags);
|
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -455,12 +456,12 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, w, h, levels, format, usage, create);
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef SH_LOGICAL_DEVICE_H
|
#pragma once
|
||||||
#define SH_LOGICAL_DEVICE_H
|
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -67,7 +66,6 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
|
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -147,7 +145,8 @@ namespace SHADE
|
||||||
uint32_t srcSize,
|
uint32_t srcSize,
|
||||||
vk::BufferUsageFlags bufferUsage,
|
vk::BufferUsageFlags bufferUsage,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
VmaAllocationCreateFlags allocFlags
|
VmaAllocationCreateFlags allocFlags,
|
||||||
|
const std::string& name = ""
|
||||||
) const noexcept;
|
) const noexcept;
|
||||||
|
|
||||||
Handle<SHVkImage> CreateImage (
|
Handle<SHVkImage> CreateImage (
|
||||||
|
@ -202,7 +201,33 @@ namespace SHADE
|
||||||
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
||||||
|
|
||||||
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
||||||
void UpdateDescriptorSet (vk::WriteDescriptorSet const& writeDescSet) noexcept;
|
void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Debug Tools */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a Vulkan HPP object's name for debugging purposes. This function will not be
|
||||||
|
/// compiled outside of Debug configurations. Hence, it is advised to use provided
|
||||||
|
/// macro function SET_VK_OBJ_NAME() instead of using this function directly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objType">Type of the object.</param>
|
||||||
|
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
|
||||||
|
/// <param name="objName">Object's name.</param>
|
||||||
|
template<typename T>
|
||||||
|
inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName);
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a Vulkan object's name for debugging purposes. This function will not be
|
||||||
|
/// compiled outside of Debug configurations. Hence, it is advised to use provided
|
||||||
|
/// macro function SET_VK_OBJ_NAME_VK() instead of using this function directly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objType">Type of the object.</param>
|
||||||
|
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
|
||||||
|
/// <param name="objName">Object's name.</param>
|
||||||
|
template<typename T>
|
||||||
|
inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
@ -220,4 +245,4 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#include "SHVkLogicalDevice.hpp"
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkLogicalDevice.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 4, 2022
|
||||||
|
\brief Contains implementation of inline and template functions of
|
||||||
|
SHVkLogicalDevice.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHVkLogicalDevice.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Debug Tools */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
template<typename T>
|
||||||
|
void SHVkLogicalDevice::SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName)
|
||||||
|
{
|
||||||
|
if (objName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk::DebugUtilsObjectNameInfoEXT info;
|
||||||
|
info.objectType = objType;
|
||||||
|
info.objectHandle = (uint64_t) static_cast<typename T::NativeType>(objHandle);
|
||||||
|
info.pObjectName = objName.data();
|
||||||
|
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void SHVkLogicalDevice::SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName)
|
||||||
|
{
|
||||||
|
if (objName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk::DebugUtilsObjectNameInfoEXT info;
|
||||||
|
info.objectType = objType;
|
||||||
|
info.objectHandle = (uint64_t) objVkHandle;
|
||||||
|
info.pObjectName = objName.data();
|
||||||
|
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------------------*/
|
||||||
|
/* Macro Definitions */
|
||||||
|
/*-------------------------------------------------------------------------------------*/
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
|
||||||
|
DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
|
||||||
|
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
|
||||||
|
DEVICE->SetVulkanObjectNameVk(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
|
||||||
|
#else
|
||||||
|
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
|
||||||
|
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
|
||||||
|
#endif
|
|
@ -61,6 +61,7 @@ namespace SHADE
|
||||||
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
|
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
|
||||||
&allocCreateInfo,
|
&allocCreateInfo,
|
||||||
&tempBuffer, &stagingAlloc, &allocInfo);
|
&tempBuffer, &stagingAlloc, &allocInfo);
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging Buffer for Image");
|
||||||
|
|
||||||
// then assign it to the hpp version
|
// then assign it to the hpp version
|
||||||
stagingBuffer = tempBuffer;
|
stagingBuffer = tempBuffer;
|
||||||
|
@ -107,6 +108,8 @@ namespace SHADE
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
vkImage = tempImage;
|
vkImage = tempImage;
|
||||||
|
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
@ -115,7 +118,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
Handle<SHVkLogicalDevice> logicalDeviceHdl,
|
||||||
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
const unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
|
@ -137,6 +141,7 @@ namespace SHADE
|
||||||
, boundToCoherent{false}
|
, boundToCoherent{false}
|
||||||
, randomAccessOptimized {false}
|
, randomAccessOptimized {false}
|
||||||
, mappedPtr{nullptr}
|
, mappedPtr{nullptr}
|
||||||
|
, device { logicalDeviceHdl }
|
||||||
{
|
{
|
||||||
usageFlags = imageDetails.usageFlags;
|
usageFlags = imageDetails.usageFlags;
|
||||||
createFlags = imageDetails.createFlags;
|
createFlags = imageDetails.createFlags;
|
||||||
|
@ -175,7 +180,9 @@ namespace SHADE
|
||||||
VmaAllocationInfo allocInfo{};
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
|
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
|
||||||
|
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
@ -220,7 +227,7 @@ namespace SHADE
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
SHVkImage::SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
||||||
: width {w}
|
: width {w}
|
||||||
, height{h}
|
, height{h}
|
||||||
, depth {1}
|
, depth {1}
|
||||||
|
@ -230,11 +237,12 @@ namespace SHADE
|
||||||
, usageFlags{usage}
|
, usageFlags{usage}
|
||||||
, createFlags {create}
|
, createFlags {create}
|
||||||
, vmaAllocator {allocator}
|
, vmaAllocator {allocator}
|
||||||
|
, device { logicalDeviceHdl }
|
||||||
{
|
{
|
||||||
CreateFramebufferImage();
|
CreateFramebufferImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue