Merge branch 'main' into SP3-1-Rendering
This commit is contained in:
commit
09f1b152e8
|
@ -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: 0.00427246094, y: 0.000122070312, z: 0.00427246094}
|
||||||
|
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: 0.000244140625, y: 0.000244140625, z: 0.000244140625}
|
||||||
|
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: 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: 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.000244140625, y: 0.000244140625, z: 0.000244140625}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
- Is Trigger: true
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 0.00048828125, y: 0.00048828125, z: 0.00048828125}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
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: 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: 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.000244140625, y: 0.000244140625, z: 0.000244140625}
|
||||||
|
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: 3, y: -1, z: -1}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 5, y: 5, z: 5}
|
||||||
|
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: ~
|
|
@ -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
|
|
@ -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.
|
@ -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"
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
|
|
||||||
#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"
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
@ -60,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>();
|
||||||
|
@ -80,7 +83,11 @@ namespace Sandbox
|
||||||
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
|
||||||
|
@ -128,7 +135,7 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSystemManager::Init();
|
SHSystemManager::Init();
|
||||||
|
|
||||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
SHSceneManager::InitSceneManager<SBMainScene>(appConfig.startingSceneID);
|
||||||
|
|
||||||
SHFrameRateController::UpdateFRC();
|
SHFrameRateController::UpdateFRC();
|
||||||
|
|
||||||
|
@ -154,7 +161,7 @@ namespace Sandbox
|
||||||
editor->PollPicking();
|
editor->PollPicking();
|
||||||
|
|
||||||
static bool drawColliders = false;
|
static bool drawColliders = false;
|
||||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::SPACE))
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
||||||
{
|
{
|
||||||
drawColliders = !drawColliders;
|
drawColliders = !drawColliders;
|
||||||
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
|
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -53,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:
|
||||||
|
@ -65,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);
|
||||||
|
@ -125,7 +87,7 @@ 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);
|
||||||
|
@ -138,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.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
|
racoonCollider.GetCollider(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.GetCollider(1).SetIsTrigger(true);
|
||||||
|
|
||||||
|
itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
|
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
|
itemCollider.GetCollider(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.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
|
AICollider.GetCollider(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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
};
|
||||||
|
|
||||||
|
struct SH_API SHMeshData : SHAssetData
|
||||||
|
{
|
||||||
SHMeshAssetHeader header;
|
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;
|
||||||
};
|
};
|
|
@ -22,5 +22,10 @@ namespace SHADE
|
||||||
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());
|
||||||
|
|
||||||
|
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
||||||
|
modelPath += MODEL_EXTENSION;
|
||||||
|
newPath = modelPath;
|
||||||
|
|
||||||
|
GenerateNewMeta(newPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
assetCollection.insert({ newAsset.id, newAsset });
|
|
||||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -96,6 +96,10 @@ 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;
|
||||||
|
@ -93,6 +97,43 @@ namespace SHADE
|
||||||
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();
|
||||||
|
|
||||||
meta.path = path.parent_path().string() + "/" + path.stem().string();
|
meta.path = path.parent_path().string() + "/" + path.stem().string();
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,12 +59,31 @@ namespace SHADE
|
||||||
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::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())
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -244,9 +244,12 @@ namespace SHADE
|
||||||
SHCollider* collider = &component->GetCollider(i);
|
SHCollider* collider = &component->GetCollider(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
//collider->IsTrigger
|
||||||
|
|
||||||
if (collider->GetType() == SHCollider::Type::BOX)
|
if (collider->GetType() == SHCollider::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
|
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
||||||
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
|
@ -257,6 +260,7 @@ namespace SHADE
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
|
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
||||||
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
|
@ -372,6 +376,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]()
|
||||||
{
|
{
|
||||||
|
@ -383,6 +388,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,11 @@
|
||||||
#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"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -75,13 +80,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();
|
||||||
}
|
}
|
||||||
|
@ -155,6 +164,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +212,8 @@ namespace SHADE
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||||
|
{
|
||||||
|
if(editor->SaveScene())
|
||||||
{
|
{
|
||||||
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
|
||||||
{
|
{
|
||||||
|
@ -183,6 +223,7 @@ namespace SHADE
|
||||||
|
|
||||||
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);
|
||||||
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
if(ImGui::SmallButton(ICON_MD_PAUSE))
|
||||||
|
@ -206,6 +247,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;
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
#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,11 @@
|
||||||
#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"
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
|
@ -93,6 +97,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();
|
||||||
|
@ -146,6 +152,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
@ -170,6 +178,60 @@ 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))
|
||||||
|
@ -468,6 +530,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;
|
||||||
|
|
|
@ -16,15 +16,18 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#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/SHEventDefines.h"
|
||||||
#include "Events/SHEvent.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
|
||||||
{
|
{
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -171,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;
|
||||||
|
|
||||||
|
@ -191,6 +201,10 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
|
void RenderSceneNamePrompt() noexcept;
|
||||||
|
|
||||||
|
void RenderUnsavedChangesPrompt() noexcept;
|
||||||
|
|
||||||
void InitLayout() noexcept;
|
void InitLayout() noexcept;
|
||||||
|
|
||||||
void InitFonts() noexcept;
|
void InitFonts() noexcept;
|
||||||
|
@ -199,12 +213,22 @@ namespace SHADE
|
||||||
|
|
||||||
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
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};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
||||||
|
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -68,6 +68,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
|
|
||||||
batch->Remove(renderable);
|
batch->Remove(renderable);
|
||||||
|
|
||||||
|
// If batch is empty, remove batch
|
||||||
|
if (batch->IsEmpty())
|
||||||
|
batches.erase(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Clear() noexcept
|
void SHSuperBatch::Clear() noexcept
|
||||||
|
|
|
@ -14,7 +14,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// STL Includes
|
// STL Includes
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "../Meshes/SHMeshData.h"
|
#include "Assets/Asset Types/SHModelAsset.h"
|
||||||
#include "../Meshes/SHPrimitiveGenerator.h"
|
#include "../Meshes/SHPrimitiveGenerator.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "SHGraphicsSystem.h"
|
#include "SHGraphicsSystem.h"
|
||||||
|
|
|
@ -41,6 +41,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
#include "../Meshes/SHPrimitiveGenerator.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -52,7 +53,11 @@ namespace SHADE
|
||||||
/* BACKEND BOILERPLATE */
|
/* BACKEND BOILERPLATE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Set Up Instance
|
// Set Up Instance
|
||||||
|
#ifdef _DEBUG
|
||||||
SHVkInstance::Init(true, true, true);
|
SHVkInstance::Init(true, true, true);
|
||||||
|
#else
|
||||||
|
SHVkInstance::Init(true, false, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get Physical Device and Construct Logical Device
|
// Get Physical Device and Construct Logical Device
|
||||||
physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
|
physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
|
||||||
|
@ -255,7 +260,6 @@ namespace SHADE
|
||||||
// Generate world render graph
|
// Generate world render graph
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* BIND RENDER GRAPH TO RENDERER */
|
/* BIND RENDER GRAPH TO RENDERER */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -265,9 +269,6 @@ namespace SHADE
|
||||||
|
|
||||||
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||||
|
|
||||||
// Create default materials
|
|
||||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
|
||||||
|
|
||||||
// Create debug draw pipeline
|
// Create debug draw pipeline
|
||||||
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||||
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
||||||
|
@ -309,7 +310,29 @@ namespace SHADE
|
||||||
|
|
||||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||||
lightingSubSystem->Init(device, descPool);
|
lightingSubSystem->Init(device, descPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::InitBuiltInResources(void)
|
||||||
|
{
|
||||||
|
// Create default texture
|
||||||
|
std::array<SHTexture::PixelChannel, 4> defaultTextureData = { 255, 255, 255, 255 };
|
||||||
|
std::vector<uint32_t> mipOffsets{};
|
||||||
|
mipOffsets.push_back(0);
|
||||||
|
defaultTexture = AddTexture(4, defaultTextureData.data(), 1, 1, SHTexture::TextureFormat::eR8G8B8A8Unorm, mipOffsets);
|
||||||
|
BuildTextures();
|
||||||
|
|
||||||
|
// Create default meshes
|
||||||
|
primitiveMeshes[static_cast<int>(PrimitiveType::Cube)] = SHPrimitiveGenerator::Cube(meshLibrary);
|
||||||
|
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
|
||||||
|
BuildMeshBuffers();
|
||||||
|
|
||||||
|
// Create default materials
|
||||||
|
defaultMaterial = AddMaterial
|
||||||
|
(
|
||||||
|
defaultVertShader, defaultFragShader,
|
||||||
|
worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
||||||
|
);
|
||||||
|
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
@ -352,8 +375,7 @@ namespace SHADE
|
||||||
InitBoilerplate();
|
InitBoilerplate();
|
||||||
InitMiddleEnd();
|
InitMiddleEnd();
|
||||||
InitSubsystems();
|
InitSubsystems();
|
||||||
|
InitBuiltInResources();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
|
@ -711,6 +733,18 @@ namespace SHADE
|
||||||
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
transferCmdBuffer.Free(); transferCmdBuffer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHMesh> SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PrimitiveType::Cube:
|
||||||
|
case PrimitiveType::Sphere:
|
||||||
|
return primitiveMeshes[static_cast<int>(type)];
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Texture Registration Functions */
|
/* Texture Registration Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -743,6 +777,11 @@ namespace SHADE
|
||||||
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
|
||||||
|
{
|
||||||
|
return texLibrary.GetTextureHandle(textureId);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion ADD_REMOVE
|
#pragma endregion ADD_REMOVE
|
||||||
|
|
||||||
#pragma region ROUTINES
|
#pragma region ROUTINES
|
||||||
|
@ -755,6 +794,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
|
SHResourceManager::FinaliseChanges();
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,7 +820,6 @@ namespace SHADE
|
||||||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||||
SHResourceManager::FinaliseChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -798,11 +837,6 @@ namespace SHADE
|
||||||
if (!renderable.HasChanged())
|
if (!renderable.HasChanged())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!renderable.GetMesh())
|
|
||||||
{
|
|
||||||
SHLOG_CRITICAL("NULL Mesh provided!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
|
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
|
||||||
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
|
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
|
||||||
if (prevMaterial)
|
if (prevMaterial)
|
||||||
|
@ -812,8 +846,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to new SuperBatch if there is a material
|
// Add to new SuperBatch if there is a material
|
||||||
|
// Add to new SuperBatch if there is a material and a mesh to render
|
||||||
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
|
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
|
||||||
if (newMatInstance)
|
if (newMatInstance && renderable.GetMesh())
|
||||||
{
|
{
|
||||||
Handle<SHSuperBatch> newSuperBatch = newMatInstance->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
Handle<SHSuperBatch> newSuperBatch = newMatInstance->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||||
newSuperBatch->Add(&renderable);
|
newSuperBatch->Add(&renderable);
|
||||||
|
|
|
@ -58,6 +58,19 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Type of built-in primitive meshes that are available.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
enum class PrimitiveType
|
||||||
|
{
|
||||||
|
Cube,
|
||||||
|
Sphere
|
||||||
|
};
|
||||||
|
static constexpr int MAX_PRIMITIVE_TYPES = 2;
|
||||||
|
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
\brief
|
\brief
|
||||||
|
@ -72,6 +85,7 @@ namespace SHADE
|
||||||
void InitSceneRenderGraph (void) noexcept;
|
void InitSceneRenderGraph (void) noexcept;
|
||||||
void InitMiddleEnd (void) noexcept;
|
void InitMiddleEnd (void) noexcept;
|
||||||
void InitSubsystems (void) noexcept;
|
void InitSubsystems (void) noexcept;
|
||||||
|
void InitBuiltInResources (void);
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
void InitEditorRenderGraph (void) noexcept;
|
void InitEditorRenderGraph (void) noexcept;
|
||||||
|
@ -207,6 +221,21 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildMeshBuffers();
|
void BuildMeshBuffers();
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Retrieves the built-in mesh specified.
|
||||||
|
|
||||||
|
\param type
|
||||||
|
Type of built-in mesh to retrieve.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the mesh that was specfied. However, if an invalid type is specified,
|
||||||
|
a null Handle will be returned.
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
Handle<SHMesh> GetMeshPrimitive(PrimitiveType type) const noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Texture Registration Functions */
|
/* Texture Registration Functions */
|
||||||
|
@ -263,6 +292,33 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildTextures();
|
void BuildTextures();
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
\brief
|
||||||
|
Retrieves the texture handle at the specified texture index.
|
||||||
|
|
||||||
|
\param textureId
|
||||||
|
Index of the texture to look for.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the texture
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const;
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
\brief
|
||||||
|
Retrieves the handle to the default texture. A white 1x1 texture.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the default texture.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHTexture> GetDefaultTexture() const noexcept { return defaultTexture; }
|
||||||
|
|
||||||
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
void HandleResize(void) noexcept;
|
void HandleResize(void) noexcept;
|
||||||
|
@ -363,6 +419,13 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawPipeline;
|
Handle<SHVkPipeline> debugDrawPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
||||||
|
|
||||||
|
// Built-In Textures
|
||||||
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
||||||
|
// Built-In Meshes
|
||||||
|
std::array<Handle<SHMesh>, MAX_PRIMITIVE_TYPES> primitiveMeshes;
|
||||||
|
|
||||||
|
// Render Graphs
|
||||||
Handle<SHRenderGraph> worldRenderGraph;
|
Handle<SHRenderGraph> worldRenderGraph;
|
||||||
|
|
||||||
// Sub systems
|
// Sub systems
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialSpec.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 2, 2022
|
||||||
|
\brief Contains the function definitions of SHMaterialSpec.
|
||||||
|
|
||||||
|
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 "SHMaterialSpec.h"
|
||||||
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHMaterialSpec::SHMaterialSpec(const SHMaterial& material)
|
||||||
|
{
|
||||||
|
// Get Shader Handles
|
||||||
|
const auto& SHADERS = material.GetPipeline()->GetPipelineLayout()->GetShaderModules();
|
||||||
|
Handle<SHVkShaderModule> vShaderMod, fShaderMod;
|
||||||
|
for (const auto& shader : SHADERS)
|
||||||
|
{
|
||||||
|
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
|
||||||
|
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
|
||||||
|
vShaderMod = shader;
|
||||||
|
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
|
||||||
|
fShaderMod = shader;
|
||||||
|
}
|
||||||
|
vertexShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0);
|
||||||
|
fragShader = SHResourceManager::GetAssetID<SHVkShaderModule>(fShaderMod).value_or(0);
|
||||||
|
subpassName = material.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
||||||
|
|
||||||
|
// Write Properties
|
||||||
|
Handle<SHShaderBlockInterface> pipelineProperties = material.GetShaderBlockInterface();
|
||||||
|
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||||
|
{
|
||||||
|
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||||
|
if (!VARIABLE)
|
||||||
|
break;
|
||||||
|
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||||
|
YAML::Node propNode;
|
||||||
|
switch (VARIABLE->type)
|
||||||
|
{
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
||||||
|
propNode = material.GetProperty<float>(VARIABLE->offset);
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||||
|
propNode = material.GetProperty<int>(VARIABLE->offset);
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
|
propNode = material.GetProperty<SHVec2>(VARIABLE->offset);
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
||||||
|
propNode = material.GetProperty<SHVec3>(VARIABLE->offset);
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
||||||
|
propNode = material.GetProperty<SHVec4>(VARIABLE->offset);
|
||||||
|
break;
|
||||||
|
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
properties[VAR_NAME.data()] = propNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,9 +16,18 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include <utility>
|
#include <utility>
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Assets/SHAssetMacros.h"
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declaration */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHMaterial;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/*************************************************************************************/
|
/*************************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
\brief
|
\brief
|
||||||
|
@ -32,5 +41,11 @@ namespace SHADE
|
||||||
AssetID fragShader;
|
AssetID fragShader;
|
||||||
std::string subpassName;
|
std::string subpassName;
|
||||||
YAML::Node properties;
|
YAML::Node properties;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHMaterialSpec() = default;
|
||||||
|
explicit SHMaterialSpec(const SHMaterial& material);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/************************************************************************************//*!
|
|
||||||
\file SHPrimitiveGenerator.h
|
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
|
||||||
\par email: kahwei.tng\@digipen.edu
|
|
||||||
\date Sep 18, 2022
|
|
||||||
\brief Contains the static class definition of SHPrimitiveGenerator.
|
|
||||||
|
|
||||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
|
||||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
|
||||||
of DigiPen Institute of Technology is prohibited.
|
|
||||||
*//*************************************************************************************/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// STL Includes
|
|
||||||
#include <vector>
|
|
||||||
// Project Includes
|
|
||||||
#include "Math/SHMath.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
/*************************************************************************************/
|
|
||||||
/*!
|
|
||||||
\brief
|
|
||||||
Static class that contains functions for generating 3D primitives.
|
|
||||||
*/
|
|
||||||
/*************************************************************************************/
|
|
||||||
struct SHMeshData
|
|
||||||
{
|
|
||||||
std::vector<SHMesh::VertexPosition> VertexPositions;
|
|
||||||
std::vector<SHMesh::VertexTexCoord> VertexTexCoords;
|
|
||||||
std::vector<SHMesh::VertexTangent> VertexTangents;
|
|
||||||
std::vector<SHMesh::VertexNormal> VertexNormals;
|
|
||||||
std::vector<SHMesh::Index> Indices;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -13,7 +13,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
#include "SHMeshData.h"
|
#include "Assets/Asset Types/SHModelAsset.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
|
|
@ -156,14 +156,15 @@ namespace SHADE
|
||||||
/* Build Descriptor Set with all the Textures only if there are textures */
|
/* Build Descriptor Set with all the Textures only if there are textures */
|
||||||
if (!texOrder.empty())
|
if (!texOrder.empty())
|
||||||
{
|
{
|
||||||
if (!texDescriptors)
|
if (texDescriptors)
|
||||||
{
|
{
|
||||||
|
texDescriptors.Free();
|
||||||
|
}
|
||||||
texDescriptors = descPool->Allocate
|
texDescriptors = descPool->Allocate
|
||||||
(
|
(
|
||||||
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
|
||||||
{ static_cast<uint32_t>(texOrder.size()) }
|
{ static_cast<uint32_t>(texOrder.size()) }
|
||||||
);
|
);
|
||||||
}
|
|
||||||
texDescriptors->ModifyWriteDescImage
|
texDescriptors->ModifyWriteDescImage
|
||||||
(
|
(
|
||||||
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,
|
||||||
|
|
|
@ -129,6 +129,21 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
|
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
\brief
|
||||||
|
Retrieves the texture handle at the specified texture index.
|
||||||
|
|
||||||
|
\param textureId
|
||||||
|
Index of the texture to look for.
|
||||||
|
|
||||||
|
\returns
|
||||||
|
Handle to the texture
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const { return texOrder[textureId]; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace SHADE
|
||||||
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
|
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
|
||||||
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
|
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
|
||||||
, inputSamplers{ rhs.inputSamplers }
|
, inputSamplers{ rhs.inputSamplers }
|
||||||
|
, name { rhs.name }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,7 @@ namespace SHADE
|
||||||
inputImageDescriptors = std::move(rhs.inputImageDescriptors);
|
inputImageDescriptors = std::move(rhs.inputImageDescriptors);
|
||||||
inputDescriptorLayout = rhs.inputDescriptorLayout;
|
inputDescriptorLayout = rhs.inputDescriptorLayout;
|
||||||
inputSamplers = rhs.inputSamplers;
|
inputSamplers = rhs.inputSamplers;
|
||||||
|
name = std::move(rhs.name);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,16 +55,6 @@ namespace SHADE
|
||||||
return variables.size();
|
return variables.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept
|
|
||||||
: bytesRequired{ 0 }
|
|
||||||
{}
|
|
||||||
|
|
||||||
SHShaderBlockInterface::SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept
|
|
||||||
: variables { std::move(rhs.variables) }
|
|
||||||
, variableIndexing { std::move(rhs.variableIndexing) }
|
|
||||||
, bytesRequired { rhs.bytesRequired }
|
|
||||||
{}
|
|
||||||
|
|
||||||
void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept
|
void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept
|
||||||
{
|
{
|
||||||
bytesRequired = bytes;
|
bytesRequired = bytes;
|
||||||
|
@ -75,16 +65,4 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return bytesRequired;
|
return bytesRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADE::SHShaderBlockInterface& SHShaderBlockInterface::operator=(SHShaderBlockInterface&& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (&rhs == this)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
variables = std::move(rhs.variables);
|
|
||||||
variableIndexing = std::move(rhs.variableIndexing);
|
|
||||||
bytesRequired = rhs.bytesRequired;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ namespace SHADE
|
||||||
std::unordered_map<std::string, uint32_t> variableIndexing;
|
std::unordered_map<std::string, uint32_t> variableIndexing;
|
||||||
|
|
||||||
//! bytes required by the block (includes padding). This variable is required
|
//! bytes required by the block (includes padding). This variable is required
|
||||||
uint32_t bytesRequired;
|
uint32_t bytesRequired = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void AddVariable (std::string name, Variable&& newVariable) noexcept;
|
void AddVariable (std::string name, Variable&& newVariable) noexcept;
|
||||||
|
@ -43,13 +43,6 @@ namespace SHADE
|
||||||
const std::string& GetVariableName(uint32_t index) const noexcept;
|
const std::string& GetVariableName(uint32_t index) const noexcept;
|
||||||
size_t GetVariableCount() const noexcept;
|
size_t GetVariableCount() const noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* CTORS AND DTORS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
SHShaderBlockInterface(void) noexcept;
|
|
||||||
SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept;
|
|
||||||
SHShaderBlockInterface& operator=(SHShaderBlockInterface&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Input/SHInputManager.h"
|
#include "Input/SHInputManager.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHWindow::SHWindow()
|
SHWindow::SHWindow()
|
||||||
|
@ -151,11 +150,11 @@ namespace SHADE
|
||||||
SetWindowText(wndHWND, LPCWSTR(wndData.title.c_str()));
|
SetWindowText(wndHWND, LPCWSTR(wndData.title.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SHWindow::SHVec2 SHWindow::GetPosition() const
|
SHWindow::WindowSize SHWindow::GetPosition() const
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetWindowRect(wndHWND, &rect);
|
GetWindowRect(wndHWND, &rect);
|
||||||
return SHVec2(static_cast<uint32_t>(rect.left), static_cast<uint32_t>(rect.top));
|
return WindowSize(static_cast<uint32_t>(rect.left), static_cast<uint32_t>(rect.top));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHWindow::SetPosition(unsigned x, unsigned y)
|
void SHWindow::SetPosition(unsigned x, unsigned y)
|
||||||
|
@ -165,18 +164,18 @@ namespace SHADE
|
||||||
wndData.y = y;
|
wndData.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHWindow::SHVec2 SHWindow::GetWindowSize() const
|
SHWindow::WindowSize SHWindow::GetWindowSize() const
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect(wndHWND, &rect);
|
GetClientRect(wndHWND, &rect);
|
||||||
return SHVec2(static_cast<uint32_t>(rect.right - rect.left), static_cast<uint32_t>(rect.bottom - rect.top));
|
return WindowSize(static_cast<uint32_t>(rect.right - rect.left), static_cast<uint32_t>(rect.bottom - rect.top));
|
||||||
}
|
}
|
||||||
|
|
||||||
SHWindow::SHVec2 SHWindow::GetCurrentDisplaySize() const
|
SHWindow::WindowSize SHWindow::GetCurrentDisplaySize() const
|
||||||
{
|
{
|
||||||
unsigned screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
unsigned screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||||
unsigned screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
unsigned screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||||
return SHVec2(screenWidth, screenHeight);
|
return WindowSize(screenWidth, screenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHWindow::SetMouseVisible(bool show)
|
void SHWindow::SetMouseVisible(bool show)
|
||||||
|
@ -260,7 +259,7 @@ namespace SHADE
|
||||||
return wndHWND;
|
return wndHWND;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WindowData SHWindow::GetWindowData() const
|
const WindowData SHWindow::GetWindowData() const noexcept
|
||||||
{
|
{
|
||||||
return wndData;
|
return wndData;
|
||||||
}
|
}
|
||||||
|
@ -287,6 +286,15 @@ namespace SHADE
|
||||||
windowCloseCallbacks.erase(callbackid);
|
windowCloseCallbacks.erase(callbackid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHWindow::ToggleUnsavedChanges() noexcept
|
||||||
|
{
|
||||||
|
unsavedChanges = !unsavedChanges;
|
||||||
|
std::wstring title = wndData.title;
|
||||||
|
if(unsavedChanges)
|
||||||
|
title.append(L"*");
|
||||||
|
SetWindowText(wndHWND, title.data());
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
auto window = windowMap.GetWindow(hwnd);
|
auto window = windowMap.GetWindow(hwnd);
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace SHADE
|
||||||
class SH_API SHWindow
|
class SH_API SHWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
using WindowSize = std::pair<uint32_t, uint32_t>;
|
||||||
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
|
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
|
||||||
typedef std::function<void(void)> WindowCloseCallbackFn;
|
typedef std::function<void(void)> WindowCloseCallbackFn;
|
||||||
typedef uint16_t CALLBACKID;
|
typedef uint16_t CALLBACKID;
|
||||||
|
@ -92,15 +92,15 @@ namespace SHADE
|
||||||
|
|
||||||
void SetTitle(std::wstring title);
|
void SetTitle(std::wstring title);
|
||||||
|
|
||||||
SHVec2 GetPosition() const;
|
WindowSize GetPosition() const;
|
||||||
|
|
||||||
void SetPosition(unsigned x, unsigned y);
|
void SetPosition(unsigned x, unsigned y);
|
||||||
//void SetPosition(SHMathVec2U);
|
//void SetPosition(SHMathVec2U);
|
||||||
|
|
||||||
SHVec2 GetWindowSize() const;
|
WindowSize GetWindowSize() const;
|
||||||
|
|
||||||
//Get size of display the window is in (whichever window contains the window origin)
|
//Get size of display the window is in (whichever window contains the window origin)
|
||||||
SHVec2 GetCurrentDisplaySize() const;
|
WindowSize GetCurrentDisplaySize() const;
|
||||||
|
|
||||||
void SetMouseVisible(bool show);
|
void SetMouseVisible(bool show);
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ namespace SHADE
|
||||||
|
|
||||||
HWND GetHWND();
|
HWND GetHWND();
|
||||||
|
|
||||||
const WindowData GetWindowData() const;
|
const WindowData GetWindowData() const noexcept;
|
||||||
|
|
||||||
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
||||||
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
||||||
|
@ -131,6 +131,8 @@ namespace SHADE
|
||||||
void UnregisterWindowCloseCallback(CALLBACKID const& callbackid);
|
void UnregisterWindowCloseCallback(CALLBACKID const& callbackid);
|
||||||
bool IsMinimized() const { return wndData.isMinimised; }
|
bool IsMinimized() const { return wndData.isMinimised; }
|
||||||
|
|
||||||
|
void ToggleUnsavedChanges() noexcept;
|
||||||
|
bool IsUnsavedChanges() const noexcept{return unsavedChanges;}
|
||||||
protected:
|
protected:
|
||||||
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||||
|
|
||||||
|
@ -164,7 +166,8 @@ namespace SHADE
|
||||||
std::unordered_map<CALLBACKID, WindowCloseCallbackFn> windowCloseCallbacks;
|
std::unordered_map<CALLBACKID, WindowCloseCallbackFn> windowCloseCallbacks;
|
||||||
CALLBACKID windowResizeCallbackCount{};
|
CALLBACKID windowResizeCallbackCount{};
|
||||||
CALLBACKID windowCloseCallbackCount{};
|
CALLBACKID windowCloseCallbackCount{};
|
||||||
//TODO: Shift to events abstraction
|
|
||||||
|
bool unsavedChanges = false;
|
||||||
|
|
||||||
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
||||||
void OnClose();
|
void OnClose();
|
||||||
|
|
|
@ -25,16 +25,16 @@ namespace SHADE
|
||||||
std::map<std::string, SHInputManager::SHLogicalBindingData> SHInputManager::bindings;
|
std::map<std::string, SHInputManager::SHLogicalBindingData> SHInputManager::bindings;
|
||||||
|
|
||||||
unsigned SHInputManager::keyCount = 0;
|
unsigned SHInputManager::keyCount = 0;
|
||||||
bool SHInputManager::keys[MAX_KEYS];
|
bool SHInputManager::keys[MAX_KEYS] = {};
|
||||||
bool SHInputManager::keysLast[MAX_KEYS];
|
bool SHInputManager::keysLast[MAX_KEYS] = {};
|
||||||
double SHInputManager::keysHeldTime[MAX_KEYS];
|
double SHInputManager::keysHeldTime[MAX_KEYS] = {};
|
||||||
double SHInputManager::keysReleasedTime[MAX_KEYS];
|
double SHInputManager::keysReleasedTime[MAX_KEYS] = {};
|
||||||
|
|
||||||
unsigned SHInputManager::keyToggleCount = 0;
|
unsigned SHInputManager::keyToggleCount = 0;
|
||||||
bool SHInputManager::keysToggle[MAX_KEYS];
|
bool SHInputManager::keysToggle[MAX_KEYS] = {};
|
||||||
bool SHInputManager::keysToggleLast[MAX_KEYS];
|
bool SHInputManager::keysToggleLast[MAX_KEYS] = {};
|
||||||
double SHInputManager::keysToggleOnTime[MAX_KEYS];
|
double SHInputManager::keysToggleOnTime[MAX_KEYS] = {};
|
||||||
double SHInputManager::keysToggleOffTime[MAX_KEYS];
|
double SHInputManager::keysToggleOffTime[MAX_KEYS] = {};
|
||||||
|
|
||||||
int SHInputManager::mouseScreenX = 0;
|
int SHInputManager::mouseScreenX = 0;
|
||||||
int SHInputManager::mouseScreenY = 0;
|
int SHInputManager::mouseScreenY = 0;
|
||||||
|
@ -46,11 +46,11 @@ namespace SHADE
|
||||||
int SHInputManager::mouseWheelVerticalDeltaPoll = 0;
|
int SHInputManager::mouseWheelVerticalDeltaPoll = 0;
|
||||||
|
|
||||||
unsigned char SHInputManager::controllersConnectedCount = 0;
|
unsigned char SHInputManager::controllersConnectedCount = 0;
|
||||||
unsigned SHInputManager::controllersInputCount[XUSER_MAX_COUNT];
|
unsigned SHInputManager::controllersInputCount[XUSER_MAX_COUNT] = {};
|
||||||
unsigned SHInputManager::controllersButtonCount[XUSER_MAX_COUNT];
|
unsigned SHInputManager::controllersButtonCount[XUSER_MAX_COUNT] = {};
|
||||||
short SHInputManager::controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
short SHInputManager::controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT] = {};
|
||||||
short SHInputManager::controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
short SHInputManager::controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT] = {};
|
||||||
double SHInputManager::controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
double SHInputManager::controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT] = {};
|
||||||
double SHInputManager::controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
double SHInputManager::controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
//Internal helper function for splitting between inputs
|
//Internal helper function for splitting between inputs
|
||||||
|
@ -106,9 +106,11 @@ namespace SHADE
|
||||||
memcpy(keysLast, keys, sizeof(keys));
|
memcpy(keysLast, keys, sizeof(keys));
|
||||||
|
|
||||||
//Poll
|
//Poll
|
||||||
unsigned char keyboardState[MAX_KEYS];
|
unsigned char keyboardState[MAX_KEYS] = {};
|
||||||
|
SecureZeroMemory(keyboardState, sizeof(keyboardState));
|
||||||
//if (GetKeyboardState(keyboardState) == false) return;
|
//if (GetKeyboardState(keyboardState) == false) return;
|
||||||
SHASSERT(GetKeyboardState(keyboardState), "SHInputManager:GetKeyboardState() failed ({})", GetLastError());
|
bool keyboardStateGot = GetKeyboardState(keyboardState);
|
||||||
|
SHASSERT(keyboardStateGot, "SHInputManager:GetKeyboardState() failed ({})", GetLastError());
|
||||||
keyCount = 0;
|
keyCount = 0;
|
||||||
keyToggleCount = 0;
|
keyToggleCount = 0;
|
||||||
for (size_t i = 0; i < MAX_KEYS; ++i)
|
for (size_t i = 0; i < MAX_KEYS; ++i)
|
||||||
|
|
|
@ -13,17 +13,20 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
// STL Includes
|
// STL Includes
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace SHADE { class SHMaterial; }
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "SHResourceLibrary.h"
|
#include "SHResourceLibrary.h"
|
||||||
#include "Assets/SHAssetMacros.h"
|
#include "Assets/SHAssetMacros.h"
|
||||||
#include "Assets/Asset Types/SHMeshAsset.h"
|
#include "Assets/Asset Types/SHModelAsset.h"
|
||||||
#include "Assets/Asset Types/SHTextureAsset.h"
|
#include "Assets/Asset Types/SHTextureAsset.h"
|
||||||
#include "Assets/Asset Types/SHShaderAsset.h"
|
#include "Assets/Asset Types/SHShaderAsset.h"
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Assets/Asset Types/SHMaterialAsset.h"
|
#include "Assets/Asset Types/SHMaterialAsset.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -33,11 +36,11 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template<typename T = void>
|
template<typename T = void>
|
||||||
struct SHResourceLoader { using AssetType = void; };
|
struct SHResourceLoader { using AssetType = void; };
|
||||||
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshAsset; };
|
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; };
|
||||||
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
|
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
|
||||||
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
|
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
|
||||||
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialAsset; };
|
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
|
||||||
|
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static class responsible for loading and caching runtime resources from their
|
/// Static class responsible for loading and caching runtime resources from their
|
||||||
/// serialised Asset IDs.
|
/// serialised Asset IDs.
|
||||||
|
@ -61,6 +64,8 @@ namespace SHADE
|
||||||
/// <returns>Handle to a loaded runtime asset.</returns>
|
/// <returns>Handle to a loaded runtime asset.</returns>
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
static Handle<ResourceType> LoadOrGet(AssetID assetId);
|
static Handle<ResourceType> LoadOrGet(AssetID assetId);
|
||||||
|
template<>
|
||||||
|
static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
|
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
|
||||||
/// simply do nothing except emit a warning.
|
/// simply do nothing except emit a warning.
|
||||||
|
|
|
@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
|
#include "Serialization/SHYAMLConverters.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -34,7 +35,12 @@ namespace SHADE
|
||||||
Handle<ResourceType> SHResourceManager::LoadOrGet(AssetID assetId)
|
Handle<ResourceType> SHResourceManager::LoadOrGet(AssetID assetId)
|
||||||
{
|
{
|
||||||
// Check if it is an unsupported type
|
// Check if it is an unsupported type
|
||||||
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
if (!std::is_same_v<ResourceType, SHMesh> &&
|
||||||
|
!std::is_same_v<ResourceType, SHTexture> &&
|
||||||
|
!std::is_same_v<ResourceType, SHVkShaderModule> &&
|
||||||
|
!std::is_same_v<ResourceType, SHMaterialSpec> &&
|
||||||
|
!std::is_same_v<ResourceType, SHMaterial>
|
||||||
|
)
|
||||||
{
|
{
|
||||||
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
static_assert(true, "Unsupported Resource Type specified for SHResourceManager.");
|
||||||
}
|
}
|
||||||
|
@ -60,8 +66,35 @@ namespace SHADE
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
Handle<SHMaterial> SHResourceManager::LoadOrGet<SHMaterial>(AssetID assetId)
|
||||||
|
{
|
||||||
|
/* Attempt to get existing loaded asset */
|
||||||
|
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<SHMaterial>();
|
||||||
|
if (typedHandleMap.get().contains(assetId))
|
||||||
|
return Handle<SHMaterial>(typedHandleMap.get()[assetId]);
|
||||||
|
|
||||||
|
/* Otherwise, we need to load it! */
|
||||||
|
// Get system
|
||||||
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (gfxSystem == nullptr)
|
||||||
|
throw std::runtime_error("[SHResourceManager] Attempted to load graphics resource without a SHGraphicsSystem installed.");
|
||||||
|
|
||||||
|
// Get SHMaterialSpec
|
||||||
|
Handle<SHMaterialSpec> matSpec = LoadOrGet<SHMaterialSpec>(assetId);
|
||||||
|
if (!matSpec)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// Create the material
|
||||||
|
auto handle = load<SHMaterial>(assetId, *matSpec);
|
||||||
|
Handle genericHandle = Handle(handle);
|
||||||
|
typedHandleMap.get().emplace(assetId, genericHandle);
|
||||||
|
typedAssetIdMap.get().emplace(genericHandle, assetId);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ResourceType>
|
template<typename ResourceType>
|
||||||
void SHResourceManager::Unload(Handle<ResourceType> assetId)
|
void SHResourceManager::Unload(Handle<ResourceType> asset)
|
||||||
{
|
{
|
||||||
// Check if it is an unsupported type
|
// Check if it is an unsupported type
|
||||||
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
if (!std::is_same_v<ResourceType, SHMesh> && !std::is_same_v<ResourceType, SHTexture>)
|
||||||
|
@ -71,14 +104,18 @@ namespace SHADE
|
||||||
|
|
||||||
/* Attempt to get existing loaded asset */
|
/* Attempt to get existing loaded asset */
|
||||||
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
|
||||||
if (typedHandleMap.get().contains(assetId))
|
if (typedHandleMap.get().contains(asset))
|
||||||
{
|
{
|
||||||
|
// Remove from ResourceHub if SHMaterialSpec
|
||||||
|
if (std::is_same_v<ResourceType, SHMaterialSpec>)
|
||||||
|
resourceHub.Free(asset);
|
||||||
|
|
||||||
// Dispose
|
// Dispose
|
||||||
Handle handle = typedHandleMap.get()[assetId];
|
Handle handle = typedHandleMap.get()[asset];
|
||||||
Handle<ResourceType> typedHandle = static_cast<Handle<ResourceType>>(handle);
|
auto typedHandle = static_cast<Handle<ResourceType>>(handle);
|
||||||
typedHandle.Free();
|
typedHandle.Free();
|
||||||
typedAssetIdMap.get().erase(handle);
|
typedAssetIdMap.get().erase(handle);
|
||||||
typedHandleMap.get().erase(assetId);
|
typedHandleMap.get().erase(asset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -143,13 +180,13 @@ namespace SHADE
|
||||||
|
|
||||||
return gfxSystem->AddMesh
|
return gfxSystem->AddMesh
|
||||||
(
|
(
|
||||||
assetData.vertexPosition.size(),
|
assetData.VertexPositions.size(),
|
||||||
assetData.vertexPosition.data(),
|
assetData.VertexPositions.data(),
|
||||||
assetData.texCoords.data(),
|
assetData.VertexTexCoords.data(),
|
||||||
assetData.vertexTangent.data(),
|
assetData.VertexTangents.data(),
|
||||||
assetData.vertexNormal.data(),
|
assetData.VertexNormals.data(),
|
||||||
assetData.indices.size(),
|
assetData.Indices.size(),
|
||||||
assetData.indices.data()
|
assetData.Indices.data()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Textures
|
// Textures
|
||||||
|
@ -181,15 +218,27 @@ namespace SHADE
|
||||||
shader->Reflect();
|
shader->Reflect();
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
// Material Spec
|
||||||
|
else if constexpr (std::is_same_v<ResourceType, SHMaterialSpec>)
|
||||||
|
{
|
||||||
|
// Get the data we need to construct
|
||||||
|
auto matSpec = resourceHub.Create<SHMaterialSpec>();
|
||||||
|
YAML::convert<SHMaterialSpec>::decode(*YAML::Load(assetData.data).begin(), *matSpec);
|
||||||
|
// Failed to load
|
||||||
|
if (matSpec->subpassName == "")
|
||||||
|
{
|
||||||
|
// Use default material
|
||||||
|
*matSpec = SHMaterialSpec(*gfxSystem->GetDefaultMaterial());
|
||||||
|
}
|
||||||
|
|
||||||
|
return matSpec;
|
||||||
|
}
|
||||||
// Materials
|
// Materials
|
||||||
else if constexpr (std::is_same_v<ResourceType, SHMaterial>)
|
else if constexpr (std::is_same_v<ResourceType, SHMaterial>)
|
||||||
{
|
{
|
||||||
// Get the data we need to construct
|
|
||||||
SHMaterialSpec matSpec = YAML::Node(assetData.data).as<SHMaterialSpec>();
|
|
||||||
|
|
||||||
// Load shaders
|
// Load shaders
|
||||||
auto vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.vertexShader);
|
auto vertexShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(assetData.vertexShader);
|
||||||
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(matSpec.fragShader);
|
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(assetData.fragShader);
|
||||||
|
|
||||||
// Ensure that both shaders are present
|
// Ensure that both shaders are present
|
||||||
if (!(vertexShader && fragShader))
|
if (!(vertexShader && fragShader))
|
||||||
|
@ -205,7 +254,7 @@ namespace SHADE
|
||||||
SHLOG_ERROR("[SHResourceManager] Failed to load material as RenderPass could not be found.");
|
SHLOG_ERROR("[SHResourceManager] Failed to load material as RenderPass could not be found.");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto subPass = renderPass->GetSubpass(matSpec.subpassName);
|
auto subPass = renderPass->GetSubpass(assetData.subpassName);
|
||||||
if (!subPass)
|
if (!subPass)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("[SHResourceManager] Failed to load material as SubPass could not be found.");
|
SHLOG_ERROR("[SHResourceManager] Failed to load material as SubPass could not be found.");
|
||||||
|
@ -220,8 +269,8 @@ namespace SHADE
|
||||||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
||||||
{
|
{
|
||||||
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
|
||||||
const auto& PROP_NODE = matSpec.properties;
|
const YAML::Node& PROP_NODE = assetData.properties[PROP_NAME.data()];
|
||||||
if (PROP_NODE)
|
if (PROP_NODE.IsDefined())
|
||||||
{
|
{
|
||||||
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
||||||
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
||||||
|
@ -231,7 +280,21 @@ namespace SHADE
|
||||||
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
||||||
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
|
{
|
||||||
|
Handle<SHTexture> texture = LoadOrGet<SHTexture>(PROP_NODE.as<int>());
|
||||||
|
// HACK: Need to split this out to a separate pass before loading the materials and subsequently, the scenes
|
||||||
|
gfxSystem->BuildTextures();
|
||||||
|
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[] Attempted to load invalid texture! Setting to 0.");
|
||||||
|
matHandle->SetProperty(VARIABLE->offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
||||||
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
|
matHandle->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "SHSceneGraph.h"
|
#include "SHSceneGraph.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
#include "ECS_Base/General/SHFamily.h"
|
#include "ECS_Base/General/SHFamily.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -32,6 +33,7 @@ namespace SHADE
|
||||||
virtual ~SHScene() = default;
|
virtual ~SHScene() = default;
|
||||||
|
|
||||||
std::string sceneName;
|
std::string sceneName;
|
||||||
|
AssetID sceneAssetID;
|
||||||
|
|
||||||
SHSceneGraph& GetSceneGraph() noexcept { return sceneGraph; }
|
SHSceneGraph& GetSceneGraph() noexcept { return sceneGraph; }
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace SHADE
|
||||||
std::string SHSceneManager::newSceneName{};
|
std::string SHSceneManager::newSceneName{};
|
||||||
uint32_t SHSceneManager::currentSceneID = UINT32_MAX;
|
uint32_t SHSceneManager::currentSceneID = UINT32_MAX;
|
||||||
uint32_t SHSceneManager::nextSceneID = UINT32_MAX;
|
uint32_t SHSceneManager::nextSceneID = UINT32_MAX;
|
||||||
|
AssetID SHSceneManager::currentSceneAssetID{};
|
||||||
|
|
||||||
SHScene* SHSceneManager::currentScene = nullptr;
|
SHScene* SHSceneManager::currentScene = nullptr;
|
||||||
//SHScene* SHSceneManager::nextScene = nullptr;
|
//SHScene* SHSceneManager::nextScene = nullptr;
|
||||||
|
@ -107,16 +107,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneManager::RestartScene(std::string const& sceneName) noexcept
|
void SHSceneManager::RestartScene(AssetID const& assetID ) noexcept
|
||||||
{
|
{
|
||||||
if (currentScene->sceneName != sceneName)
|
if (currentScene->sceneAssetID != assetID)
|
||||||
{
|
{
|
||||||
cleanReload = true;
|
//cleanReload = true;
|
||||||
newSceneName = sceneName;
|
cleanReload = false;
|
||||||
|
//newSceneName = sceneName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cleanReload = false;
|
cleanReload = false;
|
||||||
|
|
||||||
|
currentScene->sceneAssetID = assetID;
|
||||||
nextSceneID = currentSceneID;
|
nextSceneID = currentSceneID;
|
||||||
sceneChanged = true;
|
sceneChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -151,4 +153,20 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return currentScene->sceneName;
|
return currentScene->sceneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSceneManager::SetCurrentSceneName(std::string const& sceneName) noexcept
|
||||||
|
{
|
||||||
|
currentScene->sceneName = sceneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHSceneManager::GetCurrentSceneAssetID() noexcept
|
||||||
|
{
|
||||||
|
return currentScene->sceneAssetID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSceneManager::SetCurrentSceneAssetID(AssetID const& newAssetID)
|
||||||
|
{
|
||||||
|
currentScene->sceneAssetID = newAssetID;
|
||||||
|
currentSceneAssetID = newAssetID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
//Project Headers
|
//Project Headers
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "ECS_Base/General/SHFamily.h"
|
#include "ECS_Base/General/SHFamily.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,9 @@ namespace SHADE
|
||||||
//pointer to the current scene
|
//pointer to the current scene
|
||||||
static SHScene* currentScene;
|
static SHScene* currentScene;
|
||||||
|
|
||||||
|
//Scene AssetID of the current scene
|
||||||
|
static AssetID currentSceneAssetID;
|
||||||
|
|
||||||
//Used in reloading scene.
|
//Used in reloading scene.
|
||||||
static std::string newSceneName;
|
static std::string newSceneName;
|
||||||
|
|
||||||
|
@ -80,10 +84,10 @@ namespace SHADE
|
||||||
* None.
|
* None.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> InitSceneManager(std::string const& sceneName) noexcept
|
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> InitSceneManager(AssetID const& sceneAssetID) noexcept
|
||||||
{
|
{
|
||||||
//prevSceneCreate = newScene;
|
//prevSceneCreate = newScene;
|
||||||
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName = sceneName; };
|
newScene = [sceneAssetID]() { currentScene = new T(); currentScene->sceneAssetID = sceneAssetID; };
|
||||||
//nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
//nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
||||||
nextSceneID = 0;
|
nextSceneID = 0;
|
||||||
|
|
||||||
|
@ -99,7 +103,7 @@ namespace SHADE
|
||||||
* None.
|
* None.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> ChangeScene(std::string const& sceneName) noexcept
|
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> ChangeScene(AssetID const& sceneAssetID) noexcept
|
||||||
{
|
{
|
||||||
//check if this new Scene is current Scene (Use RestartScene instead)
|
//check if this new Scene is current Scene (Use RestartScene instead)
|
||||||
if (currentSceneID == SHFamilyID<SHScene>::GetID<T>())
|
if (currentSceneID == SHFamilyID<SHScene>::GetID<T>())
|
||||||
|
@ -107,7 +111,7 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//prevSceneCreate = newScene;
|
//prevSceneCreate = newScene;
|
||||||
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName; };
|
newScene = [sceneAssetID]() { currentScene = new T(); currentScene->sceneAssetID = sceneAssetID; };
|
||||||
nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
||||||
sceneChanged = true;
|
sceneChanged = true;
|
||||||
}
|
}
|
||||||
|
@ -137,11 +141,11 @@ namespace SHADE
|
||||||
* Restarts current scene. Only Scene::Init() and Scene::Free()
|
* Restarts current scene. Only Scene::Init() and Scene::Free()
|
||||||
* Scene::Load() and Scene::Unload() will not be called.
|
* Scene::Load() and Scene::Unload() will not be called.
|
||||||
* Edit: allows for RestartScene to restart the scene with a different
|
* Edit: allows for RestartScene to restart the scene with a different
|
||||||
* scene name.
|
* scene asset ID.
|
||||||
* If a sceneName is different from the current one, Load and Unload will
|
* If a scene asset id is different from the current one, Load and Unload will
|
||||||
* run.
|
* run.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void RestartScene(std::string const& sceneName ) noexcept;
|
static void RestartScene(AssetID const& assetID ) noexcept;
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -164,7 +168,10 @@ namespace SHADE
|
||||||
static void Exit() noexcept;
|
static void Exit() noexcept;
|
||||||
|
|
||||||
static std::string GetSceneName() noexcept;
|
static std::string GetSceneName() noexcept;
|
||||||
|
static void SetCurrentSceneName(std::string const& sceneName) noexcept;
|
||||||
|
static AssetID GetCurrentSceneAssetID() noexcept;
|
||||||
|
//Only if scene doesn't exist, and scene asset id needs to be updated to the new one
|
||||||
|
static void SetCurrentSceneAssetID(AssetID const& newAssetID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHConfigurationManager.h"
|
||||||
|
#include "Tools/FileIO/SHFileIO.h"
|
||||||
|
#include "Serialization/SHSerializationHelper.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHApplicationConfig SHConfigurationManager::applicationConfig;
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
SHEditorConfig SHConfigurationManager::editorConfig;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SHConfigurationManager::SaveApplicationConfig()
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
out << SHSerializationHelper::RTTRToNode(applicationConfig);
|
||||||
|
SHFileIO::WriteStringToFile(applicationConfigPath, out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
SHApplicationConfig& SHConfigurationManager::LoadApplicationConfig(WindowData* wndData)
|
||||||
|
{
|
||||||
|
if(!std::filesystem::exists(applicationConfigPath))
|
||||||
|
{
|
||||||
|
SaveApplicationConfig();
|
||||||
|
return applicationConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const node = YAML::Load(SHFileIO::GetStringFromFile(applicationConfigPath));
|
||||||
|
auto properties = rttr::type::get<SHApplicationConfig>().get_properties();
|
||||||
|
for(auto const& property : properties)
|
||||||
|
{
|
||||||
|
if(node[property.get_name().data()].IsDefined())
|
||||||
|
SHSerializationHelper::InitializeProperty(&applicationConfig, property, node[property.get_name().data()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wndData != nullptr)
|
||||||
|
{
|
||||||
|
wndData->isFullscreen = applicationConfig.startInFullScreen;
|
||||||
|
wndData->title = std::wstring(applicationConfig.windowTitle.begin(), applicationConfig.windowTitle.end());
|
||||||
|
wndData->width = static_cast<uint32_t>(applicationConfig.windowSize.x);
|
||||||
|
wndData->height = static_cast<uint32_t>(applicationConfig.windowSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return applicationConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
void SHConfigurationManager::SaveEditorConfig()
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
out << SHSerializationHelper::RTTRToNode(editorConfig);
|
||||||
|
SHFileIO::WriteStringToFile(editorConfigPath, out.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEditorConfig& SHConfigurationManager::LoadEditorConfig()
|
||||||
|
{
|
||||||
|
auto const node = YAML::Load(SHFileIO::GetStringFromFile(editorConfigPath));
|
||||||
|
auto properties = rttr::type::get<SHApplicationConfig>().get_properties();
|
||||||
|
for(auto const& property : properties)
|
||||||
|
{
|
||||||
|
if(node[property.get_name().data()].IsDefined())
|
||||||
|
SHSerializationHelper::InitializeProperty(&editorConfig, property, node[property.get_name().data()]);
|
||||||
|
}
|
||||||
|
return editorConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHConfigurationManager::FetchEditorCameraData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHConfigurationManager::SetEditorCameraData()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace rttr;
|
||||||
|
using namespace SHADE;
|
||||||
|
|
||||||
|
registration::class_<SHApplicationConfig>("Application Config")
|
||||||
|
.property("Start in Fullscreen", &SHApplicationConfig::startInFullScreen)
|
||||||
|
.property("Starting Scene ID", &SHApplicationConfig::startingSceneID)
|
||||||
|
.property("Window Size", &SHApplicationConfig::windowSize)
|
||||||
|
.property("Window Title", &SHApplicationConfig::windowTitle);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#include <rttr/registration>
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SHApplicationConfig
|
||||||
|
{
|
||||||
|
bool startInFullScreen{ false };
|
||||||
|
AssetID startingSceneID{};
|
||||||
|
SHVec2 windowSize {1920, 1080};
|
||||||
|
std::string windowTitle {"SHADE Engine"};
|
||||||
|
RTTR_ENABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHEditorConfig
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SH_API SHConfigurationManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr std::string_view applicationConfigPath{"../../Assets/Application.SHConfig"};
|
||||||
|
static constexpr std::string_view editorConfigPath{"../../Assets/Editor/Editor.SHConfig"};
|
||||||
|
|
||||||
|
static void SaveApplicationConfig();
|
||||||
|
static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr);
|
||||||
|
static SHApplicationConfig applicationConfig;
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
static void SaveEditorConfig();
|
||||||
|
static SHEditorConfig& LoadEditorConfig();
|
||||||
|
static SHEditorConfig editorConfig;
|
||||||
|
private:
|
||||||
|
static void FetchEditorCameraData();
|
||||||
|
static void SetEditorCameraData();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
#include "SHSerializationHelper.hpp"
|
|
||||||
#include "SHSerialization.h"
|
#include "SHSerialization.h"
|
||||||
|
#include "SHSerializationHelper.hpp"
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Camera/SHCameraComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
@ -17,19 +18,23 @@
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "Tools/FileIO/SHFileIO.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
|
bool SHSerialization::SerializeSceneToFile(AssetID const& sceneAssetID)
|
||||||
{
|
{
|
||||||
|
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
|
||||||
|
if(!assetData)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Asset does not exist: {}", sceneAssetID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
YAML::Emitter out;
|
YAML::Emitter out;
|
||||||
SerializeSceneToEmitter(out);
|
SerializeSceneToEmitter(out);
|
||||||
std::ofstream file(path.c_str());
|
assetData->data = out.c_str();
|
||||||
if (file.good())
|
|
||||||
{
|
return SHAssetManager::SaveAsset(sceneAssetID);
|
||||||
file << out.c_str();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SHSerialization::SerializeSceneToString()
|
std::string SHSerialization::SerializeSceneToString()
|
||||||
|
@ -91,31 +96,16 @@ namespace SHADE
|
||||||
return eid;
|
return eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
std::string SHSerialization::DeserializeSceneFromFile(AssetID const& sceneAssetID) noexcept
|
||||||
{
|
{
|
||||||
//TODO:Shift to using XQ's FileIO
|
auto assetData = SHAssetManager::GetData<SHSceneAsset>(sceneAssetID);
|
||||||
std::ifstream iFile;
|
if(!assetData)
|
||||||
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
||||||
std::string fileContent = "";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
// Open file
|
SHLOG_ERROR("Attempted to load scene that doesn't exist {}", sceneAssetID)
|
||||||
// Read file's buffer contents into streams
|
SHSceneManager::SetCurrentSceneAssetID(0);
|
||||||
iFile.open(path);
|
return NewSceneName.data();
|
||||||
std::stringstream fileStream;
|
|
||||||
fileStream << iFile.rdbuf();
|
|
||||||
|
|
||||||
fileContent = fileStream.str();
|
|
||||||
|
|
||||||
// Close file handler
|
|
||||||
iFile.close();
|
|
||||||
}
|
}
|
||||||
catch (std::ifstream::failure e)
|
YAML::Node entities = YAML::Load(assetData->data);
|
||||||
{
|
|
||||||
SHLOG_ERROR("Could not read file");
|
|
||||||
}
|
|
||||||
YAML::Node entities = YAML::Load(fileContent);
|
|
||||||
std::vector<EntityID> createdEntities{};
|
std::vector<EntityID> createdEntities{};
|
||||||
|
|
||||||
//Create Entities
|
//Create Entities
|
||||||
|
@ -126,14 +116,23 @@ namespace SHADE
|
||||||
if (createdEntities.empty())
|
if (createdEntities.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||||
return;
|
return NewSceneName.data();
|
||||||
}
|
}
|
||||||
//Initialize Entity
|
|
||||||
auto entityVecIt = createdEntities.begin();
|
auto entityVecIt = createdEntities.begin();
|
||||||
|
AssetQueue assetQueue;
|
||||||
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
SHSerializationHelper::FetchAssetsFromComponent<SHRenderable>((*it)[ComponentsNode], *entityVecIt, assetQueue);
|
||||||
|
}
|
||||||
|
LoadAssetsFromAssetQueue(assetQueue);
|
||||||
|
//Initialize Entity
|
||||||
|
entityVecIt = createdEntities.begin();
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
{
|
{
|
||||||
InitializeEntity(*it, *entityVecIt++);
|
InitializeEntity(*it, *entityVecIt++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return assetData->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
||||||
|
@ -264,6 +263,33 @@ namespace SHADE
|
||||||
return componentIDList;
|
return componentIDList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSerialization::LoadAssetsFromAssetQueue(AssetQueue& assetQueue)
|
||||||
|
{
|
||||||
|
for (auto& [assetId, assetType] : assetQueue)
|
||||||
|
{
|
||||||
|
switch(assetType)
|
||||||
|
{
|
||||||
|
case AssetType::INVALID: break;
|
||||||
|
case AssetType::SHADER: break;
|
||||||
|
case AssetType::SHADER_BUILT_IN: break;
|
||||||
|
case AssetType::TEXTURE:
|
||||||
|
SHResourceManager::LoadOrGet<SHTexture>(assetId);
|
||||||
|
break;
|
||||||
|
case AssetType::MESH:
|
||||||
|
SHResourceManager::LoadOrGet<SHMesh>(assetId);
|
||||||
|
break;
|
||||||
|
case AssetType::SCENE: break;
|
||||||
|
case AssetType::PREFAB: break;
|
||||||
|
case AssetType::MATERIAL:
|
||||||
|
SHResourceManager::LoadOrGet<SHMaterial>(assetId);
|
||||||
|
break;
|
||||||
|
case AssetType::MAX_COUNT: break;
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SHResourceManager::FinaliseChanges();
|
||||||
|
}
|
||||||
|
|
||||||
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||||
{
|
{
|
||||||
auto const componentsNode = entityNode[ComponentsNode];
|
auto const componentsNode = entityNode[ComponentsNode];
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <ECS_Base/Components/SHComponent.h>
|
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include <Assets/SHAssetMacros.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
@ -25,12 +28,11 @@ namespace SHADE
|
||||||
|
|
||||||
struct SH_API SHSerialization
|
struct SH_API SHSerialization
|
||||||
{
|
{
|
||||||
//TODO: change paths to resource ID
|
static bool SerializeSceneToFile(AssetID const& sceneAssetID);
|
||||||
static void SerializeSceneToFile(std::filesystem::path const& path);
|
|
||||||
static std::string SerializeSceneToString();
|
static std::string SerializeSceneToString();
|
||||||
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||||
|
|
||||||
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
static std::string DeserializeSceneFromFile(AssetID const& sceneAssetID) noexcept;
|
||||||
|
|
||||||
|
|
||||||
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||||
|
@ -42,7 +44,11 @@ namespace SHADE
|
||||||
static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept;
|
static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept;
|
||||||
|
|
||||||
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||||
|
|
||||||
|
static void LoadAssetsFromAssetQueue(std::unordered_map<AssetID, AssetType>& assetQueue);
|
||||||
private:
|
private:
|
||||||
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||||
|
|
||||||
|
static constexpr std::string_view NewSceneName = "New Scene";
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,392 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHYAMLConverters.h"
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
|
||||||
#include <rttr/registration>
|
#include <rttr/registration>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
|
||||||
#include "Math/Vector/SHVec3.h"
|
|
||||||
#include "Math/Vector/SHVec4.h"
|
|
||||||
#include "Resource/SHResourceManager.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
|
||||||
#include "SHSerializationTools.h"
|
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
using namespace SHADE;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHVec4>
|
|
||||||
{
|
|
||||||
static constexpr const char* x = "x";
|
|
||||||
static constexpr const char* y = "y";
|
|
||||||
static constexpr const char* z = "z";
|
|
||||||
static constexpr const char* w = "w";
|
|
||||||
|
|
||||||
static Node encode(SHVec4 const& rhs)
|
|
||||||
{
|
|
||||||
Node node;
|
|
||||||
node.SetStyle(EmitterStyle::Flow);
|
|
||||||
node[x] = rhs.x;
|
|
||||||
node[y] = rhs.y;
|
|
||||||
node[z] = rhs.z;
|
|
||||||
node[w] = rhs.w;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(Node const& node, SHVec4& rhs)
|
|
||||||
{
|
|
||||||
if (node[x].IsDefined())
|
|
||||||
rhs.x = node[x].as<float>();
|
|
||||||
if (node[y].IsDefined())
|
|
||||||
rhs.y = node[y].as<float>();
|
|
||||||
if (node[z].IsDefined())
|
|
||||||
rhs.z = node[z].as<float>();
|
|
||||||
if (node[w].IsDefined())
|
|
||||||
rhs.w = node[w].as<float>();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHVec3>
|
|
||||||
{
|
|
||||||
static constexpr const char* x = "x";
|
|
||||||
static constexpr const char* y = "y";
|
|
||||||
static constexpr const char* z = "z";
|
|
||||||
|
|
||||||
static Node encode(SHVec3 const& rhs)
|
|
||||||
{
|
|
||||||
Node node;
|
|
||||||
node.SetStyle(EmitterStyle::Flow);
|
|
||||||
node[x] = rhs.x;
|
|
||||||
node[y] = rhs.y;
|
|
||||||
node[z] = rhs.z;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(Node const& node, SHVec3& rhs)
|
|
||||||
{
|
|
||||||
if (node[x].IsDefined())
|
|
||||||
rhs.x = node[x].as<float>();
|
|
||||||
if (node[y].IsDefined())
|
|
||||||
rhs.y = node[y].as<float>();
|
|
||||||
if (node[z].IsDefined())
|
|
||||||
rhs.z = node[z].as<float>();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHVec2>
|
|
||||||
{
|
|
||||||
static constexpr const char* x = "x";
|
|
||||||
static constexpr const char* y = "y";
|
|
||||||
|
|
||||||
static Node encode(SHVec2 const& rhs)
|
|
||||||
{
|
|
||||||
Node node;
|
|
||||||
node.SetStyle(EmitterStyle::Flow);
|
|
||||||
node[x] = rhs.x;
|
|
||||||
node[y] = rhs.y;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(Node const& node, SHVec2& rhs)
|
|
||||||
{
|
|
||||||
if (node[x].IsDefined())
|
|
||||||
rhs.x = node[x].as<float>();
|
|
||||||
if (node[y].IsDefined())
|
|
||||||
rhs.y = node[y].as<float>();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHCollider>
|
|
||||||
{
|
|
||||||
static constexpr const char* IsTrigger = "Is Trigger";
|
|
||||||
|
|
||||||
static constexpr const char* Type = "Type";
|
|
||||||
static constexpr const char* HalfExtents = "Half Extents";
|
|
||||||
static constexpr const char* Radius = "Radius";
|
|
||||||
|
|
||||||
static constexpr const char* Friction = "Friction";
|
|
||||||
static constexpr const char* Bounciness = "Bounciness";
|
|
||||||
static constexpr const char* Density = "Density";
|
|
||||||
static constexpr const char* PositionOffset = "Position Offset";
|
|
||||||
|
|
||||||
static Node encode(SHCollider& rhs)
|
|
||||||
{
|
|
||||||
Node node;
|
|
||||||
|
|
||||||
node[IsTrigger] = rhs.IsTrigger();
|
|
||||||
|
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
|
||||||
SHCollider::Type colliderType = rhs.GetType();
|
|
||||||
|
|
||||||
node[Type] = enumAlign.value_to_name(colliderType).data();
|
|
||||||
|
|
||||||
switch (colliderType)
|
|
||||||
{
|
|
||||||
case SHCollider::Type::BOX:
|
|
||||||
{
|
|
||||||
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
|
||||||
node[HalfExtents] = bb->GetHalfExtents();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHCollider::Type::SPHERE:
|
|
||||||
{
|
|
||||||
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
|
||||||
node[Radius] = bs->GetRadius();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHCollider::Type::CAPSULE: break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
|
|
||||||
node[Friction] = rhs.GetFriction();
|
|
||||||
node[Bounciness] = rhs.GetBounciness();
|
|
||||||
node[Density] = rhs.GetDensity();
|
|
||||||
node[PositionOffset] = rhs.GetPositionOffset();
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(Node const& node, SHCollider& rhs)
|
|
||||||
{
|
|
||||||
if (node[IsTrigger].IsDefined())
|
|
||||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
|
||||||
if (!node[Type].IsDefined())
|
|
||||||
return false;
|
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
|
||||||
bool ok;
|
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
|
||||||
if (!ok)
|
|
||||||
return false;
|
|
||||||
switch (colliderType)
|
|
||||||
{
|
|
||||||
case SHCollider::Type::BOX:
|
|
||||||
{
|
|
||||||
if(node[HalfExtents].IsDefined())
|
|
||||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHCollider::Type::SPHERE:
|
|
||||||
{
|
|
||||||
if(node[Radius].IsDefined())
|
|
||||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SHCollider::Type::CAPSULE: break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
if (node[Friction].IsDefined())
|
|
||||||
rhs.SetFriction(node[Friction].as<float>());
|
|
||||||
if (node[Bounciness].IsDefined())
|
|
||||||
rhs.SetBounciness(rhs.GetBounciness());
|
|
||||||
if (node[Density].IsDefined())
|
|
||||||
rhs.SetDensity(node[Density].as<float>());
|
|
||||||
if (node[PositionOffset].IsDefined())
|
|
||||||
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHColliderComponent>
|
|
||||||
{
|
|
||||||
static constexpr const char* Colliders = "Colliders";
|
|
||||||
static Node encode(SHColliderComponent& rhs)
|
|
||||||
{
|
|
||||||
Node node, collidersNode;
|
|
||||||
auto const& colliders = rhs.GetColliders();
|
|
||||||
int const numColliders = static_cast<int>(colliders.size());
|
|
||||||
for (int i = 0; i < numColliders; ++i)
|
|
||||||
{
|
|
||||||
auto& collider = rhs.GetCollider(i);
|
|
||||||
Node colliderNode = convert<SHCollider>::encode(collider);
|
|
||||||
if (colliderNode.IsDefined())
|
|
||||||
collidersNode[i] = colliderNode;
|
|
||||||
}
|
|
||||||
node[Colliders] = collidersNode;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(Node const& node, SHColliderComponent& rhs)
|
|
||||||
{
|
|
||||||
if (node[Colliders].IsDefined())
|
|
||||||
{
|
|
||||||
int numColliders{};
|
|
||||||
for (auto const& colliderNode : node[Colliders])
|
|
||||||
{
|
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
|
||||||
bool ok = false;
|
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
|
||||||
if (!ok)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (colliderType)
|
|
||||||
{
|
|
||||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
|
||||||
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
|
||||||
case SHCollider::Type::CAPSULE: break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHMaterial>
|
|
||||||
{
|
|
||||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
|
||||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
|
||||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
|
||||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
|
||||||
|
|
||||||
static YAML::Node encode(SHMaterial const& rhs)
|
|
||||||
{
|
|
||||||
// Write Properties
|
|
||||||
YAML::Node propertiesNode;
|
|
||||||
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
|
|
||||||
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
|
|
||||||
{
|
|
||||||
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
|
|
||||||
if (!VARIABLE)
|
|
||||||
break;
|
|
||||||
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
|
|
||||||
YAML::Node propNode;
|
|
||||||
switch (VARIABLE->type)
|
|
||||||
{
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
|
|
||||||
propNode = rhs.GetProperty<float>(VARIABLE->offset);
|
|
||||||
break;
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
|
|
||||||
propNode = rhs.GetProperty<int>(VARIABLE->offset);
|
|
||||||
break;
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
|
|
||||||
propNode = rhs.GetProperty<SHVec2>(VARIABLE->offset);
|
|
||||||
break;
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
|
|
||||||
propNode = rhs.GetProperty<SHVec3>(VARIABLE->offset);
|
|
||||||
break;
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
|
|
||||||
propNode = rhs.GetProperty<SHVec4>(VARIABLE->offset);
|
|
||||||
break;
|
|
||||||
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propertiesNode[VAR_NAME.data()] = propNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Shader Handles
|
|
||||||
const auto& SHADERS = rhs.GetPipeline()->GetPipelineLayout()->GetShaderModules();
|
|
||||||
Handle<SHVkShaderModule> vertexShader, fragShader;
|
|
||||||
for (const auto& shader : SHADERS)
|
|
||||||
{
|
|
||||||
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
|
|
||||||
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
|
|
||||||
vertexShader = shader;
|
|
||||||
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
|
|
||||||
fragShader = shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write Material
|
|
||||||
YAML::Node node;
|
|
||||||
|
|
||||||
node[VERT_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(vertexShader).value_or(0);
|
|
||||||
node[FRAG_SHADER_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHVkShaderModule>(fragShader).value_or(0);
|
|
||||||
node[SUBPASS_YAML_TAG.data()] = rhs.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
|
|
||||||
node[PROPS_YAML_TAG.data()] = propertiesNode;
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHMaterialSpec>
|
|
||||||
{
|
|
||||||
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
|
||||||
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
|
||||||
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
|
||||||
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
|
||||||
|
|
||||||
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
|
||||||
{
|
|
||||||
// Retrieve Shader Asset IDs
|
|
||||||
if (!node[VERT_SHADER_YAML_TAG.data()])
|
|
||||||
return false;
|
|
||||||
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
|
||||||
if (!node[FRAG_SHADER_YAML_TAG.data()])
|
|
||||||
return false;
|
|
||||||
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
|
||||||
|
|
||||||
// Retrieve Subpass
|
|
||||||
if (!node[SUBPASS_YAML_TAG.data()])
|
|
||||||
return false;
|
|
||||||
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
|
||||||
|
|
||||||
// Retrieve
|
|
||||||
if (!node[PROPS_YAML_TAG.data()])
|
|
||||||
return false;
|
|
||||||
rhs.properties = node[PROPS_YAML_TAG.data()];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct convert<SHRenderable>
|
|
||||||
{
|
|
||||||
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
|
||||||
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
|
||||||
|
|
||||||
static YAML::Node encode(SHRenderable const& rhs)
|
|
||||||
{
|
|
||||||
YAML::Node node;
|
|
||||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
|
||||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
|
||||||
{
|
|
||||||
if (node[MESH_YAML_TAG.data()].IsDefined())
|
|
||||||
{
|
|
||||||
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
|
||||||
}
|
|
||||||
if (node[MAT_YAML_TAG.data()].IsDefined())
|
|
||||||
{
|
|
||||||
// Temporarily, use default material
|
|
||||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
|
||||||
if (!gfxSystem)
|
|
||||||
return false;
|
|
||||||
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
|
||||||
if (!baseMat)
|
|
||||||
{
|
|
||||||
baseMat = gfxSystem->GetDefaultMaterial();
|
|
||||||
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
|
||||||
}
|
|
||||||
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
using AssetQueue = std::unordered_map<AssetID, AssetType>;
|
||||||
struct SHSerializationHelper
|
struct SHSerializationHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -460,6 +88,8 @@ namespace SHADE
|
||||||
node = YAML::Null;
|
node = YAML::Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (varType == rttr::type::get<std::string>())
|
||||||
|
node = var.to_string();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto properties = var.get_type().get_properties();
|
auto properties = var.get_type().get_properties();
|
||||||
|
@ -495,63 +125,65 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template <typename Type>
|
||||||
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
|
static void InitializeProperty(Type* object, rttr::property const& prop, YAML::Node const& propertyNode)
|
||||||
{
|
{
|
||||||
auto propType = prop.get_type();
|
auto propType = prop.get_type();
|
||||||
if (propType == rttr::type::get<SHVec4>())
|
if (propType == rttr::type::get<SHVec4>())
|
||||||
{
|
{
|
||||||
SHVec4 vec = propertyNode.as<SHVec4>();
|
SHVec4 vec = propertyNode.as<SHVec4>();
|
||||||
prop.set_value(component, vec);
|
prop.set_value(object, vec);
|
||||||
}
|
}
|
||||||
else if (propType == rttr::type::get<SHVec3>())
|
else if (propType == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
SHVec3 vec = propertyNode.as<SHVec3>();
|
SHVec3 vec = propertyNode.as<SHVec3>();
|
||||||
prop.set_value(component, vec);
|
prop.set_value(object, vec);
|
||||||
}
|
}
|
||||||
else if (propType == rttr::type::get<SHVec2>())
|
else if (propType == rttr::type::get<SHVec2>())
|
||||||
{
|
{
|
||||||
SHVec2 vec = propertyNode.as<SHVec2>();
|
SHVec2 vec = propertyNode.as<SHVec2>();
|
||||||
prop.set_value(component, vec);
|
prop.set_value(object, vec);
|
||||||
}
|
}
|
||||||
else if (propType.is_arithmetic())
|
else if (propType.is_arithmetic())
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
if (propType == rttr::type::get<bool>())
|
if (propType == rttr::type::get<bool>())
|
||||||
prop.set_value(component, propertyNode.as<bool>());
|
prop.set_value(object, propertyNode.as<bool>());
|
||||||
else if (propType == rttr::type::get<int8_t>())
|
else if (propType == rttr::type::get<int8_t>())
|
||||||
prop.set_value(component, propertyNode.as<int8_t>());
|
prop.set_value(object, propertyNode.as<int8_t>());
|
||||||
else if (propType == rttr::type::get<int16_t>())
|
else if (propType == rttr::type::get<int16_t>())
|
||||||
prop.set_value(component, propertyNode.as<int16_t>());
|
prop.set_value(object, propertyNode.as<int16_t>());
|
||||||
else if (propType == rttr::type::get<int32_t>())
|
else if (propType == rttr::type::get<int32_t>())
|
||||||
prop.set_value(component, propertyNode.as<int32_t>());
|
prop.set_value(object, propertyNode.as<int32_t>());
|
||||||
else if (propType == rttr::type::get<int64_t>())
|
else if (propType == rttr::type::get<int64_t>())
|
||||||
prop.set_value(component, propertyNode.as<int64_t>());
|
prop.set_value(object, propertyNode.as<int64_t>());
|
||||||
else if (propType == rttr::type::get<uint8_t>())
|
else if (propType == rttr::type::get<uint8_t>())
|
||||||
prop.set_value(component, propertyNode.as<uint8_t>());
|
prop.set_value(object, propertyNode.as<uint8_t>());
|
||||||
else if (propType == rttr::type::get<uint16_t>())
|
else if (propType == rttr::type::get<uint16_t>())
|
||||||
prop.set_value(component, propertyNode.as<uint16_t>());
|
prop.set_value(object, propertyNode.as<uint16_t>());
|
||||||
else if (propType == rttr::type::get<uint32_t>())
|
else if (propType == rttr::type::get<uint32_t>())
|
||||||
prop.set_value(component, propertyNode.as<uint32_t>());
|
prop.set_value(object, propertyNode.as<uint32_t>());
|
||||||
else if (propType == rttr::type::get<uint64_t>())
|
else if (propType == rttr::type::get<uint64_t>())
|
||||||
prop.set_value(component, propertyNode.as<uint64_t>());
|
prop.set_value(object, propertyNode.as<uint64_t>());
|
||||||
else if (propType == rttr::type::get<float>())
|
else if (propType == rttr::type::get<float>())
|
||||||
prop.set_value(component, propertyNode.as<float>());
|
prop.set_value(object, propertyNode.as<float>());
|
||||||
else if (propType == rttr::type::get<double>())
|
else if (propType == rttr::type::get<double>())
|
||||||
prop.set_value(component, propertyNode.as<double>());
|
prop.set_value(object, propertyNode.as<double>());
|
||||||
}
|
}
|
||||||
else if (propType.is_enumeration())
|
else if (propType.is_enumeration())
|
||||||
{
|
{
|
||||||
auto enumAlign = prop.get_enumeration();
|
auto enumAlign = prop.get_enumeration();
|
||||||
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
prop.set_value(object, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
||||||
}
|
}
|
||||||
|
else if (propType == rttr::type::get<std::string>())
|
||||||
|
prop.set_value(object, propertyNode.as<std::string>());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto properties = propType.get_properties();
|
auto properties = propType.get_properties();
|
||||||
for (auto const& property : properties)
|
for (auto const& property : properties)
|
||||||
{
|
{
|
||||||
if(propertyNode[property.get_name().data()].IsDefined())
|
if(propertyNode[property.get_name().data()].IsDefined())
|
||||||
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
InitializeProperty(object, property, propertyNode[property.get_name().data()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,18 +208,73 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static YAML::Node GetComponentNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
|
if (componentsNode.IsNull() && !component)
|
||||||
|
return {};
|
||||||
|
auto rttrType = rttr::type::get<ComponentType>();
|
||||||
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||||
|
if (!componentNode.IsDefined())
|
||||||
|
return {};
|
||||||
|
return componentNode;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
|
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
{
|
{
|
||||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
if (componentsNode.IsNull() && !component)
|
if (componentsNode.IsNull() && !component)
|
||||||
return;
|
return;
|
||||||
auto rttrType = rttr::type::get<ComponentType>();
|
|
||||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
YAML::convert<ComponentType>::decode(GetComponentNode<ComponentType>(componentsNode, eid), *component);
|
||||||
if (!componentNode.IsDefined())
|
|
||||||
return;
|
|
||||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static void FetchAssetsFromComponent(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
static void FetchAssetsFromComponent<SHRenderable>(YAML::Node const& componentsNode, EntityID const& eid, AssetQueue& assetQueue)
|
||||||
|
{
|
||||||
|
auto node = GetComponentNode<SHRenderable>(componentsNode, eid);
|
||||||
|
if(!node.IsDefined())
|
||||||
|
return;
|
||||||
|
if (auto const& meshNode = node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()]; meshNode.IsDefined())
|
||||||
|
{
|
||||||
|
assetQueue.insert({meshNode.as<AssetID>(), AssetType::MESH});
|
||||||
|
//SHResourceManager::LoadOrGet<SHMesh>(node[YAML::convert<SHRenderable>::MESH_YAML_TAG.data()].as<AssetID>());
|
||||||
|
}
|
||||||
|
if (auto const& matNode = node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()]; matNode.IsDefined())
|
||||||
|
{
|
||||||
|
auto const matAsset = SHAssetManager::GetData<SHMaterialAsset>(matNode.as<AssetID>());
|
||||||
|
if(matAsset)
|
||||||
|
{
|
||||||
|
SHMaterialSpec spec;
|
||||||
|
YAML::convert<SHMaterialSpec>::decode(*YAML::Load(matAsset->data).begin(), spec);
|
||||||
|
if(spec.properties.IsDefined())
|
||||||
|
{
|
||||||
|
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(spec.fragShader);
|
||||||
|
auto interface = fragShader->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);
|
||||||
|
if(variable->type != SHShaderBlockInterface::Variable::Type::INT)
|
||||||
|
continue;
|
||||||
|
const std::string& VAR_NAME = interface->GetVariableName(i);
|
||||||
|
if(VAR_NAME.empty())
|
||||||
|
continue;
|
||||||
|
assetQueue.insert({spec.properties[VAR_NAME.data()].as<AssetID>(), AssetType::TEXTURE});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//assetQueue.insert({matNode.as<AssetID>(), AssetType::MATERIAL});
|
||||||
|
//SHResourceManager::LoadOrGet<SHMaterial>(node[YAML::convert<SHRenderable>::MAT_YAML_TAG.data()].as<AssetID>());
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,317 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
|
#include "Physics/SHCollider.h"
|
||||||
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "SHSerializationTools.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec4>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
static constexpr const char* z = "z";
|
||||||
|
static constexpr const char* w = "w";
|
||||||
|
|
||||||
|
static Node encode(SHVec4 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
node[z] = rhs.z;
|
||||||
|
node[w] = rhs.w;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec4& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
if (node[z].IsDefined())
|
||||||
|
rhs.z = node[z].as<float>();
|
||||||
|
if (node[w].IsDefined())
|
||||||
|
rhs.w = node[w].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec3>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
static constexpr const char* z = "z";
|
||||||
|
|
||||||
|
static Node encode(SHVec3 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
node[z] = rhs.z;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec3& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
if (node[z].IsDefined())
|
||||||
|
rhs.z = node[z].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHVec2>
|
||||||
|
{
|
||||||
|
static constexpr const char* x = "x";
|
||||||
|
static constexpr const char* y = "y";
|
||||||
|
|
||||||
|
static Node encode(SHVec2 const& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
node[x] = rhs.x;
|
||||||
|
node[y] = rhs.y;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHVec2& rhs)
|
||||||
|
{
|
||||||
|
if (node[x].IsDefined())
|
||||||
|
rhs.x = node[x].as<float>();
|
||||||
|
if (node[y].IsDefined())
|
||||||
|
rhs.y = node[y].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHCollider>
|
||||||
|
{
|
||||||
|
static constexpr const char* IsTrigger = "Is Trigger";
|
||||||
|
|
||||||
|
static constexpr const char* Type = "Type";
|
||||||
|
static constexpr const char* HalfExtents = "Half Extents";
|
||||||
|
static constexpr const char* Radius = "Radius";
|
||||||
|
|
||||||
|
static constexpr const char* Friction = "Friction";
|
||||||
|
static constexpr const char* Bounciness = "Bounciness";
|
||||||
|
static constexpr const char* Density = "Density";
|
||||||
|
static constexpr const char* PositionOffset = "Position Offset";
|
||||||
|
|
||||||
|
static Node encode(SHCollider& rhs)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
|
||||||
|
node[IsTrigger] = rhs.IsTrigger();
|
||||||
|
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
SHCollider::Type colliderType = rhs.GetType();
|
||||||
|
|
||||||
|
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||||
|
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX:
|
||||||
|
{
|
||||||
|
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
||||||
|
node[HalfExtents] = bb->GetHalfExtents();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::SPHERE:
|
||||||
|
{
|
||||||
|
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
||||||
|
node[Radius] = bs->GetRadius();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
|
||||||
|
node[Friction] = rhs.GetFriction();
|
||||||
|
node[Bounciness] = rhs.GetBounciness();
|
||||||
|
node[Density] = rhs.GetDensity();
|
||||||
|
node[PositionOffset] = rhs.GetPositionOffset();
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHCollider& rhs)
|
||||||
|
{
|
||||||
|
if (node[IsTrigger].IsDefined())
|
||||||
|
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||||
|
if (!node[Type].IsDefined())
|
||||||
|
return false;
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
bool ok;
|
||||||
|
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX:
|
||||||
|
{
|
||||||
|
if (node[HalfExtents].IsDefined())
|
||||||
|
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::SPHERE:
|
||||||
|
{
|
||||||
|
if (node[Radius].IsDefined())
|
||||||
|
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
if (node[Friction].IsDefined())
|
||||||
|
rhs.SetFriction(node[Friction].as<float>());
|
||||||
|
if (node[Bounciness].IsDefined())
|
||||||
|
rhs.SetBounciness(rhs.GetBounciness());
|
||||||
|
if (node[Density].IsDefined())
|
||||||
|
rhs.SetDensity(node[Density].as<float>());
|
||||||
|
if (node[PositionOffset].IsDefined())
|
||||||
|
rhs.SetPositionOffset(node[PositionOffset].as<SHVec3>());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHColliderComponent>
|
||||||
|
{
|
||||||
|
static constexpr const char* Colliders = "Colliders";
|
||||||
|
static Node encode(SHColliderComponent& rhs)
|
||||||
|
{
|
||||||
|
Node node, collidersNode;
|
||||||
|
auto const& colliders = rhs.GetColliders();
|
||||||
|
int const numColliders = static_cast<int>(colliders.size());
|
||||||
|
for (int i = 0; i < numColliders; ++i)
|
||||||
|
{
|
||||||
|
auto& collider = rhs.GetCollider(i);
|
||||||
|
Node colliderNode = convert<SHCollider>::encode(collider);
|
||||||
|
if (colliderNode.IsDefined())
|
||||||
|
collidersNode[i] = colliderNode;
|
||||||
|
}
|
||||||
|
node[Colliders] = collidersNode;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(Node const& node, SHColliderComponent& rhs)
|
||||||
|
{
|
||||||
|
if (node[Colliders].IsDefined())
|
||||||
|
{
|
||||||
|
int numColliders{};
|
||||||
|
for (auto const& colliderNode : node[Colliders])
|
||||||
|
{
|
||||||
|
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
||||||
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
|
bool ok = false;
|
||||||
|
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
||||||
|
if (!ok)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (colliderType)
|
||||||
|
{
|
||||||
|
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
||||||
|
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||||
|
case SHCollider::Type::CAPSULE: break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHMaterialSpec>
|
||||||
|
{
|
||||||
|
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
|
||||||
|
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
|
||||||
|
static constexpr std::string_view SUBPASS_YAML_TAG = "SubPass";
|
||||||
|
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
|
||||||
|
|
||||||
|
static YAML::Node encode(SHMaterialSpec const& rhs)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
node[VERT_SHADER_YAML_TAG.data()] = rhs.vertexShader;
|
||||||
|
node[FRAG_SHADER_YAML_TAG.data()] = rhs.fragShader;
|
||||||
|
node[SUBPASS_YAML_TAG.data()] = rhs.subpassName;
|
||||||
|
node[PROPS_YAML_TAG.data()] = rhs.properties;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decode(YAML::Node const& node, SHMaterialSpec& rhs)
|
||||||
|
{
|
||||||
|
// Retrieve Shader Asset IDs
|
||||||
|
if (node[VERT_SHADER_YAML_TAG.data()].IsDefined())
|
||||||
|
rhs.vertexShader = node[VERT_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||||
|
if (node[FRAG_SHADER_YAML_TAG.data()].IsDefined())
|
||||||
|
rhs.fragShader = node[FRAG_SHADER_YAML_TAG.data()].as<AssetID>();
|
||||||
|
|
||||||
|
// Retrieve Subpass
|
||||||
|
if (node[SUBPASS_YAML_TAG.data()].IsDefined())
|
||||||
|
rhs.subpassName = node[SUBPASS_YAML_TAG.data()].as<std::string>();
|
||||||
|
|
||||||
|
// Retrieve
|
||||||
|
if (node[PROPS_YAML_TAG.data()].IsDefined())
|
||||||
|
rhs.properties = node[PROPS_YAML_TAG.data()];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<SHRenderable>
|
||||||
|
{
|
||||||
|
static constexpr std::string_view MESH_YAML_TAG = "Mesh";
|
||||||
|
static constexpr std::string_view MAT_YAML_TAG = "Material";
|
||||||
|
|
||||||
|
static YAML::Node encode(SHRenderable const& rhs)
|
||||||
|
{
|
||||||
|
YAML::Node node;
|
||||||
|
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||||
|
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||||
|
{
|
||||||
|
if (node[MESH_YAML_TAG.data()].IsDefined())
|
||||||
|
{
|
||||||
|
rhs.SetMesh(SHResourceManager::LoadOrGet<SHMesh>(node[MESH_YAML_TAG.data()].as<AssetID>()));
|
||||||
|
}
|
||||||
|
if (node[MAT_YAML_TAG.data()].IsDefined())
|
||||||
|
{
|
||||||
|
// Temporarily, use default material
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
if (!gfxSystem)
|
||||||
|
return false;
|
||||||
|
Handle<SHMaterial> baseMat = SHResourceManager::LoadOrGet<SHMaterial>(node[MAT_YAML_TAG.data()].as<AssetID>());
|
||||||
|
if (!baseMat)
|
||||||
|
{
|
||||||
|
baseMat = gfxSystem->GetDefaultMaterial();
|
||||||
|
SHLog::Warning("[SHSerializationHelper] Unable to load specified material. Falling back to default material.");
|
||||||
|
}
|
||||||
|
rhs.SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(baseMat));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHFileIO.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
int SHFileIO::WriteStringToFile(std::filesystem::path const& filePath, std::string_view const& strView)
|
||||||
|
{
|
||||||
|
std::ofstream file(filePath);
|
||||||
|
if(file.good())
|
||||||
|
{
|
||||||
|
file << strView;
|
||||||
|
file.close();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHFileIO::GetStringFromFile(std::filesystem::path const& filePath)
|
||||||
|
{
|
||||||
|
std::ifstream iFile;
|
||||||
|
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
std::string fileData{};
|
||||||
|
iFile.open(filePath, std::iostream::binary);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << iFile.rdbuf();
|
||||||
|
fileData = ss.str();
|
||||||
|
iFile.close();
|
||||||
|
return fileData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <SH_API.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SH_API SHFileIO
|
||||||
|
{
|
||||||
|
static int WriteStringToFile(std::filesystem::path const& filePath, std::string_view const& strView);
|
||||||
|
static std::string GetStringFromFile(std::filesystem::path const& file);
|
||||||
|
};
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ project "SHADE_Managed"
|
||||||
"%{IncludeDir.RTTR}/include",
|
"%{IncludeDir.RTTR}/include",
|
||||||
"%{IncludeDir.dotnet}\\include",
|
"%{IncludeDir.dotnet}\\include",
|
||||||
"%{IncludeDir.reactphysics3d}\\include",
|
"%{IncludeDir.reactphysics3d}\\include",
|
||||||
|
"%{IncludeDir.VULKAN}\\include",
|
||||||
"%{wks.location}/SHADE_Engine/src"
|
"%{wks.location}/SHADE_Engine/src"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,5 +123,14 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector3 Camera::GetRight()
|
||||||
|
{
|
||||||
|
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
SHVec3 forward, up, right;
|
||||||
|
system->GetCameraAxis(*GetNativeComponent(), forward, right, up);
|
||||||
|
return Convert::ToCLI(right);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -66,5 +66,7 @@ namespace SHADE
|
||||||
void SetMainCamera();
|
void SetMainCamera();
|
||||||
void LookAt(Vector3 targetPosition);
|
void LookAt(Vector3 targetPosition);
|
||||||
Vector3 GetForward();
|
Vector3 GetForward();
|
||||||
|
Vector3 GetRight();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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>();
|
||||||
|
@ -31,6 +34,8 @@ namespace SHADE_Scripting
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void update()
|
protected override void update()
|
||||||
|
{
|
||||||
|
if (Input.GetMouseButton(Input.MouseCode.RightButton))
|
||||||
{
|
{
|
||||||
CameraArm arm = GetComponent<CameraArm>();
|
CameraArm arm = GetComponent<CameraArm>();
|
||||||
if (arm)
|
if (arm)
|
||||||
|
@ -43,13 +48,14 @@ namespace SHADE_Scripting
|
||||||
{
|
{
|
||||||
arm.Pitch = pitchClamp;
|
arm.Pitch = pitchClamp;
|
||||||
}
|
}
|
||||||
else if(arm.Pitch < -pitchClamp)
|
else if (arm.Pitch < 0)
|
||||||
{
|
{
|
||||||
arm.Pitch = -pitchClamp;
|
arm.Pitch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -30,4 +30,5 @@ workspace "SHADE"
|
||||||
--include "Dependencies/tracy"
|
--include "Dependencies/tracy"
|
||||||
include "Dependencies/yamlcpp"
|
include "Dependencies/yamlcpp"
|
||||||
include "Dependencies/reactphysics3d"
|
include "Dependencies/reactphysics3d"
|
||||||
|
include "Dependencies/ModelCompiler"
|
||||||
group ""
|
group ""
|
||||||
|
|
Loading…
Reference in New Issue