Fixed major bug when generating new meta files for materials #254

Merged
XiaoQiDigipen merged 5 commits from SP3-13-Assets-Manager into main 2022-11-22 21:55:22 +08:00
111 changed files with 3157 additions and 902 deletions
Showing only changes of commit 5fb51511f6 - Show all commits

Binary file not shown.

Binary file not shown.

BIN
Assets/Audio/Music.bank Normal file

Binary file not shown.

BIN
Assets/Audio/SFX.bank Normal file

Binary file not shown.

BIN
Assets/Audio/UI.bank Normal file

Binary file not shown.

View File

@ -21,141 +21,6 @@
Layer: 4294967295 Layer: 4294967295
Strength: 0 Strength: 0
Scripts: ~ Scripts: ~
- EID: 1
Name: Floor
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -1.440328, y: -4.41369677, z: -5}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 49.4798889, y: 0.5, z: 17.5}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Static
Mass: 1
Drag: 0.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
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -4.40482807, y: 2.57871056, z: -5.21213436}
Rotate: {x: -0.361265004, y: 1.11661232, z: -0.626627684}
Scale: {x: 0.999982238, y: 0.999987125, z: 0.999981165}
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: true
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: false
Freeze Rotation Y: false
Freeze Rotation Z: false
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 3
Name: Empty
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -0.0094268322, y: 0, z: 0}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 1, y: 1, z: 1}
Scripts: ~
- EID: 4
Name: Empty2
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Scripts: ~
- EID: 9
Name: Bag
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 144838771
Material: 123745521
Scripts: ~
- EID: 6
Name: AI
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -8, y: -2, z: 2.5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~
- EID: 7 - EID: 7
Name: BigBoi Name: BigBoi
IsActive: true IsActive: true
@ -182,45 +47,3 @@
Layer: 4294967295 Layer: 4294967295
Strength: 0.25 Strength: 0.25
Scripts: ~ Scripts: ~
- EID: 5
Name: item
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -2, z: -5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 2, y: 2, z: 2}
Renderable Component:
Mesh: 144838771
Material: 123745521
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
- Is Trigger: true
Type: Box
Half Extents: {x: 2, y: 2, z: 2}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~

View File

@ -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: ~

View File

@ -0,0 +1,3 @@
Name: PlayerControllerTest
ID: 92100024
Type: 5

View File

@ -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<Item> listOfItems;
private IEnumerable<ScoringZone> listOfZone;
protected override void awake()
{
totalItemCount = 0;
Score = 0;
currGameState = GameState.MAINMENU;
if (itemPool)
{
listOfItems = itemPool.GetScriptsInChildren<Item>();
foreach (Item i in listOfItems)
totalItemCount += 1;
}
if (zonePool)
{
listOfZone = itemPool.GetScriptsInChildren<ScoringZone>();
foreach (ScoringZone i in listOfZone)
i.gameManger = Owner.GetScript<GameManager>();
}
}
protected override void update()
{
if (timer > 0)
timer -= Time.DeltaTimeF;
else
currGameState = GameState.LOSE;
}
protected override void onTriggerEnter(CollisionInfo info)
{
}
}

View File

@ -0,0 +1,3 @@
Name: SC_GameManager
ID: 161629605
Type: 9

View File

@ -9,9 +9,16 @@ public class Item : Script
HEAVY HEAVY
} }
public int Score = 10;
public ItemCategory currCategory; public ItemCategory currCategory;
protected override void awake() protected override void awake()
{ {
} }
protected override void onTriggerEnter(CollisionInfo info)
{
}
} }

View File

@ -0,0 +1,3 @@
Name: SC_Item
ID: 153136539
Type: 9

View File

