diff --git a/Assets/Audio/Master.bank b/Assets/Audio/Master.bank index a1b4e563..f6cce22f 100644 Binary files a/Assets/Audio/Master.bank and b/Assets/Audio/Master.bank differ diff --git a/Assets/Audio/Master.strings.bank b/Assets/Audio/Master.strings.bank index ecad89fe..d858d0f6 100644 Binary files a/Assets/Audio/Master.strings.bank and b/Assets/Audio/Master.strings.bank differ diff --git a/Assets/Audio/Music.bank b/Assets/Audio/Music.bank new file mode 100644 index 00000000..3885d5df Binary files /dev/null and b/Assets/Audio/Music.bank differ diff --git a/Assets/Audio/SFX.bank b/Assets/Audio/SFX.bank new file mode 100644 index 00000000..7a7b0bbe Binary files /dev/null and b/Assets/Audio/SFX.bank differ diff --git a/Assets/Audio/UI.bank b/Assets/Audio/UI.bank new file mode 100644 index 00000000..78ed9460 Binary files /dev/null and b/Assets/Audio/UI.bank differ diff --git a/Assets/Materials/UIMat.shmat b/Assets/Materials/UIMat.shmat new file mode 100644 index 00000000..b31fed2e --- /dev/null +++ b/Assets/Materials/UIMat.shmat @@ -0,0 +1,8 @@ +- VertexShader: 46580970 + FragmentShader: 35983630 + 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} \ No newline at end of file diff --git a/Assets/Materials/UIMat.shmat.shmeta b/Assets/Materials/UIMat.shmat.shmeta new file mode 100644 index 00000000..2a2d2572 --- /dev/null +++ b/Assets/Materials/UIMat.shmat.shmeta @@ -0,0 +1,3 @@ +Name: UIMat +ID: 129340704 +Type: 7 diff --git a/Assets/Models/Quad.gltf b/Assets/Models/Quad.gltf new file mode 100644 index 00000000..493c164d --- /dev/null +++ b/Assets/Models/Quad.gltf @@ -0,0 +1,104 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.3.27", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Quad" + } + ], + "meshes" : [ + { + "name" : "Plane", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "NORMAL" : 1, + "TEXCOORD_0" : 2 + }, + "indices" : 3 + } + ] + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 4, + "max" : [ + 0.5, + 0.5, + 3.774895063202166e-08 + ], + "min" : [ + -0.5, + -0.5, + -3.774895063202166e-08 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 4, + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 4, + "type" : "VEC2" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 6, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 48, + "byteOffset" : 48, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 32, + "byteOffset" : 96, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 12, + "byteOffset" : 128, + "target" : 34963 + } + ], + "buffers" : [ + { + "byteLength" : 140, + "uri" : "data:application/octet-stream;base64,AAAAvwAAAL9pISIzAAAAPwAAAL9pISIzAAAAvwAAAD9pISKzAAAAPwAAAD9pISKzAAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAGkhojMAAIA/AAAAAAAAgD8AAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAEAAwAAAAMAAgA=" + } + ] +} diff --git a/Assets/Models/Quad.shmodel b/Assets/Models/Quad.shmodel new file mode 100644 index 00000000..aebbb0a6 Binary files /dev/null and b/Assets/Models/Quad.shmodel differ diff --git a/Assets/Models/Quad.shmodel.shmeta b/Assets/Models/Quad.shmodel.shmeta new file mode 100644 index 00000000..9fbd4b9c --- /dev/null +++ b/Assets/Models/Quad.shmodel.shmeta @@ -0,0 +1,7 @@ +Name: Quad +ID: 80501355 +Type: 4 +Sub Assets: +Name: Quad +ID: 141771688 +Type: 8 diff --git a/Assets/Scenes/PlayerControllerTest.shade b/Assets/Scenes/PlayerControllerTest.shade new file mode 100644 index 00000000..01039622 --- /dev/null +++ b/Assets/Scenes/PlayerControllerTest.shade @@ -0,0 +1,454 @@ +- EID: 0 + Name: ScoreZone + 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 + IsActive: 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 + IsActive: true + 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} + IsActive: true + Renderable Component: + Mesh: 149697411 + Material: 126974645 + IsActive: true + RigidBody Component: + Type: Static + Mass: 1 + Drag: 0.00999999978 + Angular Drag: 0.00999999978 + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} + IsActive: true + Scripts: ~ +- EID: 2 + Name: Player + IsActive: true + NumberOfChildren: 3 + Components: + Transform Component: + Translate: {x: -18.9007454, y: -3.67369723, z: -5.23871422} + Rotate: {x: -0, y: 0, z: 0} + Scale: {x: 2, y: 2, z: 2} + IsActive: true + Renderable Component: + Mesh: 149697411 + Material: 126974645 + IsActive: true + RigidBody Component: + Type: Dynamic + Mass: 1 + Drag: 2 + Angular Drag: 0 + Use Gravity: false + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + IsActive: true + Scripts: + - Type: PlayerController + currentState: 0 + maxMoveVel: 4 + moveForce: 50 + sprintMultiplier: 1.5 + rotationFactorPerFrame: 1 + maxJumpHeight: 4 + maxJumpTime: 0.75 + fallMultipler: 2 + lightMultiper: 0.75 + mediumMultiper: 0.5 + heavyMultiper: 0.25 + - Type: PickAndThrow + holdPosition: [0, 1.20000005, 0] + throwForce: [200, 300, 200] +- EID: 3 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 1.20000005, z: 0} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Scripts: ~ +- EID: 4 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 0, z: 0} + Rotate: {x: -0.785401046, y: 1.65799224, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Camera Component: + Position: {x: -18.9007454, y: -3.67369723, z: -5.23871422} + Pitch: -45.000164 + Yaw: 94.9959564 + Roll: 0 + Width: 1920 + Height: 1080 + Near: 0.00999999978 + Far: 10000 + Perspective: true + IsActive: true + Scripts: + - Type: SHADE_Scripting.ThirdPersonCamera + armLength: 2 + turnSpeedPitch: 0.300000012 + turnSpeedYaw: 0.5 + pitchClamp: 45 +- 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} + IsActive: true + Renderable Component: + Mesh: 144838771 + Material: 123745521 + IsActive: true + Scripts: ~ +- EID: 6 + Name: AI + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -8, y: -4.42369843, z: 2.5} + Rotate: {x: -0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + Renderable Component: + Mesh: 149697411 + Material: 126974645 + IsActive: true + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 0.5, y: 0.5, z: 0.5} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + IsActive: true + Scripts: ~ +- EID: 7 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: -16.8647861, z: -14.039052} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975} + IsActive: true + Renderable Component: + Mesh: 149697411 + Material: 126974645 + IsActive: true + 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 + IsActive: true + Scripts: ~ +- EID: 11 + Name: GameManager + 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} + IsActive: true + RigidBody Component: + Type: Static + Mass: 1 + Drag: 0.00999999978 + Angular Drag: 0.00999999978 + 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 + IsActive: true + Collider Component: + Colliders: ~ + IsActive: true + Scripts: + - Type: GameManager + itemPool: 12 + zonePool: 51000 + currGameState: 0 + totalItemCount: -202 + Score: 204 + timer: 0 +- EID: 12 + Name: ItemPool + IsActive: true + NumberOfChildren: 2 + Components: ~ + Scripts: ~ +- EID: 10 + Name: item + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 3.19870043, y: -3.67369723, z: -5} + Rotate: {x: -0, y: 0, z: 0} + Scale: {x: 2, y: 2, z: 2} + IsActive: true + Renderable Component: + Mesh: 144838771 + Material: 123745521 + IsActive: true + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + - Is Trigger: true + Type: Box + Half Extents: {x: 2, y: 2, z: 2} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + IsActive: true + Scripts: + - Type: Item + Score: 1 + currCategory: 0 +- EID: 5 + Name: item + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -20.6163979, y: -0.0419634879, z: -5.08873653} + Rotate: {x: -0, y: 0, z: 0} + Scale: {x: 2, y: 2, z: 2} + IsActive: false + Renderable Component: + Mesh: 144838771 + Material: 123745521 + IsActive: false + 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 + IsActive: false + Collider Component: + Colliders: + - Is Trigger: false + Type: Box + Half Extents: {x: 1, y: 1, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + - Is Trigger: true + Type: Box + Half Extents: {x: 2, y: 2, z: 2} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0.5, z: 0} + IsActive: false + Scripts: + - Type: Item + Score: 1 + currCategory: 0 +- EID: 15 + Name: ScoreZonePool + IsActive: true + NumberOfChildren: 2 + Components: ~ + Scripts: ~ +- EID: 13 + Name: ScoreZone + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -24.5947151, y: -3.15127993, z: -3.29243231} + Rotate: {x: 0, y: 0, z: 0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + RigidBody Component: + Type: Static + Mass: 1 + Drag: 0.00999999978 + Angular Drag: 0.00999999978 + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: true + Type: Box + Half Extents: {x: 1, y: 20, z: 20} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} + IsActive: true + Scripts: ~ +- EID: 14 + Name: ScoreZone + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: -6.64785767, y: 0, z: -14.217104} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + RigidBody Component: + Type: Static + Mass: 1 + Drag: 0.00999999978 + Angular Drag: 0.00999999978 + 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 + IsActive: true + Collider Component: + Colliders: + - Is Trigger: true + Type: Box + Half Extents: {x: 20, y: 20, z: 1} + Friction: 0.400000006 + Bounciness: 0 + Density: 1 + Position Offset: {x: 0, y: 0, z: 0} + IsActive: true + Scripts: ~ \ No newline at end of file diff --git a/Assets/Scenes/PlayerControllerTest.shade.shmeta b/Assets/Scenes/PlayerControllerTest.shade.shmeta new file mode 100644 index 00000000..3d9787c8 --- /dev/null +++ b/Assets/Scenes/PlayerControllerTest.shade.shmeta @@ -0,0 +1,3 @@ +Name: PlayerControllerTest +ID: 92100024 +Type: 5 diff --git a/Assets/Scripts/SC_GameManager.cs b/Assets/Scripts/SC_GameManager.cs new file mode 100644 index 00000000..743827ed --- /dev/null +++ b/Assets/Scripts/SC_GameManager.cs @@ -0,0 +1,62 @@ +using SHADE; +using System; +using System.Collections.Generic; + +public class GameManager : Script +{ + public enum GameState + { + MAINMENU, + WIN, + LOSE, + TOTAL + } + + public GameObject itemPool; + public GameObject zonePool; + public GameState currGameState; + + [NonSerialized] + public int totalItemCount; + [NonSerialized] + public int Score; + [NonSerialized] + public float timer; + + private IEnumerable listOfItems; + private IEnumerable listOfZone; + + protected override void awake() + { + totalItemCount = 0; + Score = 0; + currGameState = GameState.MAINMENU; + + if (itemPool) + { + listOfItems = itemPool.GetScriptsInChildren(); + foreach (Item i in listOfItems) + totalItemCount += 1; + } + + if (zonePool) + { + listOfZone = itemPool.GetScriptsInChildren(); + foreach (ScoringZone i in listOfZone) + i.gameManger = Owner.GetScript(); + } + } + + protected override void update() + { + if (timer > 0) + timer -= Time.DeltaTimeF; + else + currGameState = GameState.LOSE; + } + + protected override void onTriggerEnter(CollisionInfo info) + { + } + +} diff --git a/Assets/Scripts/SC_GameManager.cs.shmeta b/Assets/Scripts/SC_GameManager.cs.shmeta new file mode 100644 index 00000000..6082d6fe --- /dev/null +++ b/Assets/Scripts/SC_GameManager.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_GameManager +ID: 161629605 +Type: 9 diff --git a/Assets/Scripts/Item.cs b/Assets/Scripts/SC_Item.cs similarity index 67% rename from Assets/Scripts/Item.cs rename to Assets/Scripts/SC_Item.cs index 5047a241..cb2a5d32 100644 --- a/Assets/Scripts/Item.cs +++ b/Assets/Scripts/SC_Item.cs @@ -9,9 +9,16 @@ public class Item : Script HEAVY } + public int Score = 10; + public ItemCategory currCategory; protected override void awake() { } + + protected override void onTriggerEnter(CollisionInfo info) + { + } + } \ No newline at end of file diff --git a/Assets/Scripts/SC_Item.cs.shmeta b/Assets/Scripts/SC_Item.cs.shmeta new file mode 100644 index 00000000..2503da21 --- /dev/null +++ b/Assets/Scripts/SC_Item.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_Item +ID: 153136539 +Type: 9 diff --git a/Assets/Scripts/PickAndThrow.cs b/Assets/Scripts/SC_PickAndThrow.cs similarity index 78% rename from Assets/Scripts/PickAndThrow.cs rename to Assets/Scripts/SC_PickAndThrow.cs index ec8846c5..15edd302 100644 --- a/Assets/Scripts/PickAndThrow.cs +++ b/Assets/Scripts/SC_PickAndThrow.cs @@ -4,8 +4,9 @@ using static PlayerController; public class PickAndThrow : Script { + public Vector3 holdPosition = new Vector3(0.0f, 1.0f, 0.0f); public Vector3 throwForce = new Vector3(100.0f, 200.0f, 100.0f); - public GameObject item; + public GameObject item { get; set; } private PlayerController pc; private Camera cam; private Transform itemTransform; @@ -22,36 +23,13 @@ public class PickAndThrow : Script if (raccoonHoldLocation == null) Debug.Log("CHILD EMPTY"); else - raccoonHoldLocation.LocalPosition = new Vector3(0.0f, 1.0f, 0.0f); + raccoonHoldLocation.LocalPosition = holdPosition; } protected override void update() { - if (cam == null) - cam = GetComponentInChildren(); - else if (cam != null) - { - Vector3 camerAixs = cam.GetForward(); - camerAixs.y = 0; - camerAixs.Normalise(); - lastXDir = camerAixs.x; - lastZDir = camerAixs.z; - } + CalculateDir(); - if (item.GetScript() != null && itemTransform == null && itemRidibody == null) - { - itemTransform = item.GetComponent(); - if (itemTransform == null) - Debug.Log("Item transform EMPTY"); - - itemRidibody = item.GetComponent(); - 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) + if (pc != null && pc.holdItem && itemRidibody != null && itemTransform != null) { itemTransform.LocalPosition = raccoonHoldLocation.GlobalPosition; itemRidibody.IsGravityEnabled = false; @@ -65,17 +43,60 @@ public class PickAndThrow : Script itemRidibody.IsGravityEnabled = true; itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir)); itemRidibody.LinearVelocity += pc.rb.LinearVelocity; + ResetItemObject(); } } else if(!pc.holdItem && itemRidibody != null) itemRidibody.IsGravityEnabled = true; + + if (pc != null && !pc.holdItem && inRange && Input.GetMouseButtonDown(Input.MouseCode.LeftButton)) + { + pc.holdItem = true; + RetrieveItemComponets(); + } } + + private void ResetItemObject() + { + itemRidibody = null; + itemTransform = null; + item = new GameObject(); + } + + private void RetrieveItemComponets() + { + //get the transform of the given item + if (item.GetScript() != null && itemTransform == null && itemRidibody == null) + { + itemTransform = item.GetComponent(); + if (itemTransform == null) + Debug.Log("Item transform EMPTY"); + + itemRidibody = item.GetComponent(); + if (itemRidibody == null) + Debug.Log("Item rb EMPTY"); + } + } + + private void CalculateDir() + { + if (cam == null) + cam = GetComponentInChildren(); + else if (cam != null) + { + Vector3 camerAixs = cam.GetForward(); + camerAixs.y = 0; + camerAixs.Normalise(); + lastXDir = camerAixs.x; + lastZDir = camerAixs.z; + } + } + protected override void onCollisionEnter(CollisionInfo info) { } protected override void onTriggerEnter(CollisionInfo info) { - //Debug.Log("ENTER"); if (info.GameObject.GetScript() != null && !pc.holdItem) { item = info.GameObject; diff --git a/Assets/Scripts/SC_PickAndThrow.cs.shmeta b/Assets/Scripts/SC_PickAndThrow.cs.shmeta new file mode 100644 index 00000000..5703d6d7 --- /dev/null +++ b/Assets/Scripts/SC_PickAndThrow.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_PickAndThrow +ID: 154802724 +Type: 9 diff --git a/Assets/Scripts/PlayerController.cs b/Assets/Scripts/SC_PlayerController.cs similarity index 61% rename from Assets/Scripts/PlayerController.cs rename to Assets/Scripts/SC_PlayerController.cs index 4a02d470..189622ac 100644 --- a/Assets/Scripts/PlayerController.cs +++ b/Assets/Scripts/SC_PlayerController.cs @@ -1,40 +1,47 @@ using SHADE; using System; +using System.Collections.Generic; using static Item; public class PlayerController : Script { public enum RaccoonStates { - IDILE, + IDLE, WALKING, RUNNING, JUMP, FALLING, + LANDED, CAUGHT, TOTAL } + public enum WalkingState + { + CARRY, + AIMING, + THROW, + WALK, + TOTAL + } + public RigidBody rb { get; set; } private Transform tranform; private Camera cam; private PickAndThrow pat; + private StateMachine stateMachine; - //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; + public RaccoonStates currentState = RaccoonStates.IDLE; //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] + public float moveForce = 2.0f; [Tooltip("increase the moveForce and maxMoveVel by its amt")] public float sprintMultiplier = 2.0f; @@ -49,7 +56,6 @@ public class PlayerController : Script public bool isMoveKeyPress { get; set; } - [SerializeField] [Tooltip("curr not working")] public float rotationFactorPerFrame = 1.0f; @@ -75,6 +81,7 @@ public class PlayerController : Script protected override void awake() { + Audio.PlayBGMOnce2D("event:/Music/player_undetected"); //default setup isMoveKeyPress = false; holdItem = false; @@ -91,10 +98,6 @@ public class PlayerController : Script else { rb.IsGravityEnabled = false; - rb.FreezeRotationX = true; - rb.FreezeRotationY = true; - rb.FreezeRotationZ = true; - rb.Drag = drag; rb.Interpolating = false; } @@ -103,14 +106,18 @@ public class PlayerController : Script if(tranform == null) Debug.LogError("tranform is NULL!"); - //PickAndThrow checl + //PickAndThrow check pat = GetScript(); 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); + stateMachine = AddScript(); + Dictionary dictionary = new Dictionary(); + dictionary.Add(typeof(IdleState), new IdleState(stateMachine)); + dictionary.Add(typeof(WalkState), new WalkState(stateMachine)); + dictionary.Add(typeof(RunState), new RunState(stateMachine)); + stateMachine.InitStateMachine(dictionary); + } protected override void update() @@ -118,117 +125,102 @@ public class PlayerController : Script if (cam == null) cam = GetComponentInChildren(); - //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}"); + //Debug.Log($" axisX: {axisMove.x} axisY:{axisMove.y}"); + //Debug.Log($"X: {rb.LinearVelocity.x}" + $" Z: {rb.LinearVelocity.z}"); //Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString()); } protected override void fixedUpdate() { //Rotation(); + + + MoveKey(); Move(); Sprint(); Jump(); Gravity(); + //Debug.Log($"X: {rb.LinearVelocity.x}" + $" Z: {rb.LinearVelocity.z}"); } 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) + axisMove.Normalise(); + isMoveKeyPress = axisMove.x != 0 || axisMove.y != 0; + + if (isMoveKeyPress && isGrounded && !Input.GetKey(Input.KeyCode.LeftShift)) + { currentState = RaccoonStates.WALKING; + if(stateMachine && !stateMachine.IsState(typeof(WalkState))) + stateMachine.SetState(typeof(WalkState)); + } + if (!isMoveKeyPress && isGrounded) - currentState = RaccoonStates.IDILE; + { + currentState = RaccoonStates.IDLE; + + if(stateMachine && !stateMachine.IsState(typeof(IdleState))) + stateMachine.SetState(typeof(IdleState)); + } } private void Move() { if (rb != null) { - rb.AddForce(new Vector3(axisMove.x, 0.0f,axisMove.y) * moveForce); + rb.LinearVelocity += new Vector3(axisMove.x * moveForce, 0.0f, axisMove.y * moveForce) * Time.DeltaTimeF; if (isMoveKeyPress) { - if (rb.LinearVelocity.x > maxMoveVel || rb.LinearVelocity.x < -maxMoveVel) + if (rb) { - 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; + Vector3 velNor = rb.LinearVelocity; + velNor.y = 0.0f; + if (velNor.GetMagnitude() > maxMoveVel) + { + velNor.Normalise(); + velNor *= maxMoveVel; + rb.LinearVelocity = new Vector3(velNor.x, rb.LinearVelocity.y, velNor.z); + } } + } } } @@ -238,6 +230,9 @@ public class PlayerController : Script if (Input.GetKey(Input.KeyCode.LeftShift) && isMoveKeyPress && isGrounded) { currentState = RaccoonStates.RUNNING; + if (stateMachine && !stateMachine.IsState(typeof(RunState))) + stateMachine.SetState(typeof(RunState)); + holdItem = false; if (!sprintIncreaseOnce) { @@ -252,8 +247,12 @@ public class PlayerController : Script if (Input.GetKeyUp(Input.KeyCode.LeftShift)) { - if(isMoveKeyPress) + if (isMoveKeyPress) + { currentState = RaccoonStates.WALKING; + if(stateMachine && !stateMachine.IsState(typeof(WalkState))) + stateMachine.SetState(typeof(WalkState)); + } sprintIncreaseOnce = false; moveForce = oldForce; maxMoveVel = maxOldVel; @@ -263,37 +262,38 @@ public class PlayerController : Script //press and hold jump private void Jump() { - if (currentState == RaccoonStates.WALKING || currentState == RaccoonStates.RUNNING || currentState == RaccoonStates.IDILE) + if (currentState == RaccoonStates.WALKING || currentState == RaccoonStates.RUNNING || currentState == RaccoonStates.IDLE) { 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() != null && holdItem) + if (holdItem && pat != null && pat.item.GetScript() != null) { Item item = pat.item.GetScript(); - if (item.currCategory == ItemCategory.LIGHT) + if (item != null && item.currCategory == ItemCategory.LIGHT) v.y *= lightMultiper; - if (item.currCategory == ItemCategory.MEDIUM) + if (item != null && item.currCategory == ItemCategory.MEDIUM) v.y *= mediumMultiper; - if (item.currCategory == ItemCategory.HEAVY) + if (item != null && item.currCategory == ItemCategory.HEAVY) v.y *= heavyMultiper; } rb.LinearVelocity = v; } } - if(rb != null && !isGrounded && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space))) + if(!isGrounded && rb != null && (rb.LinearVelocity.y < 0.0f || Input.GetKeyUp(Input.KeyCode.Space))) currentState = RaccoonStates.FALLING; + } private void Rotation() { Vector3 poitionToLookAt; - poitionToLookAt.x = xAxisMove; + poitionToLookAt.x = axisMove.x; poitionToLookAt.y = 0.0f; - poitionToLookAt.z = zAxisMove; + poitionToLookAt.z = axisMove.y; if (tranform != null) { @@ -312,7 +312,11 @@ public class PlayerController : Script { //check player vel.y if its close to zero its on the ground if (SHADE.Math.CompareFloat(rb.LinearVelocity.y, 0.0f)) + { isGrounded = true; + if (currentState == RaccoonStates.FALLING) + currentState = RaccoonStates.LANDED; + } else isGrounded = false; @@ -344,7 +348,9 @@ public class PlayerController : Script { if (currentState == RaccoonStates.CAUGHT && tranform != null) { - currentState = RaccoonStates.IDILE; + currentState = RaccoonStates.IDLE; + if (stateMachine && !stateMachine.IsState(typeof(IdleState))) + stateMachine.SetState(typeof(IdleState)); tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f); } } @@ -353,6 +359,82 @@ public class PlayerController : Script { } +} + +public class WalkState : BaseState +{ + public WalkState(StateMachine stateMachine) : base(stateMachine) + { + stateName = "Walk State"; + } + public override void OnEnter() + { + //Debug.Log("WALK ENTER"); + } + public override void update() + { + //Debug.Log("WALKING"); + } + public override void fixedUpdate() + { + //Debug.Log("FIXED WALKING"); + } + public override void OnExit() + { + //Debug.Log("WALK EXIT"); + } + public override void onTriggerEnter(CollisionInfo info) + { + //Debug.Log("TRIGGER"); + } } +public class RunState : BaseState +{ + public RunState(StateMachine stateMachine) : base(stateMachine) + { + stateName = "Run State"; + } + public override void OnEnter() + { + //Debug.Log("Run ENTER"); + } + public override void update() + { + //Debug.Log("RUNING"); + } + public override void fixedUpdate() + { + //Debug.Log("FIXED RUNNING"); + } + public override void OnExit() + { + //Debug.Log("Run EXIT"); + } +} + +public class IdleState : BaseState +{ + public IdleState(StateMachine stateMachine) : base(stateMachine) + { + stateName = "Idle State"; + } + public override void OnEnter() + { + //Debug.Log("IDLE ENTER"); + } + public override void update() + { + //Debug.Log("IDLING"); + } + public override void fixedUpdate() + { + //Debug.Log("FIXED IDLING"); + } + public override void OnExit() + { + //Debug.Log("IDLE EXIT"); + } +} + diff --git a/Assets/Scripts/SC_PlayerController.cs.shmeta b/Assets/Scripts/SC_PlayerController.cs.shmeta new file mode 100644 index 00000000..445af934 --- /dev/null +++ b/Assets/Scripts/SC_PlayerController.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_PlayerController +ID: 160432754 +Type: 9 diff --git a/Assets/Scripts/SC_ScoringZone.cs b/Assets/Scripts/SC_ScoringZone.cs new file mode 100644 index 00000000..849f3e1c --- /dev/null +++ b/Assets/Scripts/SC_ScoringZone.cs @@ -0,0 +1,21 @@ +using SHADE; +using System; +public class ScoringZone : Script +{ + public GameManager gameManger { get; set; } + + protected override void awake() + { + } + + protected override void onTriggerEnter(CollisionInfo info) + { + if (gameManger && info.GameObject.GetScript()) + { + gameManger.Score += info.GameObject.GetScript().Score; + gameManger.totalItemCount -= 1; + info.GameObject.SetActive(false); + } + } + +} \ No newline at end of file diff --git a/Assets/Scripts/SC_ScoringZone.cs.shmeta b/Assets/Scripts/SC_ScoringZone.cs.shmeta new file mode 100644 index 00000000..51ef171b --- /dev/null +++ b/Assets/Scripts/SC_ScoringZone.cs.shmeta @@ -0,0 +1,3 @@ +Name: SC_ScoringZone +ID: 153171688 +Type: 9 diff --git a/Assets/Scripts/UT_BaseSate.cs b/Assets/Scripts/UT_BaseSate.cs new file mode 100644 index 00000000..521f5936 --- /dev/null +++ b/Assets/Scripts/UT_BaseSate.cs @@ -0,0 +1,68 @@ +using SHADE; +using System; + +public abstract class BaseState +{ + + protected string stateName = "Base State"; + protected StateMachine machine; + protected string animationName = ""; + + public BaseState(StateMachine stateMachine, string animName = "") + { + machine = stateMachine; + animationName = animName; + } + + public virtual void OnEnter() + { + } + + public abstract void update(); + + public abstract void fixedUpdate(); + + public virtual void OnExit() + { + + } + + public string GetStateName() + { + return stateName; + } + + public string GetAnimName() + { + return animationName; + } + + public virtual float GetAnimPercent() + { + return 1.0f; + } + + public virtual void onCollisionEnter(CollisionInfo info) + { + } + + public virtual void onCollisionStay(CollisionInfo info) + { + } + + public virtual void onCollisionExit(CollisionInfo info) + { + } + + public virtual void onTriggerEnter(CollisionInfo info) + { + } + + public virtual void onTriggerStay(CollisionInfo info) + { + } + + public virtual void onTriggerExit(CollisionInfo info) + { + } +} diff --git a/Assets/Scripts/UT_BaseSate.cs.shmeta b/Assets/Scripts/UT_BaseSate.cs.shmeta new file mode 100644 index 00000000..49e62af3 --- /dev/null +++ b/Assets/Scripts/UT_BaseSate.cs.shmeta @@ -0,0 +1,3 @@ +Name: UT_BaseSate +ID: 154709755 +Type: 9 diff --git a/Assets/Scripts/UT_StateMachine.cs b/Assets/Scripts/UT_StateMachine.cs new file mode 100644 index 00000000..aa3cfd72 --- /dev/null +++ b/Assets/Scripts/UT_StateMachine.cs @@ -0,0 +1,126 @@ +using SHADE; +using System; +using System.Collections.Generic; +using System.Linq; + +public class StateMachine : Script +{ + private Dictionary stateDictionary; + public BaseState currentState = null; + public string currentStateName; + public string currentAnimName; + + public void InitStateMachine(Dictionary dictionary) + { + + stateDictionary = dictionary; + currentState = stateDictionary.First().Value; + currentStateName = currentState.GetStateName(); + currentAnimName = currentState.GetAnimName(); + currentState.OnEnter(); + } + + public bool HasState(Type type) + { + if (!type.IsSubclassOf(typeof(BaseState))) + { + return false; + } + else + { + return stateDictionary.ContainsKey(type); + } + } + + public void SetState(Type type) + { + if (!type.IsSubclassOf(typeof(BaseState))) + { + return; + } + + + if (stateDictionary.ContainsKey(type)) + { + currentState.OnExit(); + currentState = stateDictionary[type]; + currentState.OnEnter(); + } + else + { + SetState(stateDictionary.First().Key); + } + } + + public BaseState GetState(Type type) + { + if (!stateDictionary.ContainsKey(type)) + return null; + + return stateDictionary[type]; + } + public bool IsState(Type type) + { + return (currentState.GetType() == type); + } + + protected override void update() + { + if (currentState != (null)) + { + currentStateName = currentState.GetStateName(); + currentAnimName = currentState.GetAnimName(); + currentState.update(); + } + + } + + protected override void fixedUpdate() + { + if (currentState != (null)) + { + currentStateName = currentState.GetStateName(); + currentAnimName = currentState.GetAnimName(); + currentState.fixedUpdate(); + } + } + + protected override void onCollisionEnter(CollisionInfo info) + { + if (currentState != (null)) + currentState.onCollisionEnter(info); + } + + protected override void onCollisionStay(CollisionInfo info) + { + if (currentState != (null)) + currentState.onCollisionStay(info); + } + + protected override void onCollisionExit(CollisionInfo info) + { + if (currentState != (null)) + currentState.onCollisionExit(info); + } + + protected override void onTriggerEnter(CollisionInfo info) + { + if (currentState != (null)) + currentState.onTriggerEnter(info); + } + + protected override void onTriggerStay(CollisionInfo info) + { + if (currentState != (null)) + currentState.onTriggerStay(info); + } + + protected override void onTriggerExit(CollisionInfo info) + { + if (currentState != (null)) + currentState.onTriggerExit(info); + } + + +} + diff --git a/Assets/Scripts/UT_StateMachine.cs.shmeta b/Assets/Scripts/UT_StateMachine.cs.shmeta new file mode 100644 index 00000000..3e0b1dee --- /dev/null +++ b/Assets/Scripts/UT_StateMachine.cs.shmeta @@ -0,0 +1,3 @@ +Name: UT_StateMachine +ID: 166010611 +Type: 9 diff --git a/Assets/Shaders/DebugDraw_VS.glsl b/Assets/Shaders/DebugDraw_VS.glsl index cb0886d1..7b370730 100644 --- a/Assets/Shaders/DebugDraw_VS.glsl +++ b/Assets/Shaders/DebugDraw_VS.glsl @@ -15,6 +15,9 @@ layout(set = 2, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; + mat4 viewMat; + mat4 perspectiveMat; + mat4 orthoMat; } cameraData; void main() diff --git a/Assets/Shaders/TestCube_VS.glsl b/Assets/Shaders/TestCube_VS.glsl index 0e055395..774bc580 100644 --- a/Assets/Shaders/TestCube_VS.glsl +++ b/Assets/Shaders/TestCube_VS.glsl @@ -34,7 +34,8 @@ layout(set = 2, binding = 0) uniform CameraData vec4 position; mat4 vpMat; mat4 viewMat; - mat4 projMat; + mat4 perspectiveMat; + mat4 orthoMat; } cameraData; void main() diff --git a/Assets/Shaders/TestCube_VS.shshaderb b/Assets/Shaders/TestCube_VS.shshaderb index fb282b4d..28c4655b 100644 Binary files a/Assets/Shaders/TestCube_VS.shshaderb and b/Assets/Shaders/TestCube_VS.shshaderb differ diff --git a/Assets/Shaders/Text_VS.glsl b/Assets/Shaders/Text_VS.glsl index 62316533..6263aba6 100644 --- a/Assets/Shaders/Text_VS.glsl +++ b/Assets/Shaders/Text_VS.glsl @@ -30,7 +30,8 @@ layout(set = 2, binding = 0) uniform CameraData vec4 position; mat4 vpMat; mat4 viewMat; - mat4 projMat; + mat4 perspectiveMat; + mat4 orthoMat; } cameraData; // push constants diff --git a/Assets/Shaders/Text_VS.shshaderb b/Assets/Shaders/Text_VS.shshaderb index b6f0afe7..3f612654 100644 Binary files a/Assets/Shaders/Text_VS.shshaderb and b/Assets/Shaders/Text_VS.shshaderb differ diff --git a/Assets/Shaders/UI_FS.glsl b/Assets/Shaders/UI_FS.glsl new file mode 100644 index 00000000..4f919a04 --- /dev/null +++ b/Assets/Shaders/UI_FS.glsl @@ -0,0 +1,50 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable +#extension GL_EXT_nonuniform_qualifier : require + +struct MatPropData +{ + vec4 color; + int textureIndex; + float alpha; + vec3 beta; +}; + +layout(location = 0) in struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 normal; // location = 2 + +} In; + +// material stuff +layout(location = 3) flat in struct +{ + int materialIndex; + uint eid; + uint lightLayerIndex; +} In2; + +layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) +layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +{ + MatPropData data[]; +} MatProp; + +layout(location = 0) out vec4 position; +layout(location = 1) out uint outEntityID; +layout(location = 2) out uint lightLayerIndices; +layout(location = 3) out vec4 normals; +layout(location = 4) out vec4 albedo; + +void main() +{ + position = In.vertPos; + normals = In.normal; + albedo = vec4(1.0f); + + outEntityID = In2.eid; + lightLayerIndices = In2.lightLayerIndex; +} \ No newline at end of file diff --git a/Assets/Shaders/UI_FS.shshaderb b/Assets/Shaders/UI_FS.shshaderb new file mode 100644 index 00000000..6be9c565 Binary files /dev/null and b/Assets/Shaders/UI_FS.shshaderb differ diff --git a/Assets/Shaders/UI_FS.shshaderb.shmeta b/Assets/Shaders/UI_FS.shshaderb.shmeta new file mode 100644 index 00000000..80bb5dad --- /dev/null +++ b/Assets/Shaders/UI_FS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: UI_FS +ID: 35983630 +Type: 2 diff --git a/Assets/Shaders/UI_VS.glsl b/Assets/Shaders/UI_VS.glsl new file mode 100644 index 00000000..c4393b98 --- /dev/null +++ b/Assets/Shaders/UI_VS.glsl @@ -0,0 +1,66 @@ +#version 450 +#extension GL_KHR_vulkan_glsl : enable + +//#include "ShaderDescriptorDefinitions.glsl" + + +layout(location = 0) in vec3 aVertexPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec3 aNormal; +layout(location = 3) in vec3 aTangent; +layout(location = 4) in mat4 worldTransform; +layout(location = 8) in uvec2 integerData; + + +layout(location = 0) out struct +{ + vec4 vertPos; // location 0 + vec2 uv; // location = 1 + vec4 normal; // location = 2 + +} Out; + +// material stuff +layout(location = 3) out struct +{ + int materialIndex; + uint eid; + uint lightLayerIndex; + +} Out2; + +layout(set = 2, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; + mat4 viewMat; + mat4 perspectiveMat; + mat4 orthoMat; +} cameraData; + +void main() +{ + Out2.materialIndex = gl_InstanceIndex; + Out2.eid = integerData[0]; + Out2.lightLayerIndex = integerData[1]; + + // for transforming gBuffer position and normal data + mat4 modelViewMat = cameraData.viewMat * worldTransform; + + // gBuffer position will be in view space + Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f); + + // uvs for texturing in fragment shader + Out.uv = aUV; + + mat3 transposeInv = mat3 (transpose(inverse(modelViewMat))); + + // normals are also in view space + Out.normal.rgb = transposeInv * aNormal.rgb; + Out.normal.rgb = normalize (Out.normal.rgb); + + // clip space for rendering + gl_Position = cameraData.orthoMat * worldTransform * vec4 (aVertexPos, 1.0f); + gl_Position.z += 0.1f; // HAX + // gl_Position = vec4 (aVertexPos, 1.0f); +} \ No newline at end of file diff --git a/Assets/Shaders/UI_VS.shshaderb b/Assets/Shaders/UI_VS.shshaderb new file mode 100644 index 00000000..a1f1a8b7 Binary files /dev/null and b/Assets/Shaders/UI_VS.shshaderb differ diff --git a/Assets/Shaders/UI_VS.shshaderb.shmeta b/Assets/Shaders/UI_VS.shshaderb.shmeta new file mode 100644 index 00000000..08fa8435 --- /dev/null +++ b/Assets/Shaders/UI_VS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: UI_VS +ID: 46580970 +Type: 2 diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index d77aef53..a8871cd8 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -186,6 +186,12 @@ namespace Sandbox drawColliders = !drawColliders; SHSystemManager::GetSystem()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders); } + static bool drawRays = false; + if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F11)) + { + drawRays = !drawRays; + SHSystemManager::GetSystem()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays); + } } // Finish all graphics jobs first graphicsSystem->AwaitGraphicsExecution(); diff --git a/SHADE_CSharp/premake5.lua b/SHADE_CSharp/premake5.lua index 39ef8281..8844b84c 100644 --- a/SHADE_CSharp/premake5.lua +++ b/SHADE_CSharp/premake5.lua @@ -50,6 +50,9 @@ project "SHADE_CSharp" function platformsElementCS(cfg) _p(2,'x64') end + function configElementCS(cfg) + _p(2,'Debug;Release;Publish') + end function docsElementCS(cfg) _p(2,'true') end @@ -59,6 +62,6 @@ project "SHADE_CSharp" premake.override(premake.vstudio.cs2005.elements, "projectProperties", function (oldfn, cfg) return table.join(oldfn(cfg), { - platformsElementCS, docsElementCS, docsLocationElementCS, + platformsElementCS, configElementCS, docsElementCS, docsLocationElementCS, }) end) \ No newline at end of file diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp index c913030b..e98d895a 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.cpp @@ -84,12 +84,32 @@ namespace SHADE LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data()); LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data()); //LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data()); - LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data()); + //LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data()); + LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data()); + LoadBank((AUDIO_FOLDER_PATH + "SFX.bank").data()); + LoadBank((AUDIO_FOLDER_PATH + "UI.bank").data()); //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human"); //clip->Play(); //PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); //PlayEventOnce("event:/SFX/Dawn/Dawn_Attack"); + + #ifdef SHEDITOR + + // Subscribe to Editor State Change Events + const std::shared_ptr ON_PLAY_RECEIVER{ std::make_shared>(this, &SHAudioSystem::onPlay) }; + const ReceiverPtr ON_PLAY_RECEIVER_PTR = std::dynamic_pointer_cast(ON_PLAY_RECEIVER); + SHEventManager::SubscribeTo(SH_EDITOR_ON_PLAY_EVENT, ON_PLAY_RECEIVER_PTR); + + const std::shared_ptr ON_STOP_RECEIVER{ std::make_shared>(this, &SHAudioSystem::onStop) }; + const ReceiverPtr ON_STOP_RECEIVER_PTR = std::dynamic_pointer_cast(ON_STOP_RECEIVER); + SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR); + + const std::shared_ptr ON_PAUSE_RECEIVER{ std::make_shared>(this, &SHAudioSystem::onPause) }; + const ReceiverPtr ON_PAUSE_RECEIVER_PTR = std::dynamic_pointer_cast(ON_PAUSE_RECEIVER); + SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, ON_PAUSE_RECEIVER_PTR); + + #endif } void SHADE::SHAudioSystem::Run(double dt) @@ -179,7 +199,6 @@ namespace SHADE it->second->createInstance(&event); if (event) { - event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume)); if (spatial) { @@ -285,6 +304,7 @@ namespace SHADE if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying) channel->stop(); } + masterGroup->stop(); } std::optional SHAudioSystem::GetEventGUID(const char* path) @@ -410,6 +430,7 @@ namespace SHADE void SHAudioSystem::SetPaused(bool pause) { paused = pause; + masterGroup->setPaused(pause); for (auto const& channel : audioChannels) { channel->setPaused(paused); @@ -552,6 +573,27 @@ namespace SHADE return value; } + SHEventHandle SHAudioSystem::onStop(SHEventPtr onStopEvent) + { + StopAllSounds(); + + return onStopEvent->handle; + } + + SHEventHandle SHAudioSystem::onPause(SHEventPtr onStopEvent) + { + SetPaused(true); + + return onStopEvent->handle; + } + SHEventHandle SHAudioSystem::onPlay(SHEventPtr onStopEvent) + { + if(GetPaused()) + SetPaused(false); + + return onStopEvent->handle; + } + } #pragma warning(pop) diff --git a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h index 7196b40d..777334e6 100644 --- a/SHADE_Engine/src/AudioSystem/SHAudioSystem.h +++ b/SHADE_Engine/src/AudioSystem/SHAudioSystem.h @@ -10,6 +10,8 @@ #include "Math/Vector/SHVec3.h" #include #include +#include "Events/SHEvent.h" + #include "SH_API.h" #define AUDIO_SYS_MAX_CHANNELS 1024 @@ -104,6 +106,10 @@ namespace SHADE std::vector* denseListener; AudioClipID clipID = 0; + + SHEventHandle onPlay(SHEventPtr onStopEvent); + SHEventHandle onStop(SHEventPtr onStopEvent); + SHEventHandle onPause(SHEventPtr onStopEvent); }; } diff --git a/SHADE_Engine/src/Camera/SHCameraSystem.cpp b/SHADE_Engine/src/Camera/SHCameraSystem.cpp index 78dabc37..489b05a1 100644 --- a/SHADE_Engine/src/Camera/SHCameraSystem.cpp +++ b/SHADE_Engine/src/Camera/SHCameraSystem.cpp @@ -246,7 +246,7 @@ namespace SHADE camera.orthoProjMatrix(2, 3) = -n / (f-n); camera.orthoProjMatrix(3, 3) = 1.0f; - camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar()); + //camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar()); //camera.projMatrix.Transpose(); camera.dirtyProj = false; diff --git a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp index f111eaeb..50930e4f 100644 --- a/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp +++ b/SHADE_Engine/src/Editor/DragDrop/SHDragDrop.hpp @@ -21,7 +21,7 @@ namespace SHADE template static bool SetPayload(DragDropTag const& type, T* object, ImGuiCond const cond = 0) { - ImGui::SetDragDropPayload(type.data(), static_cast(object), sizeof(T), cond); + hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast(object), sizeof(T), cond); hasDragDrop = true; currentDragDropTag = type; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 46ffd3bf..ab844b88 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -264,14 +264,19 @@ namespace SHADE SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::TextLabel("Freeze Position"); + ImGui::PushID("FreezePos"); SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Freeze Position - X"); ImGui::SameLine(); SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Freeze Position - Y"); ImGui::SameLine(); SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Freeze Position - Z"); + ImGui::PopID(); + SHEditorWidgets::TextLabel("Freeze Rotation"); + ImGui::PushID("FreezeRot"); SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Freeze Rotation - X"); ImGui::SameLine(); SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Freeze Rotation - Y"); ImGui::SameLine(); SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Freeze Rotation - Z"); + ImGui::PopID(); SHEditorWidgets::EndPanel(); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 3a5a15b5..655ad68a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -21,6 +21,7 @@ #include "UI/SHUIComponent.h" #include "UI/SHCanvasComponent.h" #include "SHEditorComponentView.h" +#include "AudioSystem/SHAudioListenerComponent.h" namespace SHADE { @@ -130,7 +131,8 @@ namespace SHADE if (auto cameraComponent = SHComponentManager::GetComponent_s(eid)) { DrawComponent(cameraComponent); - }if (auto cameraArmComponent = SHComponentManager::GetComponent_s(eid)) + } + if (auto cameraArmComponent = SHComponentManager::GetComponent_s(eid)) { DrawComponent(cameraArmComponent); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 88de7b73..9dbb9542 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -172,17 +172,24 @@ namespace SHADE // Shader bool shaderChanged = false; - const auto* SHADER_INFO = SHAssetManager::GetData(currentMatSpec->fragShader); - const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader"; - ImGui::BeginDisabled(); + const auto* VERT_SHADER_INFO = SHAssetManager::GetData(currentMatSpec->vertexShader); + const std::string VERT_SHADER_NAME = VERT_SHADER_INFO ? VERT_SHADER_INFO->name : "Unknown Shader"; isDirty |= SHEditorWidgets::DragDropReadOnlyField ( - "Fragment Shader", SHADER_NAME.data(), + "Fragment Shader", VERT_SHADER_NAME.data(), + [this]() { return currentMatSpec->vertexShader; }, + [this](const AssetID& id) { currentMatSpec->vertexShader = id; }, + SHDragDrop::DRAG_RESOURCE + ); + const auto* FRAG_SHADER_INFO = SHAssetManager::GetData(currentMatSpec->fragShader); + const std::string FRAG_SHADER_NAME = FRAG_SHADER_INFO ? FRAG_SHADER_INFO->name : "Unknown Shader"; + isDirty |= SHEditorWidgets::DragDropReadOnlyField + ( + "Fragment Shader", FRAG_SHADER_NAME.data(), [this]() { return currentMatSpec->fragShader; }, [this](const AssetID& id) { currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE ); - ImGui::EndDisabled(); // Load the shader to access it's data auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 2a2b66d4..9b4b02b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -27,6 +27,8 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Scene/SHSceneManager.h" +#include "UI/SHUIComponent.h" namespace SHADE { @@ -49,7 +51,7 @@ namespace SHADE , referencedMatInstances { std::move(rhs.referencedMatInstances) } , matBufferDirty { std::move(rhs.matBufferDirty) } , subBatches { std::move(rhs.subBatches) } - , drawData { std::move(drawData) } + , drawData { std::move(rhs.drawData) } , transformData { std::move(rhs.transformData) } , instancedIntegerData { std::move(rhs.instancedIntegerData) } , matPropsData { std::move(rhs.matPropsData) } @@ -80,7 +82,7 @@ namespace SHADE referencedMatInstances = std::move(rhs.referencedMatInstances); matBufferDirty = std::move(rhs.matBufferDirty) ; subBatches = std::move(rhs.subBatches) ; - drawData = std::move(drawData) ; + drawData = std::move(rhs.drawData) ; transformData = std::move(rhs.transformData) ; instancedIntegerData = std::move(rhs.instancedIntegerData) ; matPropsData = std::move(rhs.matPropsData) ; @@ -218,9 +220,13 @@ namespace SHADE for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) { drawDataBuffer[i].Free(); + drawDataBuffer[i] = {}; transformDataBuffer[i].Free(); + transformDataBuffer[i] = {}; instancedIntegerBuffer[i].Free(); + instancedIntegerBuffer[i] = {}; matPropsBuffer[i].Free(); + matPropsBuffer[i] = {}; } } @@ -302,7 +308,28 @@ namespace SHADE auto transform = SHComponentManager::GetComponent(rendId); if (transform) { - transformData.emplace_back(transform->GetTRS()); + if (SHSceneManager::CheckNodeAndComponentsActive(rendId)) + { + auto uiComp = SHComponentManager::GetComponent_s(rendId); + if (uiComp) + { + transformData.emplace_back(uiComp->GetMatrix()); + } + else + transformData.emplace_back(transform->GetTRS()); + } + else + { + // Should be deactivated + static const SHMatrix ZERO_MTX = + { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }; + transformData.emplace_back(ZERO_MTX); + } } else { @@ -424,15 +451,30 @@ namespace SHADE for (auto rendId : subBatch.Renderables) { // Transform - auto transform = SHComponentManager::GetComponent_s(rendId); - if (!transform) + auto transform = SHComponentManager::GetComponent_s(rendId); + if (transform) { - SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); - transformData.emplace_back(); + if (SHSceneManager::CheckNodeAndComponentsActive(rendId)) + { + transformData.emplace_back(transform->GetTRS()); + } + else + { + // Should be deactivated + static const SHMatrix ZERO_MTX = + { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }; + transformData.emplace_back(ZERO_MTX); + } } else { - transformData.emplace_back(transform->GetTRS()); + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); } const SHRenderable* renderable = SHComponentManager::GetComponent(rendId); @@ -507,9 +549,13 @@ namespace SHADE return; } + // Nothing to draw + if (subBatches.empty()) + return; + // Bind all required objects before drawing static std::array dynamicOffset{ 0 }; - cmdBuffer->BeginLabeledSegment("SHBatch"); + cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index)); cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 6760d937..91728d71 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -55,13 +55,14 @@ namespace SHADE void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + Handle baseMat = renderable->GetMaterial()->GetBaseMaterial(); + const Handle PIPELINE = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); // Check if we have a Batch with the same pipeline yet auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); + { + return batch.GetPipeline() == PIPELINE; + }); // Attempt to remove if it exists if (batch == batches.end()) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 12f12c6a..3932298c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -119,6 +119,11 @@ namespace SHADE SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false); + SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false); + SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false); + SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false); + + SHAssetManager::CompileAsset("../../Assets/Models/Quad.gltf", false); // Load Built In Shaders static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet(VS_DEFAULT); @@ -181,7 +186,7 @@ namespace SHADE //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); worldRenderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); worldRenderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm); @@ -280,7 +285,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Initialize screen render graph screenRenderGraph = resourceManager.Create(); - screenRenderGraph->Init("Scene Render Graph", device, swapchain, &resourceManager); + screenRenderGraph->Init("Screen Render Graph", device, swapchain, &resourceManager); screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene"); screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Entity ID"); screenRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); @@ -576,7 +581,7 @@ namespace SHADE { auto editorSystem = SHSystemManager::GetSystem(); if (editorSystem->editorState != SHEditor::State::PLAY) - worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix()); + worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix(), cameraSystem->GetEditorCamera()->GetOrthoMatrix()); else renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); } @@ -966,7 +971,9 @@ namespace SHADE Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); if (prevMaterial) { - Handle oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + Handle baseMat = prevMaterial->GetBaseMaterial(); + Handle prevPipeline = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); + Handle oldSuperBatch = prevPipeline->GetPipelineState().GetSubpass()->GetSuperBatch(); oldSuperBatch->Remove(&renderable); } @@ -981,6 +988,14 @@ namespace SHADE // Unset change flag renderable.ResetChangedFlag(); } + + // Unset all material old pipeline since we would have finished processing + auto gfxSystem = reinterpret_cast(system); + auto [matBegin, matEnd] = gfxSystem->resourceManager.GetDenseAccess(); + for (auto iter = matBegin; iter != matEnd; ++iter) + { + iter->ForgetOldPipeline(); + } } #pragma endregion ROUTINES diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index 7ca7c394..1a007b95 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -21,6 +21,8 @@ namespace SHADE if (_pipeline == pipeline) return; + // Mark old pipeline and set new pipeline + oldPipeline = pipeline; pipeline = _pipeline; // Set up properties based on the pipeline @@ -41,9 +43,6 @@ namespace SHADE // Reset since pipeline changed ResetProperties(); - - // Mark changed so that we know to update dependent material instances - propertiesChanged = true; } Handle SHMaterial::GetPipeline() const @@ -111,4 +110,9 @@ namespace SHADE { propertiesChanged = false; } + + void SHMaterial::ForgetOldPipeline() noexcept + { + oldPipeline = {}; + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index c75692f2..7913d912 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -44,6 +44,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void SetPipeline(Handle _pipeline); Handle GetPipeline() const; + Handle GetPrevPipeline() const { return oldPipeline; }; /*-----------------------------------------------------------------------------*/ /* Property Functions */ @@ -68,10 +69,11 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------*/ Handle GetShaderBlockInterface() const noexcept; - bool HasPipelineChanged() const noexcept { return pipelineChanged; } + bool HasPipelineChanged() const noexcept { return oldPipeline; } bool HasPropertiesChanged() const noexcept { return propertiesChanged; } - bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; } + bool HasChanged() const noexcept { return oldPipeline || propertiesChanged; } void ClearChangeFlag() noexcept; + void ForgetOldPipeline() noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -81,7 +83,7 @@ namespace SHADE std::unique_ptr propMemory; Byte propMemorySize = 0; bool propertiesChanged = true; - bool pipelineChanged = true; + Handle oldPipeline; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 55b52645..e47055df 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -90,13 +90,13 @@ namespace SHADE if (camera && cameraDirector) { //UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix())); - UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix()); + UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix(), cameraDirector->GetOrthoMatrix()); } } - void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept + void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept { - SetViewProjectionMatrix(viewMatrix, projMatrix); + SetViewProjectionMatrix(viewMatrix, projMatrix, orthoMatrix); //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); @@ -116,12 +116,13 @@ namespace SHADE { } - void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept + void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept { //cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix(); cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix); cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix); cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix); + cpuCameraData.orthoMatrix = SHMatrix::Transpose (orthoMatrix); } Handle SHRenderer::GetRenderGraph(void) const noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index c6146a56..83291700 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -48,6 +48,7 @@ namespace SHADE SHMatrix viewProjectionMatrix; SHMatrix viewMatrix; SHMatrix projectionMatrix; + SHMatrix orthoMatrix; }; /*---------------------------------------------------------------------------------*/ @@ -82,10 +83,10 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void Draw(uint32_t frameIndex, Handle descPool) noexcept; void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept; - void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept; + void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept; void BindDescSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; void UpdateCameraDataToBuffer (void) noexcept; - void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept; + void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp index 7d8e2b44..3dd54ca5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp @@ -65,7 +65,7 @@ namespace SHADE // allocate GPU buffer for matrices matrixDataBuffer = logicalDevice->CreateBuffer(glyphDataSize, fontAsset.glyphTransformations.data(), glyphDataSize, vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, {}); - + sampler = logicalDevice->CreateSampler(SHVkSamplerParams{}); } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index 3a405e0d..040433cb 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -129,7 +129,7 @@ namespace SHADE // Otherwise just copy the data over else { - bufferHandle->MapWriteUnmap(src, size, 0, 0); + bufferHandle->WriteToMemory(src, size, 0, 0); } } else diff --git a/SHADE_Engine/src/Math/SHRay.cpp b/SHADE_Engine/src/Math/SHRay.cpp index 87f12b81..c4931aba 100644 --- a/SHADE_Engine/src/Math/SHRay.cpp +++ b/SHADE_Engine/src/Math/SHRay.cpp @@ -30,11 +30,17 @@ namespace SHADE , direction { dir } {} + SHRay::SHRay(const reactphysics3d::Ray rp3dRay) noexcept + : position { rp3dRay.point1 } + , direction { SHVec3::Normalise(rp3dRay.point2 - rp3dRay.point1) } + {} + + /*-----------------------------------------------------------------------------------*/ /* Operator Overload Definitions */ /*-----------------------------------------------------------------------------------*/ - bool SHRay::operator==(const SHRay& rhs) noexcept + bool SHRay::operator==(const SHRay& rhs) const noexcept { const XMVECTOR LHS_POS = XMLoadFloat3(&position); const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position); @@ -45,7 +51,7 @@ namespace SHADE return XMVector3Equal(LHS_POS, RHS_POS) && XMVector3NotEqual(LHS_DIR, RHS_DIR); } - bool SHRay::operator!=(const SHRay& rhs) noexcept + bool SHRay::operator!=(const SHRay& rhs) const noexcept { const XMVECTOR LHS_POS = XMLoadFloat3(&position); const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position); @@ -56,5 +62,16 @@ namespace SHADE return XMVector3NotEqual(LHS_POS, RHS_POS) || XMVector3NotEqual(LHS_DIR, RHS_DIR); } + SHRay::operator reactphysics3d::Ray() const noexcept + { + // We use 2km. Temp solution. + return reactphysics3d::Ray{ position, position + (direction * MAX_RAYCAST_DIST) }; + } + + SHRaycastResult::operator bool() const noexcept + { + return hit; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHRay.h b/SHADE_Engine/src/Math/SHRay.h index 29d55b16..18efc224 100644 --- a/SHADE_Engine/src/Math/SHRay.h +++ b/SHADE_Engine/src/Math/SHRay.h @@ -1,7 +1,7 @@ /**************************************************************************************** * \file SHRay.h * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Interface for a Ray. + * \brief Interface for a Ray & Raycast Result * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -10,7 +10,7 @@ #pragma once -#include +#include // Project Headers #include "SH_API.h" @@ -29,6 +29,8 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ + static constexpr float MAX_RAYCAST_DIST = 2000.0f; // We use 2km as physics typically tends to lose accuracy beyond 2km. + SHVec3 position; SHVec3 direction; @@ -36,19 +38,46 @@ namespace SHADE /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHRay() noexcept; - SHRay(const SHVec3& pos, const SHVec3& dir) noexcept; - SHRay(const SHRay& rhs) noexcept = default; - SHRay(SHRay&& rhs) noexcept = default; + SHRay () noexcept; + SHRay (const SHVec3& pos, const SHVec3& dir) noexcept; + SHRay (const reactphysics3d::Ray rp3dRay) noexcept; + + SHRay (const SHRay&) noexcept = default; + SHRay (SHRay&& ) noexcept = default; + ~SHRay() = default; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ /*---------------------------------------------------------------------------------*/ - SHRay& operator= (const SHRay& rhs) noexcept = default; - SHRay& operator= (SHRay&& rhs) noexcept = default; + SHRay& operator= (const SHRay&) noexcept = default; + SHRay& operator= (SHRay&&) noexcept = default; + + [[nodiscard]] bool operator==(const SHRay& rhs) const noexcept; + [[nodiscard]] bool operator!=(const SHRay& rhs) const noexcept; + + operator reactphysics3d::Ray() const noexcept; + }; + + struct SH_API SHRaycastResult + { + public: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + bool hit = false; + float distance = std::numeric_limits::infinity(); + float angle = 0.0f; + + SHVec3 position; + SHVec3 normal; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + operator bool() const noexcept; - [[nodiscard]] bool operator==(const SHRay& rhs) noexcept; - [[nodiscard]] bool operator!=(const SHRay& rhs) noexcept; }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.h b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.h index 6262b946..62882556 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionListener.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionListener.h @@ -32,7 +32,6 @@ namespace SHADE class SH_API SHCollisionListener final : public rp3d::EventListener { public: - /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycastResult.h b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycastResult.h new file mode 100644 index 00000000..cce01845 --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycastResult.h @@ -0,0 +1,34 @@ +/**************************************************************************************** + * \file SHPhysicsRaycastResult.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Physics Raycast Result + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Includes +#include "ECS_Base/SHECSMacros.h" +#include "Math/SHRay.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + struct SH_API SHPhysicsRaycastResult : public SHRaycastResult + { + public: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + EntityID entityHit = MAX_EID; + int shapeIndex = -1; + + }; +} diff --git a/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.cpp b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.cpp new file mode 100644 index 00000000..11b9fcab --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.cpp @@ -0,0 +1,350 @@ +/**************************************************************************************** + * \file SHPhysicsRaycaster.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Physics Raycaster. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHPhysicsRaycaster.h" + +/* + * TODO(DIREN): + * Once the physics engine has been rebuilt, this whole implementation should change + * and just call PhysicsWorld.Raycast etc. + * + * SHRaycastResult can be converted to a bool when necessary. + */ + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsRaycaster::SHPhysicsRaycaster() noexcept + : world { nullptr } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const SHPhysicsRaycaster::RaycastPairs& SHPhysicsRaycaster::GetRaycasts() const noexcept + { + return raycasts; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsRaycaster::SetObjectManager(SHPhysicsObjectManager* physicsObjectManager) noexcept + { + objectManager = physicsObjectManager; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsRaycaster::BindToWorld(rp3d::PhysicsWorld* physicsWorld) noexcept + { + world = physicsWorld; + } + + void SHPhysicsRaycaster::ClearFrame() noexcept + { + raycasts.clear(); + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::Raycast(const SHRay& ray, float distance) noexcept + { + // Reset temp + temp = SHPhysicsRaycastResult{}; + temp.distance = distance; + + if (!world) + { + SHLOG_ERROR("Physics world missing for raycasting!") + return temp; + } + + // If distance in infinity, cast to the default max distance of 2 km. + if (distance == std::numeric_limits::infinity()) + { + world->raycast(ray, this); + } + else + { + const SHVec3 END_POINT = ray.position + ray.direction * distance; + const rp3d::Ray RP3D_RAY{ ray.position, END_POINT }; + world->raycast(RP3D_RAY, this); + } + + // If a hit was found, populate temp info for return. + if (temp.hit) + { + temp.distance = SHVec3::Distance(ray.position, temp.position); + temp.angle = SHVec3::Angle(ray.position, temp.position); + } + + raycasts.emplace_back(ray, temp); + return temp; + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::Linecast(const SHVec3& start, const SHVec3& end) noexcept + { + temp = SHPhysicsRaycastResult{}; + temp.distance = SHVec3::Distance(start, end); + + if (!world) + { + SHLOG_ERROR("Physics world missing for raycasting!") + return temp; + } + + const rp3d::Ray RP3D_RAY{ start, end }; + world->raycast(RP3D_RAY, this); + + if (temp.hit) + { + temp.distance = SHVec3::Distance(start, temp.position); + temp.angle = SHVec3::Angle(start, temp.position); + } + + raycasts.emplace_back(RP3D_RAY, temp); + return temp; + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::ColliderRaycast(EntityID eid, const SHRay& ray, float distance) noexcept + { + SHPhysicsRaycastResult result; + result.distance = distance; + + // Get a valid physics object with at least 1 collider. + const auto* PHYSICS_OBJECT = validateColliderRaycast(eid); + if (!PHYSICS_OBJECT) + return result; + + auto* rp3dBody = PHYSICS_OBJECT->GetCollisionBody(); + + // Data to populate + rp3d::RaycastInfo rp3dRaycastInfo; + bool hit = false; + + if (distance == std::numeric_limits::infinity()) + { + hit = rp3dBody->raycast(ray, rp3dRaycastInfo); + } + else + { + const SHVec3 END_POINT = ray.position + ray.direction * distance; + const rp3d::Ray RP3D_RAY{ ray.position, END_POINT }; + hit = rp3dBody->raycast(RP3D_RAY, rp3dRaycastInfo); + } + + if (hit) + { + result.hit = true; + result.position = rp3dRaycastInfo.worldPoint; + result.normal = rp3dRaycastInfo.worldPoint; + result.distance = SHVec3::Distance(ray.position, result.position); + result.angle = SHVec3::Angle(ray.position, result.position); + result.entityHit = eid; + result.shapeIndex = findColliderIndex(rp3dBody, rp3dRaycastInfo.collider->getEntity()); + } + + raycasts.emplace_back(ray, result); + return result; + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::ColliderRaycast(EntityID eid, int shapeIndex, const SHRay& ray, float distance) noexcept + { + SHPhysicsRaycastResult result; + result.distance = distance; + + // Get a valid physics object with at least 1 collider. + const auto* PHYSICS_OBJECT = validateColliderRaycast(eid); + if (!PHYSICS_OBJECT) + return result; + + // Boundary check for shape index + if (shapeIndex < 0 || shapeIndex >= static_cast(PHYSICS_OBJECT->GetCollisionBody()->getNbColliders())) + { + SHLOGV_WARNING("Invalid collision shape index passed in") + return result; + } + + auto* rp3dCollider = PHYSICS_OBJECT->GetCollisionBody()->getCollider(shapeIndex); + + rp3d::RaycastInfo rp3dRaycastInfo; + bool hit = false; + if (distance == std::numeric_limits::infinity()) + { + hit = rp3dCollider->raycast(ray, rp3dRaycastInfo); + } + else + { + const SHVec3 END_POINT = ray.position + ray.direction * distance; + const rp3d::Ray RP3D_RAY{ ray.position, END_POINT }; + hit = rp3dCollider->raycast(RP3D_RAY, rp3dRaycastInfo); + } + + if (hit) + { + result.hit = true; + result.position = rp3dRaycastInfo.worldPoint; + result.normal = rp3dRaycastInfo.worldPoint; + result.distance = SHVec3::Distance(ray.position, result.position); + result.angle = SHVec3::Angle(ray.position, result.position); + result.entityHit = eid; + result.shapeIndex = shapeIndex; + } + + raycasts.emplace_back(ray, result); + return result; + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::ColliderLinecast(EntityID eid, const SHVec3& start, const SHVec3& end) noexcept + { + SHPhysicsRaycastResult result; + result.distance = SHVec3::Distance(start, end); + + const auto* PHYSICS_OBJECT = validateColliderRaycast(eid); + if (!PHYSICS_OBJECT) + return result; + + auto* rp3dBody = PHYSICS_OBJECT->GetCollisionBody(); + + rp3d::RaycastInfo rp3dRaycastInfo; + + const rp3d::Ray RP3D_RAY{ start, end }; + if (rp3dBody->raycast(RP3D_RAY, rp3dRaycastInfo)) + { + result.hit = true; + result.position = rp3dRaycastInfo.worldPoint; + result.normal = rp3dRaycastInfo.worldPoint; + result.distance = SHVec3::Distance(start, result.position); + result.angle = SHVec3::Angle(end, result.position); + result.entityHit = eid; + result.shapeIndex = findColliderIndex(rp3dBody, rp3dRaycastInfo.collider->getEntity()); + } + + raycasts.emplace_back(RP3D_RAY, result); + return result; + } + + SHPhysicsRaycastResult SHPhysicsRaycaster::ColliderLinecast(EntityID eid, int shapeIndex, const SHVec3& start, const SHVec3& end) noexcept + { + SHPhysicsRaycastResult result; + result.distance = SHVec3::Distance(start, end); + + const auto* PHYSICS_OBJECT = validateColliderRaycast(eid); + if (!PHYSICS_OBJECT) + return result; + + if (shapeIndex < 0 || shapeIndex >= static_cast(PHYSICS_OBJECT->GetCollisionBody()->getNbColliders())) + { + SHLOGV_WARNING("Invalid collision shape index passed in") + return result; + } + + auto* rp3dCollider = PHYSICS_OBJECT->GetCollisionBody()->getCollider(shapeIndex); + + rp3d::RaycastInfo rp3dRaycastInfo; + + const rp3d::Ray RP3D_RAY{ start, end }; + if (rp3dCollider->raycast(RP3D_RAY, rp3dRaycastInfo)) + { + result.hit = true; + result.position = rp3dRaycastInfo.worldPoint; + result.normal = rp3dRaycastInfo.worldPoint; + result.distance = SHVec3::Distance(start, result.position); + result.angle = SHVec3::Angle(end, result.position); + result.entityHit = eid; + result.shapeIndex = shapeIndex; + } + + raycasts.emplace_back(RP3D_RAY, result); + return result; + } + + rp3d::decimal SHPhysicsRaycaster::notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) + { + temp.hit = true; + temp.position = raycastInfo.worldPoint; + temp.normal = raycastInfo.worldNormal; + + if (!objectManager) + { + SHLOGV_ERROR("No physics object manager linked with raycaster to match bodies") + return 0.0f; + } + + // Compare body IDs to find the matching physics object + const auto HIT_BODY_EID = raycastInfo.body->getEntity(); + + for (const auto& [entityID, physicsObject] : objectManager->GetPhysicsObjects()) + { + const auto RP3D_BODY = physicsObject.GetCollisionBody(); + + // Match rp3d bodies + if (RP3D_BODY->getEntity() != HIT_BODY_EID) + continue; + + temp.entityHit = entityID; + + // Find collider index + if (const int INDEX = findColliderIndex(RP3D_BODY, raycastInfo.collider->getEntity()); INDEX > -1) + { + temp.shapeIndex = INDEX; + break; + } + } + + return 0.0f; + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject* SHPhysicsRaycaster::validateColliderRaycast(EntityID eid) noexcept + { + if (!objectManager) + { + SHLOGV_ERROR("No physics object manager linked with raycaster to match bodies") + return nullptr; + } + + auto* physicsObject = objectManager->GetPhysicsObject(eid); + if (!physicsObject || physicsObject->GetCollisionBody()->getNbColliders() == 0) + { + SHLOGV_WARNING("Cannot cast ray at an entity without colliders!") + return nullptr; + } + + return physicsObject; + } + + int SHPhysicsRaycaster::findColliderIndex(const rp3d::CollisionBody* rp3dBody, rp3d::Entity rp3dColliderEID) noexcept + { + const int NUM_COLLISION_SHAPES = static_cast(rp3dBody->getNbColliders()); + for (int i = 0; i < NUM_COLLISION_SHAPES; ++i) + { + const auto COLLIDER_EID = rp3dBody->getCollider(i)->getEntity(); + if (COLLIDER_EID == rp3dColliderEID) + return i; + } + + return -1; + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.h b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.h new file mode 100644 index 00000000..81165b56 --- /dev/null +++ b/SHADE_Engine/src/Physics/Collision/SHPhysicsRaycaster.h @@ -0,0 +1,131 @@ +/**************************************************************************************** + * \file SHPhysicsRaycaster.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Physics Raycaster. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +#include + +// Project Headers +#include "Math/SHRay.h" +#include "Physics/PhysicsObject/SHPhysicsObjectManager.h" +#include "Physics/SHPhysicsWorld.h" +#include "SH_API.h" +#include "SHPhysicsRaycastResult.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHPhysicsRaycaster : public reactphysics3d::RaycastCallback + { + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + using RaycastPair = std::pair; + using RaycastPairs = std::vector; + + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsRaycaster() noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] const RaycastPairs& GetRaycasts() const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetObjectManager(SHPhysicsObjectManager* physicsObjectManager) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void BindToWorld (rp3d::PhysicsWorld* physicsWorld) noexcept; + void ClearFrame () noexcept; + + // TODO(Diren): Filtering, return all shades ray hits + + SHPhysicsRaycastResult Raycast + ( + const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + SHPhysicsRaycastResult Linecast + ( + const SHVec3& start + , const SHVec3& end + ) noexcept; + + SHPhysicsRaycastResult ColliderRaycast + ( + EntityID eid + , const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + SHPhysicsRaycastResult ColliderRaycast + ( + EntityID eid + , int shapeIndex + , const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + SHPhysicsRaycastResult ColliderLinecast + ( + EntityID eid + , const SHVec3& start + , const SHVec3& end + ) noexcept; + + SHPhysicsRaycastResult ColliderLinecast + ( + EntityID eid + , int shapeIndex + , const SHVec3& start + , const SHVec3& end + ) noexcept; + + rp3d::decimal notifyRaycastHit(const rp3d::RaycastInfo& raycastInfo) override; + + private: + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + rp3d::PhysicsWorld* world; + SHPhysicsObjectManager* objectManager; // For + SHPhysicsRaycastResult temp; // Holds the temporary result after casting into the world + RaycastPairs raycasts; // Used for debug drawing + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsObject* validateColliderRaycast (EntityID eid) noexcept; + static int findColliderIndex (const rp3d::CollisionBody* rp3dBody, rp3d::Entity rp3dColliderEID) noexcept; + }; + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 0a0ff201..3cfa3ec9 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -294,7 +294,7 @@ namespace SHADE if (!rp3dBody->isActive()) return; - const int NUM_SHAPES = static_cast(component.collisionShapes.size()); + const int NUM_SHAPES = static_cast(rp3dBody->getNbColliders()); for (int i = 0; i < NUM_SHAPES; ++i) { auto& collisionShape = component.collisionShapes[i]; diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp index ffd10e0c..389983c3 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp @@ -23,11 +23,10 @@ namespace SHADE /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[2][3] + SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[3][2] { - addRigidBody , addCollider - , removeRigidBody , removeCollider - , addCollisionShape , removeCollisionShape + addRigidBody , addCollider , addCollisionShape + , removeRigidBody , removeCollider , removeCollisionShape }; /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h index 641fd9df..f41c62ad 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h @@ -150,7 +150,7 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - static CommandFunctionPtr componentFunc[2][3]; // 2 commands, 3 components + static CommandFunctionPtr componentFunc[3][2]; // 3 components, 2 commands rp3d::PhysicsCommon* factory = nullptr; rp3d::PhysicsWorld* world = nullptr; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp index 7ccfb225..bf1debac 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.cpp @@ -15,7 +15,6 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" -#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Scene/SHSceneManager.h" namespace SHADE @@ -26,11 +25,12 @@ namespace SHADE const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[NUM_FLAGS] = { - SHPhysicsDebugDrawSystem::drawColliders - , SHPhysicsDebugDrawSystem::drawColliderAABBs - , SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs - , SHPhysicsDebugDrawSystem::drawContactPoints - , SHPhysicsDebugDrawSystem::drawContactNormals + drawColliders + , drawColliderAABBs + , drawBroadPhaseAABBs + , drawContactPoints + , drawContactNormals + , drawRaycasts }; SHVec3 SHPhysicsDebugDrawSystem::boxVertices[NUM_BOX_VERTICES]; @@ -42,13 +42,13 @@ namespace SHADE SHPhysicsDebugDrawSystem::SHPhysicsDebugDrawSystem() noexcept : debugDrawFlags { 0 } , physicsSystem { nullptr } - , rp3dDebugRenderer { nullptr } { debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = SHColour::GREEN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB)] = SHColour::YELLOW; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB)] = SHColour::CYAN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS)] = SHColour::RED; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_NORMALS)] = SHColour::RED; + debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::RAYCASTS)] = SHColour::ORANGE; } SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine::PhysicsDebugDrawRoutine() @@ -111,19 +111,30 @@ namespace SHADE { auto* system = reinterpret_cast(GetSystem()); + auto* debugDrawSystem = SHSystemManager::GetSystem(); + if (debugDrawSystem == nullptr) + { + SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!") + return; + } + for (int i = 0; i < SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); ++i) { const bool DRAW = (system->debugDrawFlags & (1U << i)) > 0; if (DRAW) - drawFunctions[i](system->rp3dDebugRenderer); + drawFunctions[i](debugDrawSystem); } + + // Automatically clear the container of raycasts despite debug drawing state + // TODO(Diren): Move this somewhere else + system->physicsSystem->raycaster.ClearFrame(); } /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsDebugDrawSystem::drawColliders(rp3d::DebugRenderer* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawColliders(SHDebugDrawSystem* debugRenderer) noexcept { const auto& COLLIDER_SET = SHComponentManager::GetDense(); for (const auto& COLLIDER : COLLIDER_SET) @@ -136,34 +147,58 @@ namespace SHADE { switch (collisionShape.GetType()) { - case SHCollisionShape::Type::BOX: debugDrawBox(COLLIDER, collisionShape); break; - case SHCollisionShape::Type::SPHERE: debugDrawSphere(COLLIDER, collisionShape); break; + case SHCollisionShape::Type::BOX: debugDrawBox(debugRenderer, COLLIDER, collisionShape); break; + case SHCollisionShape::Type::SPHERE: debugDrawSphere(debugRenderer, COLLIDER, collisionShape); break; default: break; } } } } - void SHPhysicsDebugDrawSystem::drawColliderAABBs(rp3d::DebugRenderer* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawColliderAABBs(SHDebugDrawSystem* debugRenderer) noexcept { } - void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(rp3d::DebugRenderer* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawBroadPhaseAABBs(SHDebugDrawSystem* debugRenderer) noexcept { } - void SHPhysicsDebugDrawSystem::drawContactPoints(rp3d::DebugRenderer* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawContactPoints(SHDebugDrawSystem* debugRenderer) noexcept { } - void SHPhysicsDebugDrawSystem::drawContactNormals(rp3d::DebugRenderer* debugRenderer) noexcept + void SHPhysicsDebugDrawSystem::drawContactNormals(SHDebugDrawSystem* debugRenderer) noexcept { } + void SHPhysicsDebugDrawSystem::drawRaycasts(SHDebugDrawSystem* debugRenderer) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (!physicsSystem) + { + SHLOG_ERROR("Unable to retrieve physics system for debug drawing raycasts!") + return; + } + + const SHColour& RAY_COLOUR = SHColour::ORANGE; + + // Draw all raycast pairs + for (const auto& [ray, raycastResult] : physicsSystem->raycaster.GetRaycasts()) + { + // If infinity, it is an infinite raycast. If not, render the distance in raycastResult. + // Ignore the hit variable as it will always correspond to the length of the raycast, hit or miss. + const float RENDER_DIST = raycastResult.distance == std::numeric_limits::infinity() ? SHRay::MAX_RAYCAST_DIST : raycastResult.distance; + const SHVec3 END_POS = ray.position + (ray.direction * RENDER_DIST); + + debugRenderer->DrawLine(RAY_COLOUR, ray.position, END_POS); + } + } + + void SHPhysicsDebugDrawSystem::generateBox() noexcept { boxVertices[0] = { 0.5f, 0.5f, -0.5f }; // TOP_RIGHT_BACK @@ -176,15 +211,8 @@ namespace SHADE boxVertices[7] = { -0.5f, -0.5f, 0.5f }; // BTM_LEFT_FRONT } - void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept + void SHPhysicsDebugDrawSystem::debugDrawBox(SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept { - auto* debugDrawSystem = SHSystemManager::GetSystem(); - if (debugDrawSystem == nullptr) - { - SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!") - return; - } - auto* BOX = reinterpret_cast(collisionShape.GetShape()); // Calculate final position & orientation @@ -211,27 +239,20 @@ namespace SHADE transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS); // Draw 4 line to connect the quads - debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); + debugRenderer->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); } // A, B, C, D std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] }; - debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); + debugRenderer->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); // E, F, G, H std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] }; - debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); + debugRenderer->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); } - void SHPhysicsDebugDrawSystem::debugDrawSphere(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept + void SHPhysicsDebugDrawSystem::debugDrawSphere(SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept { - auto* debugDrawSystem = SHSystemManager::GetSystem(); - if (debugDrawSystem == nullptr) - { - SHLOG_ERROR("Unable to get a debug draw system for Physics Debug Drawing!") - return; - } - auto* SPHERE = reinterpret_cast(collisionShape.GetShape()); const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; @@ -240,7 +261,7 @@ namespace SHADE const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition()); - debugDrawSystem->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius()); + debugRenderer->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius()); } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h index 149ed6c1..867a6e11 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsDebugDrawSystem.h @@ -14,6 +14,7 @@ // Project Headers #include "ECS_Base/System/SHSystemRoutine.h" +#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Math/SHColour.h" #include "SHPhysicsSystem.h" #include "Tools/Utilities/SHUtilities.h" @@ -38,6 +39,7 @@ namespace SHADE , BROAD_PHASE_AABB , CONTACT_POINTS , CONTACT_NORMALS + , RAYCASTS , NUM_FLAGS }; @@ -91,7 +93,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using DebugDrawFunction = void(*)(rp3d::DebugRenderer*) noexcept; + using DebugDrawFunction = void(*)(SHDebugDrawSystem*) noexcept; /*---------------------------------------------------------------------------------*/ /* Data Members */ @@ -108,7 +110,6 @@ namespace SHADE uint8_t debugDrawFlags; SHPhysicsSystem* physicsSystem; - rp3d::DebugRenderer* rp3dDebugRenderer; SHColour debugColours[NUM_FLAGS]; /*---------------------------------------------------------------------------------*/ @@ -117,11 +118,12 @@ namespace SHADE // Generic Draw Functions - static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept; - static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; - static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; - static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept; - static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept; + static void drawColliders (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawColliderAABBs (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawBroadPhaseAABBs (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawContactPoints (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawContactNormals (SHDebugDrawSystem* debugRenderer) noexcept; + static void drawRaycasts (SHDebugDrawSystem* debugRenderer) noexcept; // Shape Generation Functions @@ -129,8 +131,8 @@ namespace SHADE // Shape Draw Functions - static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; - static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; + static void debugDrawBox (SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; + static void debugDrawSphere (SHDebugDrawSystem* debugRenderer, const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; }; } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 50590e04..f3513ffb 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -22,10 +22,6 @@ #include "Scene/SHSceneManager.h" #include "Scripting/SHScriptEngine.h" -/*-------------------------------------------------------------------------------------*/ -/* Local Helper Functions */ -/*-------------------------------------------------------------------------------------*/ - namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -115,8 +111,9 @@ namespace SHADE SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR); #endif - // Link Physics Object Manager with System + // Link Physics Object Manager with System & Raycaster objectManager.SetFactory(factory); + raycaster.SetObjectManager(&objectManager); // Link Collision Listener with System collisionListener.BindToSystem(this); @@ -183,6 +180,35 @@ namespace SHADE } } + SHPhysicsRaycastResult SHPhysicsSystem::Raycast(const SHRay& ray, float distance) noexcept + { + return raycaster.Raycast(ray, distance); + } + + SHPhysicsRaycastResult SHPhysicsSystem::Linecast(const SHVec3& start, const SHVec3& end) noexcept + { + return raycaster.Linecast(start, end); + } + + SHPhysicsRaycastResult SHPhysicsSystem::ColliderRaycast(EntityID eid, const SHRay& ray, float distance) noexcept + { + return raycaster.ColliderRaycast(eid, ray, distance); + } + + SHPhysicsRaycastResult SHPhysicsSystem::ColliderRaycast(EntityID eid, int shapeIndex, const SHRay& ray, float distance) noexcept + { + return raycaster.ColliderRaycast(eid, shapeIndex, ray, distance); + } + + SHPhysicsRaycastResult SHPhysicsSystem::ColliderLinecast(EntityID eid, const SHVec3& start, const SHVec3& end) noexcept + { + return raycaster.ColliderLinecast(eid, start, end); + } + + SHPhysicsRaycastResult SHPhysicsSystem::ColliderLinecast(EntityID eid, int shapeIndex, const SHVec3& start, const SHVec3& end) noexcept + { + return raycaster.ColliderLinecast(eid, shapeIndex, start, end); + } void SHPhysicsSystem::AddCollisionShape(EntityID eid, int shapeIndex) { @@ -325,10 +351,14 @@ namespace SHADE //////////////////////////////// // Create physics world + if (worldState.world != nullptr) + return onPlayEvent->handle; + worldState.CreateWorld(factory); - // Link Collision Listener + // Link Collision Listener & Raycaster collisionListener.BindToWorld(worldState.world); + raycaster.BindToWorld(worldState.world); // Link with object manager & create all physics objects objectManager.SetWorld(worldState.world); diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 9638e05c..f92be4cd 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -21,11 +21,11 @@ #include "ECS_Base/System/SHFixedSystemRoutine.h" #include "Math/Transform/SHTransformComponent.h" - #include "Physics/Collision/SHCollisionListener.h" +#include "Physics/Collision/SHPhysicsRaycaster.h" #include "Physics/Interface/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" -#include "Physics/PhysicsObject//SHPhysicsObjectManager.h" +#include "Physics/PhysicsObject/SHPhysicsObjectManager.h" #include "Physics/SHPhysicsWorld.h" @@ -79,6 +79,90 @@ namespace SHADE void ForceUpdate (); + /** + * @brief Casts a ray into the world. + * @param ray The ray to cast. + * @param distance The distance to cast the ray. Defaults to infinity. + * @return The result of the raycast. + */ + SHPhysicsRaycastResult Raycast + ( + const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + /** + * @brief Casts a bounded ray into the world. + * @param start The starting point of the ray. + * @param end The end point of the ray. + * @return The result of the raycast. + */ + SHPhysicsRaycastResult Linecast + ( + const SHVec3& start + , const SHVec3& end + ) noexcept; + + /** + * @brief Casts a ray at a body with colliders. + * @param eid The entity to cast to. + * @param ray The ray to cast. + * @param distance The distance to cast the ray. Defaults to infinity. + * @return The result of the raycast. + */ + SHPhysicsRaycastResult ColliderRaycast + ( + EntityID eid + , const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + /** + * @brief Casts a ray at a collider. + * @param eid The entity to cast to. + * @param shapeIndex The index of the collision shape. + * @param ray The ray to cast. + * @param distance The distance to cast the ray. Defaults to infinity. + * @return The result of the raycast. + */ + SHPhysicsRaycastResult ColliderRaycast + ( + EntityID eid + , int shapeIndex + , const SHRay& ray + , float distance = std::numeric_limits::infinity() + ) noexcept; + + /** + * @brief Casts a bounded ray at a body with colliders. + * @param eid + * @param start + * @param end + * @return The result of the raycast. + */ + SHPhysicsRaycastResult ColliderLinecast + ( + EntityID eid + , const SHVec3& start + , const SHVec3& end + ) noexcept; + + /** + * @brief + * @param eid + * @param shapeIndex + * @param start + * @param end + * @return The result of the raycast. + */ + SHPhysicsRaycastResult ColliderLinecast + ( + EntityID eid + , int shapeIndex + , const SHVec3& start + , const SHVec3& end + ) noexcept; + // Specific Handling for Collision Shapes as they are not under the Component System. // This is done as events need to be sent out. // TODO(Diren): Consider using a static method through the ColliderComponent. @@ -190,6 +274,7 @@ namespace SHADE SHPhysicsWorldState worldState; SHPhysicsObjectManager objectManager; SHCollisionListener collisionListener; + SHPhysicsRaycaster raycaster; /*---------------------------------------------------------------------------------*/ /* Function Members */ diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.cpp index b142d54c..a028ffb5 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.cpp @@ -33,7 +33,7 @@ namespace SHADE return phySystem->GetAllCollisionInfo(); } - SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get collision events. Empty vector returned instead."); + SHLOGV_WARNING("Failed to get collision events. Empty vector returned instead."); return emptyVec; } const std::vector& SHPhysicsSystemInterface::GetTriggerInfo() noexcept @@ -46,7 +46,7 @@ namespace SHADE return phySystem->GetAllTriggerInfo(); } - SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get trigger events. Empty vector returned instead."); + SHLOGV_WARNING("Failed to get trigger events. Empty vector returned instead."); return emptyVec; } @@ -58,7 +58,79 @@ namespace SHADE return phySystem->GetFixedUpdateRate(); } - SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get fixed delta time. 0.0 returned instead."); + SHLOGV_WARNING("Failed to get fixed delta time. 0.0 returned instead."); return 0.0; } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::Raycast(const SHRay& ray, float distance) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->Raycast(ray, distance); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::Linecast(const SHVec3& start, const SHVec3& end) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->Linecast(start, end); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::ColliderRaycast(EntityID eid, const SHRay& ray, float distance) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->ColliderRaycast(eid, ray, distance); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::ColliderRaycast(EntityID eid, int shapeIndex, const SHRay& ray, float distance) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->ColliderRaycast(eid, shapeIndex, ray, distance); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::ColliderLinecast(EntityID eid, const SHVec3& start, const SHVec3& end) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->ColliderLinecast(eid, start, end); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } + + SHPhysicsRaycastResult SHPhysicsSystemInterface::ColliderLinecast(EntityID eid, int shapeIndex, const SHVec3& start, const SHVec3& end) noexcept + { + auto* physicsSystem = SHSystemManager::GetSystem(); + if (physicsSystem) + { + return physicsSystem->ColliderLinecast(eid, shapeIndex, start, end); + } + + SHLOGV_WARNING("Failed to get the physics system. No ray was casted."); + return SHPhysicsRaycastResult{}; + } } diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.h index bdd04686..0065aee3 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemInterface.h @@ -14,12 +14,21 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include +// Project Headers +#include "ECS_Base/Entity/SHEntity.h" + + namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Forward Declarations */ /*-----------------------------------------------------------------------------------*/ - class SHCollisionInfo; + + class SHCollisionInfo; + class SHVec3; + struct SHRay; + struct SHPhysicsRaycastResult; + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -39,8 +48,16 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Static Usage Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] static const std::vector& GetCollisionInfo() noexcept; - [[nodiscard]] static const std::vector& GetTriggerInfo() noexcept; - [[nodiscard]] static double GetFixedDT() noexcept; + + [[nodiscard]] static const std::vector& GetCollisionInfo() noexcept; + [[nodiscard]] static const std::vector& GetTriggerInfo () noexcept; + [[nodiscard]] static double GetFixedDT () noexcept; + + [[nodiscard]] static SHPhysicsRaycastResult Raycast (const SHRay& ray, float distance = std::numeric_limits::infinity()) noexcept; + [[nodiscard]] static SHPhysicsRaycastResult Linecast (const SHVec3& start, const SHVec3& end) noexcept; + [[nodiscard]] static SHPhysicsRaycastResult ColliderRaycast (EntityID eid, const SHRay& ray, float distance = std::numeric_limits::infinity()) noexcept; + [[nodiscard]] static SHPhysicsRaycastResult ColliderRaycast (EntityID eid, int shapeIndex, const SHRay& ray, float distance = std::numeric_limits::infinity()) noexcept; + [[nodiscard]] static SHPhysicsRaycastResult ColliderLinecast (EntityID eid, const SHVec3& start, const SHVec3& end) noexcept; + [[nodiscard]] static SHPhysicsRaycastResult ColliderLinecast (EntityID eid, int shapeIndex, const SHVec3& start, const SHVec3& end) noexcept; }; } diff --git a/SHADE_Managed/src/Math/Ray.cxx b/SHADE_Managed/src/Math/Ray.cxx index ee614cbe..bfb99578 100644 --- a/SHADE_Managed/src/Math/Ray.cxx +++ b/SHADE_Managed/src/Math/Ray.cxx @@ -1,28 +1,37 @@ -/************************************************************************************//*! -\file Ray.cxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Oct 20, 2022 -\brief Contains the definitions of functions of the Vector2 struct. - - Note: This file is written in C++17/CLI. +/**************************************************************************************** + * \file Ray.cxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the managed Ray struct. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ -Copyright (C) 2022 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent -of DigiPen Institute of Technology is prohibited. -*//*************************************************************************************/ -// Precompiled Headers #include "SHpch.h" + // Primary Header -#include "Math/Ray.hxx" +#include "Ray.hxx" namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Constructors */ - /*---------------------------------------------------------------------------------*/ - Ray::Ray(Vector3 origin, Vector3 direction) - : Origin { origin } - , Direction{ direction } - {} -} \ No newline at end of file + /*-----------------------------------------------------------------------------------*/ + /* Constructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + Ray::Ray(Vector3 position, Vector3 direction) + { + Position = position; + Direction = direction; + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void Ray::LookAt(Vector3 target) + { + Direction = (target - Position).GetNormalised(); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Math/Ray.hxx b/SHADE_Managed/src/Math/Ray.hxx index c50191f8..b684aa91 100644 --- a/SHADE_Managed/src/Math/Ray.hxx +++ b/SHADE_Managed/src/Math/Ray.hxx @@ -1,50 +1,61 @@ -/************************************************************************************//*! -\file Ray.hxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Oct 20, 2021 -\brief Contains the definitions of Vector2 struct. - - Note: This file is written in C++17/CLI. +/**************************************************************************************** + * \file Ray.hxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the managed Ray struct. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ -Copyright (C) 2022 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent -of DigiPen Institute of Technology is prohibited. -*//*************************************************************************************/ #pragma once // Project Includes -#include "Vector3.hxx" +#include "Math/Vector3.hxx" namespace SHADE { - /// - /// CLR version of the the SHADE Engine's Ray class that represents a ray in - /// 3-Dimensional space. - /// - public value struct Ray - { - public: - /*-----------------------------------------------------------------------------*/ - /* Public Members */ - /*-----------------------------------------------------------------------------*/ - /// - /// The start point of the ray. - /// - Vector3 Origin; - /// - /// The direction that a ray travels in. - /// - Vector3 Direction; + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------*/ - /* Constructors */ - /*-----------------------------------------------------------------------------*/ - /// - /// Creates a ray starting at origin along direction. - /// - /// Source of the ray. - /// Direction the ray travels in. - Ray(Vector3 origin, Vector3 direction); - }; -} + public value struct Ray + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + + /// + /// Constructor for a ray. + /// + /// The starting position of the ray. + /// The direction of the ray. + Ray(Vector3 position, Vector3 direction); + + + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + + /// + /// The starting point of the Ray. + /// + property Vector3 Position; + /// + /// The direction of the ray. This should be a normalised vector. + /// + property Vector3 Direction; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + /// + /// Rotates the ray's direction towards a target. + /// + /// The target to direct the ray towards. + void LookAt(Vector3 target); + }; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Physics/Physics.cxx b/SHADE_Managed/src/Physics/Physics.cxx new file mode 100644 index 00000000..9e2c1413 --- /dev/null +++ b/SHADE_Managed/src/Physics/Physics.cxx @@ -0,0 +1,105 @@ +/**************************************************************************************** + * \file Physics.cxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the managed Physics class. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include "SHpch.h" + +// Primary Header +#include "Physics.hxx" +// External Dependencies +#include "Physics/System/SHPhysicsSystemInterface.h" +// Project Header +#include "Engine/GameObject.hxx" +#include "Utility/Convert.hxx" +#include "Utility/Debug.hxx" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Property Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + Vector3 Physics::Gravity::get() + { + // TODO(Diren) + + return Vector3::Zero; + } + + void Physics::Gravity::set(Vector3 value) + { + (void)value; + } + + /*-----------------------------------------------------------------------------------*/ + /* Raycast Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + RaycastHit Physics::Raycast(Ray ray) + { + return Convert::ToCLI(SHPhysicsSystemInterface::Raycast(Convert::ToNative(ray))); + } + + RaycastHit Physics::Raycast(Ray ray, float distance) + { + return Convert::ToCLI(SHPhysicsSystemInterface::Raycast(Convert::ToNative(ray), distance)); + } + + RaycastHit Physics::Linecast(Vector3 start, Vector3 end) + { + return Convert::ToCLI(SHPhysicsSystemInterface::Linecast(Convert::ToNative(start), Convert::ToNative(end))); + } + + RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderRaycast(object.EntityId, Convert::ToNative(ray))); + } + + RaycastHit Physics::ColliderRaycast(GameObject object, Ray ray, float distance) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderRaycast(object.EntityId, Convert::ToNative(ray), distance)); + } + + RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderRaycast(object.EntityId, shapeIndex, Convert::ToNative(ray))); + } + + RaycastHit Physics::ColliderRaycast(GameObject object, int shapeIndex, Ray ray, float distance) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderRaycast(object.EntityId, shapeIndex, Convert::ToNative(ray), distance)); + } + + RaycastHit Physics::ColliderLineCast(GameObject object, Vector3 start, Vector3 end) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderLinecast(object.EntityId, Convert::ToNative(start), Convert::ToNative(end))); + } + + RaycastHit Physics::ColliderLineCast(GameObject object, int shapeIndex, Vector3 start, Vector3 end) + { + return Convert::ToCLI(SHPhysicsSystemInterface::ColliderLinecast(object.EntityId, shapeIndex, Convert::ToNative(start), Convert::ToNative(end))); + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + RaycastHit Physics::generateDefaultResult() + { + RaycastHit default; + default.Hit = false; + default.Other = System::Nullable(); + default.Position = Vector3::Zero; + default.Normal = Vector3::Zero; + default.Distance = System::Single::PositiveInfinity; + default.CollisionShapeIndex = -1; + + return default; + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Physics/Physics.hxx b/SHADE_Managed/src/Physics/Physics.hxx new file mode 100644 index 00000000..f13e5952 --- /dev/null +++ b/SHADE_Managed/src/Physics/Physics.hxx @@ -0,0 +1,128 @@ +/**************************************************************************************** + * \file Physics.hxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the managed Physics class. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Includes +#include "Math/Ray.hxx" +#include "RaycastHit.hxx" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + public ref class Physics abstract sealed + { + public: + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + + static property Vector3 Gravity + { + Vector3 get(); + void set(Vector3 value); + } + + // TODO(Diren): Add more properties for physics system settings. + + /*---------------------------------------------------------------------------------*/ + /* Raycast Function Members */ + /*---------------------------------------------------------------------------------*/ + + /// + /// Casts an infinite ray into the world. + /// + /// The ray to cast. + /// The result of the raycast. + static RaycastHit Raycast (Ray ray); + + /// + /// Casts a ray for a given distance into the world. + /// + /// The ray to cast. + /// The distance to cast the ray. + /// The result of the raycast. + static RaycastHit Raycast (Ray ray, float distance); + + /// + /// Casts a bounded ray into the world. + /// + /// The start of the bounded ray. + /// The end of the bounded ray. + /// The result of the raycast. + static RaycastHit Linecast (Vector3 start, Vector3 end); + + /// + /// Casts an infinite ray w.r.t a GameObject. + /// + /// The GameObject to cast the ray to. + /// The ray to cast. + /// The result of the raycast. + static RaycastHit ColliderRaycast (GameObject object, Ray ray); + + /// + /// Casts a ray for a given distance w.r.t a GameObject. + /// + /// The GameObject to cast the ray to. + /// The ray to cast. + /// The distance to cast the ray. + /// The result of the raycast. + static RaycastHit ColliderRaycast (GameObject object, Ray ray, float distance); + + /// + /// Casts an infinite ray w.r.t a specific collider on a GameObject. + /// + /// The GameObject to cast the ray to. + /// The collision shape index on the collider to cast to. + /// The ray to cast. + /// The result of the raycast. + static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray); + + /// + /// Casts a ray for a given distance w.r.t a specific collider on a GameObject. + /// + /// The GameObject to cast the ray to. + /// The collision shape index on the collider to cast to. + /// The ray to cast. + /// The distance to cast the ray. + /// The result of the raycast. + static RaycastHit ColliderRaycast (GameObject object, int shapeIndex, Ray ray, float distance); + + /// + /// Casts a bounded ray w.r.t a GameObject. + /// + /// The GameObject to cast the ray to. + /// The start of the bounded ray. + /// + /// The result of the raycast. + static RaycastHit ColliderLineCast (GameObject object, Vector3 start, Vector3 end); + + /// + /// Casts a bounded ray w.r.t a specific collider on a GameObject. + /// + /// The GameObject to cast the ray to. + /// The collision shape index on the collider to cast to. + /// The start of the bounded ray. + /// The end of the bounded ray. + /// The result of the raycast. + static RaycastHit ColliderLineCast (GameObject object, int shapeIndex, Vector3 start, Vector3 end); + + private: + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + static RaycastHit generateDefaultResult (); + }; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Physics/RaycastHit.cxx b/SHADE_Managed/src/Physics/RaycastHit.cxx new file mode 100644 index 00000000..e7ee9b89 --- /dev/null +++ b/SHADE_Managed/src/Physics/RaycastHit.cxx @@ -0,0 +1,19 @@ +/**************************************************************************************** + * \file RaycastHit.cxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the managed RaycastHit struct. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include "SHpch.h" + +// Primary Header +#include "RaycastHit.hxx" + +namespace SHADE +{ + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Physics/RaycastHit.hxx b/SHADE_Managed/src/Physics/RaycastHit.hxx new file mode 100644 index 00000000..260da2a1 --- /dev/null +++ b/SHADE_Managed/src/Physics/RaycastHit.hxx @@ -0,0 +1,64 @@ +/**************************************************************************************** + * \file RaycastHit.hxx + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the managed RaycastHit struct. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Project Includes +#include "Engine/GameObject.hxx" +#include "Math/Vector3.hxx" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + /// + /// Defines a struct that contains the information of a raycast. + /// + public value struct RaycastHit + { + public: + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + + /// + /// Whether or not the raycast hit a collider. + /// + property bool Hit; + + /// + /// The other game object hit. + /// + property System::Nullable Other; + + /// + /// The position where the ray cast hit. Zero if not hit. + /// + property Vector3 Position; + + /// + /// The normal where the ray cast hit. Zero if not hit. + /// + property Vector3 Normal; + + /// + /// The distance the ray was cast. Infinity if not hit. + /// + property float Distance; + + /// + /// The index of the collision shape hit on the collider. -1 if not hit. + /// + property int CollisionShapeIndex; + }; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Managed/src/Utility/Convert.cxx b/SHADE_Managed/src/Utility/Convert.cxx index 3b1f0f38..38ea2f50 100644 --- a/SHADE_Managed/src/Utility/Convert.cxx +++ b/SHADE_Managed/src/Utility/Convert.cxx @@ -19,6 +19,8 @@ of DigiPen Institute of Technology is prohibited. // External Dependencies #include #include "ECS_Base/Managers/SHEntityManager.h" +// Project Headers +#include "Engine/GameObject.hxx" namespace SHADE { @@ -62,14 +64,14 @@ namespace SHADE return Quaternion{ quat.x, quat.y, quat.z, quat.w }; } - SHRay Convert::ToNative(Ray vec) + SHRay Convert::ToNative(Ray ray) { - return SHRay(ToNative(vec.Origin), ToNative(vec.Direction)); + return SHRay(ToNative(ray.Position), ToNative(ray.Direction)); } - Ray Convert::ToCLI(const SHRay& vec) + Ray Convert::ToCLI(const SHRay& ray) { - return Ray(ToCLI(vec.position), ToCLI(vec.direction)); + return Ray(ToCLI(ray.position), ToCLI(ray.direction)); } SHColour Convert::ToNative(Color col) @@ -95,6 +97,42 @@ namespace SHADE return msclr::interop::marshal_as(str); } + /*---------------------------------------------------------------------------------*/ + /* Physics Conversions */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsRaycastResult Convert::ToNative(RaycastHit cli) + { + // This function shouldn't be used anyway, so we leave the entityHit empty. + + SHPhysicsRaycastResult native; + + native.hit = cli.Hit; + native.position = ToNative(cli.Position); + native.normal = ToNative(cli.Normal); + native.distance = cli.Distance; + native.shapeIndex = cli.CollisionShapeIndex; + + return native; + } + + RaycastHit Convert::ToCLI(const SHPhysicsRaycastResult& native) + { + RaycastHit cli; + + cli.Hit = native.hit; + cli.Position = ToCLI(native.position); + cli.Normal = ToCLI(native.normal); + cli.Distance = native.distance; + cli.CollisionShapeIndex = native.shapeIndex; + + cli.Other = SHEntityManager::IsValidEID(native.entityHit) + ? GameObject(native.entityHit) + : System::Nullable(); + + return cli; + } + /*---------------------------------------------------------------------------------*/ /* Handle Conversions */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Utility/Convert.hxx b/SHADE_Managed/src/Utility/Convert.hxx index 4d0c5b59..04407f77 100644 --- a/SHADE_Managed/src/Utility/Convert.hxx +++ b/SHADE_Managed/src/Utility/Convert.hxx @@ -28,9 +28,11 @@ of DigiPen Institute of Technology is prohibited. #include "Math/Vector3.hxx" #include "Math/Quaternion.hxx" #include "Math/Ray.hxx" +#include "Physics/RaycastHit.hxx" #include "Engine/GenericHandle.hxx" #include "Math/SHColour.h" #include "Graphics/Color.hxx" +#include "Physics/Collision/SHPhysicsRaycastResult.h" namespace SHADE { @@ -95,22 +97,22 @@ namespace SHADE /// The native Quaternion to convert from. /// Managed copy of a native Quaternion. static Quaternion ToCLI(const SHQuaternion& quat); - /// Converts from a managed Vector2 to a native Vector2. + /// Converts from a managed Ray to a native Ray. /// - /// The managed Vector2 to convert from. - /// Native copy of a managed Vector2. + /// The managed Ray to convert from. + /// Native copy of a managed Ray. static SHRay ToNative(Ray vec); /// - /// Converts from a native Vector2 to a managed Vector2. + /// Converts from a native Ray to a managed Ray. /// - /// The native Vector2 to convert from. - /// Managed copy of a native Vector2. - static Ray ToCLI(const SHRay& vec); + /// The native Ray to convert from. + /// Managed copy of a native Ray. + static Ray ToCLI(const SHRay& ray); /// Converts from a managed Color to a native Colour. /// /// The managed Color to convert from. /// Native copy of a managed Color. - static SHColour ToNative(Color col); + static SHColour ToNative(Color ray); /// /// Converts from a native Colour to a managed Color. /// @@ -134,9 +136,27 @@ namespace SHADE /// Managed copy of a native std::string. static System::String^ ToCLI(const std::string& str); + /*-----------------------------------------------------------------------------*/ + /* Physics Conversions */ + /*-----------------------------------------------------------------------------*/ + + /// + /// Converts from a managed RaycastHit to a native SHPhysicsRaycastResult + /// + /// The managed RaycastHit to convert from. + /// Native copy of a managed RaycastHit. + static SHPhysicsRaycastResult ToNative(RaycastHit cli); + + /// + /// Converts from native SHPhysicsRaycastResult to a managed RaycastHit. + /// + /// The native SHPhysicsRaycastResult to convert from. + /// Managed copy of a native SHPhysicsRaycastResult. + static RaycastHit ToCLI(const SHPhysicsRaycastResult& native); + /*-----------------------------------------------------------------------------*/ /* Handle Conversions */ - /*-----------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------*/ /// /// Converts from a managed GenericHandle to a Handle. ///