@ -4,8 +4,9 @@ using static PlayerController;
public class PickAndThrow : Script 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 Vector3 throwForce = new Vector3(100.0f, 200.0f, 100.0f);
public GameObject item; public GameObject item { get; set; }
private PlayerController pc; private PlayerController pc;
private Camera cam; private Camera cam;
private Transform itemTransform; private Transform itemTransform;
@ -22,36 +23,13 @@ public class PickAndThrow : Script
if (raccoonHoldLocation == null) if (raccoonHoldLocation == null)
Debug.Log("CHILD EMPTY"); Debug.Log("CHILD EMPTY");
else else
raccoonHoldLocation.LocalPosition = new Vector3(0.0f, 1.0f, 0.0f); raccoonHoldLocation.LocalPosition = holdPosition;
} }
protected override void update() protected override void update()
{ {
if (cam == null) CalculateDir();
cam = GetComponentInChildren<Camera>();
else if (cam != null)
{
Vector3 camerAixs = cam.GetForward();
camerAixs.y = 0;
camerAixs.Normalise();
lastXDir = camerAixs.x;
lastZDir = camerAixs.z;
}
if (item.GetScript<Item>() != null && itemTransform == null && itemRidibody == null) if (pc != null && pc.holdItem && itemRidibody != null && itemTransform != null)
{
itemTransform = item.GetComponent<Transform>();
if (itemTransform == null)
Debug.Log("Item transform EMPTY");
itemRidibody = item.GetComponent<RigidBody>();
if (itemRidibody == null)
Debug.Log("Item rb EMPTY");
}
if (pc != null && inRange && !pc.holdItem && Input.GetKey(Input.KeyCode.E))
pc.holdItem = true;
if (pc != null && itemRidibody != null && itemTransform != null && pc.holdItem)
{ {
itemTransform.LocalPosition = raccoonHoldLocation.GlobalPosition; itemTransform.LocalPosition = raccoonHoldLocation.GlobalPosition;
itemRidibody.IsGravityEnabled = false; itemRidibody.IsGravityEnabled = false;
@ -65,17 +43,60 @@ public class PickAndThrow : Script
itemRidibody.IsGravityEnabled = true; itemRidibody.IsGravityEnabled = true;
itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir)); itemRidibody.AddForce(new Vector3(throwForce.x * lastXDir, throwForce.y, throwForce.z * lastZDir));
itemRidibody.LinearVelocity += pc.rb.LinearVelocity; itemRidibody.LinearVelocity += pc.rb.LinearVelocity;
ResetItemObject();
} }
} }
else if(!pc.holdItem && itemRidibody != null) else if(!pc.holdItem && itemRidibody != null)
itemRidibody.IsGravityEnabled = true; 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<Item>() != null && itemTransform == null && itemRidibody == null)
{
itemTransform = item.GetComponent<Transform>();
if (itemTransform == null)
Debug.Log("Item transform EMPTY");
itemRidibody = item.GetComponent<RigidBody>();
if (itemRidibody == null)
Debug.Log("Item rb EMPTY");
}
}
private void CalculateDir()
{
if (cam == null)
cam = GetComponentInChildren<Camera>();
else if (cam != null)
{
Vector3 camerAixs = cam.GetForward();
camerAixs.y = 0;
camerAixs.Normalise();
lastXDir = camerAixs.x;
lastZDir = camerAixs.z;
}
}
protected override void onCollisionEnter(CollisionInfo info) protected override void onCollisionEnter(CollisionInfo info)
{ {
} }
protected override void onTriggerEnter(CollisionInfo info) protected override void onTriggerEnter(CollisionInfo info)
{ {
//Debug.Log("ENTER");
if (info.GameObject.GetScript<Item>() != null && !pc.holdItem) if (info.GameObject.GetScript<Item>() != null && !pc.holdItem)
{ {
item = info.GameObject; item = info.GameObject;

View File

@ -0,0 +1,3 @@
Name: SC_PickAndThrow
ID: 154802724
Type: 9

View File

@ -1,40 +1,47 @@
using SHADE; using SHADE;
using System; using System;
using System.Collections.Generic;
using static Item; using static Item;
public class PlayerController : Script public class PlayerController : Script
{ {
public enum RaccoonStates public enum RaccoonStates
{ {
IDILE, IDLE,
WALKING, WALKING,
RUNNING, RUNNING,
JUMP, JUMP,
FALLING, FALLING,
LANDED,
CAUGHT, CAUGHT,
TOTAL TOTAL
} }
public enum WalkingState
{
CARRY,
AIMING,
THROW,
WALK,
TOTAL
}
public RigidBody rb { get; set; } public RigidBody rb { get; set; }
private Transform tranform; private Transform tranform;
private Camera cam; private Camera cam;
private PickAndThrow pat; private PickAndThrow pat;
private StateMachine stateMachine;
//to be remove
public float drag = 2.0f;
public bool holdItem { get; set; } public bool holdItem { get; set; }
[SerializeField]
[Tooltip("The current state fo the raccoon")] [Tooltip("The current state fo the raccoon")]
public RaccoonStates currentState = RaccoonStates.IDILE; public RaccoonStates currentState = RaccoonStates.IDLE;
//Movement variables============================================================ //Movement variables============================================================
[SerializeField]
[Tooltip("Max vel for walking")] [Tooltip("Max vel for walking")]
public float maxMoveVel = 2.0f; public float maxMoveVel = 2.0f;
[SerializeField]
[Tooltip("how much force is apply for walking")] [Tooltip("how much force is apply for walking")]
public float moveForce = 50.0f; public float moveForce = 2.0f;
[SerializeField]
[Tooltip("increase the moveForce and maxMoveVel by its amt")] [Tooltip("increase the moveForce and maxMoveVel by its amt")]
public float sprintMultiplier = 2.0f; public float sprintMultiplier = 2.0f;
@ -49,7 +56,6 @@ public class PlayerController : Script
public bool isMoveKeyPress { get; set; } public bool isMoveKeyPress { get; set; }
[SerializeField]
[Tooltip("curr not working")] [Tooltip("curr not working")]
public float rotationFactorPerFrame = 1.0f; public float rotationFactorPerFrame = 1.0f;
@ -75,6 +81,7 @@ public class PlayerController : Script
protected override void awake() protected override void awake()
{ {
Audio.PlayBGMOnce2D("event:/Music/player_undetected");
//default setup //default setup
isMoveKeyPress = false; isMoveKeyPress = false;
holdItem = false; holdItem = false;
@ -91,10 +98,6 @@ public class PlayerController : Script
else else
{ {
rb.IsGravityEnabled = false; rb.IsGravityEnabled = false;
rb.FreezeRotationX = true;
rb.FreezeRotationY = true;
rb.FreezeRotationZ = true;
rb.Drag = drag;
rb.Interpolating = false; rb.Interpolating = false;
} }
@ -103,14 +106,18 @@ public class PlayerController : Script
if(tranform == null) if(tranform == null)
Debug.LogError("tranform is NULL!"); Debug.LogError("tranform is NULL!");
//PickAndThrow checl //PickAndThrow check
pat = GetScript<PickAndThrow>(); pat = GetScript<PickAndThrow>();
if (pat == null) if (pat == null)
Debug.LogError("PickAndThrow is NULL!"); Debug.LogError("PickAndThrow is NULL!");
//toRemove stateMachine = AddScript<StateMachine>();
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f); Dictionary<Type, BaseState> dictionary = new Dictionary<Type, BaseState>();
tranform.LocalRotation = Quaternion.Euler(0.0f, 0.0f, 0.0f); 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() protected override void update()
@ -118,118 +125,103 @@ public class PlayerController : Script
if (cam == null) if (cam == null)
cam = GetComponentInChildren<Camera>(); cam = GetComponentInChildren<Camera>();
//toRemove
if (Input.GetKey(Input.KeyCode.G))
{
tranform.LocalRotation = Quaternion.Euler(0.0f, 0.0f, 0.0f);
tranform.LocalPosition = new Vector3(-3.0f, -2.0f, -5.0f);
}
GotCaught(); 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()); //Debug.Log(currentState.ToString() + " x:" + rb.LinearVelocity.x.ToString() + " y:" + rb.LinearVelocity.y.ToString() + " z:" + rb.LinearVelocity.z.ToString());
} }
protected override void fixedUpdate() protected override void fixedUpdate()
{ {
//Rotation(); //Rotation();
MoveKey();
Move(); Move();
Sprint(); Sprint();
Jump(); Jump();
Gravity(); Gravity();
//Debug.Log($"X: {rb.LinearVelocity.x}" + $" Z: {rb.LinearVelocity.z}");
} }
private void MoveKey() 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; axisMove = Vector2.Zero;
if (Input.GetKey(Input.KeyCode.W)) if (Input.GetKey(Input.KeyCode.W))
{ {
Vector3 camerAixs = cam.GetForward(); Vector3 camerAixs = cam.GetForward();
camerAixs.y = 0; camerAixs.y = 0;
camerAixs.Normalise(); camerAixs.Normalise();
xAxisMove = camerAixs.x;
zAxisMove = camerAixs.z;
axisMove += new Vector2(camerAixs.x, camerAixs.z); axisMove += new Vector2(camerAixs.x, camerAixs.z);
} }
if (Input.GetKey(Input.KeyCode.S)) if (Input.GetKey(Input.KeyCode.S))
{ {
Vector3 camerAixs = cam.GetForward(); Vector3 camerAixs = cam.GetForward();
camerAixs.y = 0; camerAixs.y = 0;
camerAixs.Normalise(); camerAixs.Normalise();
xAxisMove = -camerAixs.x;
zAxisMove = -camerAixs.z;
axisMove -= new Vector2(camerAixs.x, camerAixs.z); axisMove -= new Vector2(camerAixs.x, camerAixs.z);
} }
if (Input.GetKey(Input.KeyCode.A)) if (Input.GetKey(Input.KeyCode.A))
{ {
Vector3 camerAixs = cam.GetRight(); Vector3 camerAixs = cam.GetRight();
camerAixs.y = 0; camerAixs.y = 0;
camerAixs.Normalise(); camerAixs.Normalise();
xAxisMove = -camerAixs.x;
zAxisMove = -camerAixs.z;
axisMove -= new Vector2(camerAixs.x, camerAixs.z); axisMove -= new Vector2(camerAixs.x, camerAixs.z);
} }
if (Input.GetKey(Input.KeyCode.D)) if (Input.GetKey(Input.KeyCode.D))
{ {
Vector3 camerAixs = cam.GetRight(); Vector3 camerAixs = cam.GetRight();
camerAixs.y = 0; camerAixs.y = 0;
camerAixs.Normalise(); camerAixs.Normalise();
xAxisMove = camerAixs.x;
zAxisMove = camerAixs.z;
axisMove += new Vector2(camerAixs.x, 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; currentState = RaccoonStates.WALKING;
if(stateMachine && !stateMachine.IsState(typeof(WalkState)))
stateMachine.SetState(typeof(WalkState));
}
if (!isMoveKeyPress && isGrounded) if (!isMoveKeyPress && isGrounded)
currentState = RaccoonStates.IDILE; {
currentState = RaccoonStates.IDLE;
if(stateMachine && !stateMachine.IsState(typeof(IdleState)))
stateMachine.SetState(typeof(IdleState));
}
} }
private void Move() private void Move()
{ {
if (rb != null) 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 (isMoveKeyPress)
{ {
if (rb.LinearVelocity.x > maxMoveVel || rb.LinearVelocity.x < -maxMoveVel) if (rb)
{ {
Vector3 v = rb.LinearVelocity; Vector3 velNor = rb.LinearVelocity;
v.x = System.Math.Clamp(v.x, -maxMoveVel, maxMoveVel); velNor.y = 0.0f;
rb.LinearVelocity = v; if (velNor.GetMagnitude() > maxMoveVel)
}
if (rb.LinearVelocity.z > maxMoveVel || rb.LinearVelocity.z < -maxMoveVel)
{ {
Vector3 v = rb.LinearVelocity; velNor.Normalise();
v.z = System.Math.Clamp(v.z, -maxMoveVel, maxMoveVel); velNor *= maxMoveVel;
rb.LinearVelocity = v; 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) if (Input.GetKey(Input.KeyCode.LeftShift) && isMoveKeyPress && isGrounded)
{ {
currentState = RaccoonStates.RUNNING; currentState = RaccoonStates.RUNNING;
if (stateMachine && !stateMachine.IsState(typeof(RunState)))
stateMachine.SetState(typeof(RunState));
holdItem = false; holdItem = false;
if (!sprintIncreaseOnce) if (!sprintIncreaseOnce)
{ {
@ -253,7 +248,11 @@ public class PlayerController : Script
if (Input.GetKeyUp(Input.KeyCode.LeftShift)) if (Input.GetKeyUp(Input.KeyCode.LeftShift))
{ {
if (isMoveKeyPress) if (isMoveKeyPress)
{
currentState = RaccoonStates.WALKING; currentState = RaccoonStates.WALKING;
if(stateMachine && !stateMachine.IsState(typeof(WalkState)))
stateMachine.SetState(typeof(WalkState));
}
sprintIncreaseOnce = false; sprintIncreaseOnce = false;
moveForce = oldForce; moveForce = oldForce;
maxMoveVel = maxOldVel; maxMoveVel = maxOldVel;
@ -263,37 +262,38 @@ public class PlayerController : Script
//press and hold jump //press and hold jump
private void 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) if (Input.GetKeyDown(Input.KeyCode.Space) && isGrounded && rb != null)
{ {
currentState = RaccoonStates.JUMP; currentState = RaccoonStates.JUMP;
Vector3 v = rb.LinearVelocity; Vector3 v = rb.LinearVelocity;
v.y = initialJumpVel * 0.5f; v.y = initialJumpVel * 0.5f;
if (pat != null && pat.item.GetScript<Item>() != null && holdItem) if (holdItem && pat != null && pat.item.GetScript<Item>() != null)
{ {
Item item = pat.item.GetScript<Item>(); Item item = pat.item.GetScript<Item>();
if (item.currCategory == ItemCategory.LIGHT) if (item != null && item.currCategory == ItemCategory.LIGHT)
v.y *= lightMultiper; v.y *= lightMultiper;
if (item.currCategory == ItemCategory.MEDIUM) if (item != null && item.currCategory == ItemCategory.MEDIUM)
v.y *= mediumMultiper; v.y *= mediumMultiper;
if (item.currCategory == ItemCategory.HEAVY) if (item != null && item.currCategory == ItemCategory.HEAVY)
v.y *= heavyMultiper; v.y *= heavyMultiper;
} }
rb.LinearVelocity = v; 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; currentState = RaccoonStates.FALLING;
} }
private void Rotation() private void Rotation()
{ {
Vector3 poitionToLookAt; Vector3 poitionToLookAt;
poitionToLookAt.x = xAxisMove; poitionToLookAt.x = axisMove.x;
poitionToLookAt.y = 0.0f; poitionToLookAt.y = 0.0f;
poitionToLookAt.z = zAxisMove; poitionToLookAt.z = axisMove.y;
if (tranform != null) if (tranform != null)
{ {
@ -312,7 +312,11 @@ public class PlayerController : Script
{ {
//check player vel.y if its close to zero its on the ground //check player vel.y if its close to zero its on the ground
if (SHADE.Math.CompareFloat(rb.LinearVelocity.y, 0.0f)) if (SHADE.Math.CompareFloat(rb.LinearVelocity.y, 0.0f))
{
isGrounded = true; isGrounded = true;
if (currentState == RaccoonStates.FALLING)
currentState = RaccoonStates.LANDED;
}
else else
isGrounded = false; isGrounded = false;
@ -344,7 +348,9 @@ public class PlayerController : Script
{ {
if (currentState == RaccoonStates.CAUGHT && tranform != null) 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); 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");
}
}

View File

@ -0,0 +1,3 @@
Name: SC_PlayerController
ID: 160432754
Type: 9

View File

@ -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<Item>())
{
gameManger.Score += info.GameObject.GetScript<Item>().Score;
gameManger.totalItemCount -= 1;
info.GameObject.SetActive(false);
}
}
}

View File

@ -0,0 +1,3 @@
Name: SC_ScoringZone
ID: 153171688
Type: 9

View File

@ -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)
{
}
}

View File

@ -0,0 +1,3 @@
Name: UT_BaseSate
ID: 154709755
Type: 9

View File

@ -0,0 +1,126 @@
using SHADE;
using System;
using System.Collections.Generic;
using System.Linq;
public class StateMachine : Script
{
private Dictionary<Type, BaseState> stateDictionary;
public BaseState currentState = null;
public string currentStateName;
public string currentAnimName;
public void InitStateMachine(Dictionary<Type, BaseState> 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);
}
}

View File

@ -0,0 +1,3 @@
Name: UT_StateMachine
ID: 166010611
Type: 9

View File

@ -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 = normals * texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Normals_FS
ID: 48689301
Type: 2

View File

@ -33,6 +33,7 @@
#include "Physics/System/SHPhysicsSystem.h" #include "Physics/System/SHPhysicsSystem.h"
#include "Physics/System/SHPhysicsDebugDrawSystem.h" #include "Physics/System/SHPhysicsDebugDrawSystem.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "UI/SHUISystem.h"
// Components // Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -77,6 +78,7 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHAudioSystem>(); SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>(); SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHUISystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>(); SHSystemManager::CreateSystem<SHGraphicsSystem>();
@ -115,10 +117,13 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>(); SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::PrepareRenderRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
//SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>(); //SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
SHSystemManager::RegisterRoutine<SHUISystem, SHUISystem::AddUIComponentRoutine>();
SHSystemManager::RegisterRoutine<SHUISystem, SHUISystem::UpdateUIMatrixRoutine>();
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>(); SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
#ifdef SHEDITOR #ifdef SHEDITOR

View File

@ -143,6 +143,28 @@ namespace SHADE
return result; return result;
} }
AssetType SHAssetManager::GetType(AssetID id) noexcept
{
if (assetCollection.contains(id))
{
return assetCollection[id].type;
}
SHLOG_WARNING("AssetID {}, does not belong to an asset", id)
return AssetType::INVALID;
}
std::optional<SHADE::SHAsset> SHAssetManager::GetAsset(AssetID id) noexcept
{
if (assetCollection.contains(id))
{
return assetCollection[id];
}
return {};
}
/**************************************************************************** /****************************************************************************
* \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM * \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM
* ASSETS CREATED BY THE ENGINE. * ASSETS CREATED BY THE ENGINE.

View File

@ -50,6 +50,9 @@ namespace SHADE
* \return const& to unordered_map<AssetName, AssetID> * \return const& to unordered_map<AssetName, AssetID>
****************************************************************************/ ****************************************************************************/
static std::vector<SHAsset> GetAllAssets() noexcept; static std::vector<SHAsset> GetAllAssets() noexcept;
static std::optional<SHAsset> GetAsset(AssetID id) noexcept;
static AssetType GetType(AssetID id) noexcept;
/**************************************************************************** /****************************************************************************
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM

View File

@ -84,12 +84,32 @@ namespace SHADE
LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data()); LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data()); LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
//LoadBank((AUDIO_FOLDER_PATH + "Music.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"); //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
//clip->Play(); //clip->Play();
//PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); //PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
//PlayEventOnce("event:/SFX/Dawn/Dawn_Attack"); //PlayEventOnce("event:/SFX/Dawn/Dawn_Attack");
#ifdef SHEDITOR
// Subscribe to Editor State Change Events
const std::shared_ptr ON_PLAY_RECEIVER{ std::make_shared<SHEventReceiverSpec<SHAudioSystem>>(this, &SHAudioSystem::onPlay) };
const ReceiverPtr ON_PLAY_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ON_PLAY_RECEIVER);
SHEventManager::SubscribeTo(SH_EDITOR_ON_PLAY_EVENT, ON_PLAY_RECEIVER_PTR);
const std::shared_ptr ON_STOP_RECEIVER{ std::make_shared<SHEventReceiverSpec<SHAudioSystem>>(this, &SHAudioSystem::onStop) };
const ReceiverPtr ON_STOP_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ON_STOP_RECEIVER);
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, ON_STOP_RECEIVER_PTR);
const std::shared_ptr ON_PAUSE_RECEIVER{ std::make_shared<SHEventReceiverSpec<SHAudioSystem>>(this, &SHAudioSystem::onPause) };
const ReceiverPtr ON_PAUSE_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ON_PAUSE_RECEIVER);
SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, ON_PAUSE_RECEIVER_PTR);
#endif
} }
void SHADE::SHAudioSystem::Run(double dt) void SHADE::SHAudioSystem::Run(double dt)
@ -179,7 +199,6 @@ namespace SHADE
it->second->createInstance(&event); it->second->createInstance(&event);
if (event) if (event)
{ {
event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume)); event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume));
if (spatial) if (spatial)
{ {
@ -285,6 +304,7 @@ namespace SHADE
if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying) if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying)
channel->stop(); channel->stop();
} }
masterGroup->stop();
} }
std::optional<FMOD_GUID> SHAudioSystem::GetEventGUID(const char* path) std::optional<FMOD_GUID> SHAudioSystem::GetEventGUID(const char* path)
@ -410,6 +430,7 @@ namespace SHADE
void SHAudioSystem::SetPaused(bool pause) void SHAudioSystem::SetPaused(bool pause)
{ {
paused = pause; paused = pause;
masterGroup->setPaused(pause);
for (auto const& channel : audioChannels) for (auto const& channel : audioChannels)
{ {
channel->setPaused(paused); channel->setPaused(paused);
@ -552,6 +573,27 @@ namespace SHADE
return value; 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) #pragma warning(pop)

View File

@ -7,9 +7,11 @@
#include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "Math/SHMath.h" #include "Math/Vector/SHVec3.h"
#include <optional> #include <optional>
#include <FMOD/fmod_studio.hpp> #include <FMOD/fmod_studio.hpp>
#include "Events/SHEvent.h"
#include "SH_API.h" #include "SH_API.h"
#define AUDIO_SYS_MAX_CHANNELS 1024 #define AUDIO_SYS_MAX_CHANNELS 1024
@ -104,6 +106,10 @@ namespace SHADE
std::vector<SHAudioListenerComponent>* denseListener; std::vector<SHAudioListenerComponent>* denseListener;
AudioClipID clipID = 0; AudioClipID clipID = 0;
SHEventHandle onPlay(SHEventPtr onStopEvent);
SHEventHandle onStop(SHEventPtr onStopEvent);
SHEventHandle onPause(SHEventPtr onStopEvent);
}; };
} }

View File

@ -12,7 +12,7 @@ namespace SHADE
:yaw(0.0f), pitch(0.0f), roll(0.0f) :yaw(0.0f), pitch(0.0f), roll(0.0f)
, width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f) , width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f)
, perspProj(true), dirtyView(true), dirtyProj(true) , perspProj(true), dirtyView(true), dirtyProj(true)
, viewMatrix(), projMatrix() , viewMatrix(), perspProjMatrix(), orthoProjMatrix()
, position(), offset() , position(), offset()
{ {
ComponentFamily::GetID<SHCameraComponent>(); ComponentFamily::GetID<SHCameraComponent>();
@ -213,7 +213,20 @@ namespace SHADE
const SHMatrix& SHCameraComponent::GetProjMatrix() const noexcept const SHMatrix& SHCameraComponent::GetProjMatrix() const noexcept
{ {
return projMatrix; if (perspProj)
return perspProjMatrix;
else
return orthoProjMatrix;
}
const SHMatrix& SHCameraComponent::GetOrthoMatrix() const noexcept
{
return orthoProjMatrix;
}
const SHMatrix& SHCameraComponent::GetPerspectiveMatrix() const noexcept
{
return orthoProjMatrix;
} }
//void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept //void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept

View File

@ -29,7 +29,8 @@ namespace SHADE
SHMatrix viewMatrix; SHMatrix viewMatrix;
SHMatrix projMatrix; SHMatrix perspProjMatrix;
SHMatrix orthoProjMatrix;
SHVec3 position; SHVec3 position;
bool perspProj; bool perspProj;
@ -37,6 +38,7 @@ namespace SHADE
public: public:
friend class SHCameraSystem; friend class SHCameraSystem;
@ -78,6 +80,8 @@ namespace SHADE
const SHMatrix& GetViewMatrix() const noexcept; const SHMatrix& GetViewMatrix() const noexcept;
const SHMatrix& GetProjMatrix() const noexcept; const SHMatrix& GetProjMatrix() const noexcept;
const SHMatrix& GetOrthoMatrix() const noexcept;
const SHMatrix& GetPerspectiveMatrix() const noexcept;
//void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept; //void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept;

View File

@ -15,27 +15,27 @@ namespace SHADE
} }
SHMatrix SHCameraDirector::GetViewMatrix() const noexcept SHMatrix const& SHCameraDirector::GetViewMatrix() const noexcept
{ {
return viewMatrix; return viewMatrix;
} }
SHMatrix SHCameraDirector::GetProjMatrix() const noexcept SHMatrix const& SHCameraDirector::GetProjMatrix() const noexcept
{ {
return projMatrix; return projMatrix;
} }
SHMatrix SHCameraDirector::GetVPMatrix() const noexcept SHMatrix const& SHCameraDirector::GetVPMatrix() const noexcept
{ {
return projMatrix * viewMatrix; return projMatrix * viewMatrix;
} }
void SHCameraDirector::UpdateMatrix() noexcept SHCameraComponent* SHCameraDirector::GetMainCameraComponent() noexcept
{ {
if (mainCameraEID == MAX_EID) if (mainCameraEID == MAX_EID)
{ {
auto& dense = SHComponentManager::GetDense<SHCameraComponent>(); auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
if (dense.size() == 0) if (dense.size() == 0)
{ {
return; return nullptr;
} }
mainCameraEID = dense[0].GetEID(); mainCameraEID = dense[0].GetEID();
} }
@ -44,7 +44,13 @@ namespace SHADE
{ {
SHLOG_WARNING("Camera Director warning: Entity does not have a camera"); SHLOG_WARNING("Camera Director warning: Entity does not have a camera");
} }
else }
void SHCameraDirector::UpdateMatrix() noexcept
{
SHCameraComponent* camComponent = GetMainCameraComponent();
if(camComponent)
{ {
viewMatrix = camComponent->GetViewMatrix(); viewMatrix = camComponent->GetViewMatrix();
projMatrix = camComponent->GetProjMatrix(); projMatrix = camComponent->GetProjMatrix();
@ -62,6 +68,24 @@ namespace SHADE
mainCameraEID = camera.GetEID(); mainCameraEID = camera.GetEID();
} }
SHMatrix const& SHCameraDirector::GetOrthoMatrix() noexcept
{
SHCameraComponent* camComponent = GetMainCameraComponent();
if (camComponent)
return camComponent->GetOrthoMatrix();
else
return SHMatrix::Identity;
}
SHMatrix const& SHCameraDirector::GetPerspectiveMatrix() noexcept
{
SHCameraComponent* camComponent = GetMainCameraComponent();
if (camComponent)
return camComponent->GetPerspectiveMatrix();
else
return SHMatrix::Identity;
}
} }

View File

@ -23,20 +23,20 @@ namespace SHADE
EntityID transitionCameraEID; EntityID transitionCameraEID;
SHMatrix GetViewMatrix() const noexcept; SHMatrix const& GetViewMatrix() const noexcept;
SHMatrix GetProjMatrix() const noexcept; SHMatrix const& GetProjMatrix() const noexcept;
SHMatrix GetVPMatrix() const noexcept; SHMatrix const& GetVPMatrix() const noexcept;
void UpdateMatrix() noexcept; void UpdateMatrix() noexcept;
void SetMainCamera(SHCameraComponent& cam) noexcept; void SetMainCamera(SHCameraComponent& cam) noexcept;
SHMatrix const& GetOrthoMatrix() noexcept;
SHMatrix const& GetPerspectiveMatrix() noexcept;
private: private:
protected:
SHMatrix viewMatrix; SHMatrix viewMatrix;
SHMatrix projMatrix; SHMatrix projMatrix;
SHCameraComponent* GetMainCameraComponent() noexcept;
}; };
typedef Handle<SHCameraDirector> DirectorHandle; typedef Handle<SHCameraDirector> DirectorHandle;

View File

@ -107,7 +107,11 @@ namespace SHADE
editorCamera.SetPitch(0.0f); editorCamera.SetPitch(0.0f);
editorCamera.SetYaw(0.0f); editorCamera.SetYaw(0.0f);
editorCamera.SetRoll(0.0f); editorCamera.SetRoll(0.0f);
editorCamera.SetWidth(1080.0f);
editorCamera.SetHeight(720.0f);
editorCamera.SetFar(10000000.0f);
editorCamera.movementSpeed = 2.0f; editorCamera.movementSpeed = 2.0f;
editorCamera.perspProj = true;
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>(); SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>(); SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>();
@ -210,39 +214,43 @@ namespace SHADE
} }
if (camera.dirtyProj == true) if (camera.dirtyProj == true)
{ {
if (camera.perspProj == true) //Perspective projection matrix.
{
const float ASPECT_RATIO = (camera.GetAspectRatio()); const float ASPECT_RATIO = (camera.GetAspectRatio());
const float TAN_HALF_FOV = tan(SHMath::DegreesToRadians(camera.fov) * 0.5f); const float TAN_HALF_FOV = tan(SHMath::DegreesToRadians(camera.fov) * 0.5f);
camera.projMatrix = SHMatrix::Identity; camera.perspProjMatrix = SHMatrix::Identity;
camera.projMatrix(0, 0) = 1.0f / (ASPECT_RATIO * TAN_HALF_FOV); camera.perspProjMatrix(0, 0) = 1.0f / (ASPECT_RATIO * TAN_HALF_FOV);
camera.projMatrix(1, 1) = 1.0f / TAN_HALF_FOV; camera.perspProjMatrix(1, 1) = 1.0f / TAN_HALF_FOV;
camera.projMatrix(2, 2) = camera.zFar / (camera.zFar - camera.zNear); camera.perspProjMatrix(2, 2) = camera.zFar / (camera.zFar - camera.zNear);
camera.projMatrix(3, 3) = 0.0f; camera.perspProjMatrix(3, 3) = 0.0f;
camera.projMatrix(3, 2) = 1.0f; camera.perspProjMatrix(3, 2) = 1.0f;
camera.projMatrix(2, 3) = -(camera.zFar * camera.zNear) / (camera.zFar - camera.zNear); camera.perspProjMatrix(2, 3) = -(camera.zFar * camera.zNear) / (camera.zFar - camera.zNear);
//Orthographic projection matrix
const float right = camera.GetWidth() * 0.5f;
const float left = -right;
const float top = camera.GetHeight() * 0.5f;
const float btm = -top;
const float n = camera.GetNear();
const float f = camera.GetFar();
camera.orthoProjMatrix = SHMatrix::Identity;
camera.orthoProjMatrix(0, 0) = 2.0f / (right - left);
camera.orthoProjMatrix(1, 1) = 2.0f / (btm - top);
camera.orthoProjMatrix(2, 2) = 1.0f / (f-n);
camera.orthoProjMatrix(0, 3) = -(right + left) / (right - left);
camera.orthoProjMatrix(1, 3) = -(btm + top) / (btm - top);
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.projMatrix.Transpose();
camera.dirtyProj = false; camera.dirtyProj = false;
}
else
{
//const float R = camera.width * 0.5f;
//const float L = -R;
//const float T = camera.height * 0.5f;
//const float B = -T;
//camera.projMatrix = SHMatrix::Identity;
//camera.projMatrix(0, 0) = 2.0f / (R - L);
//camera.projMatrix(1, 1) = 2.0f / (B - T);
//camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear);
//camera.projMatrix(3, 0) = -(R + L) / (R - L);
//camera.projMatrix(3, 1) = -(B + T) / (B - T);
//camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear);
camera.dirtyProj = false;
}
} }
} }
@ -252,8 +260,6 @@ namespace SHADE
SHVec3 up = { 0.0f,1.0f,0.0f }; SHVec3 up = { 0.0f,1.0f,0.0f };
target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch)); target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw)); target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
target += camera.position; target += camera.position;
@ -287,6 +293,9 @@ namespace SHADE
if (SHSceneManager::CheckNodeAndComponentsActive<SHCameraComponent>(cam.GetEID())) if (SHSceneManager::CheckNodeAndComponentsActive<SHCameraComponent>(cam.GetEID()))
system->UpdateCameraComponent(cam); system->UpdateCameraComponent(cam);
} }
for (auto& handle : system->directorHandleList) for (auto& handle : system->directorHandleList)
{ {
handle->UpdateMatrix(); handle->UpdateMatrix();

View File

@ -37,8 +37,6 @@ namespace SHADE
void Exit (void); void Exit (void);
friend class EditorCameraUpdate;
class SH_API CameraSystemUpdate final: public SHSystemRoutine class SH_API CameraSystemUpdate final: public SHSystemRoutine
{ {
public: public:

View File

@ -218,7 +218,7 @@ namespace SHADE
EntityID result = MAX_EID; EntityID result = MAX_EID;
for (auto& entity : entityVec) for (auto& entity : entityVec)
{ {
if (entity->name == name) if (entity && entity->name == name)
result = entity->GetEID(); result = entity->GetEID();
} }
return result; return result;

View File

@ -5,6 +5,7 @@
namespace SHADE namespace SHADE
{ {
bool SHDragDrop::hasDragDrop = false; bool SHDragDrop::hasDragDrop = false;
SHDragDrop::DragDropTag SHDragDrop::currentDragDropTag{};
bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags) bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags)
{ return ImGui::BeginDragDropSource(flags); } { return ImGui::BeginDragDropSource(flags); }
@ -16,6 +17,10 @@ namespace SHADE
{ return ImGui::BeginDragDropTarget(); } { return ImGui::BeginDragDropTarget(); }
void SHDragDrop::EndTarget() void SHDragDrop::EndTarget()
{ ImGui::EndDragDropTarget(); hasDragDrop = false;} {
ImGui::EndDragDropTarget();
hasDragDrop = false;
currentDragDropTag = {};
}
} }

View File

@ -19,9 +19,13 @@ namespace SHADE
static void EndSource(); static void EndSource();
template<typename T> template<typename T>
static bool SetPayload(std::string_view const type, T* object, ImGuiCond const cond = 0) static bool SetPayload(DragDropTag const& type, T* object, ImGuiCond const cond = 0)
{ {
hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond); ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
hasDragDrop = true;
currentDragDropTag = type;
return hasDragDrop; return hasDragDrop;
} }
@ -32,13 +36,16 @@ namespace SHADE
static void EndTarget(); static void EndTarget();
template<typename T> template<typename T>
static T* AcceptPayload(std::string_view const type, ImGuiDragDropFlags const flags = 0) static T* AcceptPayload(DragDropTag const& type, ImGuiDragDropFlags const flags = 0)
{ {
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags)) if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags))
{
return static_cast<T*>(payload->Data); return static_cast<T*>(payload->Data);
}
return nullptr; return nullptr;
} }
static bool hasDragDrop; static bool hasDragDrop;
static DragDropTag currentDragDropTag;
}; };
} }

View File

@ -109,7 +109,7 @@ namespace SHADE
ImVec2 vertLineEnd = vertLineStart; ImVec2 vertLineEnd = vertLineStart;
for (auto const& subFolder : subFolders) for (auto const& subFolder : subFolders)
{ {
const float horizontalLineSize = 8.0f; const float horizontalLineSize = (subFolder->subFolders.empty() && subFolder->files.empty()) ? 25.0f : 8.0f;
const ImRect childRect = RecursivelyDrawTree(subFolder); const ImRect childRect = RecursivelyDrawTree(subFolder);
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
@ -117,7 +117,7 @@ namespace SHADE
} }
for (auto& file : files) for (auto& file : files)
{ {
const float horizontalLineSize = 25.0f; const float horizontalLineSize = (file.assetMeta && !file.assetMeta->subAssets.empty()) ? 8.0f : 25.0f;
const ImRect childRect = DrawFile(file); const ImRect childRect = DrawFile(file);
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
@ -182,7 +182,10 @@ namespace SHADE
return nodeRect; return nodeRect;
} }
if(file.assetMeta) if(file.assetMeta)
DrawAsset(file.assetMeta, file.ext); {
const ImRect childRect = DrawAsset(file.assetMeta, file.ext);
return childRect;
}
} }
ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept

View File

@ -116,12 +116,15 @@ namespace SHADE
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{ {
if(ImGui::IsDragDropActive()) if(ImGui::IsDragDropActive())
{
if (SHDragDrop::currentDragDropTag == SHDragDrop::DRAG_EID)
{ {
ParentSelectedEntities(MAX_EID, draggingEntities); ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear(); draggingEntities.clear();
ImGui::ClearDragDrop(); ImGui::ClearDragDrop();
} }
} }
}
ImGui::End(); ImGui::End();
} }
@ -233,8 +236,9 @@ namespace SHADE
{ {
ParentSelectedEntities(eid, draggingEntities); ParentSelectedEntities(eid, draggingEntities);
draggingEntities.clear(); draggingEntities.clear();
SHDragDrop::EndTarget(); //ImGui::ClearDragDrop();
} }
SHDragDrop::EndTarget();
} }
//Context menu //Context menu
@ -342,13 +346,16 @@ namespace SHADE
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID); SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
} }
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept
{ {
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
std::vector<EntityID> entitiesToParent = CleanUpEIDList(entities);
//auto const editor = SHSystemManager::GetSystem<SHEditor>(); //auto const editor = SHSystemManager::GetSystem<SHEditor>();
SHEntityParentCommand::EntityParentData entityParentData; SHEntityParentCommand::EntityParentData entityParentData;
std::vector<EntityID> parentedEIDS; std::vector<EntityID> parentedEIDS;
for (auto const& eid : entities) for (auto const& eid : entitiesToParent)
{ {
if(eid == parentEID) if(eid == parentEID)
continue; continue;
@ -411,14 +418,7 @@ namespace SHADE
void SHHierarchyPanel::CopySelectedEntities() void SHHierarchyPanel::CopySelectedEntities()
{ {
const auto editor = SHSystemManager::GetSystem<SHEditor>(); const auto editor = SHSystemManager::GetSystem<SHEditor>();
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); std::vector<EntityID> entitiesToCopy = CleanUpEIDList(editor->selectedEntities);
std::vector<EntityID> entitiesToCopy{};
std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToCopy), [&sceneGraph](EntityID const& eid)
{
if(sceneGraph.GetParent(eid)->GetEntityID() == MAX_EID)
return true;
return false;
});
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy)); SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
} }
@ -431,19 +431,25 @@ namespace SHADE
void SHHierarchyPanel::DeleteSelectedEntities() void SHHierarchyPanel::DeleteSelectedEntities()
{ {
const auto editor = SHSystemManager::GetSystem<SHEditor>(); const auto editor = SHSystemManager::GetSystem<SHEditor>();
std::vector<EntityID> entitiesToDelete = CleanUpEIDList(editor->selectedEntities);
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
}
std::vector<EntityID> SHHierarchyPanel::CleanUpEIDList(std::vector<EntityID> const& entities)
{
std::vector<EntityID> result;
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
std::vector<EntityID> entitiesToDelete{}; std::ranges::copy_if(entities, std::back_inserter(result), [&sceneGraph, &entities](EntityID const& eid)
std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToDelete), [&sceneGraph, &selectedEntities = editor->selectedEntities](EntityID const& eid)
{ {
EntityID parentEID = sceneGraph.GetParent(eid)->GetEntityID(); EntityID parentEID = sceneGraph.GetParent(eid)->GetEntityID();
if (parentEID == MAX_EID) if (parentEID == MAX_EID)
return true; return true;
else if(std::ranges::find(selectedEntities, parentEID) == selectedEntities.end()) if (std::ranges::find(entities, parentEID) == entities.end())
return true; return true;
return false; return false;
}); });
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete)); return result;
} }
}//namespace SHADE }//namespace SHADE

View File

@ -27,12 +27,13 @@ namespace SHADE
void DrawMenuBar() const noexcept; void DrawMenuBar() const noexcept;
ImRect RecursivelyDrawEntityNode(SHSceneNode* const); ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
void CreateChildEntity(EntityID parentEID) const noexcept; void CreateChildEntity(EntityID parentEID) const noexcept;
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept; void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept;
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID); void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
void SelectAllEntities(); void SelectAllEntities();
void CopySelectedEntities(); void CopySelectedEntities();
void PasteEntities(EntityID parentEID = MAX_EID); void PasteEntities(EntityID parentEID = MAX_EID);
void DeleteSelectedEntities(); void DeleteSelectedEntities();
std::vector<EntityID> CleanUpEIDList(std::vector<EntityID> const& entities);
bool skipFrame = false; bool skipFrame = false;
std::string filter; std::string filter;
bool isAnyNodeSelected = false; bool isAnyNodeSelected = false;

View File

@ -68,10 +68,10 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
const auto componentType = rttr::type::get<T>(); const auto componentType = rttr::type::get<T>();
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>()); ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::PopID();
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data())) if (ImGui::CollapsingHeader(componentType.get_name().data()))
{ {
@ -216,6 +216,90 @@ namespace SHADE
} }
} }
else DrawContextMenu(component); else DrawContextMenu(component);
ImGui::PopID();
}
template<>
static void DrawComponent(SHRigidBodyComponent* component)
{
if(!component)
return;
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHRigidBodyComponent>());
const auto componentType = rttr::type::get<SHRigidBodyComponent>();
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data()))
{
DrawContextMenu(component);
SHRigidBodyComponent::Type rbType = component->GetType();
auto enumAlign = rttr::type::get<SHRigidBodyComponent::Type>().get_enumeration();
auto names = enumAlign.get_names();
std::vector<const char*> list;
for (auto const& name : names)
list.push_back(name.data());
SHEditorWidgets::ComboBox("Type", list, [component] {return static_cast<int>(component->GetType()); }, [component, enumAlign](int const& idx)
{
auto values = enumAlign.get_values();
auto it = std::next(values.begin(), idx);
component->SetType((*it).convert<SHRigidBodyComponent::Type>());
}, "RigidBody Type");
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
{
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity");
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
}
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
{
SHEditorWidgets::DragFloat("Drag", [component] {return component->GetDrag(); }, [component](float const& value) {component->SetDrag(value); }, "Drag");
SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag");
SHEditorWidgets::CheckBox("Interpolate", [component] {return component->IsInterpolating(); }, [component](bool const& value) {component->SetInterpolate(value); }, "Interpolate");
SHEditorWidgets::BeginPanel(std::format("{} Constraints", ICON_FA_LOCK).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::TextLabel("Freeze Position");
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");
SHEditorWidgets::TextLabel("Freeze Rotation");
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");
SHEditorWidgets::EndPanel();
}
//Debug Info (Read-Only)
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
{
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component] {return component->GetRotation(); }, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields
{
SHEditorWidgets::DragVec3("Velocity", { "X", "Y", "Z" }, [component] {return component->GetLinearVelocity(); }, [](SHVec3 const& value) {}, false, "Linear Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::DragVec3("Angular\nVelocity", { "X", "Y", "Z" }, [component] {return component->GetAngularVelocity(); }, [](SHVec3 const& value) {}, false, "Angular Velocity", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
}
if (rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
{
SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep");
}
}
}
else
{
DrawContextMenu(component);
}
ImGui::PopID();
} }
template<> template<>
@ -223,7 +307,8 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
ImGui::PushID(component); ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHColliderComponent>());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine(); ImGui::SameLine();
@ -275,21 +360,12 @@ namespace SHADE
[&collider] [&collider]
{ {
auto offset = collider->GetRotationOffset(); auto offset = collider->GetRotationOffset();
offset.x = SHMath::RadiansToDegrees(offset.x);
offset.y = SHMath::RadiansToDegrees(offset.y);
offset.z = SHMath::RadiansToDegrees(offset.z);
return offset; return offset;
}, },
[&collider](SHVec3 const& vec) [&collider](SHVec3 const& vec)
{ {
const SHVec3 vecInRad collider->SetRotationOffset(vec);
{ }, true);
SHMath::DegreesToRadians(vec.x)
, SHMath::DegreesToRadians(vec.y)
, SHMath::DegreesToRadians(vec.z)
};
collider->SetRotationOffset(vecInRad);
});
SHEditorWidgets::EndPanel(); SHEditorWidgets::EndPanel();
} }
@ -330,6 +406,7 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHLightComponent>());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine(); ImGui::SameLine();
@ -353,6 +430,7 @@ namespace SHADE
{ {
DrawContextMenu(component); DrawContextMenu(component);
} }
ImGui::PopID();
} }
template<> template<>
@ -360,6 +438,7 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHRenderable>());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine(); ImGui::SameLine();
@ -368,19 +447,26 @@ namespace SHADE
DrawContextMenu(component); DrawContextMenu(component);
Handle<SHMesh> const& mesh = component->GetMesh(); Handle<SHMesh> const& mesh = component->GetMesh();
Handle<SHMaterialInstance> const& mat = component->GetMaterial(); Handle<SHMaterialInstance> const& mat = component->GetMaterial();
const auto MESH_NAME = SHResourceManager::GetAssetName<SHMesh>(mesh).value_or("");
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]() SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", MESH_NAME, [component]()
{ {
Handle<SHMesh> const& mesh = component->GetMesh(); Handle<SHMesh> const& mesh = component->GetMesh();
return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0); return SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0);
}, },
[component](AssetID const& id) [component](AssetID const& id)
{ {
if(SHAssetManager::GetType(id) != AssetType::MESH)
{
SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!")
return;
}
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id)); component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
SHResourceManager::FinaliseChanges(); SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE); }, SHDragDrop::DRAG_RESOURCE);
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]() const auto MAT_NAME = mat ? SHResourceManager::GetAssetName<SHMaterial>(mat->GetBaseMaterial()).value_or("") : "";
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", MAT_NAME,
[component]()
{ {
Handle<SHMaterialInstance> const& mat = component->GetMaterial(); Handle<SHMaterialInstance> const& mat = component->GetMaterial();
if (!mat) if (!mat)
@ -389,6 +475,11 @@ namespace SHADE
}, },
[component](AssetID const& id) [component](AssetID const& id)
{ {
if (SHAssetManager::GetType(id) != AssetType::MATERIAL)
{
SHLOG_WARNING("Attempted to assign non material asset to Renderable Mesh property!")
return;
}
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id))); component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id)));
}, SHDragDrop::DRAG_RESOURCE); }, SHDragDrop::DRAG_RESOURCE);
@ -397,5 +488,6 @@ namespace SHADE
{ {
DrawContextMenu(component); DrawContextMenu(component);
} }
ImGui::PopID();
} }
} }

View File

@ -18,7 +18,10 @@
#include "Physics/Interface/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Camera/SHCameraComponent.h" #include "Camera/SHCameraComponent.h"
#include "Camera/SHCameraArmComponent.h" #include "Camera/SHCameraArmComponent.h"
#include "UI/SHUIComponent.h"
#include "UI/SHCanvasComponent.h"
#include "SHEditorComponentView.h" #include "SHEditorComponentView.h"
#include "AudioSystem/SHAudioListenerComponent.h"
namespace SHADE namespace SHADE
{ {
@ -128,10 +131,19 @@ namespace SHADE
if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid)) if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid))
{ {
DrawComponent(cameraComponent); DrawComponent(cameraComponent);
}if (auto cameraArmComponent = SHComponentManager::GetComponent_s<SHCameraArmComponent>(eid)) }
if (auto cameraArmComponent = SHComponentManager::GetComponent_s<SHCameraArmComponent>(eid))
{ {
DrawComponent(cameraArmComponent); DrawComponent(cameraArmComponent);
} }
if (auto canvasComponent= SHComponentManager::GetComponent_s<SHCanvasComponent>(eid))
{
DrawComponent(canvasComponent);
}
if (auto uiComponent = SHComponentManager::GetComponent_s<SHUIComponent>(eid))
{
DrawComponent(uiComponent);
}
ImGui::Separator(); ImGui::Separator();
// Render Scripts // Render Scripts
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>()); SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
@ -143,6 +155,7 @@ namespace SHADE
DrawAddComponentButton<SHCameraComponent>(eid); DrawAddComponentButton<SHCameraComponent>(eid);
DrawAddComponentButton<SHCameraArmComponent>(eid); DrawAddComponentButton<SHCameraArmComponent>(eid);
DrawAddComponentButton<SHLightComponent>(eid); DrawAddComponentButton<SHLightComponent>(eid);
DrawAddComponentButton<SHCanvasComponent>(eid);
// Components that require Transforms // Components that require Transforms

View File

@ -78,7 +78,26 @@ namespace SHADE
ImGui::BeginDisabled(!isDirty); ImGui::BeginDisabled(!isDirty);
if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data())) if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
{ {
//save auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
// Replace Material if it's been instantiated
auto matHandle = SHResourceManager::Get<SHMaterial>(currentViewedMaterial);
if (matHandle)
{
// - Get Shader Modules
auto vertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->vertexShader);
auto fragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
if (vertShader && fragShader && gfxSystem)
{
// - Retrieve pipeline from pipeline library
auto renderPass = gfxSystem->GetPrimaryRenderpass();
auto subPass = renderPass->GetSubpass(currentMatSpec->subpassName);
auto pipeline = renderPass->GetOrCreatePipeline({ vertShader, fragShader }, subPass);
// - Set Pipeline
matHandle->SetPipeline(pipeline);
}
}
// Save Properties
if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial)) if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial))
{ {
YAML::Emitter out; YAML::Emitter out;
@ -102,7 +121,20 @@ namespace SHADE
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>()); currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT: case SHADE::SHShaderBlockInterface::Variable::Type::INT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<int>()); {
Handle<SHTexture> texture = SHResourceManager::LoadOrGet<SHTexture>(PROP_NODE.as<int>());
// HACK: Need to split this out to a separate pass before loading the materials and subsequently, the scenes
gfxSystem->BuildTextures();
if (texture)
{
matHandle->SetProperty(VARIABLE->offset, texture->TextureArrayIndex);
}
else
{
SHLOG_WARNING("[] Attempted to load invalid texture! Setting to 0.");
matHandle->SetProperty(VARIABLE->offset, 0);
}
}
break; break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2: case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>()); currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
@ -136,12 +168,38 @@ namespace SHADE
{ {
/*if(!shaderModule) /*if(!shaderModule)
return;*/ return;*/
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface();
//auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); //auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
int const varCount = static_cast<int>(interface->GetVariableCount()); // Shader
bool shaderChanged = false;
const auto* SHADER_INFO = SHAssetManager::GetData<SHShaderAsset>(currentMatSpec->fragShader);
const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader";
ImGui::BeginDisabled();
isDirty |= SHEditorWidgets::DragDropReadOnlyField<AssetID>
(
"Fragment Shader", 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<SHVkShaderModule>(currentMatSpec->fragShader);
if (!fragShader)
return;
// Get interface for the shader combination
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
);
if (!interface)
return;
// Properties
int const varCount = static_cast<int>(interface->GetVariableCount());
for (int i = 0; i < varCount; ++i) for (int i = 0; i < varCount; ++i)
{ {
auto variable = interface->GetVariable(i); auto variable = interface->GetVariable(i);

View File

@ -220,14 +220,21 @@ namespace SHADE
const auto editor = SHSystemManager::GetSystem<SHEditor>(); const auto editor = SHSystemManager::GetSystem<SHEditor>();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY); ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW)) if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
{
if(editor->editorState == SHEditor::State::STOP)
{ {
if (editor->SaveScene()) if (editor->SaveScene())
{ {
editor->Play(); editor->Play();
} }
} }
else
{
editor->Play();
}
}
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP || editor->editorState == SHEditor::State::PAUSE);
if(ImGui::SmallButton(ICON_MD_PAUSE)) if(ImGui::SmallButton(ICON_MD_PAUSE))
{ {
editor->Pause(); editor->Pause();

View File

@ -14,6 +14,7 @@
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
#include "../../SHEditorWidgets.hpp"
constexpr std::string_view windowName = "\xef\x80\x95 Viewport"; constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
@ -85,7 +86,7 @@ namespace SHADE
shouldUpdateCamArm = ImGui::IsWindowHovered() && ImGui::IsKeyDown(ImGuiKey_LeftAlt) && ImGui::IsMouseDown(ImGuiMouseButton_Left); shouldUpdateCamArm = ImGui::IsWindowHovered() && ImGui::IsKeyDown(ImGuiKey_LeftAlt) && ImGui::IsMouseDown(ImGuiMouseButton_Left);
if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) if (editor->editorState != SHEditor::State::PLAY && !ImGui::IsAnyItemActive() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
{ {
if (ImGui::IsKeyReleased(ImGuiKey_W)) if (ImGui::IsKeyReleased(ImGuiKey_W))
{ {
@ -151,7 +152,7 @@ namespace SHADE
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{ {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::Text("Translate [Q]"); ImGui::Text("Translate [W]");
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
if (isTranslate) if (isTranslate)
@ -169,7 +170,7 @@ namespace SHADE
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{ {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::Text("Rotate [W]"); ImGui::Text("Rotate [E]");
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
if (isRotate) if (isRotate)
@ -187,12 +188,19 @@ namespace SHADE
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{ {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::Text("Scale [E]"); ImGui::Text("Scale [R]");
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
if (isScale) if (isScale)
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::EndDisabled(); ImGui::EndDisabled();
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
auto editorCamera = camSystem->GetEditorCamera();
//ImGui::SetNextItemWidth(10.0f);
SHEditorWidgets::SliderFloat("CamSpeed", 0.0f, 5.0f, [editorCamera] {return editorCamera->movementSpeed; }, [editorCamera](float const& value) {editorCamera->movementSpeed = value; });
SHEditorWidgets::DragVec3("TurnSpeed", { "X", "Y", "Z" }, [editorCamera] {return editorCamera->turnSpeed; }, [editorCamera](SHVec3 const& value) {editorCamera->turnSpeed = value; });
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
} }

View File

@ -166,14 +166,14 @@ namespace SHADE
const ImGuiWindow* const window = ImGui::GetCurrentWindow(); const ImGuiWindow* const window = ImGui::GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
return false; return false;
static constexpr float defaultLabelColWidth = 80.0f;
const ImGuiContext& g = *GImGui; const ImGuiContext& g = *GImGui;
bool valueChanged = false; bool valueChanged = false;
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.c_str()); ImGui::PushID(label.c_str());
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f); PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize); ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
ImGui::SetColumnWidth(-1, 80.0f); ImGui::SetColumnWidth(-1, defaultLabelColWidth);
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered) if (isHovered)
*isHovered |= ImGui::IsItemHovered(); *isHovered |= ImGui::IsItemHovered();
@ -219,7 +219,7 @@ namespace SHADE
} }
bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags); bool const changed = DragN<float, 2>(label, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags);
static bool startRecording = false; static bool startRecording = false;
if (changed) if (!(flags & ImGuiSliderFlags_ReadOnly) && changed)
{ {
if(isAnAngleInRad) if(isAnAngleInRad)
{ {
@ -255,7 +255,7 @@ namespace SHADE
bool isHovered = false; bool isHovered = false;
bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags, &isHovered); bool const changed = DragN<float, 3>(label, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags, &isHovered);
static bool startRecording = false; static bool startRecording = false;
if (changed) if (!(flags & ImGuiSliderFlags_ReadOnly) && changed)
{ {
SHVec3 old = get(); SHVec3 old = get();
if(isAnAngleInRad) if(isAnAngleInRad)
@ -293,7 +293,7 @@ namespace SHADE
} }
bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags); bool const changed = DragN<float, 4>(label, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags);
static bool startRecording = false; static bool startRecording = false;
if (changed) if (!(flags & ImGuiSliderFlags_ReadOnly) && changed)
{ {
if(isAnAngleInRad) if(isAnAngleInRad)
{ {
@ -422,7 +422,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
bool changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr); bool changed = ImGui::InputText("##inputText", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
if(SHDragDrop::BeginTarget()) if(SHDragDrop::BeginTarget())
{ {
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag)) if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
@ -454,7 +454,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
const bool hasChange = ImGui::DragScalar("##", data_type, &value, speed, &p_min, &p_max, displayFormat, flags); const bool hasChange = ImGui::DragScalar("##dragScalar", data_type, &value, speed, &p_min, &p_max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {
@ -487,7 +487,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
const bool hasChange = ImGui::DragFloat("##", &value, speed, p_min, p_max, displayFormat, flags); const bool hasChange = ImGui::DragFloat("##dragFloat", &value, speed, p_min, p_max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {
@ -520,7 +520,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
const bool hasChange = ImGui::DragInt("##", &value, speed, p_min, p_max, displayFormat, flags); const bool hasChange = ImGui::DragInt("##dragInt", &value, speed, p_min, p_max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {
@ -553,7 +553,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
bool const hasChange = ImGui::SliderScalar("##", data_type, &value, &min, &max, displayFormat, flags); bool const hasChange = ImGui::SliderScalar("##sliderScalar", data_type, &value, &min, &max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {
@ -587,7 +587,8 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
bool const hasChange = ImGui::SliderFloat("##", &value, min, max, displayFormat, flags); ImGui::SetNextItemWidth(ImGui::CalcTextSize(displayFormat).x + ImGui::GetStyle().ItemInnerSpacing.x * 2.0f);
bool const hasChange = ImGui::SliderFloat("##sliderFloat", &value, min, max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {
@ -621,7 +622,7 @@ namespace SHADE
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::PushID(label.data()); ImGui::PushID(label.data());
TextLabel(label); TextLabel(label);
bool const hasChange = ImGui::SliderInt("##", &value, min, max, displayFormat, flags); bool const hasChange = ImGui::SliderInt("##sliderInt", &value, min, max, displayFormat, flags);
static bool startRecording = false; static bool startRecording = false;
if (hasChange) if (hasChange)
{ {

View File

@ -38,11 +38,11 @@ namespace SHADE
/// </summary> /// </summary>
std::vector<vk::DescriptorPoolSize> Limits = std::vector<vk::DescriptorPoolSize> Limits =
{ {
{ vk::DescriptorType::eCombinedImageSampler, 100 }, { vk::DescriptorType::eCombinedImageSampler, 1000 },
{ vk::DescriptorType::eUniformBuffer, 100 }, { vk::DescriptorType::eUniformBuffer, 1000 },
{ vk::DescriptorType::eUniformBufferDynamic, 100 }, { vk::DescriptorType::eUniformBufferDynamic, 1000 },
{ vk::DescriptorType::eStorageImage, 100}, { vk::DescriptorType::eStorageImage, 1000 },
{ vk::DescriptorType::eStorageBufferDynamic, 100 } { vk::DescriptorType::eStorageBufferDynamic, 1000 }
}; };
/// <summary> /// <summary>
/// Maximum number of descriptor sets allowed /// Maximum number of descriptor sets allowed

View File

@ -43,6 +43,85 @@ namespace SHADE
setAllDirtyFlags(); setAllDirtyFlags();
} }
SHBatch::SHBatch(SHBatch&& rhs)
: device { rhs.device }
, pipeline { rhs.pipeline }
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
, matBufferDirty { std::move(rhs.matBufferDirty) }
, subBatches { std::move(rhs.subBatches) }
, drawData { std::move(drawData) }
, transformData { std::move(rhs.transformData) }
, instancedIntegerData { std::move(rhs.instancedIntegerData) }
, matPropsData { std::move(rhs.matPropsData) }
, matPropsDataSize { rhs.matPropsDataSize }
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
, singleMatPropSize { rhs.singleMatPropSize }
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
, drawDataBuffer { rhs.drawDataBuffer }
, transformDataBuffer { rhs.transformDataBuffer }
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
, matPropsBuffer { rhs.matPropsBuffer }
, matPropsDescSet { rhs.matPropsDescSet }
{
rhs.drawDataBuffer = {};
rhs.transformDataBuffer = {};
rhs.instancedIntegerBuffer = {};
rhs.matPropsBuffer = {};
rhs.matPropsDescSet = {};
}
SHBatch& SHBatch::operator=(SHBatch&& rhs)
{
if (this == &rhs)
return *this;
device = rhs.device ;
pipeline = rhs.pipeline ;
referencedMatInstances = std::move(rhs.referencedMatInstances);
matBufferDirty = std::move(rhs.matBufferDirty) ;
subBatches = std::move(rhs.subBatches) ;
drawData = std::move(drawData) ;
transformData = std::move(rhs.transformData) ;
instancedIntegerData = std::move(rhs.instancedIntegerData) ;
matPropsData = std::move(rhs.matPropsData) ;
matPropsDataSize = rhs.matPropsDataSize ;
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
singleMatPropSize = rhs.singleMatPropSize ;
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
drawDataBuffer = rhs.drawDataBuffer ;
transformDataBuffer = rhs.transformDataBuffer ;
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
matPropsBuffer = rhs.matPropsBuffer ;
matPropsDescSet = rhs.matPropsDescSet ;
// Unset values
rhs.drawDataBuffer = {};
rhs.transformDataBuffer = {};
rhs.instancedIntegerBuffer = {};
rhs.matPropsBuffer = {};
rhs.matPropsDescSet = {};
return *this;
}
SHBatch::~SHBatch()
{
// Free GPU buffers
for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{
if (drawDataBuffer[i])
drawDataBuffer[i].Free();
if (transformDataBuffer[i])
transformDataBuffer[i].Free();
if (instancedIntegerBuffer[i])
instancedIntegerBuffer[i].Free();
if (matPropsBuffer[i])
matPropsBuffer[i].Free();
if (matPropsDescSet[i])
matPropsDescSet[i].Free();
}
}
void SHBatch::Add(const SHRenderable* renderable) void SHBatch::Add(const SHRenderable* renderable)
{ {
// Ignore if null // Ignore if null

View File

@ -71,6 +71,11 @@ namespace SHADE
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHBatch(Handle<SHVkPipeline> pipeline); SHBatch(Handle<SHVkPipeline> pipeline);
SHBatch(const SHBatch&) = delete;
SHBatch(SHBatch&& rhs);
SHBatch& operator=(const SHBatch&) = delete;
SHBatch& operator=(SHBatch&& rhs);
~SHBatch();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */

View File

@ -69,9 +69,9 @@ namespace SHADE
batch->Remove(renderable); batch->Remove(renderable);
// If batch is empty, remove batch // TODO: If the pipeline is unloaded, we remove the batch
if (batch->IsEmpty()) /*if (batch->IsEmpty() && !batch->GetPipeline())
batches.erase(batch); batches.erase(batch);*/
} }
void SHSuperBatch::Clear() noexcept void SHSuperBatch::Clear() noexcept

View File

@ -570,13 +570,6 @@ namespace SHADE
return; return;
} }
// Finalise all batches
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// Resize // Resize
auto windowDims = window->GetWindowSize(); auto windowDims = window->GetWindowSize();
if (renderContext.GetResizeAndReset()) if (renderContext.GetResizeAndReset())
@ -591,6 +584,13 @@ namespace SHADE
// #BackEndTest: For for the fence initialized by queue submit // #BackEndTest: For for the fence initialized by queue submit
renderContext.WaitForFence(); renderContext.WaitForFence();
// Finalise all batches
for (auto vp : viewports)
for (auto renderer : vp->GetRenderers())
{
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool);
}
// #BackEndTest: Acquire the next image in the swapchain available // #BackEndTest: Acquire the next image in the swapchain available
renderContext.AcquireNextIamge(); renderContext.AcquireNextIamge();
const uint32_t CURR_FRAME_IDX_2 = renderContext.GetCurrentFrame(); const uint32_t CURR_FRAME_IDX_2 = renderContext.GetCurrentFrame();
@ -602,8 +602,6 @@ namespace SHADE
if (currFrameData.cmdPoolHdls.empty()) if (currFrameData.cmdPoolHdls.empty())
throw std::runtime_error("No command pools available!"); throw std::runtime_error("No command pools available!");
currFrameData.cmdPoolHdls[0]->Reset(); currFrameData.cmdPoolHdls[0]->Reset();
} }
/***************************************************************************/ /***************************************************************************/
@ -710,6 +708,11 @@ namespace SHADE
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial()); return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
} }
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> SHGraphicsSystem::GetAllMaterialInstances()
{
return resourceManager.GetDenseAccess<SHMaterialInstance>();
}
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance) void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
{ {
resourceManager.Free(materialInstance); resourceManager.Free(materialInstance);
@ -807,7 +810,7 @@ namespace SHADE
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
{ {
SHResourceManager::FinaliseChanges(); // Begin rendering
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender(); reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
} }
@ -833,6 +836,36 @@ namespace SHADE
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{ {
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender(); reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
// Reset all material isDirty
auto gfxSystem = reinterpret_cast<SHGraphicsSystem*>(system);
auto [matBegin, matEnd] = gfxSystem->resourceManager.GetDenseAccess<SHMaterial>();
for (auto iter = matBegin; iter != matEnd; ++iter)
{
iter->ClearChangeFlag();
}
}
SHGraphicsSystem::PrepareRenderRoutine::PrepareRenderRoutine()
: SHSystemRoutine("Graphics System Pre-Render", true)
{}
void SHGraphicsSystem::PrepareRenderRoutine::Execute(double) noexcept
{
// Finish up, loading, unloading any resources
SHResourceManager::FinaliseChanges();
// Clean up and update all materials
auto gfxSystem = reinterpret_cast<SHGraphicsSystem*>(system);
auto [matInstBegin, matInstEnd] = gfxSystem->resourceManager.GetDenseAccess<SHMaterialInstance>();
for (auto iter = matInstBegin; iter != matInstEnd; ++iter)
{
auto baseMat = iter->GetBaseMaterial();
if (baseMat && baseMat->HasPipelineChanged())
{
iter->ResetProperties();
}
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -847,6 +880,9 @@ namespace SHADE
auto& renderables = SHComponentManager::GetDense<SHRenderable>(); auto& renderables = SHComponentManager::GetDense<SHRenderable>();
for (auto& renderable : renderables) for (auto& renderable : renderables)
{ {
// Check if the material instance is now unused
renderable.CleanUpMaterials();
if (!renderable.HasChanged()) if (!renderable.HasChanged())
continue; continue;
@ -858,7 +894,6 @@ namespace SHADE
oldSuperBatch->Remove(&renderable); oldSuperBatch->Remove(&renderable);
} }
// Add to new SuperBatch if there is a material
// Add to new SuperBatch if there is a material and a mesh to render // Add to new SuperBatch if there is a material and a mesh to render
Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial(); Handle<SHMaterialInstance> newMatInstance = renderable.GetMaterial();
if (newMatInstance && renderable.GetMesh()) if (newMatInstance && renderable.GetMesh())

View File

@ -110,6 +110,12 @@ namespace SHADE
EndRoutine(); EndRoutine();
virtual void Execute(double dt) noexcept override final; virtual void Execute(double dt) noexcept override final;
}; };
class SH_API PrepareRenderRoutine final : public SHSystemRoutine
{
public:
PrepareRenderRoutine();
virtual void Execute(double dt) noexcept override final;
};
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
{ {
public: public:
@ -156,6 +162,7 @@ namespace SHADE
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance();
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst); Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> GetAllMaterialInstances();
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance); void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; } Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; }
Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); } Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); }

View File

@ -6,24 +6,26 @@
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "SHMaterialInstance.h"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Pipeline Functions */ /* Pipeline Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline) void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline)
{ {
// Reassignment, we ignore
if (_pipeline == pipeline)
return;
pipeline = _pipeline; pipeline = _pipeline;
// Set up properties based on the pipeline // Set up properties based on the pipeline
if (!pipeline) if (pipeline)
{ {
// Clear memory and all that
propMemory.reset();
return;
}
// Allocate memory for properties // Allocate memory for properties
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
@ -35,7 +37,13 @@ namespace SHADE
{ {
propMemory.reset(new char[propMemorySize]); propMemory.reset(new char[propMemorySize]);
} }
}
// Reset since pipeline changed
ResetProperties(); ResetProperties();
// Mark changed so that we know to update dependent material instances
propertiesChanged = true;
} }
Handle<SHVkPipeline> SHMaterial::GetPipeline() const Handle<SHVkPipeline> SHMaterial::GetPipeline() const
@ -43,9 +51,9 @@ namespace SHADE
return pipeline; return pipeline;
} }
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Property Functions */ /* Property Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterial::ResetProperties() void SHMaterial::ResetProperties()
{ {
// Reset all the properties to default values // Reset all the properties to default values
@ -67,6 +75,8 @@ namespace SHADE
break; break;
} }
} }
propertiesChanged = true;
} }
void SHMaterial::ExportProperties(void* dest) const noexcept void SHMaterial::ExportProperties(void* dest) const noexcept
@ -81,9 +91,9 @@ namespace SHADE
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
} }
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{ {
return pipeline->GetPipelineLayout()->GetShaderBlockInterface return pipeline->GetPipelineLayout()->GetShaderBlockInterface
@ -93,4 +103,12 @@ namespace SHADE
vk::ShaderStageFlagBits::eFragment vk::ShaderStageFlagBits::eFragment
); );
} }
/*-----------------------------------------------------------------------------------*/
/* Query Functions */
/*-----------------------------------------------------------------------------------*/
void SHMaterial::ClearChangeFlag() noexcept
{
propertiesChanged = false;
}
} }

View File

@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
#include "SHCommonTypes.h" #include "SHCommonTypes.h"
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
@ -35,7 +36,7 @@ namespace SHADE
Describes a Pipeline along with it's associated properties for this instance. Describes a Pipeline along with it's associated properties for this instance.
*/ */
/***********************************************************************************/ /***********************************************************************************/
class SHMaterial class SH_API SHMaterial : public ISelfHandle<SHMaterial>
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -67,6 +68,10 @@ namespace SHADE
/* Query Functions */ /* Query Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept; Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept;
bool HasPipelineChanged() const noexcept { return pipelineChanged; }
bool HasPropertiesChanged() const noexcept { return propertiesChanged; }
bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; }
void ClearChangeFlag() noexcept;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -75,6 +80,8 @@ namespace SHADE
Handle<SHVkPipeline> pipeline; Handle<SHVkPipeline> pipeline;
std::unique_ptr<char> propMemory; std::unique_ptr<char> propMemory;
Byte propMemorySize = 0; Byte propMemorySize = 0;
bool propertiesChanged = true;
bool pipelineChanged = true;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -33,8 +33,7 @@ namespace SHADE
} }
// Get offset and modify the memory directly // Get offset and modify the memory directly
T* dataPtr = reinterpret_cast<T*>(propMemory.get() + PROP_INFO->offset); setPropertyUnsafe(PROP_INFO->offset, value);
*dataPtr = value;
} }
template<typename T> template<typename T>
@ -85,6 +84,12 @@ namespace SHADE
template<typename T> template<typename T>
void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value) void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value)
{ {
// Size check
if (memOffset + sizeof(T) > propMemorySize)
{
throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory");
}
(*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value; (*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value;
propertiesChanged = true;
} }
} }

View File

@ -31,11 +31,11 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterialInstance::ResetProperties() noexcept void SHMaterialInstance::ResetProperties() noexcept
{ {
// Reset all the properties to default values // Reset all the properties to default values
memset(dataStore.get(), 0, dataStoreSize); memset(dataStore.get(), 0, dataStoreSize);
overrideData.clear(); overrideData.clear();
dataStore.reset(); dataStore.reset();
dataWasChanged = true;
} }
void SHMaterialInstance::ExportProperties(void* dest) void SHMaterialInstance::ExportProperties(void* dest)
@ -65,9 +65,17 @@ namespace SHADE
dataWasChanged = false; dataWasChanged = false;
} }
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Query Functions */
/*-----------------------------------------------------------------------------------*/
bool SHMaterialInstance::HasChanged() const noexcept
{
return dataWasChanged || (baseMaterial && baseMaterial->HasChanged());
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterialInstance::getShaderBlockInterface() const noexcept
{ {
return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface

View File

@ -43,9 +43,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
struct OverrideData struct OverrideData
{ {
size_t Index; uint32_t Index;
size_t DataSize; uint32_t DataSize;
size_t StoredDataOffset; uint32_t StoredDataOffset;
}; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -69,7 +69,8 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; } Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; }
bool HasChanged() const noexcept { return dataWasChanged; } bool HasChanged() const noexcept;
bool IsBlank() const noexcept { return overrideData.empty(); } // No overrides
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -11,6 +11,7 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
#include "SHMaterialInstance.h" #include "SHMaterialInstance.h"
#include "SHMaterial.h"
namespace SHADE namespace SHADE
{ {
@ -34,9 +35,20 @@ namespace SHADE
dataStore.reset(new char[dataStoreSize]); dataStore.reset(new char[dataStoreSize]);
} }
// Check if this was stored before
const uint32_t VAR_IDX = SHADER_INFO->GetVariableIndex(key);
auto existingOverride = std::find_if(overrideData.begin(), overrideData.end(), [&](const OverrideData& od)
{
return od.Index == VAR_IDX;
});
// Otherwise, create it
if (existingOverride == overrideData.end())
{
OverrideData od; OverrideData od;
od.Index = SHADER_INFO->GetVariableIndex(key); od.Index = VAR_IDX;
od.DataSize = sizeof(T); od.DataSize = sizeof(T);
if (overrideData.empty()) if (overrideData.empty())
{ {
od.StoredDataOffset = 0; od.StoredDataOffset = 0;
@ -47,12 +59,20 @@ namespace SHADE
od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize; od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize;
} }
// Get offset and modify the memory directly // Size check
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + od.StoredDataOffset); if (od.StoredDataOffset + sizeof(T) > dataStoreSize)
*dataPtr = value; {
throw std::runtime_error("Attempted to write to out of bounds MaterialInstance properties memory");
}
// Save the override data information // Save the override data information
overrideData.emplace_back(std::move(od)); overrideData.emplace_back(std::move(od));
existingOverride = overrideData.end() - 1;
}
// Get offset and modify the memory directly
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + existingOverride->StoredDataOffset);
*dataPtr = value;
// Flag // Flag
dataWasChanged = true; dataWasChanged = true;
@ -73,8 +93,19 @@ namespace SHADE
{ {
return PROP_IDX == data.Index; return PROP_IDX == data.Index;
}); });
// No overrides, we get from the base material instead
if (prop == overrideData.end()) if (prop == overrideData.end())
{
if (baseMaterial)
{
return baseMaterial->GetProperty<T>(key);
}
else
{
throw std::invalid_argument("Attempted to get an property that was not set previously!"); throw std::invalid_argument("Attempted to get an property that was not set previously!");
}
}
// Get offset and return the memory directly // Get offset and return the memory directly
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + prop->StoredDataOffset); T* dataPtr = reinterpret_cast<T*>(dataStore.get() + prop->StoredDataOffset);

View File

@ -91,11 +91,20 @@ namespace SHADE
{ {
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
material = gfxSystem->AddMaterialInstanceCopy(sharedMaterial); material = gfxSystem->AddMaterialInstanceCopy(sharedMaterial);
matChanged = true;
} }
return material; return material;
} }
void SHRenderable::CleanUpMaterials() noexcept
{
if (material && material->IsBlank())
{
SetMaterial(sharedMaterial);
}
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Mesh Functions */ /* Mesh Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -114,6 +123,20 @@ namespace SHADE
return lightLayer; return lightLayer;
} }
bool SHRenderable::HasChanged() const noexcept
{
if (matChanged || meshChanged)
return true;
// If the underlying material has changed
auto mat = GetMaterial();
if (mat)
{
return mat->HasChanged();
}
return false;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -53,6 +53,10 @@ namespace SHADE
Handle<SHMaterialInstance> GetModifiableMaterial(); Handle<SHMaterialInstance> GetModifiableMaterial();
Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; } Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; }
bool HasMaterialChanged() const noexcept { return matChanged; } bool HasMaterialChanged() const noexcept { return matChanged; }
/// <summary>
/// Clears the modifiable material if it is unused.
/// </summary>
void CleanUpMaterials() noexcept;
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Mesh Functions */ /* Mesh Functions */
@ -70,7 +74,7 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
bool HasChanged() const noexcept { return matChanged || meshChanged; } // Whether or not the mesh or material has changed bool HasChanged() const noexcept; // Whether or not the mesh or material has changed
void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this void ResetChangedFlag(); // TODO: Lock it so that only SHBatcherDispatcher can access this
private: private:

View File

@ -34,7 +34,7 @@ namespace SHADE
{ {
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{ {
.blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd, .colorBlendOp = vk::BlendOp::eAdd,

View File

@ -129,11 +129,11 @@ namespace SHADE
for (auto& predResource : prereq->attResources) for (auto& predResource : prereq->attResources)
{ {
// if a predecessor's resource is used by this node, we want to copy the final layout from the pred to the initial of this node // if a predecessor's resource is used by this node, we want to copy the final layout from the pred to the initial of this node
if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping.contains(resourceID)) if (uint64_t resourceID = predResource.GetId().Raw; node->resourceAttachmentMapping->contains(resourceID))
{ {
// Get the resource's attachment index in BOTH the predecessor and the current node // Get the resource's attachment index in BOTH the predecessor and the current node
uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping[resourceID]; uint32_t prereqResourceAttIndex = prereq->resourceAttachmentMapping->at(resourceID);
uint32_t resourceAttIndex = node->resourceAttachmentMapping[resourceID]; uint32_t resourceAttIndex = node->resourceAttachmentMapping->at(resourceID);
// Use the resource attachment index to get the attachment description in the renderpass // Use the resource attachment index to get the attachment description in the renderpass
auto& attDesc = node->attachmentDescriptions[resourceAttIndex]; auto& attDesc = node->attachmentDescriptions[resourceAttIndex];

View File

@ -124,7 +124,7 @@ namespace SHADE
, framebuffers{} , framebuffers{}
, prereqNodes{ std::move(predecessors) } , prereqNodes{ std::move(predecessors) }
, attachmentDescriptions{} , attachmentDescriptions{}
, resourceAttachmentMapping{} , resourceAttachmentMapping { new std::unordered_map<uint64_t, uint32_t> }
, attResources{ } , attResources{ }
, subpasses{} , subpasses{}
, executed{ false } , executed{ false }
@ -163,7 +163,7 @@ namespace SHADE
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
containsSwapchainImage = true; containsSwapchainImage = true;
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); resourceAttachmentMapping->try_emplace(attResources[i].GetId().Raw, i);
} }
if (!containsSwapchainImage) if (!containsSwapchainImage)
@ -254,7 +254,7 @@ namespace SHADE
( (
subpassName, subpassName,
graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()), graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()),
&resourceAttachmentMapping resourceAttachmentMapping.get()
) )
); );
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u); subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);

View File

@ -60,7 +60,7 @@ namespace SHADE
std::vector<vk::SubpassDependency> spDeps; std::vector<vk::SubpassDependency> spDeps;
//! For indexing resources fast //! For indexing resources fast
std::unordered_map<uint64_t, uint32_t> resourceAttachmentMapping; std::unique_ptr<std::unordered_map<uint64_t, uint32_t>> resourceAttachmentMapping;
//! For indexing subpasses //! For indexing subpasses
std::map<std::string, uint32_t> subpassIndexing; std::map<std::string, uint32_t> subpassIndexing;

View File

@ -97,7 +97,7 @@ namespace SHADE
colorReferences = std::move(rhs.colorReferences); colorReferences = std::move(rhs.colorReferences);
depthReferences = std::move(rhs.depthReferences); depthReferences = std::move(rhs.depthReferences);
inputReferences = std::move(rhs.inputReferences); inputReferences = std::move(rhs.inputReferences);
resourceAttachmentMapping = rhs.resourceAttachmentMapping; resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
descriptorSetLayout = rhs.descriptorSetLayout; descriptorSetLayout = rhs.descriptorSetLayout;
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
graphStorage = rhs.graphStorage; graphStorage = rhs.graphStorage;

View File

@ -86,9 +86,17 @@ namespace SHADE
{ {
if (bufferHandle) if (bufferHandle)
{ {
// Resize // Resize if we need to resize
if (bufferHandle->GetSizeStored() < size)
{
bufferHandle->ResizeReplace(size, src, size); bufferHandle->ResizeReplace(size, src, size);
} }
// Otherwise just copy the data over
else
{
bufferHandle->MapWriteUnmap(src, size, 0, 0);
}
}
else else
{ {
// Create new // Create new
@ -113,8 +121,16 @@ namespace SHADE
{ {
if (bufferHandle) if (bufferHandle)
{ {
// Resize // Resize if we need to resize
bufferHandle->ResizeReplace(size, src, size); // TODO: Set to host visible method? if (bufferHandle->GetSizeStored() < size)
{
bufferHandle->ResizeReplace(size, src, size);
}
// Otherwise just copy the data over
else
{
bufferHandle->MapWriteUnmap(src, size, 0, 0);
}
} }
else else
{ {

View File

@ -1,5 +1,5 @@
/**************************************************************************************** /****************************************************************************************
* \file SHBoundingBox.cpp * \file SHBox.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box * \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
* *

View File

@ -1,5 +1,5 @@
/**************************************************************************************** /****************************************************************************************
* \file SHBoundingBox.h * \file SHBox.h
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box * \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
* *

View File

@ -483,6 +483,16 @@ namespace SHADE
return result; return result;
} }
SHMatrix SHMatrix::Transform(const SHVec3& pos, const SHVec3& eulerAngles, const SHVec3& scale) noexcept
{
return Scale(scale) * Rotate(eulerAngles) * Translate(pos);
}
SHMatrix SHMatrix::Transform(const SHVec3& pos, const SHQuaternion& rot, const SHVec3& scale) noexcept
{
return Scale(scale) * Rotate(rot) * Translate(pos);
}
SHMatrix SHMatrix::LookAtRH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept SHMatrix SHMatrix::LookAtRH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept
{ {
SHMatrix result; SHMatrix result;

View File

@ -149,6 +149,9 @@ namespace SHADE
[[nodiscard]] static SHMatrix Scale (float x, float y, float z) noexcept; [[nodiscard]] static SHMatrix Scale (float x, float y, float z) noexcept;
[[nodiscard]] static SHMatrix Scale (const SHVec3& scale) noexcept; [[nodiscard]] static SHMatrix Scale (const SHVec3& scale) noexcept;
[[nodiscard]] static SHMatrix Transform (const SHVec3& pos, const SHVec3& eulerAngles, const SHVec3& scale) noexcept;
[[nodiscard]] static SHMatrix Transform (const SHVec3& pos, const SHQuaternion& rot, const SHVec3& scale) noexcept;
[[nodiscard]] static SHMatrix LookAtRH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept; [[nodiscard]] static SHMatrix LookAtRH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix LookAtLH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept; [[nodiscard]] static SHMatrix LookAtLH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix CamToWorldRH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept; [[nodiscard]] static SHMatrix CamToWorldRH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept;

View File

@ -16,6 +16,7 @@
// Project Headers // Project Headers
#include "Physics/PhysicsObject/SHPhysicsObject.h" #include "Physics/PhysicsObject/SHPhysicsObject.h"
#include "Physics/System/SHPhysicsSystem.h" #include "Physics/System/SHPhysicsSystem.h"
#include "Scene/SHSceneManager.h"
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/* Local Helper Functions */ /* Local Helper Functions */
@ -80,10 +81,15 @@ namespace SHADE
{ {
for (auto eventIter = container.begin(); eventIter != container.end();) for (auto eventIter = container.begin(); eventIter != container.end();)
{ {
const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionInfo::State::EXIT const SHCollisionInfo& C_INFO = *eventIter;
|| eventIter->GetCollisionState() == SHCollisionInfo::State::INVALID;
if (CLEAR_EVENT) const bool CLEAR_EVENT = C_INFO.GetCollisionState() == SHCollisionInfo::State::EXIT
|| C_INFO.GetCollisionState() == SHCollisionInfo::State::INVALID;
const bool INACTIVE_OBJECT = !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityA())
|| !SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(C_INFO.GetEntityB());
if (CLEAR_EVENT || INACTIVE_OBJECT)
eventIter = container.erase(eventIter); eventIter = container.erase(eventIter);
else else
++eventIter; ++eventIter;

View File

@ -304,6 +304,9 @@ namespace SHADE
const auto* RHS_BOX = reinterpret_cast<const SHBox*>(rhs); const auto* RHS_BOX = reinterpret_cast<const SHBox*>(rhs);
shape = new SHBox{ positionOffset, RHS_BOX->GetWorldExtents() }; shape = new SHBox{ positionOffset, RHS_BOX->GetWorldExtents() };
auto* lhsBox = reinterpret_cast<SHBox*>(shape);
lhsBox->SetRelativeExtents(RHS_BOX->GetRelativeExtents());
break; break;
} }
case Type::SPHERE: case Type::SPHERE:
@ -311,6 +314,9 @@ namespace SHADE
const auto* RHS_SPHERE = reinterpret_cast<const SHSphere*>(rhs); const auto* RHS_SPHERE = reinterpret_cast<const SHSphere*>(rhs);
shape = new SHSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() }; shape = new SHSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() };
auto* lhsSphere = reinterpret_cast<SHSphere*>(shape);
lhsSphere->SetRelativeRadius(RHS_SPHERE->GetRelativeRadius());
break; break;
} }
default: break; default: break;

View File

@ -29,7 +29,6 @@ namespace SHADE
SHRigidBodyComponent::SHRigidBodyComponent() noexcept SHRigidBodyComponent::SHRigidBodyComponent() noexcept
: type { Type::DYNAMIC } : type { Type::DYNAMIC }
, interpolate { true }
, flags { 0 } , flags { 0 }
, dirtyFlags { std::numeric_limits<uint16_t>::max() } , dirtyFlags { std::numeric_limits<uint16_t>::max() }
, mass { 1.0f } , mass { 1.0f }
@ -40,6 +39,7 @@ namespace SHADE
// Initialise default flags // Initialise default flags
flags |= 1U << 0; // Gravity set to true flags |= 1U << 0; // Gravity set to true
flags |= 1U << 1; // Sleeping allowed flags |= 1U << 1; // Sleeping allowed
flags |= 1U << 8; // Interpolate by default
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -60,7 +60,16 @@ namespace SHADE
bool SHRigidBodyComponent::IsInterpolating() const noexcept bool SHRigidBodyComponent::IsInterpolating() const noexcept
{ {
return interpolate; static constexpr int FLAG_POS = 8;
return flags & (1U << FLAG_POS);
}
bool SHRigidBodyComponent::GetIsSleeping() const noexcept
{
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
return physicsObject->GetRigidBody()->isSleeping();
return false;
} }
SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept
@ -68,21 +77,6 @@ namespace SHADE
return type; return type;
} }
float SHRigidBodyComponent::GetMass() const noexcept
{
return mass;
}
float SHRigidBodyComponent::GetDrag() const noexcept
{
return drag;
}
float SHRigidBodyComponent::GetAngularDrag() const noexcept
{
return angularDrag;
}
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
{ {
static constexpr int FLAG_POS = 2; static constexpr int FLAG_POS = 2;
@ -119,6 +113,27 @@ namespace SHADE
return flags & (1U << FLAG_POS); return flags & (1U << FLAG_POS);
} }
//bool SHRigidBodyComponent::GetAutoMass() const noexcept
//{
// static constexpr int FLAG_POS = 9;
// return flags & (1U << FLAG_POS);
//}
float SHRigidBodyComponent::GetMass() const noexcept
{
return mass;
}
float SHRigidBodyComponent::GetDrag() const noexcept
{
return drag;
}
float SHRigidBodyComponent::GetAngularDrag() const noexcept
{
return angularDrag;
}
SHVec3 SHRigidBodyComponent::GetForce() const noexcept SHVec3 SHRigidBodyComponent::GetForce() const noexcept
{ {
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
@ -295,9 +310,18 @@ namespace SHADE
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
{ {
interpolate = allowInterpolation; static constexpr int FLAG_POS = 8;
allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS);
} }
//void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept
//{
// static constexpr int FLAG_POS = 9;
// autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS);
// dirtyFlags |= 1U << FLAG_POS;
//}
void SHRigidBodyComponent::SetMass(float newMass) noexcept void SHRigidBodyComponent::SetMass(float newMass) noexcept
{ {
static constexpr int FLAG_POS = 9; static constexpr int FLAG_POS = 9;
@ -313,6 +337,9 @@ namespace SHADE
dirtyFlags |= 1U << FLAG_POS; dirtyFlags |= 1U << FLAG_POS;
mass = newMass; mass = newMass;
// Turn off automass
flags &= ~(1U << FLAG_POS);
} }
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
@ -467,6 +494,8 @@ RTTR_REGISTRATION
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
.property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate )
.property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep)
//.property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass )
.property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX )
.property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY )
.property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ )

View File

@ -71,19 +71,23 @@ namespace SHADE
[[nodiscard]] bool IsAllowedToSleep () const noexcept; [[nodiscard]] bool IsAllowedToSleep () const noexcept;
[[nodiscard]] bool IsInterpolating () const noexcept; [[nodiscard]] bool IsInterpolating () const noexcept;
[[nodiscard]] bool GetIsSleeping () const noexcept;
[[nodiscard]] Type GetType () const noexcept; [[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] float GetMass () const noexcept;
[[nodiscard]] float GetDrag () const noexcept;
[[nodiscard]] float GetAngularDrag () const noexcept;
[[nodiscard]] bool GetFreezePositionX () const noexcept; [[nodiscard]] bool GetFreezePositionX () const noexcept;
[[nodiscard]] bool GetFreezePositionY () const noexcept; [[nodiscard]] bool GetFreezePositionY () const noexcept;
[[nodiscard]] bool GetFreezePositionZ () const noexcept; [[nodiscard]] bool GetFreezePositionZ () const noexcept;
[[nodiscard]] bool GetFreezeRotationX () const noexcept; [[nodiscard]] bool GetFreezeRotationX () const noexcept;
[[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationY () const noexcept;
[[nodiscard]] bool GetFreezeRotationZ () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept;
//[[nodiscard]] bool GetAutoMass () const noexcept;
[[nodiscard]] float GetMass () const noexcept;
[[nodiscard]] float GetDrag () const noexcept;
[[nodiscard]] float GetAngularDrag () const noexcept;
[[nodiscard]] SHVec3 GetForce () const noexcept; [[nodiscard]] SHVec3 GetForce () const noexcept;
[[nodiscard]] SHVec3 GetTorque () const noexcept; [[nodiscard]] SHVec3 GetTorque () const noexcept;
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
@ -108,6 +112,7 @@ namespace SHADE
void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationY (bool freezeRotationY) noexcept;
void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept;
void SetInterpolate (bool allowInterpolation) noexcept; void SetInterpolate (bool allowInterpolation) noexcept;
//void SetAutoMass (bool autoMass) noexcept;
void SetMass (float newMass) noexcept; void SetMass (float newMass) noexcept;
void SetDrag (float newDrag) noexcept; void SetDrag (float newDrag) noexcept;
@ -144,8 +149,7 @@ namespace SHADE
Type type; Type type;
bool interpolate; uint16_t flags; // 0 0 0 0 0 0 am ip aZ aY aX lZ lY lX slp g
uint8_t flags; // aZ aY aX lZ lY lX slp g
uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g
float mass; float mass;

View File

@ -109,8 +109,17 @@ namespace SHADE
{ {
// TODO(Diren): Add more collider shapes // TODO(Diren): Add more collider shapes
case SHCollisionShape::Type::BOX: addBoxShape(collisionShape); break; case SHCollisionShape::Type::BOX:
case SHCollisionShape::Type::SPHERE: addSphereShape(collisionShape); break; {
addBoxShape(collisionShape);
break;
}
case SHCollisionShape::Type::SPHERE:
{
addSphereShape(collisionShape);
break;
}
default: break; default: break;
} }
@ -245,9 +254,17 @@ namespace SHADE
} }
case 9: // Mass case 9: // Mass
{ {
//if (component.GetAutoMass())
//{
// rp3dBody->updateMassPropertiesFromColliders();
// component.mass = rp3dBody->getMass();
//}
//else
//{
rp3dBody->setMass(component.mass); rp3dBody->setMass(component.mass);
rp3dBody->updateLocalCenterOfMassFromColliders(); rp3dBody->updateLocalCenterOfMassFromColliders();
rp3dBody->updateLocalInertiaTensorFromColliders(); rp3dBody->updateLocalInertiaTensorFromColliders();
//}
break; break;
} }

View File

@ -38,8 +38,8 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
SHVec3 gravity = SHVec3{ 0.0f, -9.81f, 0.0f }; SHVec3 gravity = SHVec3{ 0.0f, -9.81f, 0.0f };
uint16_t numVelocitySolverIterations = 15; uint16_t numVelocitySolverIterations = 10;
uint16_t numPositionSolverIterations = 8; uint16_t numPositionSolverIterations = 5;
bool sleepingEnabled = true; bool sleepingEnabled = true;
}; };

View File

@ -24,7 +24,7 @@ namespace SHADE
/* Static Data Member Definitions */ /* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[SHPhysicsDebugDrawSystem::NUM_FLAGS] = const SHPhysicsDebugDrawSystem::DebugDrawFunction SHPhysicsDebugDrawSystem::drawFunctions[NUM_FLAGS] =
{ {
SHPhysicsDebugDrawSystem::drawColliders SHPhysicsDebugDrawSystem::drawColliders
, SHPhysicsDebugDrawSystem::drawColliderAABBs , SHPhysicsDebugDrawSystem::drawColliderAABBs
@ -33,6 +33,8 @@ namespace SHADE
, SHPhysicsDebugDrawSystem::drawContactNormals , SHPhysicsDebugDrawSystem::drawContactNormals
}; };
SHVec3 SHPhysicsDebugDrawSystem::boxVertices[NUM_BOX_VERTICES];
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -42,7 +44,7 @@ namespace SHADE
, physicsSystem { nullptr } , physicsSystem { nullptr }
, rp3dDebugRenderer { nullptr } , rp3dDebugRenderer { nullptr }
{ {
debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER)] = SHColour::GREEN;
debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB)] = SHColour::YELLOW; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB)] = SHColour::YELLOW;
debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB)] = SHColour::CYAN; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB)] = SHColour::CYAN;
debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS)] = SHColour::RED; debugColours[SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS)] = SHColour::RED;
@ -95,6 +97,9 @@ namespace SHADE
SHASSERT(physicsSystem == nullptr, "Non-existent physics system attached to the physics debug draw system!") SHASSERT(physicsSystem == nullptr, "Non-existent physics system attached to the physics debug draw system!")
physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>(); physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
// Generate shapes
generateBox();
} }
void SHPhysicsDebugDrawSystem::Exit() void SHPhysicsDebugDrawSystem::Exit()
@ -159,21 +164,20 @@ namespace SHADE
} }
void SHPhysicsDebugDrawSystem::generateBox() noexcept
{
boxVertices[0] = { 0.5f, 0.5f, -0.5f }; // TOP_RIGHT_BACK
boxVertices[1] = { -0.5f, 0.5f, -0.5f }; // TOP_LEFT_BACK
boxVertices[2] = { 0.5f, -0.5f, -0.5f }; // BTM_RIGHT_BACK
boxVertices[3] = { -0.5f, -0.5f, -0.5f }; // BTM_LEFT_BACK
boxVertices[4] = { 0.5f, 0.5f, 0.5f }; // TOP_RIGHT_FRONT
boxVertices[5] = { -0.5f, 0.5f, 0.5f }; // TOP_LEFT_FRONT
boxVertices[6] = { 0.5f, -0.5f, 0.5f }; // BTM_RIGHT_FRONT
boxVertices[7] = { -0.5f, -0.5f, 0.5f }; // BTM_LEFT_FRONT
}
void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept void SHPhysicsDebugDrawSystem::debugDrawBox(const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept
{ {
static constexpr uint32_t NUM_BOX_VERTICES = 8;
static const SHVec3 boxVertices[NUM_BOX_VERTICES]
{
{ 0.5f, 0.5f, -0.5f } // TOP_RIGHT_BACK
, { -0.5f, 0.5f, -0.5f } // TOP_LEFT_BACK
, { 0.5f, -0.5f, -0.5f } // BTM_RIGHT_BACK
, { -0.5f, -0.5f, -0.5f } // BTM_LEFT_BACK
, { 0.5f, 0.5f, 0.5f } // TOP_RIGHT_FRONT
, { -0.5f, 0.5f, 0.5f } // TOP_LEFT_FRONT
, { 0.5f, -0.5f, 0.5f } // BTM_RIGHT_FRONT
, { -0.5f, -0.5f, 0.5f } // BTM_LEFT_FRONT
};
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>(); auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
if (debugDrawSystem == nullptr) if (debugDrawSystem == nullptr)
{ {
@ -184,10 +188,16 @@ namespace SHADE
auto* BOX = reinterpret_cast<const SHBox*>(collisionShape.GetShape()); auto* BOX = reinterpret_cast<const SHBox*>(collisionShape.GetShape());
// Calculate final position & orientation // Calculate final position & orientation
const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); const SHVec3 COLLIDER_POS = colliderComponent.GetPosition();
const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset()); const SHVec3 BOX_POS = collisionShape.GetPositionOffset();
const SHQuaternion COLLIDER_ROT = colliderComponent.GetOrientation();
const SHQuaternion BOX_ROT = SHQuaternion::FromEuler(collisionShape.GetRotationOffset());
const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(FINAL_POS);
const SHMatrix COLLIDER_TR = SHMatrix::Rotate(COLLIDER_ROT) * SHMatrix::Translate(COLLIDER_POS);
const SHMatrix BOX_TRS = SHMatrix::Scale(BOX->GetWorldExtents() * 2.0f) * SHMatrix::Rotate(BOX_ROT) * SHMatrix::Translate(BOX_POS);
const SHMatrix FINAL_TRS = BOX_TRS * COLLIDER_TR;
const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN;
@ -197,8 +207,8 @@ namespace SHADE
const uint32_t IDX1 = i; const uint32_t IDX1 = i;
const uint32_t IDX2 = i + NUM_BOX_VERTICES / 2; const uint32_t IDX2 = i + NUM_BOX_VERTICES / 2;
transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], BOX_TRS); transformedVertices[IDX1] = SHVec3::Transform(boxVertices[IDX1], FINAL_TRS);
transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], BOX_TRS); transformedVertices[IDX2] = SHVec3::Transform(boxVertices[IDX2], FINAL_TRS);
// Draw 4 line to connect the quads // Draw 4 line to connect the quads
debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]); debugDrawSystem->DrawLine(COLLIDER_COLOUR, transformedVertices[IDX1], transformedVertices[IDX2]);
@ -207,6 +217,7 @@ namespace SHADE
// A, B, C, D // A, B, C, D
std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] }; std::array backQuad { transformedVertices[0], transformedVertices[1], transformedVertices[3], transformedVertices[2] };
debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end()); debugDrawSystem->DrawPoly(COLLIDER_COLOUR, backQuad.begin(), backQuad.end());
// E, F, G, H // E, F, G, H
std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] }; std::array frontQuad { transformedVertices[4], transformedVertices[5], transformedVertices[7], transformedVertices[6] };
debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end()); debugDrawSystem->DrawPoly(COLLIDER_COLOUR, frontQuad.begin(), frontQuad.end());
@ -226,8 +237,10 @@ namespace SHADE
const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN; const SHColour COLLIDER_COLOUR = collisionShape.IsTrigger() ? SHColour::PURPLE : SHColour::GREEN;
// Calculate final position & orientation // Calculate final position & orientation
const SHVec3 FINAL_POS = colliderComponent.GetPosition() + collisionShape.GetPositionOffset(); const SHQuaternion FINAL_ROT = colliderComponent.GetOrientation() * SHQuaternion::FromEuler(collisionShape.GetRotationOffset());
debugDrawSystem->DrawSphere(COLLIDER_COLOUR, FINAL_POS, SPHERE->GetWorldRadius()); const SHMatrix TR = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(colliderComponent.GetPosition());
debugDrawSystem->DrawSphere(COLLIDER_COLOUR, SHVec3::Transform(collisionShape.GetPositionOffset(), TR), SPHERE->GetWorldRadius());
} }
} // namespace SHADE } // namespace SHADE

View File

@ -98,9 +98,14 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS); static constexpr int NUM_FLAGS = SHUtilities::ConvertEnum(DebugDrawFlags::NUM_FLAGS);
static const DebugDrawFunction drawFunctions[NUM_FLAGS]; static const DebugDrawFunction drawFunctions[NUM_FLAGS];
// SHAPES INFO
static constexpr size_t NUM_BOX_VERTICES = 8;
static SHVec3 boxVertices[NUM_BOX_VERTICES];
uint8_t debugDrawFlags; uint8_t debugDrawFlags;
SHPhysicsSystem* physicsSystem; SHPhysicsSystem* physicsSystem;
rp3d::DebugRenderer* rp3dDebugRenderer; rp3d::DebugRenderer* rp3dDebugRenderer;
@ -110,12 +115,20 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
// Generic Draw Functions
static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawColliders (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawColliderAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawBroadPhaseAABBs (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactPoints (rp3d::DebugRenderer* debugRenderer) noexcept;
static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept; static void drawContactNormals (rp3d::DebugRenderer* debugRenderer) noexcept;
// Shape Generation Functions
static void generateBox () noexcept;
// Shape Draw Functions
static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; static void debugDrawBox (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept;
static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept; static void debugDrawSphere (const SHColliderComponent& colliderComponent, const SHCollisionShape& collisionShape) noexcept;
}; };

View File

@ -154,14 +154,32 @@ namespace SHADE
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID); auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
postUpdateSyncTransforms const auto& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
( const auto& RENDER_POS = CURRENT_TF.getPosition();
physicsObject const auto& RENDER_ROT = CURRENT_TF.getOrientation();
, transformComponent
, rigidBodyComponent // Cache transform
, colliderComponent physicsObject.prevTransform = CURRENT_TF;
, 1.0 // We use 1.0 here to avoid any interpolation
); // Sync with physics components
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(entityID))
{
rigidBodyComponent->position = RENDER_POS;
rigidBodyComponent->orientation = RENDER_ROT;
}
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(entityID))
{
colliderComponent->position = RENDER_POS;
colliderComponent->orientation = RENDER_ROT;
}
// Set transform for rendering
if (transformComponent)
{
transformComponent->SetWorldPosition(RENDER_POS);
transformComponent->SetWorldOrientation(RENDER_ROT);
}
} }
} }
@ -337,93 +355,4 @@ namespace SHADE
return onStopEvent->handle; return onStopEvent->handle;
} }
void SHPhysicsSystem::preUpdateSyncTransform
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
) noexcept
{
if (!transformComponent)
return;
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation();
const SHVec3& WORLD_SCL = transformComponent->GetWorldScale();
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT;
}
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT;
colliderComponent->scale = WORLD_SCL;
colliderComponent->RecomputeCollisionShapes();
}
}
void SHPhysicsSystem::postUpdateSyncTransforms
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
, double interpolationFactor
) noexcept
{
const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
auto renderPos = CURRENT_TF.getPosition();
auto renderRot = CURRENT_TF.getOrientation();
// Cache transforms
if (physicsObject.GetRigidBody()->isActive())
physicsObject.prevTransform = CURRENT_TF;
// Sync with rigid bodies
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
// Skip static bodies
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
return;
// Check if transform should be interpolated
if (rigidBodyComponent->IsInterpolating())
{
// Interpolate transforms between current and predicted next transform
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
renderPos = INTERPOLATED_TF.getPosition();
renderRot = INTERPOLATED_TF.getOrientation();
}
rigidBodyComponent->position = CURRENT_TF.getPosition();
rigidBodyComponent->orientation = CURRENT_TF.getOrientation();
}
// Sync with colliders
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
// Set transform for rendering
if (transformComponent)
{
transformComponent->SetWorldPosition(renderPos);
transformComponent->SetWorldOrientation(renderRot);
}
}
} // namespace SHADE } // namespace SHADE

View File

@ -113,6 +113,14 @@ namespace SHADE
void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept; void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
static void syncOnPlay (EntityID eid, SHPhysicsObject& physicsObject) noexcept; static void syncOnPlay (EntityID eid, SHPhysicsObject& physicsObject) noexcept;
static void preUpdateSyncTransform
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
) noexcept;
}; };
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
@ -145,6 +153,21 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
void Execute(double dt) noexcept override; void Execute(double dt) noexcept override;
private:
/*-------------------------------------------------------------------------------*/
/* Function Members */
/*-------------------------------------------------------------------------------*/
static void postUpdateSyncTransforms
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
, double interpolationFactor
) noexcept;
}; };
private: private:
@ -178,24 +201,5 @@ namespace SHADE
SHEventHandle onPlay (SHEventPtr onPlayEvent); SHEventHandle onPlay (SHEventPtr onPlayEvent);
SHEventHandle onStop (SHEventPtr onStopEvent); SHEventHandle onStop (SHEventPtr onStopEvent);
static void preUpdateSyncTransform
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
) noexcept;
static void postUpdateSyncTransforms
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
, double interpolationFactor
) noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -262,4 +262,94 @@ namespace SHADE
if (colliderComponent) if (colliderComponent)
physicsObject.SyncColliders(*colliderComponent); physicsObject.SyncColliders(*colliderComponent);
} }
void SHPhysicsSystem::PhysicsPreUpdate::preUpdateSyncTransform
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
) noexcept
{
if (!transformComponent)
return;
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation();
const SHVec3& WORLD_SCL = transformComponent->GetWorldScale();
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
physicsObject.prevTransform = RP3D_TRANSFORM;
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT;
}
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT;
colliderComponent->scale = WORLD_SCL;
colliderComponent->RecomputeCollisionShapes();
}
}
void SHPhysicsSystem::PhysicsPostUpdate::postUpdateSyncTransforms
(
SHPhysicsObject& physicsObject
, SHTransformComponent* transformComponent
, SHRigidBodyComponent* rigidBodyComponent
, SHColliderComponent* colliderComponent
, double interpolationFactor
) noexcept
{
const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
auto renderPos = CURRENT_TF.getPosition();
auto renderRot = CURRENT_TF.getOrientation();
// Cache transforms
if (physicsObject.GetRigidBody()->isActive())
physicsObject.prevTransform = CURRENT_TF;
// Sync with rigid bodies
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
// Skip static bodies
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
return;
// Check if transform should be interpolated
if (rigidBodyComponent->IsInterpolating())
{
// Interpolate transforms between current and predicted next transform
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
renderPos = INTERPOLATED_TF.getPosition();
renderRot = INTERPOLATED_TF.getOrientation();
}
rigidBodyComponent->position = CURRENT_TF.getPosition();
rigidBodyComponent->orientation = CURRENT_TF.getOrientation();
}
// Sync with colliders
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
// Set transform for rendering
if (transformComponent)
{
transformComponent->SetWorldPosition(renderPos);
transformComponent->SetWorldOrientation(renderRot);
}
}
} // namespace SHADE } // namespace SHADE

View File

@ -38,6 +38,11 @@ namespace SHADE
class SHResourceLibrary : public SHResourceLibraryBase class SHResourceLibrary : public SHResourceLibraryBase
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using dense_iterator = typename SparseSet<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor */ /* Constructor */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -74,6 +79,16 @@ namespace SHADE
/// <returns>Read-only reference to the resource object.</returns> /// <returns>Read-only reference to the resource object.</returns>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -96,6 +111,12 @@ namespace SHADE
class SHResourceHub final class SHResourceHub final
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
template<typename T>
using dense_iterator = typename SHResourceLibrary<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -138,6 +159,18 @@ namespace SHADE
template<typename T> template<typename T>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <typeparam name="T">Type of resource to access.</typeparam>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
template <typename T>
std::pair<dense_iterator<T>, dense_iterator<T>> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Type Definition */ /* Type Definition */

View File

@ -79,6 +79,15 @@ namespace SHADE
return objects[handle.GetId().Data.Index]; return objects[handle.GetId().Data.Index];
} }
/*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SHResourceLibrary<T>::dense_iterator, typename SHResourceLibrary<T>::dense_iterator> SHResourceLibrary<T>::GetDenseAccess()
{
return objects.GetDenseAccess();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Helper Functions */ /* ResourceLibrary - Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -105,7 +114,7 @@ namespace SHADE
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceManager - Usage Functions */ /* ResourceHub - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template <typename T, typename ... Args> template <typename T, typename ... Args>
Handle<T> SHResourceHub::Create(Args&&... args) Handle<T> SHResourceHub::Create(Args&&... args)
@ -132,7 +141,7 @@ namespace SHADE
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ResourceManager - Helper Functions */ /* ResourceHub - Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
template <typename T> template <typename T>
SHResourceLibrary<T>& SHResourceHub::getLibrary() SHResourceLibrary<T>& SHResourceHub::getLibrary()
@ -161,4 +170,13 @@ namespace SHADE
{ {
return const_cast<SHResourceHub*>(this).getLibrary<T>(); return const_cast<SHResourceHub*>(this).getLibrary<T>();
} }
/*---------------------------------------------------------------------------------*/
/* ResourceHub - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template <typename T>
std::pair<typename SHResourceHub::dense_iterator<T>, typename SHResourceHub::dense_iterator<T>> SHResourceHub::GetDenseAccess()
{
return getLibrary<T>().GetDenseAccess();
}
} }

View File

@ -103,4 +103,17 @@ namespace SHADE
return {}; return {};
} }
std::optional<std::string> SHResourceManager::GetAssetName(Handle<void> handle)
{
const Handle GENERIC_HANDLE = Handle(handle);
auto assetId = GetAssetID(GENERIC_HANDLE);
if (assetId.has_value())
{
const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value());
if (ASSET_INFO.has_value())
return ASSET_INFO.value().name;
}
return {};
}
} }

View File

@ -13,8 +13,6 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <unordered_map> #include <unordered_map>
namespace SHADE { class SHMaterial; }
// Project Includes // Project Includes
#include "SH_API.h" #include "SH_API.h"
#include "SHResourceLibrary.h" #include "SHResourceLibrary.h"
@ -31,6 +29,14 @@ namespace SHADE { class SHMaterial; }
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterial;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Template structs that maps a resource to their loaded asset representation type. /// Template structs that maps a resource to their loaded asset representation type.
/// </summary> /// </summary>
@ -41,6 +47,7 @@ namespace SHADE
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; }; template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
/// <summary> /// <summary>
/// Static class responsible for loading and caching runtime resources from their /// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs. /// serialised Asset IDs.
@ -57,9 +64,7 @@ namespace SHADE
/// Note that for specific types, the retrieved Handle may not be valid until after /// Note that for specific types, the retrieved Handle may not be valid until after
/// FinaliseChanges() is called. /// FinaliseChanges() is called.
/// </summary> /// </summary>
/// <typeparam name="ResourceType"> /// <typeparam name="ResourceType">Type of resource to load.</typeparam>
/// Type of resource to load.
/// </typeparam>
/// <param name="assetId">Asset ID of the resource to load.</param> /// <param name="assetId">Asset ID of the resource to load.</param>
/// <returns>Handle to a loaded runtime asset.</returns> /// <returns>Handle to a loaded runtime asset.</returns>
template<typename ResourceType> template<typename ResourceType>
@ -67,6 +72,17 @@ namespace SHADE
template<> template<>
static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId); static inline Handle<SHMaterial> LoadOrGet<SHMaterial>(AssetID assetId);
/// <summary> /// <summary>
/// Retrieves an existing loaded object of the specified type if it has already been
/// loaded prior.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to load.</typeparam>
/// <param name="assetId">Asset ID of the resource to retrieve.</param>
/// <returns>
/// Handle to a loaded runtime asset. Null handle if not loaded before.
/// </returns>
template<typename ResourceType>
static Handle<ResourceType> Get(AssetID assetId);
/// <summary>
/// Unloads an existing loaded asset. Attempting to unload an invalid Handle will /// Unloads an existing loaded asset. Attempting to unload an invalid Handle will
/// simply do nothing except emit a warning. /// simply do nothing except emit a warning.
/// Faster than the untemplated version. /// Faster than the untemplated version.
@ -114,6 +130,31 @@ namespace SHADE
/// value. /// value.
/// </return> /// </return>
static std::optional<AssetID> GetAssetID(Handle<void> handle); static std::optional<AssetID> GetAssetID(Handle<void> handle);
/// <summary>
/// Retrieves the name associated with the AssetID that is associated with the
/// specified Handle.
/// Faster than the untemplated version.
/// </summary>
/// <typeparam name="ResourceType">Type of resource to get the name of.</typeparam>
/// <param name="handle">Handle to get the name of.</param>
/// <return>
/// Name for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
template<typename T>
static std::optional<std::string> GetAssetName(Handle<T> handle);
/// <summary>
/// Retrieves the name associated with the AssetID that is associated with the
/// specified Handle.
/// Compared to the templated version, this function is slower as it requires
/// searching through the storage of all resource types.
/// </summary>
/// <param name="handle">Handle to get the name of.</param>
/// <return>
/// Name for the specified Handle. If the Handle is invalid, there will be no
/// value.
/// </return>
static std::optional<std::string> GetAssetName(Handle<void> handle);
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -93,6 +93,16 @@ namespace SHADE
return handle; return handle;
} }
template<typename ResourceType>
Handle<ResourceType> SHResourceManager::Get(AssetID assetId)
{
auto [typedHandleMap, typedAssetIdMap] = getAssetHandleMap<ResourceType>();
if (typedHandleMap.get().contains(assetId))
return Handle<ResourceType>(typedHandleMap.get()[assetId]);
else
return Handle<ResourceType>();
}
template<typename ResourceType> template<typename ResourceType>
void SHResourceManager::Unload(Handle<ResourceType> asset) void SHResourceManager::Unload(Handle<ResourceType> asset)
{ {
@ -139,6 +149,18 @@ namespace SHADE
return {}; return {};
} }
template<typename T>
std::optional<std::string> SHADE::SHResourceManager::GetAssetName(Handle<T> handle)
{
auto assetId = GetAssetID<T>(handle);
if (assetId.has_value())
{
const auto ASSET_INFO = SHAssetManager::GetAsset(assetId.value());
if (ASSET_INFO.has_value())
return ASSET_INFO.value().name;
}
return {};
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -49,6 +49,7 @@ namespace SHADE
using const_pointer = const T*; using const_pointer = const T*;
using reference = T&; using reference = T&;
using const_reference = const T&; using const_reference = const T&;
using dense_iterator = typename std::vector<T>::iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
@ -59,10 +60,6 @@ namespace SHADE
SparseSet(); SparseSet();
~SparseSet() = default; ~SparseSet() = default;
//// Disallow moving or copying
//SparseSet(const SparseSet&) = delete;
//SparseSet(SparseSet&&) = delete;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -192,6 +189,16 @@ namespace SHADE
/// </exception> /// </exception>
const T& operator[](index_type idx) const; const T& operator[](index_type idx) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
protected: protected:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constants */ /* Constants */

View File

@ -143,4 +143,13 @@ namespace SHADE
{ {
return at(idx); return at(idx);
} }
/*---------------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SparseSet<T>::dense_iterator, typename SparseSet<T>::dense_iterator> SparseSet<T>::GetDenseAccess()
{
return { denseArray.begin(), denseArray.end() };
}
} }

View File

@ -58,10 +58,9 @@ namespace SHADE
loadFunctions(); loadFunctions();
// Generate script assembly if it hasn't been before // Generate script assembly if it hasn't been before
if (!fileExists(std::string(MANAGED_SCRIPT_LIB_NAME) + ".dll")) #ifndef _PUBLISH
{
BuildScriptAssembly(); BuildScriptAssembly();
} #endif
// Initialise the CSharp Engine // Initialise the CSharp Engine
csEngineInit(); csEngineInit();
@ -307,7 +306,7 @@ namespace SHADE
SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr)
{ {
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get()); auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
csScriptsRemoveAll(eventData->data->eid); csScriptsRemoveAllImmediately(eventData->data->eid, true);
return eventData->handle; return eventData->handle;
} }

View File

@ -12,8 +12,8 @@
#include "Assets/Asset Types/SHSceneAsset.h" #include "Assets/Asset Types/SHSceneAsset.h"
#include "Camera/SHCameraComponent.h" #include "Camera/SHCameraComponent.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Physics/Interface/SHRigidBodyComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
@ -179,7 +179,9 @@ namespace SHADE
{ {
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid)) if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
{ {
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = YAML::convert<ComponentType>::encode(*component); auto componentNode = YAML::convert<ComponentType>::encode(*component);
componentNode[IsActive.data()] = component->isActive;
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = componentNode;
} }
} }

View File

@ -14,6 +14,8 @@
namespace SHADE namespace SHADE
{ {
static constexpr std::string_view IsActive = "IsActive";
using AssetQueue = std::unordered_map<AssetID, AssetType>; using AssetQueue = std::unordered_map<AssetID, AssetType>;
struct SHSerializationHelper struct SHSerializationHelper
{ {
@ -118,9 +120,9 @@ namespace SHADE
YAML::Node node{}; YAML::Node node{};
if (!component) if (!component)
return node; return node;
auto componentType = rttr::type::get<ComponentType>(); auto componentType = rttr::type::get<ComponentType>();
node = RTTRToNode(*component); node = RTTRToNode(*component);
node[IsActive.data()] = component->isActive;
return node; return node;
} }
@ -198,6 +200,9 @@ namespace SHADE
auto componentNode = componentsNode[rttrType.get_name().data()]; auto componentNode = componentsNode[rttrType.get_name().data()];
if (!componentNode.IsDefined()) if (!componentNode.IsDefined())
return; return;
if(componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
auto properties = rttrType.get_properties(); auto properties = rttrType.get_properties();
for (auto const& prop : properties) for (auto const& prop : properties)
{ {
@ -227,8 +232,10 @@ namespace SHADE
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid); auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component) if (componentsNode.IsNull() && !component)
return; return;
auto componentNode = GetComponentNode<ComponentType>(componentsNode, eid);
YAML::convert<ComponentType>::decode(GetComponentNode<ComponentType>(componentsNode, eid), *component); if (componentNode[IsActive.data()].IsDefined())
component->isActive = componentNode[IsActive.data()].as<bool>();
YAML::convert<ComponentType>::decode(componentNode, *component);
} }
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true> template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>

View File

@ -44,13 +44,6 @@ namespace SHADE
SHLOG_FLOOR() SHLOG_FLOOR()
} }
#ifdef _DEBUG
void SHLog::Trace(const std::string& msg) noexcept
{
SHLOG_TRACE(msg)
}
#endif
void SHLog_Info(const char* msg) noexcept void SHLog_Info(const char* msg) noexcept
{ {
SHLOG_INFO(msg) SHLOG_INFO(msg)

View File

@ -323,34 +323,6 @@ namespace SHADE
SHLOG_FLOOR() SHLOG_FLOOR()
} }
#ifdef _DEBUG
void SHLogger::LogTrace(const std::string& msg) noexcept
{
SHLOG_TRACE(msg)
}
void SHLogger::LogVerboseTrace(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_TRACE(ss.str())
}
#endif
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -0,0 +1,60 @@
#include "SHpch.h"
#include "SHCanvasComponent.h"
namespace SHADE
{
SHCanvasComponent::SHCanvasComponent()
:width(1),height(1), dirtyMatrix(false), canvasMatrix()
{
}
void SHCanvasComponent::SetCanvasSize(CanvasSizeType width, CanvasSizeType height) noexcept
{
this->width = width;
this->height = height;
}
void SHCanvasComponent::SetCanvasWidth(CanvasSizeType val) noexcept
{
width = val;
}
void SHCanvasComponent::SetCanvasHeight(CanvasSizeType val) noexcept
{
height = val;
}
SHCanvasComponent::CanvasSizeType SHCanvasComponent::GetCanvasWidth() const noexcept
{
return width;
}
SHCanvasComponent::CanvasSizeType SHCanvasComponent::GetCanvasHeight() const noexcept
{
return height;
}
SHMatrix const& SHCanvasComponent::GetMatrix() const noexcept
{
return canvasMatrix;
}
}
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHCanvasComponent>("Canvas Component")
.property("Canvas Width", &SHCanvasComponent::GetCanvasWidth, &SHCanvasComponent::SetCanvasWidth)
.property("Canvas Height", &SHCanvasComponent::GetCanvasHeight, &SHCanvasComponent::SetCanvasHeight)
;
}

View File

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <rttr/registration>
#include "SH_API.h" #include "SH_API.h"
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
namespace SHADE namespace SHADE
@ -13,6 +16,9 @@ namespace SHADE
public: public:
friend class SHUISystem;
SHCanvasComponent(); SHCanvasComponent();
~SHCanvasComponent() = default; ~SHCanvasComponent() = default;
@ -20,15 +26,18 @@ namespace SHADE
void SetCanvasWidth(CanvasSizeType width) noexcept; void SetCanvasWidth(CanvasSizeType width) noexcept;
void SetCanvasHeight(CanvasSizeType height) noexcept; void SetCanvasHeight(CanvasSizeType height) noexcept;
CanvasSizeType const GetCanvasWidth() const noexcept; CanvasSizeType GetCanvasWidth() const noexcept;
CanvasSizeType const GetCanvasHeight() const noexcept; CanvasSizeType GetCanvasHeight() const noexcept;
SHMatrix const& GetMatrix() const noexcept;
private: private:
CanvasSizeType width; CanvasSizeType width;
CanvasSizeType height; CanvasSizeType height;
bool dirtyMatrix;
SHMatrix canvasMatrix;
RTTR_ENABLE()
}; };

View File

@ -0,0 +1,43 @@
#include "SHpch.h"
#include "SHUIComponent.h"
namespace SHADE
{
SHUIComponent::SHUIComponent()
{
}
SHMatrix const& SHUIComponent::GetMatrix()const noexcept
{
return localToCanvasMatrix;
}
EntityID SHUIComponent::GetCanvasID() const noexcept
{
return canvasID;
}
void SHUIComponent::SetCanvasID(EntityID id) noexcept
{
(void)id;
}
}
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHUIComponent>("UI Component")
.property("Canvas ID", &SHUIComponent::GetCanvasID, &SHUIComponent::SetCanvasID)
;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include <rttr/registration>
#include "SH_API.h"
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
namespace SHADE
{
class SH_API SHUIComponent final: public SHComponent
{
public:
friend class SHUISystem;
SHUIComponent();
~SHUIComponent() = default;
SHMatrix const& GetMatrix() const noexcept;
EntityID GetCanvasID() const noexcept;
void SetCanvasID(EntityID id) noexcept;
private:
SHMatrix localToCanvasMatrix;
EntityID canvasID;
RTTR_ENABLE()
};
}

View File

@ -0,0 +1,113 @@
#include "SHpch.h"
#include "SHUISystem.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
void SHUISystem::Init()
{
SystemFamily::GetID<SHUISystem>();
SHComponentManager::CreateComponentSparseSet<SHCanvasComponent>();
SHComponentManager::CreateComponentSparseSet<SHUIComponent>();
}
void SHUISystem::Exit()
{
}
void SHUISystem::AddUIComponentRoutine::Execute(double dt) noexcept
{
auto& dense = SHComponentManager::GetDense<SHCanvasComponent>();
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
//Go through all the canvases and make sure all the children has a UIComponent.
for (auto& canvas : dense)
{
auto& children = sceneGraph.GetChildren(canvas.GetEID());
for (auto& child : children)
{
RecurssiveUIComponentCheck(child, canvas);
}
}
//Go through all the UI Component and make sure the parent has a UI or Canvas Component
std::vector<EntityID> entitiesToRemove;
auto& UIDense = SHComponentManager::GetDense<SHUIComponent>();
for (auto& ui : UIDense)
{
SHSceneNode* parentNode = sceneGraph.GetParent(ui.GetEID());
if (parentNode == nullptr || !(SHComponentManager::HasComponent<SHUIComponent>(parentNode->GetEntityID()) || SHComponentManager::HasComponent<SHCanvasComponent>(parentNode->GetEntityID())))
entitiesToRemove.push_back(ui.GetEID());
}
for (auto& id : entitiesToRemove)
{
SHComponentManager::RemoveComponent<SHUIComponent>(id);
}
}
void SHUISystem::AddUIComponentRoutine::RecurssiveUIComponentCheck(SHSceneNode* node, SHCanvasComponent& canvas) noexcept
{
if (node == nullptr)
return;
EntityID eid = node->GetEntityID();
if(SHComponentManager::HasComponent<SHUIComponent>(eid) == false)
SHComponentManager::AddComponent<SHUIComponent>(eid);
else
{
SHComponentManager::GetComponent<SHUIComponent>(eid)->canvasID = canvas.GetEID();
}
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eid);
for (auto& child : children)
{
RecurssiveUIComponentCheck(child, canvas);
}
}
void SHUISystem::UpdateUIMatrixRoutine::Execute(double dt) noexcept
{
SHUISystem* system = (SHUISystem* )GetSystem();
auto& dense = SHComponentManager::GetDense<SHUIComponent>();
for (auto& comp : dense)
{
system->UpdateUIComponent(comp);
}
}
void SHUISystem::UpdateUIComponent(SHUIComponent& comp) noexcept
{
auto canvasComp = SHComponentManager::GetComponent_s<SHCanvasComponent>(comp.canvasID);
if (SHComponentManager::HasComponent<SHTransformComponent>(comp.GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
if (canvasComp != nullptr)
comp.localToCanvasMatrix = canvasComp->GetMatrix() * transform->GetTRS();
else
comp.localToCanvasMatrix = transform->GetTRS();
}
else //If for some reason UI Components entities does not have a transform.
{
if (canvasComp != nullptr)
comp.localToCanvasMatrix = canvasComp->GetMatrix();
else
comp.localToCanvasMatrix = SHMatrix::Identity;
}
}
}//end namespace

Some files were not shown because too many files have changed in this diff Show More