Set to force the use of dedicated GPU #324
|
@ -1,4 +1,4 @@
|
|||
Start in Fullscreen: false
|
||||
Starting Scene ID: 97402985
|
||||
Starting Scene ID: 87244611
|
||||
Window Size: {x: 1920, y: 1080}
|
||||
Window Title: SHADE Engine
|
|
@ -1,16 +1,16 @@
|
|||
0 1 3
|
||||
1 2 3
|
||||
2 3 65535
|
||||
3 4 65535
|
||||
4 5 65535
|
||||
5 6 65535
|
||||
6 7 65535
|
||||
7 8 65535
|
||||
8 9 65535
|
||||
9 10 65535
|
||||
10 11 65535
|
||||
11 12 65535
|
||||
12 13 65535
|
||||
13 14 65535
|
||||
14 15 65535
|
||||
15 16 65535
|
||||
0 1
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
- VertexShader: 47911992
|
||||
FragmentShader: 46377769
|
||||
SubPass: G-Buffer Write
|
||||
Properties:
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 58303057
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
|||
Name: AnimatedBag
|
||||
ID: 117923942
|
||||
Type: 7
|
|
@ -0,0 +1,8 @@
|
|||
- VertexShader: 47911992
|
||||
FragmentShader: 46377769
|
||||
SubPass: G-Buffer Write
|
||||
Properties:
|
||||
data.color: {x: 1, y: 1, z: 1, w: 1}
|
||||
data.textureIndex: 64651793
|
||||
data.alpha: 0
|
||||
data.beta: {x: 1, y: 1, z: 1}
|
|
@ -0,0 +1,3 @@
|
|||
Name: AnimatedRaccoon
|
||||
ID: 128805346
|
||||
Type: 7
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
Name: BoneIKTest4
|
||||
ID: 81814706
|
||||
Type: 4
|
||||
Sub Assets:
|
||||
Name: Cube
|
||||
ID: 137599708
|
||||
Type: 8
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1,247 +0,0 @@
|
|||
- EID: 0
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 2.72256827, y: 0.501797795, z: -0.0273017883}
|
||||
Rotate: {x: 0, y: 0, z: 0.436332315}
|
||||
Scale: {x: 4.61070776, y: 0.99999392, z: 0.999996722}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 1
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Camera Component:
|
||||
Position: {x: 0, y: 2, z: 10}
|
||||
Pitch: 0
|
||||
Yaw: 0
|
||||
Roll: 0
|
||||
Width: 1920
|
||||
Height: 1080
|
||||
Near: 0.00999999978
|
||||
Far: 10000
|
||||
Perspective: true
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 3
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 2, y: 7.5, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: 0.785398185}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Auto Mass: false
|
||||
Mass: 0.52359879
|
||||
Drag: 0.00999999978
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Gravity Scale: 1
|
||||
Interpolate: true
|
||||
Sleeping Enabled: true
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: true
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: false
|
||||
Freeze Rotation Y: false
|
||||
Freeze Rotation Z: false
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Sphere
|
||||
Radius: 1
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 2
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: 4, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: -0.436332315}
|
||||
Scale: {x: 4.61071014, y: 0.999995887, z: 1}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 2
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 4
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: -3, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 10, y: 3, z: 10}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 5
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: -4.80025721, y: 3, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: 1.57079601}
|
||||
Scale: {x: 9.99975109, y: 0.499992192, z: 10}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 6
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 4.80000019, y: 3, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: 1.57079601}
|
||||
Scale: {x: 9.99975109, y: 0.499992192, z: 10}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
||||
- EID: 7
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: 7, z: 0}
|
||||
Rotate: {x: 0, y: 0, z: 0.785398185}
|
||||
Scale: {x: 0.999990404, y: 0.999994457, z: 0.999985337}
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
Type: Dynamic
|
||||
Auto Mass: false
|
||||
Mass: 1
|
||||
Drag: 0.00999999978
|
||||
Angular Drag: 0
|
||||
Use Gravity: true
|
||||
Gravity Scale: 1
|
||||
Interpolate: true
|
||||
Sleeping Enabled: true
|
||||
Freeze Position X: false
|
||||
Freeze Position Y: false
|
||||
Freeze Position Z: false
|
||||
Freeze Rotation X: false
|
||||
Freeze Rotation Y: false
|
||||
Freeze Rotation Z: false
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts:
|
||||
- Type: PhysicsTestObj
|
||||
Enabled: true
|
||||
forceAmount: 50
|
||||
torqueAmount: 5
|
||||
- EID: 8
|
||||
Name: Default
|
||||
IsActive: true
|
||||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: 0, z: 3}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
Collider Component:
|
||||
DrawColliders: false
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
Bounciness: 0
|
||||
Density: 1
|
||||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
IsActive: true
|
||||
Scripts: ~
|
|
@ -1,3 +0,0 @@
|
|||
Name: PhysicsSandbox
|
||||
ID: 97402985
|
||||
Type: 5
|
|
@ -159,7 +159,7 @@ public partial class LeafSearch : BehaviourTreeNode
|
|||
//Since transform position is often the raccoon's base and the ray needs to hit somewhere higher to be more reliable
|
||||
Vector3 rayDestination = plrT.GlobalPosition + plrT.GlobalScale * playerCollider.PositionOffset;
|
||||
Ray sightRay = new Ray(eyePosition, rayDestination - eyePosition);
|
||||
RaycastHit sightRayHit = Physics.Raycast(sightRay, false)[0];
|
||||
RaycastHit sightRayHit = Physics.Raycast(sightRay);
|
||||
//As of November 2022, RaycastHit contains only the FIRST object hit by
|
||||
//the ray in the Other GameObject data member
|
||||
//Diren may likely add ALL objects hit by the ray over December
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using SHADE;
|
||||
using SHADE_Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static PlayerController;
|
||||
using static Item;
|
||||
|
||||
|
@ -204,13 +203,9 @@ public class PickAndThrow : Script
|
|||
Vector3 playerRayPos = pc.tranform.GlobalPosition;
|
||||
playerRayPos.y += 0.05f;
|
||||
dirNor.Normalise();
|
||||
List<RaycastHit> rayList1 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(22.5f))), rayDistance, false);
|
||||
List<RaycastHit> rayList2 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-22.5f))), rayDistance, false);
|
||||
List<RaycastHit> rayList3 = Physics.Raycast(new Ray(playerRayPos, dirNor), rayDistance * 0.75f, false);
|
||||
|
||||
RaycastHit ray1 = rayList1[0];
|
||||
RaycastHit ray2 = rayList2[0];
|
||||
RaycastHit ray3 = rayList3[0];
|
||||
RaycastHit ray1 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(22.5f))), rayDistance);
|
||||
RaycastHit ray2 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-22.5f))), rayDistance);
|
||||
RaycastHit ray3 = Physics.Raycast(new Ray(playerRayPos, dirNor), rayDistance * 0.75f);
|
||||
inRange = CheckForItem(ray1) || CheckForItem(ray2) || CheckForItem(ray3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System;
|
|||
|
||||
public class SoundsBoard : Script
|
||||
{
|
||||
AudioClipHandler test;
|
||||
protected override void awake()
|
||||
{
|
||||
/*
|
||||
|
@ -31,13 +32,21 @@ event:/Homeowner/homeowner_humming
|
|||
event:/Homeowner/homeowner_footsteps
|
||||
event:/Homeowner/homeowner_detect_raccoon
|
||||
*/
|
||||
test = Audio.CreateAudioClip("event:/Music/player_undetected");
|
||||
Audio.AddAudioClipToSFXChannelGroup(test);
|
||||
}
|
||||
|
||||
protected override void start()
|
||||
{
|
||||
test.Play();
|
||||
}
|
||||
protected override void update()
|
||||
{
|
||||
|
||||
if (Input.GetKeyDown(Input.KeyCode.Q))
|
||||
Audio.PlayBGMOnce2D("event:/UI/mouse_down_element");
|
||||
test.Play();
|
||||
if (Input.GetKeyDown(Input.KeyCode.W))
|
||||
Audio.PlayBGMOnce2D("event:/UI/mouse_down_empty");
|
||||
test.Stop(true);
|
||||
if (Input.GetKeyDown(Input.KeyCode.E))
|
||||
Audio.PlayBGMOnce2D("event:/UI/mouse_enter_element");
|
||||
if (Input.GetKeyDown(Input.KeyCode.R))
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
using SHADE;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static Item;
|
||||
|
||||
|
||||
public class PhysicsTestObj : Script
|
||||
{
|
||||
public RigidBody body { get; set; }
|
||||
public Collider collider { get; set; }
|
||||
|
||||
// Movement input booleans
|
||||
public enum Direction
|
||||
{
|
||||
UP,
|
||||
DOWN,
|
||||
FORWARD,
|
||||
BACK,
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
internal bool[] move = new bool[6];
|
||||
internal bool[] rotate = new bool[6];
|
||||
|
||||
internal Vector3[] moveVec = new Vector3[6]
|
||||
{
|
||||
Vector3.Up,
|
||||
Vector3.Down,
|
||||
Vector3.Back,
|
||||
Vector3.Forward,
|
||||
Vector3.Left,
|
||||
Vector3.Right
|
||||
};
|
||||
|
||||
internal Vector3[] rotateVec = new Vector3[6]
|
||||
{
|
||||
Vector3.Right,
|
||||
Vector3.Left,
|
||||
Vector3.Forward,
|
||||
Vector3.Down,
|
||||
Vector3.Up,
|
||||
Vector3.Down
|
||||
};
|
||||
|
||||
internal Input.KeyCode[] moveInputKeys = new Input.KeyCode[6]
|
||||
{
|
||||
Input.KeyCode.Space,
|
||||
Input.KeyCode.LeftControl,
|
||||
Input.KeyCode.W,
|
||||
Input.KeyCode.S,
|
||||
Input.KeyCode.A,
|
||||
Input.KeyCode.D
|
||||
};
|
||||
|
||||
internal Input.KeyCode[] rotateInputKeys = new Input.KeyCode[6]
|
||||
{
|
||||
Input.KeyCode.I,
|
||||
Input.KeyCode.K,
|
||||
Input.KeyCode.U,
|
||||
Input.KeyCode.O,
|
||||
Input.KeyCode.J,
|
||||
Input.KeyCode.L
|
||||
};
|
||||
|
||||
public float forceAmount = 50.0f;
|
||||
public float torqueAmount = 500.0f;
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
body = GetComponent<RigidBody>();
|
||||
collider = GetComponent<Collider>();
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
move[i] = false;
|
||||
rotate[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void update()
|
||||
{
|
||||
Ray colliderRay = new Ray();
|
||||
colliderRay.Direction = Vector3.Right;
|
||||
Physics.ColliderRaycast(collider.Owner, colliderRay, false);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
if (Input.GetKeyDown(moveInputKeys[i]))
|
||||
move[i] = true;
|
||||
|
||||
if (Input.GetKeyDown(rotateInputKeys[i]))
|
||||
rotate[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void fixedUpdate()
|
||||
{
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
bool shouldMove = move[i];
|
||||
bool shouldRotate = rotate[i];
|
||||
|
||||
if (shouldMove)
|
||||
{
|
||||
//Vector3 offset = new Vector3(0.25f, 0.0f, 0.0f);
|
||||
//rb.AddForceAtLocalPos(moveVec[i] * forceAmount, offset);
|
||||
body.AddForce(moveVec[i] * forceAmount);
|
||||
move[i] = false;
|
||||
}
|
||||
|
||||
if (shouldRotate)
|
||||
{
|
||||
body.AddTorque(rotateVec[i] * torqueAmount);
|
||||
rotate[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
Name: PhysicsTestObj
|
||||
ID: 159293012
|
||||
Type: 9
|
|
@ -0,0 +1,78 @@
|
|||
#version 450
|
||||
#extension GL_KHR_vulkan_glsl : enable
|
||||
|
||||
//#include "ShaderDescriptorDefinitions.glsl"
|
||||
|
||||
|
||||
layout(location = 0) in vec3 aVertexPos;
|
||||
layout(location = 1) in vec2 aUV;
|
||||
layout(location = 2) in vec3 aNormal;
|
||||
layout(location = 3) in vec3 aTangent;
|
||||
layout(location = 4) in mat4 worldTransform;
|
||||
layout(location = 8) in uvec2 integerData;
|
||||
layout(location = 9) in uvec4 aBoneIndices;
|
||||
layout(location = 10) in vec4 aBoneWeights;
|
||||
layout(location = 11) in uint firstBoneIndex;
|
||||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
vec4 vertPos; // location 0
|
||||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
} Out;
|
||||
|
||||
// material stuff
|
||||
layout(location = 4) out struct
|
||||
{
|
||||
int materialIndex;
|
||||
uint eid;
|
||||
uint lightLayerIndex;
|
||||
|
||||
} Out2;
|
||||
|
||||
layout(set = 1, binding = 0) uniform CameraData
|
||||
{
|
||||
vec4 position;
|
||||
mat4 vpMat;
|
||||
mat4 viewMat;
|
||||
mat4 projMat;
|
||||
} cameraData;
|
||||
|
||||
layout (std430, set = 2, binding = 1) buffer AnimBoneMatrices
|
||||
{
|
||||
mat4 data[];
|
||||
} BoneMatrices;
|
||||
|
||||
void main()
|
||||
{
|
||||
Out2.materialIndex = gl_InstanceIndex;
|
||||
Out2.eid = integerData[0];
|
||||
Out2.lightLayerIndex = integerData[1];
|
||||
|
||||
// for transforming gBuffer position and normal data
|
||||
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||
|
||||
// gBuffer position will be in view space
|
||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||
|
||||
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||
|
||||
// uvs for texturing in fragment shader
|
||||
Out.uv = aUV;
|
||||
|
||||
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||
|
||||
// normals are also in view space
|
||||
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||
|
||||
// Compute bone matrix
|
||||
mat4 boneMatrix = BoneMatrices.data[firstBoneIndex + aBoneIndices[0]] * aBoneWeights[0];
|
||||
boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[1]] * aBoneWeights[1];
|
||||
boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[2]] * aBoneWeights[2];
|
||||
boneMatrix += BoneMatrices.data[firstBoneIndex + aBoneIndices[3]] * aBoneWeights[3];
|
||||
|
||||
// clip space for rendering
|
||||
gl_Position = cameraData.vpMat * worldTransform * boneMatrix * vec4 (aVertexPos, 1.0f);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
Name: Anim_VS
|
||||
ID: 47911992
|
||||
Type: 2
|
|
@ -17,7 +17,6 @@ layout(location = 0) in struct
|
|||
vec2 uv; // location = 1
|
||||
vec4 normal; // location = 2
|
||||
vec4 worldPos; // location = 3
|
||||
|
||||
} In;
|
||||
|
||||
// material stuff
|
||||
|
|
|
@ -10,7 +10,9 @@ layout(location = 2) in vec3 aNormal;
|
|||
layout(location = 3) in vec3 aTangent;
|
||||
layout(location = 4) in mat4 worldTransform;
|
||||
layout(location = 8) in uvec2 integerData;
|
||||
|
||||
layout(location = 9) in uvec4 aBoneIndices;
|
||||
layout(location = 10) in vec4 aBoneWeights;
|
||||
layout(location = 11) in uint firstBoneIndex;
|
||||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -34,6 +34,7 @@
|
|||
#include "Physics/System/SHPhysicsDebugDrawSystem.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "UI/SHUISystem.h"
|
||||
#include "Animation/SHAnimationSystem.h"
|
||||
|
||||
// Components
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
|
||||
#include "Tools/Logger/SHLogger.h"
|
||||
#include "Tools/SHDebugDraw.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
|
||||
using namespace SHADE;
|
||||
|
||||
|
@ -77,6 +79,9 @@ namespace Sandbox
|
|||
SHSystemManager::CreateSystem<SHScriptEngine>();
|
||||
SHSystemManager::CreateSystem<SHTransformSystem>();
|
||||
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
||||
#ifndef _PUBLISH
|
||||
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
||||
#endif
|
||||
|
||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||
|
@ -87,10 +92,12 @@ namespace Sandbox
|
|||
|
||||
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||
SHPhysicsSystem* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||
|
||||
// Link up SHDebugDraw
|
||||
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||
SHSystemManager::CreateSystem<SHAnimationSystem>();
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
@ -101,8 +108,6 @@ namespace Sandbox
|
|||
editor->SetSDLWindow(sdlWindow);
|
||||
editor->SetSHWindow(&window);
|
||||
}
|
||||
|
||||
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
|
||||
#endif
|
||||
|
||||
// Create Routines
|
||||
|
@ -114,11 +119,11 @@ namespace Sandbox
|
|||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostLogicUpdate>();
|
||||
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDraw>();
|
||||
#ifndef _PUBLISH
|
||||
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
|
||||
#endif
|
||||
|
||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||
|
@ -139,7 +144,7 @@ namespace Sandbox
|
|||
#ifdef SHEDITOR
|
||||
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
|
||||
#endif
|
||||
|
||||
SHSystemManager::RegisterRoutine<SHAnimationSystem, SHAnimationSystem::UpdateRoutine>();
|
||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::RenderRoutine>();
|
||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::EndRoutine>();
|
||||
|
||||
|
@ -147,6 +152,7 @@ namespace Sandbox
|
|||
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
|
||||
SHComponentManager::CreateComponentSparseSet<SHAnimatorComponent>();
|
||||
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
|
||||
|
||||
SHAssetManager::Load();
|
||||
|
@ -168,6 +174,10 @@ namespace Sandbox
|
|||
|
||||
// Link up SHDebugDraw
|
||||
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||
|
||||
auto clip = SHResourceManager::LoadOrGet<SHAnimationClip>(77816045);
|
||||
auto rig = SHResourceManager::LoadOrGet<SHRig>(77816045);
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
void SBApplication::Update(void)
|
||||
|
@ -191,12 +201,32 @@ namespace Sandbox
|
|||
#endif
|
||||
SHSceneManager::SceneUpdate(0.016f);
|
||||
#ifdef SHEDITOR
|
||||
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, SHFrameRateController::GetRawDeltaTime());
|
||||
editor->PollPicking();
|
||||
#else
|
||||
SHSystemManager::RunRoutines(false, SHFrameRateController::GetRawDeltaTime());
|
||||
#endif
|
||||
// TODO: Move into an Editor menu
|
||||
static bool drawContacts = false;
|
||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F9))
|
||||
{
|
||||
drawContacts = !drawContacts;
|
||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_POINTS, drawContacts);
|
||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACT_NORMALS, drawContacts);
|
||||
}
|
||||
static bool drawColliders = false;
|
||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
|
||||
{
|
||||
drawColliders = !drawColliders;
|
||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders);
|
||||
}
|
||||
static bool drawRays = false;
|
||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F11))
|
||||
{
|
||||
drawRays = !drawRays;
|
||||
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||
}
|
||||
|
||||
}
|
||||
// Finish all graphics jobs first
|
||||
graphicsSystem->AwaitGraphicsExecution();
|
||||
|
@ -210,7 +240,13 @@ namespace Sandbox
|
|||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
// Unload scenes
|
||||
SHSceneManager::Exit();
|
||||
|
||||
// Free all remaining resources
|
||||
SHResourceManager::UnloadAll();
|
||||
|
||||
// Shut down engine
|
||||
SHSystemManager::Exit();
|
||||
SHAssetManager::Exit();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,23 @@ namespace Sandbox
|
|||
{
|
||||
sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID);
|
||||
|
||||
auto* physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||
if (!physicsSystem)
|
||||
{
|
||||
SHLOGV_CRITICAL("Failed to get the physics system for building the scene!")
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SHEDITOR
|
||||
|
||||
physicsSystem->ForceBuild(SHSceneManager::GetCurrentSceneGraph());
|
||||
|
||||
#else
|
||||
|
||||
physicsSystem->BuildScene(SHSceneManager::GetCurrentSceneGraph());
|
||||
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* TESTING CODE */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Sandbox
|
|||
|
||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||
|
||||
//floorCollider.AddBoundingBox();
|
||||
floorCollider.AddBoundingBox();
|
||||
|
||||
// Create blank entity with a script
|
||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
|
@ -113,9 +113,9 @@ namespace Sandbox
|
|||
racoonTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||
|
||||
//racoonCollider.AddBoundingBox();
|
||||
//racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||
//racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
racoonCollider.AddBoundingBox();
|
||||
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||
racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
||||
|
@ -138,15 +138,15 @@ namespace Sandbox
|
|||
itemTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||
itemTransform.SetWorldPosition({ 0.0f, -2.0f, -5.0f });
|
||||
|
||||
//itemCollider.AddBoundingBox();
|
||||
//itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||
//itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||
itemCollider.AddBoundingBox();
|
||||
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||
itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||
|
||||
//itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
//itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
//itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
//itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||
itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
itemRigidBody.SetInterpolate(false);
|
||||
itemRigidBody.SetFreezeRotationX(true);
|
||||
|
@ -167,9 +167,9 @@ namespace Sandbox
|
|||
AITransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
|
||||
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||
|
||||
//AICollider.AddBoundingBox();
|
||||
//AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
//AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
AICollider.AddBoundingBox();
|
||||
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||
AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
AIRigidBody.SetInterpolate(false);
|
||||
AIRigidBody.SetFreezeRotationX(true);
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimationClip.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the function definitions of the SHAnimationClip class.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Pre-compiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SHAnimationClip.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
||||
: ticksPerSecond { static_cast<int>(asset.ticksPerSecond) }
|
||||
, totalTime { static_cast<float>(asset.duration) / static_cast<int>(asset.ticksPerSecond) }
|
||||
{
|
||||
// Populate keyframes
|
||||
for (const auto& channel : asset.nodeChannels)
|
||||
{
|
||||
// Create a channel
|
||||
Channel newChannel;
|
||||
newChannel.Name = std::string(channel.name);
|
||||
newChannel.PositionKeyFrames.reserve(channel.positionKeys.size());
|
||||
newChannel.RotationKeyFrames.reserve(channel.rotationKeys.size());
|
||||
newChannel.ScaleKeyFrames.reserve(channel.scaleKeys.size());
|
||||
|
||||
// Populate Keyframes
|
||||
for (const auto& posKey : channel.positionKeys)
|
||||
{
|
||||
newChannel.PositionKeyFrames.emplace_back(SHAnimationKeyFrame<SHVec3>{ static_cast<int>(posKey.time), posKey.value});
|
||||
}
|
||||
for (const auto& rotKey : channel.rotationKeys)
|
||||
{
|
||||
newChannel.RotationKeyFrames.emplace_back(SHAnimationKeyFrame<SHQuaternion>{ static_cast<int>(rotKey.time), rotKey.value});
|
||||
}
|
||||
for (const auto& scaleKey : channel.scaleKeys)
|
||||
{
|
||||
newChannel.ScaleKeyFrames.emplace_back(SHAnimationKeyFrame<SHVec3>{ static_cast<int>(scaleKey.time), scaleKey.value});
|
||||
}
|
||||
|
||||
newChannel.MaxFrames = std::max({ newChannel.PositionKeyFrames.size(), newChannel.RotationKeyFrames.size(), newChannel.ScaleKeyFrames.size() });
|
||||
|
||||
// Insert the channel
|
||||
channels.emplace_back(std::move(newChannel));
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimationClip.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Dec 12, 2022
|
||||
\brief Contains the definition of the SHAnimationClip struct and related types.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "SH_API.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "Assets/Asset Types/Models/SHAnimationAsset.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Defines a single key frame in an animation for a specific type of data.
|
||||
/// </summary>
|
||||
template<typename T>
|
||||
struct SHAnimationKeyFrame
|
||||
{
|
||||
int FrameIndex;
|
||||
T Data;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Represents a animation clip of a 3D animation that is made for a specific model
|
||||
/// rig.
|
||||
/// </summary>
|
||||
class SH_API SHAnimationClip
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Defines the animations of a single bone in a rig.
|
||||
/// </summary>
|
||||
struct Channel
|
||||
{
|
||||
std::string Name;
|
||||
std::vector<SHAnimationKeyFrame<SHVec3>> PositionKeyFrames;
|
||||
std::vector<SHAnimationKeyFrame<SHQuaternion>> RotationKeyFrames;
|
||||
std::vector<SHAnimationKeyFrame<SHVec3>> ScaleKeyFrames;
|
||||
int MaxFrames;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructs an SHAnimation Clip from a specified SHAnimAsset.
|
||||
/// </summary>
|
||||
/// <param name="asset">Animation asset to load.</param>
|
||||
explicit SHAnimationClip(const SHAnimAsset& asset);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||
int GetTicksPerSecond() const noexcept { return ticksPerSecond; }
|
||||
float GetTotalTime() const noexcept { return totalTime; }
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
std::vector<Channel> channels;
|
||||
int ticksPerSecond;
|
||||
float totalTime;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimationSystem.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the function definitions of the SHAnimationSystem class.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Include
|
||||
#include "SHAnimationSystem.h"
|
||||
// Project Includes
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "SHAnimatorComponent.h"
|
||||
#include "ECS_Base/General/SHFamily.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - UpdateRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHAnimationSystem::UpdateRoutine::UpdateRoutine()
|
||||
: SHSystemRoutine("Animation System Update", true)
|
||||
{
|
||||
SHFamilyID<SHSystem>::GetID<SHAnimationSystem>();
|
||||
}
|
||||
|
||||
void SHAnimationSystem::UpdateRoutine::Execute(double dt) noexcept
|
||||
{
|
||||
auto& animators = SHComponentManager::GetDense<SHAnimatorComponent>();
|
||||
for (auto& animator : animators)
|
||||
{
|
||||
animator.Update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* SHSystem Overrides */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHAnimationSystem::Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHAnimationSystem::Exit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimationSystem.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the definition of the SHAnimationSystem class and related types.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/System/SHSystem.h"
|
||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// System that is responsible for updating all animations.
|
||||
/// </summary>
|
||||
class SH_API SHAnimationSystem : public SHSystem
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Responsible for updating the playback of all animator components and computing
|
||||
/// the required bone matrices.
|
||||
/// </summary>
|
||||
class SH_API UpdateRoutine final : public SHSystemRoutine
|
||||
{
|
||||
public:
|
||||
UpdateRoutine();
|
||||
void Execute(double dt) noexcept override final;
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHAnimationSystem() = default;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* SHSystem Overrides */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
virtual void Init(void) override final;
|
||||
virtual void Exit(void) override final;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimatorComponent.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the definition of functions of the SHAnimatorComponent Component
|
||||
class.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Include
|
||||
#include "SHAnimatorComponent.h"
|
||||
// STL Includes
|
||||
#include <queue>
|
||||
// Project Includes
|
||||
#include "SHRig.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "SHAnimationClip.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Tools/SHDebugDraw.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::Play()
|
||||
{
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Play(Handle<SHAnimationClip> clip)
|
||||
{
|
||||
currClip = clip;
|
||||
currPlaybackTime = 0.0f;
|
||||
Play();
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::PlayFromStart()
|
||||
{
|
||||
isPlaying = true;
|
||||
currPlaybackTime = 0.0f;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Pause()
|
||||
{
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Stop()
|
||||
{
|
||||
isPlaying = false;
|
||||
currPlaybackTime = 0.0f;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::SetRig(Handle<SHRig> newRig)
|
||||
{
|
||||
// Same rig, don't bother
|
||||
if (rig == newRig)
|
||||
return;
|
||||
|
||||
rig = newRig;
|
||||
|
||||
// Populate bone matrices based on new rig's default pose
|
||||
boneMatrices.clear();
|
||||
if (rig)
|
||||
{
|
||||
std::fill_n(std::back_inserter(boneMatrices), rig->GetNodeCount(), SHMatrix::Identity);
|
||||
}
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::SetClip(Handle<SHAnimationClip> newClip)
|
||||
{
|
||||
// No change
|
||||
if (currClip == newClip)
|
||||
return;
|
||||
|
||||
// Set parameters
|
||||
currClip = newClip;
|
||||
secsPerTick = 1.0f / currClip->GetTicksPerSecond();
|
||||
|
||||
// Build channel map
|
||||
channelMap.clear();
|
||||
if (currClip)
|
||||
{
|
||||
for (const auto& channel : currClip->GetChannels())
|
||||
{
|
||||
channelMap.emplace(channel.Name, &channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (rig && currClip)
|
||||
{
|
||||
updatePoseWithClip(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Update Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::Update(float dt)
|
||||
{
|
||||
// Nothing to animate
|
||||
if (!currClip || !isPlaying || !rig)
|
||||
return;
|
||||
|
||||
// Update time on the playback
|
||||
currPlaybackTime += dt;
|
||||
if (currPlaybackTime > currClip->GetTotalTime())
|
||||
{
|
||||
currPlaybackTime = currPlaybackTime - currClip->GetTotalTime();
|
||||
}
|
||||
|
||||
// Reset all matrices
|
||||
for (auto& mat : boneMatrices)
|
||||
{
|
||||
mat = SHMatrix::Identity;
|
||||
}
|
||||
|
||||
// Play the clip
|
||||
updatePoseWithClip(currPlaybackTime);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::updatePoseWithClip(float poseTime)
|
||||
{
|
||||
// Get closest frame index
|
||||
const int CLOSEST_FRAME_IDX = static_cast<int>(std::floorf(poseTime * currClip->GetTicksPerSecond()));
|
||||
updatePoseWithClip(CLOSEST_FRAME_IDX, poseTime, rig->GetRootNode(), SHMatrix::Identity);
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::updatePoseWithClip(int closestFrameIndex, float poseTime, Handle<SHRigNode> node, const SHMatrix& parentMatrix)
|
||||
{
|
||||
// Check if there is a channel for this node
|
||||
const std::string& BONE_NAME = rig->GetName(node);
|
||||
SHMatrix transformMatrix = node->TransformMatrix;
|
||||
if (channelMap.contains(BONE_NAME))
|
||||
{
|
||||
const auto CHANNEL = channelMap[BONE_NAME];
|
||||
transformMatrix = SHMatrix::Transform
|
||||
(
|
||||
getInterpolatedValue(CHANNEL->PositionKeyFrames, closestFrameIndex, poseTime),
|
||||
getInterpolatedValue(CHANNEL->RotationKeyFrames, closestFrameIndex, poseTime),
|
||||
getInterpolatedValue(CHANNEL->ScaleKeyFrames, closestFrameIndex, poseTime)
|
||||
);
|
||||
}
|
||||
|
||||
// Apply parent's transformation
|
||||
transformMatrix = transformMatrix * parentMatrix;
|
||||
|
||||
// Apply transformations to this node
|
||||
const int BONE_MTX_IDX = rig->GetNodeIndex(node);
|
||||
std::optional<SHVec3> position;
|
||||
if (BONE_MTX_IDX >= 0)
|
||||
{
|
||||
boneMatrices[BONE_MTX_IDX] = node->OffsetMatrix * transformMatrix;
|
||||
}
|
||||
|
||||
// Apply pose to children
|
||||
for (auto& child : node->Children)
|
||||
{
|
||||
updatePoseWithClip(closestFrameIndex, poseTime, child, transformMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* RTTR Registration */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
using namespace SHADE;
|
||||
using namespace rttr;
|
||||
|
||||
registration::class_<SHAnimatorComponent>("Animator Component");
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimatorComponent.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the definition of the SHAnimatorComponent class and related
|
||||
types.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// STL Includes
|
||||
#include <vector>
|
||||
// External Dependencies
|
||||
#include <rttr/registration>
|
||||
// Project Includes
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/SHQuaternion.h"
|
||||
#include "SHAnimationClip.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
class SHRig;
|
||||
struct SHRigNode;
|
||||
class SHAnimationClip;
|
||||
class SHVkBuffer;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Component that holds and controls the animation related properties of a skinned
|
||||
/// mesh.
|
||||
/// </summary>
|
||||
class SH_API SHAnimatorComponent final : public SHComponent
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Plays the currently loaded animation from the last time.
|
||||
/// </summary>
|
||||
void Play();
|
||||
/// <summary>
|
||||
/// Plays the specified animation clip from the start.
|
||||
/// </summary>
|
||||
/// <param name="clip"></param>
|
||||
void Play(Handle<SHAnimationClip> clip);
|
||||
/// <summary>
|
||||
/// Plays the currently loaded animation clip from the start.
|
||||
/// </summary>
|
||||
void PlayFromStart();
|
||||
/// <summary>
|
||||
/// Pauses the animation at the current time.
|
||||
/// </summary>
|
||||
void Pause();
|
||||
/// <summary>
|
||||
/// Stops the animation and resets the play time back to 0.
|
||||
/// </summary>
|
||||
void Stop();
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the animation rig for this animator.
|
||||
/// </summary>
|
||||
/// <param name="newRig">Rig to use.</param>
|
||||
void SetRig(Handle<SHRig> newRig);
|
||||
/// <summary>
|
||||
/// Sets the animation clip of this animator without playing it.
|
||||
/// This will set the pose of the model to it's initial pose.
|
||||
/// If the clip is the same as the current clip, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="newClip">Clip to use.</param>
|
||||
void SetClip(Handle<SHAnimationClip> newClip);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves all the bone matrices of this animator.
|
||||
/// </summary>
|
||||
/// <returns>Reference to a vector of the bone matrices.</returns>
|
||||
const std::vector<SHMatrix>& GetBoneMatrices() const noexcept { return boneMatrices; }
|
||||
/// <summary>
|
||||
/// Retrieve the currently set model rig.
|
||||
/// </summary>
|
||||
/// <returns>Handle to the currently set rig.</returns>
|
||||
Handle<SHRig> GetRig() const noexcept { return rig; }
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Retrieve the currently set animation clip.
|
||||
/// </summary>
|
||||
/// <returns>Handle to the currently set animation clip.</returns>
|
||||
Handle<SHAnimationClip> GetCurrentClip() const noexcept { return currClip; }
|
||||
/// <summary>
|
||||
/// Checks if an animation is currently playing.
|
||||
/// </summary>
|
||||
/// <returns>True if an animation clip is currently playing.</returns>
|
||||
bool IsPlaying() const { return isPlaying; }
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Update Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Updates the current state of the animation if one is specified based on the
|
||||
/// current animation clip and frames. This will update the bone matrices.
|
||||
/// </summary>
|
||||
/// <param name="dt">Time passed since the last frame.</param>
|
||||
void Update(float dt);
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
// Resources
|
||||
Handle<SHRig> rig;
|
||||
Handle<SHAnimationClip> currClip;
|
||||
// Playback Tracking
|
||||
float currPlaybackTime = 0.0f;
|
||||
bool isPlaying = true;
|
||||
// Useful Cached Data
|
||||
float secsPerTick = 0.0f;
|
||||
// Buffer
|
||||
std::vector<SHMatrix> boneMatrices;
|
||||
// Caches
|
||||
std::unordered_map<std::string, const SHAnimationClip::Channel*> channelMap;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void updatePoseWithClip(float poseTime);
|
||||
void updatePoseWithClip(int closestFrameIndex, float poseTime, Handle<SHRigNode> node, const SHMatrix& parentMatrix);
|
||||
template<typename T>
|
||||
T getInterpolatedValue(const std::vector<SHAnimationKeyFrame<T>>& keyframes, int closestFrameIndex, float poseTime);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* RTTR */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
}
|
||||
|
||||
#include "SHAnimatorComponent.hpp"
|
|
@ -0,0 +1,82 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHAnimatorComponent.hpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Jan 10, 2023
|
||||
\brief Contains the definition of function templates of the SHAnimatorComponent
|
||||
Component class.
|
||||
|
||||
Copyright (C) 2023 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Primary Include
|
||||
#include "SHAnimatorComponent.h"
|
||||
// Project Includes
|
||||
#include "SHRig.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "SHAnimationClip.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
template<typename T>
|
||||
T SHAnimatorComponent::getInterpolatedValue(const std::vector<SHAnimationKeyFrame<T>>& keyframes, int closestFrameIndex, float poseTime)
|
||||
{
|
||||
// Only allow SHVec3 and SHQuaternion
|
||||
static_assert(std::is_same_v<T, SHVec3> || std::is_same_v<T, SHQuaternion>, "Only interpolation for SHVec3 and SHQuaternion is allowed.");
|
||||
|
||||
// Find the key frames that surround the current frame index
|
||||
auto firstKeyFrame = keyframes.end();
|
||||
auto nextKeyFrame = keyframes.end();
|
||||
for (auto iter = keyframes.begin(); iter != keyframes.end(); ++iter)
|
||||
{
|
||||
const auto& KEYFRAME = *iter;
|
||||
|
||||
if (KEYFRAME.FrameIndex <= closestFrameIndex)
|
||||
{
|
||||
firstKeyFrame = iter;
|
||||
}
|
||||
else // KEYFRAME.FrameIndex > closestFrameIndex
|
||||
{
|
||||
nextKeyFrame = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Edge Cases
|
||||
if (firstKeyFrame == keyframes.end())
|
||||
{
|
||||
// No keyframes at all, means no changes
|
||||
if (nextKeyFrame == keyframes.end())
|
||||
return T();
|
||||
// Out of range, clamp to the back
|
||||
else
|
||||
return nextKeyFrame->Data;
|
||||
}
|
||||
// At the back, so no keyframes will follow
|
||||
else if (nextKeyFrame == keyframes.end())
|
||||
{
|
||||
return firstKeyFrame->Data;
|
||||
}
|
||||
|
||||
// Get interpolated vector
|
||||
const float PREV_FRAME_TIME = firstKeyFrame->FrameIndex * secsPerTick;
|
||||
const float NEXT_FRAME_TIME = nextKeyFrame->FrameIndex * secsPerTick;
|
||||
const float NORMALISED_TIME = (poseTime - PREV_FRAME_TIME) / (NEXT_FRAME_TIME - PREV_FRAME_TIME);
|
||||
|
||||
if constexpr (std::is_same_v<T, SHQuaternion>)
|
||||
{
|
||||
return SHQuaternion::Slerp(firstKeyFrame->Data, nextKeyFrame->Data, NORMALISED_TIME);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, SHVec3>)
|
||||
{
|
||||
return SHVec3::Lerp(firstKeyFrame->Data, nextKeyFrame->Data, NORMALISED_TIME);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHRig.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the function definitions of the SHRig class.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Pre-compiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SHRig.h"
|
||||
// STL Includes
|
||||
#include <stack>
|
||||
// Project Headers
|
||||
#include "Assets/Asset Types/Models/SHRigAsset.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHRig::SHRig(const SHRigAsset& asset, SHResourceLibrary<SHRigNode>& nodeStore)
|
||||
{
|
||||
// Don't bother if empty
|
||||
if (asset.root == nullptr)
|
||||
{
|
||||
SHLOG_ERROR("[SHRig] Attempted to load an invalid rig with no root.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a recursive depth first traversal to populate the rig
|
||||
rootNode = recurseCreateNode(asset, asset.root, nodeStore);
|
||||
if (rootNode)
|
||||
{
|
||||
globalInverseMatrix = SHMatrix::Inverse(rootNode->TransformMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
SHRig::SHRig(SHRig&& rhs)
|
||||
: rootNode { rhs.rootNode }
|
||||
, nodeNames { std::move(rhs.nodeNames) }
|
||||
, nodesByName { std::move(rhs.nodesByName) }
|
||||
, nodes { std::move(rhs.nodes) }
|
||||
, nodeIndexMap { std::move(rhs.nodeIndexMap) }
|
||||
, globalInverseMatrix { std::move(rhs.globalInverseMatrix) }
|
||||
{
|
||||
rhs.rootNode = {};
|
||||
}
|
||||
SHRig::~SHRig()
|
||||
{
|
||||
// Unload all nodes
|
||||
for (auto node : nodes)
|
||||
{
|
||||
if (node)
|
||||
node.Free();
|
||||
}
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
SHRig& SHRig::operator=(SHRig&& rhs)
|
||||
{
|
||||
rootNode = rhs.rootNode;
|
||||
nodeNames = std::move(rhs.nodeNames);
|
||||
nodesByName = std::move(rhs.nodesByName);
|
||||
nodes = std::move(rhs.nodes);
|
||||
nodeIndexMap = std::move(rhs.nodeIndexMap);
|
||||
globalInverseMatrix = std::move(rhs.globalInverseMatrix);
|
||||
|
||||
rhs.rootNode = {};
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
const std::string& SHRig::GetName(Handle<SHRigNode> node) const noexcept
|
||||
{
|
||||
static const std::string EMPTY_STRING = "";
|
||||
|
||||
if (nodeNames.contains(node))
|
||||
return nodeNames.at(node);
|
||||
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
Handle<SHRigNode> SHRig::GetNode(const std::string& name) const noexcept
|
||||
{
|
||||
if (nodesByName.contains(name))
|
||||
return nodesByName.at(name);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
int SHRig::GetNodeCount() const noexcept
|
||||
{
|
||||
return static_cast<int>(nodes.size());
|
||||
}
|
||||
|
||||
int SHRig::GetNodeIndex(Handle<SHRigNode> node) const noexcept
|
||||
{
|
||||
if (nodeIndexMap.contains(node))
|
||||
{
|
||||
return nodeIndexMap.at(node);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
Handle<SHRigNode> SHRig::recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode, SHResourceLibrary<SHRigNode>& nodeStore)
|
||||
{
|
||||
// Construct the node
|
||||
auto newNode = nodeStore.Create();
|
||||
|
||||
// Fill the node with data
|
||||
const auto& NODE_DATA = asset.nodeDataCollection.at(sourceNode->idRef);
|
||||
newNode->OffsetMatrix = SHMatrix::Transpose(NODE_DATA.offset);
|
||||
newNode->TransformMatrix = SHMatrix::Transpose(NODE_DATA.transform);
|
||||
|
||||
// Populate maps
|
||||
if (!NODE_DATA.name.empty())
|
||||
{
|
||||
nodeNames.emplace(newNode, NODE_DATA.name);
|
||||
nodesByName.emplace(NODE_DATA.name, newNode);
|
||||
}
|
||||
nodeIndexMap.emplace(newNode, sourceNode->idRef);
|
||||
nodes.emplace_back(newNode);
|
||||
|
||||
// Fill child nodes
|
||||
for (const auto& child : sourceNode->children)
|
||||
{
|
||||
// Ignore nulls
|
||||
if (child == nullptr)
|
||||
continue;
|
||||
|
||||
// Recursively create children
|
||||
auto childNode = recurseCreateNode(asset, child, nodeStore); // Not sure why this works but it is required for
|
||||
newNode->Children.emplace_back(childNode); // the emplace_back operation to not crash
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHRig.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 20, 2022
|
||||
\brief Contains the definition of the SHRig struct and related types.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// STL Includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
// Project Includes
|
||||
#include "SH_API.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Resource/SHResourceLibrary.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
struct SHRigAsset;
|
||||
struct SHRigNodeAsset;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
struct SHRigNode
|
||||
{
|
||||
/// <summary>
|
||||
/// Matrix that performs a transformation from local space to bone (node) space.
|
||||
/// </summary>
|
||||
SHMatrix OffsetMatrix;
|
||||
/// <summary>
|
||||
/// Matrix that performs a transformation from bone (node) space to local space.
|
||||
/// </summary>
|
||||
SHMatrix TransformMatrix;
|
||||
/// <summary>
|
||||
/// Child nodes of this node.
|
||||
/// </summary>
|
||||
std::vector<Handle<SHRigNode>> Children;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Represents an animation skeletal rig for a model.
|
||||
/// </summary>
|
||||
class SH_API SHRig
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors/Destructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructs a rig from a SHRigAsset.
|
||||
/// </summary>
|
||||
/// <param name="asset">
|
||||
/// SHRigAsset to load.
|
||||
/// </param>
|
||||
/// <param name="nodeStore">
|
||||
/// Reference to a ResourceLibrary to use to create the rig's nodes.
|
||||
/// </param>
|
||||
explicit SHRig(const SHRigAsset& asset, SHResourceLibrary<SHRigNode>& nodeStore);
|
||||
/// <summary>
|
||||
/// Move Constructor
|
||||
/// </summary>
|
||||
/// <param name="rhs>SHRig to move from.</param>
|
||||
SHRig(SHRig&& rhs);
|
||||
/// <summary>
|
||||
/// Default destructor.
|
||||
/// </summary>
|
||||
~SHRig();
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Move assignment operator.
|
||||
/// </summary>
|
||||
/// <param name="rhs>SHRig to move from.</param>
|
||||
/// <returns>Reference to this object.</returns>
|
||||
SHRig& operator=(SHRig&& rhs);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves the name of a node.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to get the name of.</param>
|
||||
/// <returns>
|
||||
/// Name of the node. If it does not have a name or is invalid, an empty string will
|
||||
/// be provided.
|
||||
/// </returns>
|
||||
const std::string& GetName(Handle<SHRigNode> node) const noexcept;
|
||||
/// <summary>
|
||||
/// Retrieves the root node of the rig.
|
||||
/// </summary>
|
||||
/// <returns>Handle to the root node of the rig.</returns>
|
||||
Handle<SHRigNode> GetRootNode() const noexcept { return rootNode; }
|
||||
const SHMatrix& GetGlobalInverseMatrix() const noexcept { return globalInverseMatrix; }
|
||||
/// <summary>
|
||||
/// Retrieves a node via name.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the node to retrieve.</param>
|
||||
/// <returns>
|
||||
/// Node with the specified name. If it does not have a name or is invalid, an empty
|
||||
/// handle will be provided.
|
||||
/// </returns>
|
||||
Handle<SHRigNode> GetNode(const std::string& name) const noexcept;
|
||||
/// <summary>
|
||||
/// Returns the number of nodes in the rig. This matches the number of bone matrices
|
||||
/// needed.
|
||||
/// </summary>
|
||||
int GetNodeCount() const noexcept;
|
||||
/// <summary>
|
||||
/// Retrieves the index in the node storage.
|
||||
/// </summary>
|
||||
int GetNodeIndex(Handle<SHRigNode> node) const noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHRigNode> rootNode;
|
||||
std::unordered_map<Handle<SHRigNode>, std::string> nodeNames;
|
||||
std::unordered_map<std::string, Handle<SHRigNode>> nodesByName;
|
||||
std::vector<Handle<SHRigNode>> nodes;
|
||||
std::unordered_map<Handle<SHRigNode>, int> nodeIndexMap;
|
||||
SHMatrix globalInverseMatrix;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHRigNode> recurseCreateNode(const SHRigAsset& asset, const SHRigNodeAsset* sourceNode, SHResourceLibrary<SHRigNode>& nodeStore);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*************************************************************************//**
|
||||
* \file SHAnimationAsset.h
|
||||
* \author Loh Xiao Qi
|
||||
* \date October 2022
|
||||
* \brief
|
||||
*
|
||||
* Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
*****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Math/SHMath.h"
|
||||
#include "Assets/Asset Types/SHAssetData.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
enum class SHAnimationBehaviour : uint8_t
|
||||
{
|
||||
DEFAULT = 0x0,
|
||||
CONSTANT = 0x1,
|
||||
LINEAR = 0x2,
|
||||
REPEAT = 0x3
|
||||
};
|
||||
|
||||
// Smallest data containers
|
||||
struct PositionKey
|
||||
{
|
||||
float time;
|
||||
SHVec3 value;
|
||||
};
|
||||
|
||||
struct RotationKey
|
||||
{
|
||||
float time;
|
||||
SHVec4 value;
|
||||
};
|
||||
|
||||
struct ScaleKey
|
||||
{
|
||||
float time;
|
||||
SHVec3 value;
|
||||
};
|
||||
|
||||
// Headers for read/write
|
||||
struct SHAnimNodeInfo
|
||||
{
|
||||
uint32_t charCount;
|
||||
uint32_t posKeyCount;
|
||||
uint32_t rotKeyCount;
|
||||
uint32_t scaKeyCount;
|
||||
};
|
||||
|
||||
struct SHAnimDataHeader
|
||||
{
|
||||
uint32_t charCount;
|
||||
uint32_t animNodeCount;
|
||||
std::vector<SHAnimNodeInfo> nodeHeaders;
|
||||
};
|
||||
|
||||
// Main data containers
|
||||
struct SHAnimData
|
||||
{
|
||||
std::string name;
|
||||
SHAnimationBehaviour pre;
|
||||
SHAnimationBehaviour post;
|
||||
|
||||
std::vector<PositionKey> positionKeys;
|
||||
std::vector<RotationKey> rotationKeys;
|
||||
std::vector<ScaleKey> scaleKeys;
|
||||
|
||||
};
|
||||
|
||||
struct SH_API SHAnimAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
|
||||
double duration;
|
||||
double ticksPerSecond;
|
||||
|
||||
std::vector<SHAnimData> nodeChannels;
|
||||
//std::vector<aiMeshAnim*> meshChannels;
|
||||
//std::vector<aiMeshMorphAnim*> morphMeshChannels;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
* \file SHMeshAsset.h
|
||||
* \author Loh Xiao Qi
|
||||
* \date 19 November 2022
|
||||
* \brief
|
||||
*
|
||||
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||
* or disclosure of this file or its contents without the prior
|
||||
* written consent of Digipen Institute of Technology is prohibited.
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Math/SHMath.h"
|
||||
#include "Assets/Asset Types/SHAssetData.h"
|
||||
#include "Math/Vector/SHVec4U.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
constexpr int BONE_INDEX_ALIGHTMENT = 4;
|
||||
|
||||
struct SHMeshDataHeader
|
||||
{
|
||||
uint32_t vertexCount;
|
||||
uint32_t indexCount;
|
||||
uint32_t charCount;
|
||||
uint32_t boneCount;
|
||||
};
|
||||
|
||||
struct MeshBoneInfo
|
||||
{
|
||||
uint32_t charCount;
|
||||
uint32_t weightCount; // Size should be same as boneCount
|
||||
};
|
||||
|
||||
struct BoneWeight
|
||||
{
|
||||
uint32_t index;
|
||||
float weight;
|
||||
};
|
||||
|
||||
struct MeshBone
|
||||
{
|
||||
std::string name;
|
||||
SHMatrix offset;
|
||||
std::vector<BoneWeight> weights;
|
||||
};
|
||||
|
||||
struct SH_API SHMeshAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
std::vector<SHVec3> VertexPositions;
|
||||
std::vector<SHVec3> VertexTangents;
|
||||
std::vector<SHVec3> VertexNormals;
|
||||
std::vector<SHVec2> VertexTexCoords;
|
||||
std::vector<uint32_t> Indices;
|
||||
std::vector<SHVec4U> VertexBoneIndices;
|
||||
std::vector<SHVec4> VertexBoneWeights;
|
||||
uint32_t BoneCount;
|
||||
};
|
||||
}
|
|
@ -13,36 +13,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Math/SHMath.h"
|
||||
#include "SHAssetData.h"
|
||||
|
||||
#include "Assets/Asset Types/Models/SHAnimationAsset.h"
|
||||
#include "Assets/Asset Types/Models/SHMeshAsset.h"
|
||||
#include "Assets/Asset Types/Models/SHRigAsset.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHMeshAssetHeader
|
||||
{
|
||||
uint32_t vertexCount;
|
||||
uint32_t indexCount;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct SHModelAssetHeader
|
||||
{
|
||||
size_t meshCount;
|
||||
};
|
||||
|
||||
struct SH_API SHMeshData : SHAssetData
|
||||
{
|
||||
SHMeshAssetHeader header;
|
||||
std::vector<SHVec3> VertexPositions;
|
||||
std::vector<SHVec3> VertexTangents;
|
||||
std::vector<SHVec3> VertexNormals;
|
||||
std::vector<SHVec2> VertexTexCoords;
|
||||
std::vector<uint32_t> Indices;
|
||||
size_t animCount;
|
||||
};
|
||||
|
||||
struct SH_API SHModelAsset : SHAssetData
|
||||
{
|
||||
SHModelAssetHeader header;
|
||||
std::vector<SHMeshData*> subMeshes;
|
||||
SHRigAsset rig;
|
||||
|
||||
std::vector<SHMeshDataHeader> meshHeaders;
|
||||
std::vector<SHAnimDataHeader> animHeaders;
|
||||
|
||||
std::vector<SHMeshAsset*> meshes;
|
||||
std::vector<SHAnimAsset*> anims;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHRigAsset.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
SHRigAsset::~SHRigAsset()
|
||||
{
|
||||
if (root != nullptr)
|
||||
delete[] root;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************
|
||||
* \file SHRigAsset.h
|
||||
* \author Loh Xiao Qi
|
||||
* \date 19 November 2022
|
||||
* \brief
|
||||
*
|
||||
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||
* or disclosure of this file or its contents without the prior
|
||||
* written consent of Digipen Institute of Technology is prohibited.
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Math/SHMath.h"
|
||||
#include "Assets/Asset Types/SHAssetData.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHRigDataHeader
|
||||
{
|
||||
uint32_t nodeCount;
|
||||
std::vector<uint32_t> charCounts;
|
||||
};
|
||||
|
||||
struct SHRigNodeData
|
||||
{
|
||||
std::string name;
|
||||
SHMatrix transform;
|
||||
SHMatrix offset;
|
||||
};
|
||||
|
||||
struct SHRigNodeAsset
|
||||
{
|
||||
uint32_t idRef;
|
||||
std::vector<SHRigNodeAsset*> children;
|
||||
};
|
||||
|
||||
struct SH_API SHRigAsset : SHAssetData
|
||||
{
|
||||
~SHRigAsset();
|
||||
|
||||
SHRigDataHeader header;
|
||||
std::vector<SHRigNodeData> nodeDataCollection;
|
||||
SHRigNodeAsset* root;
|
||||
};
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*************************************************************************//**
|
||||
* \file SHAnimationAsset.h
|
||||
* \author Loh Xiao Qi
|
||||
* \date October 2022
|
||||
* \brief
|
||||
*
|
||||
* Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
*****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <assimp/anim.h>
|
||||
#include "SHAssetData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SH_API SHAnimationAsset : SHAssetData
|
||||
{
|
||||
std::string name;
|
||||
|
||||
std::vector<aiNodeAnim*> nodeChannels;
|
||||
std::vector<aiMeshAnim*> meshChannels;
|
||||
std::vector<aiMeshMorphAnim*> morphMeshChannels;
|
||||
|
||||
double duration;
|
||||
double ticksPerSecond;
|
||||
};
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "SHModelAsset.h"
|
||||
#include "Models/SHModelAsset.h"
|
||||
#include "SHTextureAsset.h"
|
|
@ -13,73 +13,321 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHModelLoader.h"
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHModelLoader::ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept
|
||||
void SHModelLoader::ReadHeaders(FileReference file, SHModelAsset& asset)
|
||||
{
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&header),
|
||||
sizeof(SHMeshLoaderHeader)
|
||||
reinterpret_cast<char*>(&asset.header),
|
||||
sizeof(asset.header)
|
||||
);
|
||||
|
||||
if (asset.header.meshCount > 0)
|
||||
{
|
||||
asset.meshHeaders.resize(asset.header.meshCount);
|
||||
file.read(
|
||||
reinterpret_cast<char*>(asset.meshHeaders.data()),
|
||||
asset.header.meshCount * sizeof(SHMeshDataHeader)
|
||||
);
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept
|
||||
if (asset.header.animCount > 0)
|
||||
{
|
||||
asset.animHeaders.resize(asset.header.animCount);
|
||||
for (auto i {0}; i < asset.header.animCount; ++i)
|
||||
{
|
||||
auto& animHeader = asset.animHeaders[i];
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&animHeader.charCount),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&animHeader.animNodeCount),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
animHeader.nodeHeaders.resize(animHeader.animNodeCount);
|
||||
for (auto j {0}; j < animHeader.animNodeCount; ++j)
|
||||
{
|
||||
auto& nodeHeader = animHeader.nodeHeaders[j];
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&nodeHeader),
|
||||
sizeof(SHAnimNodeInfo)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadData(FileReference file, SHModelAsset& asset)
|
||||
{
|
||||
ReadMeshData(file, asset.meshHeaders, asset.meshes);
|
||||
ReadAnimData(file, asset.animHeaders, asset.anims);
|
||||
|
||||
// Not eof yet, animation exists
|
||||
if (file.peek() != EOF)
|
||||
{
|
||||
ReadRigHeader(file, asset.rig.header);
|
||||
ReadRigData(file, asset.rig.header, asset.rig.nodeDataCollection);
|
||||
ReadRigTree(file, asset.rig.header, asset.rig.root);
|
||||
}
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadAnimNode(FileReference file, SHAnimNodeInfo const& info, SHAnimData& data)
|
||||
{
|
||||
data.name.resize(info.charCount);
|
||||
file.read(
|
||||
data.name.data(),
|
||||
info.charCount
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&data.pre),
|
||||
sizeof(SHAnimationBehaviour)
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&data.post),
|
||||
sizeof(SHAnimationBehaviour)
|
||||
);
|
||||
|
||||
uint32_t keySize {0};
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&keySize),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
data.positionKeys.resize(keySize);
|
||||
data.rotationKeys.resize(keySize);
|
||||
data.scaleKeys.resize(keySize);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(data.positionKeys.data()),
|
||||
sizeof(PositionKey) * keySize
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(data.rotationKeys.data()),
|
||||
sizeof(RotationKey) * keySize
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(data.scaleKeys.data()),
|
||||
sizeof(ScaleKey) * keySize
|
||||
);
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadRigHeader(FileReference file, SHRigDataHeader& header)
|
||||
{
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&header.nodeCount),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
header.charCounts.resize(header.nodeCount);
|
||||
file.read(
|
||||
reinterpret_cast<char*>(header.charCounts.data()),
|
||||
sizeof(uint32_t) * header.nodeCount
|
||||
);
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector<SHRigNodeData>& data)
|
||||
{
|
||||
data.resize(header.nodeCount);
|
||||
|
||||
for (auto i {0}; i < header.nodeCount; ++i)
|
||||
{
|
||||
data[i].name.resize(header.charCounts[i]);
|
||||
file.read(
|
||||
data[i].name.data(),
|
||||
header.charCounts[i]
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&data[i].transform),
|
||||
sizeof(SHMatrix)
|
||||
);
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&data[i].offset),
|
||||
sizeof(SHMatrix)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNodeAsset*& root)
|
||||
{
|
||||
// Read All nodes into one contiguous data block
|
||||
struct NodeTemp
|
||||
{
|
||||
uint32_t id, numChild;
|
||||
};
|
||||
|
||||
NodeTemp* dst = new NodeTemp[header.nodeCount];
|
||||
|
||||
file.read(
|
||||
reinterpret_cast<char*>(dst),
|
||||
sizeof(NodeTemp) * header.nodeCount
|
||||
);
|
||||
|
||||
// Build and populate tree
|
||||
SHRigNodeAsset* nodePool = new SHRigNodeAsset[header.nodeCount];
|
||||
root = nodePool;
|
||||
|
||||
std::queue<std::pair<SHRigNodeAsset*, NodeTemp*>> nodeQueue;
|
||||
nodeQueue.emplace(std::make_pair(nodePool, dst));
|
||||
|
||||
SHRigNodeAsset* depthPtr = nodePool + 1;
|
||||
NodeTemp* depthTempPtr = dst + 1;
|
||||
|
||||
while(!nodeQueue.empty())
|
||||
{
|
||||
auto currPair = nodeQueue.front();
|
||||
nodeQueue.pop();
|
||||
auto currNode = currPair.first;
|
||||
auto currTemp = currPair.second;
|
||||
|
||||
currNode->idRef = currTemp->id;
|
||||
|
||||
for (auto i{0}; i < currTemp->numChild; ++i)
|
||||
{
|
||||
currNode->children.push_back(depthPtr);
|
||||
nodeQueue.emplace(depthPtr++, depthTempPtr++);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] dst;
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers,
|
||||
std::vector<SHMeshAsset*>& meshes)
|
||||
{
|
||||
meshes.resize(headers.size());
|
||||
for (auto i {0}; i < headers.size(); ++i)
|
||||
{
|
||||
auto const& header = headers[i];
|
||||
auto& data = *new SHMeshAsset;
|
||||
|
||||
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
|
||||
auto const vertexVec2Byte{ sizeof(SHVec2) * header.vertexCount };
|
||||
|
||||
data.name.resize(header.charCount);
|
||||
data.VertexPositions.resize(header.vertexCount);
|
||||
data.VertexTangents.resize(header.vertexCount);
|
||||
data.VertexNormals.resize(header.vertexCount);
|
||||
data.VertexTexCoords.resize(header.vertexCount);
|
||||
data.Indices.resize(header.indexCount);
|
||||
data.header.name.resize(header.charCount);
|
||||
data.BoneCount = header.boneCount;
|
||||
|
||||
file.read(data.header.name.data(), header.charCount);
|
||||
file.read(data.name.data(), header.charCount);
|
||||
file.read(reinterpret_cast<char*>(data.VertexPositions.data()), vertexVec3Byte);
|
||||
file.read(reinterpret_cast<char*>(data.VertexTangents.data()), vertexVec3Byte);
|
||||
file.read(reinterpret_cast<char*>(data.VertexNormals.data()), vertexVec3Byte);
|
||||
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
|
||||
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
|
||||
|
||||
data.header.vertexCount = header.vertexCount;
|
||||
data.header.indexCount = header.indexCount;
|
||||
if (header.boneCount)
|
||||
{
|
||||
std::vector<MeshBoneInfo> boneInfos(header.boneCount);
|
||||
std::vector<MeshBone> bones(header.boneCount);
|
||||
|
||||
file.read(reinterpret_cast<char*>(boneInfos.data()), sizeof(MeshBoneInfo) * header.boneCount);
|
||||
|
||||
for (auto i{ 0 }; i < header.boneCount; ++i)
|
||||
{
|
||||
auto& bone = bones[i];
|
||||
auto const& info = boneInfos[i];
|
||||
|
||||
bone.name.resize(info.charCount);
|
||||
file.read(bone.name.data(), info.charCount);
|
||||
file.read(reinterpret_cast<char*>(&bone.offset), sizeof(SHMatrix));
|
||||
|
||||
bone.weights.resize(info.weightCount);
|
||||
file.read(reinterpret_cast<char*>(bone.weights.data()), sizeof(BoneWeight) * info.weightCount);
|
||||
}
|
||||
|
||||
void SHModelLoader::LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept
|
||||
data.VertexBoneIndices.resize(header.vertexCount);
|
||||
data.VertexBoneWeights.resize(header.vertexCount);
|
||||
|
||||
for (uint32_t boneIndex{0}; boneIndex < bones.size(); ++boneIndex)
|
||||
{
|
||||
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||
if (!file.is_open())
|
||||
auto const& bone = bones[boneIndex];
|
||||
for (auto const& weight : bone.weights)
|
||||
{
|
||||
SHLOG_ERROR("[Model Loader] Unable to open SHModel File: {}", path.string());
|
||||
return;
|
||||
auto& boneIndices = data.VertexBoneIndices[weight.index];
|
||||
auto& boneWeight = data.VertexBoneWeights[weight.index];
|
||||
|
||||
for (auto j{0}; j < BONE_INDEX_ALIGHTMENT; ++j)
|
||||
{
|
||||
if (boneWeight[j] == 0.f)
|
||||
{
|
||||
boneIndices[j] = boneIndex;
|
||||
boneWeight[j] = weight.weight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.seekg(0);
|
||||
meshes[i] = &data;
|
||||
}
|
||||
}
|
||||
|
||||
void SHModelLoader::ReadAnimData(FileReference file, std::vector<SHAnimDataHeader> const& headers,
|
||||
std::vector<SHAnimAsset*>& anims)
|
||||
{
|
||||
anims.resize(headers.size());
|
||||
for (auto i {0}; i < headers.size(); ++i)
|
||||
{
|
||||
auto const& header = headers[i];
|
||||
auto& animAsset = *new SHAnimAsset;
|
||||
|
||||
animAsset.name.resize(header.charCount);
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&model.header),
|
||||
sizeof(SHModelAssetHeader)
|
||||
animAsset.name.data(),
|
||||
header.charCount
|
||||
);
|
||||
|
||||
std::vector<SHMeshLoaderHeader> headers(model.header.meshCount);
|
||||
model.subMeshes.resize(model.header.meshCount);
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&animAsset.duration),
|
||||
sizeof(double)
|
||||
);
|
||||
|
||||
for (auto i{ 0 }; i < model.header.meshCount; ++i)
|
||||
file.read(
|
||||
reinterpret_cast<char*>(&animAsset.ticksPerSecond),
|
||||
sizeof(double)
|
||||
);
|
||||
|
||||
animAsset.nodeChannels.resize(header.animNodeCount);
|
||||
for (auto i {0}; i < header.animNodeCount; ++i)
|
||||
{
|
||||
model.subMeshes[i] = new SHMeshData();
|
||||
ReadHeader(file, headers[i]);
|
||||
ReadData(file, headers[i], *model.subMeshes[i]);
|
||||
ReadAnimNode(file, header.nodeHeaders[i], animAsset.nodeChannels[i]);
|
||||
}
|
||||
|
||||
anims[i] = &animAsset;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
SHAssetData* SHModelLoader::Load(AssetPath path)
|
||||
{
|
||||
auto result = new SHModelAsset();
|
||||
|
||||
LoadSHMesh(path, *result);
|
||||
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||
if (!file.is_open())
|
||||
{
|
||||
SHLOG_ERROR("[Model Loader] Unable to open SHModel File: {}", path.string());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ReadHeaders(file, *result);
|
||||
ReadData(file, *result);
|
||||
|
||||
file.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* of DigiPen Institute of Technology is prohibited.
|
||||
*****************************************************************************/
|
||||
#pragma once
|
||||
#include "Assets/Asset Types/SHModelAsset.h"
|
||||
#include "Assets/Asset Types/Models/SHModelAsset.h"
|
||||
#include "SHAssetLoader.h"
|
||||
#include <fstream>
|
||||
|
||||
|
@ -18,19 +18,20 @@ namespace SHADE
|
|||
{
|
||||
class SHModelLoader : public SHAssetLoader
|
||||
{
|
||||
struct SHMeshLoaderHeader
|
||||
{
|
||||
uint32_t vertexCount;
|
||||
uint32_t indexCount;
|
||||
uint32_t charCount;
|
||||
};
|
||||
using FileReference = std::ifstream&;
|
||||
|
||||
void ReadAnimNode(FileReference file, SHAnimNodeInfo const& info, SHAnimData& data);
|
||||
|
||||
void ReadHeader(std::ifstream& file, SHMeshLoaderHeader& header) noexcept;
|
||||
void ReadData(std::ifstream& file, SHMeshLoaderHeader const& header, SHMeshData& data) noexcept;
|
||||
void ReadRigHeader(FileReference file, SHRigDataHeader& header);
|
||||
void ReadRigData(FileReference file, SHRigDataHeader const& header, std::vector<SHRigNodeData>& data);
|
||||
void ReadRigTree(FileReference file, SHRigDataHeader const& header, SHRigNodeAsset*& root);
|
||||
|
||||
void ReadMeshData(FileReference file, std::vector<SHMeshDataHeader> const& headers, std::vector<SHMeshAsset*>& meshes);
|
||||
void ReadAnimData(FileReference file, std::vector<SHAnimDataHeader> const& headers, std::vector<SHAnimAsset*>& anims);
|
||||
|
||||
void ReadHeaders(FileReference file, SHModelAsset& asset);
|
||||
void ReadData(FileReference file, SHModelAsset& asset);
|
||||
public:
|
||||
void LoadSHMesh(AssetPath path, SHModelAsset& model) noexcept;
|
||||
SHAssetData* Load(AssetPath path) override;
|
||||
void Write(SHAssetData const* data, AssetPath path) override;
|
||||
};
|
||||
|
|
|
@ -492,8 +492,8 @@ namespace SHADE
|
|||
****************************************************************************/
|
||||
void SHAssetManager::Load() noexcept
|
||||
{
|
||||
BuildAssetCollection();
|
||||
InitLoaders();
|
||||
BuildAssetCollection();
|
||||
//CompileAll();
|
||||
//LoadAllData();
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ namespace SHADE
|
|||
{
|
||||
assetData.emplace(
|
||||
parent.subAssets[i]->id,
|
||||
parentModel->subMeshes[i]
|
||||
parentModel->meshes[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -607,10 +607,10 @@ namespace SHADE
|
|||
|
||||
SHModelAsset* const data = reinterpret_cast<SHModelAsset*>(LoadData(newAsset));
|
||||
assetData.emplace(newAsset.id, data);
|
||||
for(auto const& subMesh : data->subMeshes)
|
||||
for(auto const& subMesh : data->meshes)
|
||||
{
|
||||
SHAsset subAsset{
|
||||
.name = subMesh->header.name,
|
||||
.name = subMesh->name,
|
||||
.id = GenerateAssetID(AssetType::MESH),
|
||||
.type = AssetType::MESH,
|
||||
.isSubAsset = true,
|
||||
|
|
|
@ -6,6 +6,11 @@ namespace SHADE
|
|||
template<typename T>
|
||||
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T* const> SHAssetManager::GetData(AssetID id) noexcept
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!assetData.contains(id))
|
||||
{
|
||||
for (auto const& asset : std::ranges::views::values(assetCollection))
|
||||
|
|
|
@ -125,14 +125,29 @@ namespace SHADE
|
|||
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||
if (listenerTransform)
|
||||
{
|
||||
listener.SetPos(listenerTransform->GetLocalPosition());
|
||||
listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f });
|
||||
listener.SetPos(listenerTransform->GetWorldPosition()); // TODO: Clean up listener
|
||||
listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f }); //TODO: USE CORRECT FORWARD
|
||||
FMOD_VECTOR pos = { listener.pos[0] ,listener.pos[1] ,0.f };
|
||||
FMOD_VECTOR forward = { listener.forward[0] ,listener.forward[1] ,listener.forward[2] };
|
||||
FMOD_VECTOR up = { listener.up[0] ,listener.up[1] ,listener.up[2] };
|
||||
fmodSystem->set3DListenerAttributes(0, &pos, nullptr, &forward, &up);
|
||||
}
|
||||
}
|
||||
|
||||
auto [begin, end] = audioClipLibrary.GetDenseAccess();
|
||||
for(auto it = begin; it != end; ++it)
|
||||
{
|
||||
if(it->instance && (it->transformRef != MAX_EID))
|
||||
{
|
||||
if(SHTransformComponent* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(it->transformRef))
|
||||
{
|
||||
FMOD_3D_ATTRIBUTES attribs{}; //TODO: Set other attribs
|
||||
auto pos = transformComponent->GetWorldPosition();
|
||||
attribs.position = {pos.x, pos.y, pos.z};
|
||||
it->instance->set3DAttributes(&attribs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SHAudioSystem::AudioRoutine::AudioRoutine()
|
||||
|
@ -325,27 +340,83 @@ namespace SHADE
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
AudioClip* SHAudioSystem::CreateAudioClip(const char* path)
|
||||
Handle<AudioClip> SHAudioSystem::CreateAudioClip(const char* path)
|
||||
{
|
||||
AudioClipID newID{};
|
||||
AudioClip* clip = nullptr;
|
||||
auto it = eventMap.find(path);
|
||||
if (it != eventMap.end())
|
||||
Handle<AudioClip> audioClipHandle{};
|
||||
|
||||
if(auto it = eventMap.find(path); it != eventMap.end())
|
||||
{
|
||||
FMOD::Studio::EventInstance* event = nullptr;
|
||||
it->second->createInstance(&event);
|
||||
if (event)
|
||||
audioClipHandle = audioClipLibrary.Create();
|
||||
it->second->createInstance(&audioClipHandle->instance);
|
||||
}
|
||||
|
||||
return audioClipHandle;
|
||||
}
|
||||
|
||||
void SHAudioSystem::AddAudioClipToBGMChannelGroup(Handle<AudioClip> handle)
|
||||
{
|
||||
//event->start();
|
||||
newID = clipID;
|
||||
clipID++;
|
||||
eventInstances.emplace(newID, AudioClip(newID, event));
|
||||
clip = &eventInstances[newID];
|
||||
if(!handle->instance)
|
||||
return;
|
||||
FMOD::ChannelGroup* channelGroup;
|
||||
handle->instance->getChannelGroup(&channelGroup);
|
||||
|
||||
if(!channelGroup)
|
||||
{
|
||||
SHLOG_ERROR("Event instance has no channel group")
|
||||
return;
|
||||
}
|
||||
bgmChannelGroup->addGroup(channelGroup);
|
||||
}
|
||||
|
||||
void SHAudioSystem::AddAudioClipToSFXChannelGroup(Handle<AudioClip> handle)
|
||||
{
|
||||
if (!handle->instance)
|
||||
return;
|
||||
FMOD::ChannelGroup* channelGroup;
|
||||
handle->instance->getChannelGroup(&channelGroup);
|
||||
|
||||
if (!channelGroup)
|
||||
{
|
||||
SHLOG_ERROR("Event instance has no channel group")
|
||||
return;
|
||||
}
|
||||
sfxChannelGroup->addGroup(channelGroup);
|
||||
}
|
||||
|
||||
void SHAudioSystem::AttachAudioClipToObject(Handle<AudioClip> handle, EntityID eid)
|
||||
{
|
||||
if (auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||
{
|
||||
handle->transformRef = eid;
|
||||
}
|
||||
}
|
||||
return clip;
|
||||
|
||||
void SHAudioSystem::DetachAudioClipFromObject(Handle<AudioClip> handle)
|
||||
{
|
||||
handle->transformRef = MAX_EID;
|
||||
}
|
||||
|
||||
//AudioClip* SHAudioSystem::CreateAudioClip(const char* path)
|
||||
//{
|
||||
// AudioClipID newID{};
|
||||
// AudioClip* clip = nullptr;
|
||||
// auto it = eventMap.find(path);
|
||||
// if (it != eventMap.end())
|
||||
// {
|
||||
// FMOD::Studio::EventInstance* event = nullptr;
|
||||
// it->second->createInstance(&event);
|
||||
// if (event)
|
||||
// {
|
||||
// //event->start();
|
||||
// newID = clipID;
|
||||
// clipID++;
|
||||
// eventInstances.emplace(newID, AudioClip(newID, event));
|
||||
// clip = &eventInstances[newID];
|
||||
// }
|
||||
// }
|
||||
// return clip;
|
||||
//}
|
||||
|
||||
//std::vector<const char*> SHAudioSystem::GetAllEvents()
|
||||
//{
|
||||
// int count{};
|
||||
|
@ -489,41 +560,39 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
AudioClip::AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst)
|
||||
:instance(inst), id(clipID)
|
||||
{
|
||||
}
|
||||
|
||||
AudioClip::~AudioClip()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioClip::Play(bool isSfx)
|
||||
void AudioClip::Play()
|
||||
{
|
||||
if(!instance)
|
||||
return;
|
||||
instance->start();
|
||||
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||
instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||
}
|
||||
|
||||
void AudioClip::Play(SHVec3 position, bool isSfx)
|
||||
{
|
||||
if (!instance)
|
||||
return;
|
||||
instance->start();
|
||||
FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||
attributes.forward.z = 1.0f;
|
||||
attributes.up.y = 1.0f;
|
||||
//void AudioClip::Play(bool isSfx)
|
||||
//{
|
||||
// if (!instance)
|
||||
// return;
|
||||
// instance->start();
|
||||
// auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||
// instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||
//}
|
||||
|
||||
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||
SHVec3 listenerPos = audioSystem->GetListenerPosition();
|
||||
attributes.position.x = position[0];
|
||||
attributes.position.y = position[1];
|
||||
attributes.position.z = listenerPos[2];
|
||||
instance->set3DAttributes(&attributes);
|
||||
instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||
}
|
||||
//void AudioClip::Play(SHVec3 position, bool isSfx)
|
||||
//{
|
||||
// if (!instance)
|
||||
// return;
|
||||
// instance->start();
|
||||
// FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||
// attributes.forward.z = 1.0f;
|
||||
// attributes.up.y = 1.0f;
|
||||
|
||||
// auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||
// SHVec3 listenerPos = audioSystem->GetListenerPosition();
|
||||
// attributes.position.x = position[0];
|
||||
// attributes.position.y = position[1];
|
||||
// attributes.position.z = listenerPos[2];
|
||||
// instance->set3DAttributes(&attributes);
|
||||
// instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||
//}
|
||||
|
||||
void AudioClip::Stop(bool fadeOut)
|
||||
{
|
||||
|
@ -557,12 +626,12 @@ namespace SHADE
|
|||
instance->setParameterByName(paramName, value);
|
||||
}
|
||||
|
||||
void AudioClip::SetParameterLabel(const char* paramName, const char* label)
|
||||
{
|
||||
if (!instance)
|
||||
return;
|
||||
instance->setParameterByNameWithLabel(paramName, label);
|
||||
}
|
||||
//void AudioClip::SetParameterLabel(const char* paramName, const char* label)
|
||||
//{
|
||||
// if (!instance)
|
||||
// return;
|
||||
// instance->setParameterByNameWithLabel(paramName, label);
|
||||
//}
|
||||
|
||||
float AudioClip::GetParameterValue(const char* paramName)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Events/SHEvent.h"
|
||||
|
||||
#include "SH_API.h"
|
||||
#include <Resource/SHResourceLibrary.h>
|
||||
#define AUDIO_SYS_MAX_CHANNELS 1024
|
||||
|
||||
namespace SHADE
|
||||
|
@ -22,27 +23,22 @@ namespace SHADE
|
|||
|
||||
class SHAudioListenerComponent;
|
||||
|
||||
typedef uint64_t AudioClipID;
|
||||
|
||||
class AudioClip
|
||||
class SH_API AudioClip
|
||||
{
|
||||
public:
|
||||
AudioClip() = default;
|
||||
AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst);
|
||||
~AudioClip();
|
||||
void Play(bool isSfx = true);
|
||||
void Play(SHVec3 position, bool isSfx = true);
|
||||
void Play();
|
||||
//void Play(SHVec3 position);
|
||||
void Stop(bool fadeOut = true);
|
||||
|
||||
void SetPause(bool pause);
|
||||
bool IsPaused();
|
||||
void SetParameter(const char* paramName, float value);
|
||||
void SetParameterLabel(const char* paramName, const char* label);
|
||||
//void SetParameterLabel(const char* paramName, const char* label);
|
||||
float GetParameterValue(const char* paramName);
|
||||
friend class SHAudioSystem;
|
||||
private:
|
||||
FMOD::Studio::EventInstance* instance;
|
||||
AudioClipID id;
|
||||
FMOD::Studio::EventInstance* instance = nullptr;
|
||||
EntityID transformRef = MAX_EID;
|
||||
};
|
||||
|
||||
class SH_API SHAudioSystem : public SHSystem
|
||||
|
@ -62,7 +58,7 @@ namespace SHADE
|
|||
void Exit();
|
||||
|
||||
int GetAvailableChannelIndex();
|
||||
/*std::vector<SHSound>::size_type CreateSound(const char* filepath, bool loop = false);*/
|
||||
|
||||
void PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f);
|
||||
void PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f);
|
||||
void PlayEventOnce(const char* path, bool isSFX = true, EntityID eid = MAX_EID, bool spatial = false);
|
||||
|
@ -71,9 +67,15 @@ namespace SHADE
|
|||
void StopAllSounds();
|
||||
|
||||
std::optional<FMOD_GUID> GetEventGUID(const char* path);
|
||||
AudioClip* CreateAudioClip(const char* path);
|
||||
//std::vector<const char*> GetAllEvents();
|
||||
//AudioClip* CreateAudioClip(const char* path);
|
||||
//AUDIO CLIP
|
||||
Handle<AudioClip> CreateAudioClip(const char* path);
|
||||
void AddAudioClipToBGMChannelGroup(Handle<AudioClip> handle);
|
||||
void AddAudioClipToSFXChannelGroup(Handle<AudioClip> handle);
|
||||
|
||||
void AttachAudioClipToObject(Handle<AudioClip> handle, EntityID eid);
|
||||
void DetachAudioClipFromObject(Handle<AudioClip> handle);
|
||||
///
|
||||
float GetBgmVolume();
|
||||
float GetSfxVolume();
|
||||
float GetMasterVolume();
|
||||
|
@ -84,6 +86,7 @@ namespace SHADE
|
|||
bool GetPaused() const;
|
||||
SHVec3 GetListenerPosition();
|
||||
void LoadBank(const char* path);
|
||||
|
||||
private:
|
||||
FMOD::Studio::System* fmodStudioSystem;
|
||||
FMOD::System* fmodSystem;
|
||||
|
@ -95,7 +98,9 @@ namespace SHADE
|
|||
//std::unordered_map<ResourceID, SHBank> bankMap;
|
||||
std::unordered_map<std::string, SHBank> bankMap;
|
||||
std::unordered_map<std::string, FMOD::Studio::EventDescription*> eventMap;
|
||||
std::unordered_map<AudioClipID, AudioClip> eventInstances;
|
||||
//std::unordered_map<AudioClipID, AudioClip> eventInstances;
|
||||
SHResourceLibrary<AudioClip> audioClipLibrary{};
|
||||
|
||||
FMOD::ChannelGroup* bgmChannelGroup, * sfxChannelGroup, * masterGroup;
|
||||
FMOD::Channel* audioChannels[AUDIO_SYS_MAX_CHANNELS];
|
||||
FMOD_RESULT result;
|
||||
|
@ -105,7 +110,6 @@ namespace SHADE
|
|||
SHBank masterBank, stringsBank, musicBank, sfxBank; //To do: change to map of banks loaded by resource manager
|
||||
|
||||
std::vector<SHAudioListenerComponent>* denseListener;
|
||||
AudioClipID clipID = 0;
|
||||
|
||||
SHEventHandle onPlay(SHEventPtr onStopEvent);
|
||||
SHEventHandle onStop(SHEventPtr onStopEvent);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
namespace SHADE
|
||||
{
|
||||
|
||||
class SHAABB;
|
||||
class SHBox;
|
||||
class SHRay;
|
||||
|
||||
class SH_API SHCameraArmComponent final: public SHComponent
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "Scene/SHSceneManager.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Math/Geometry/SHAABB.h"
|
||||
#include "Math/Geometry/SHBox.h"
|
||||
#include "Math/SHRay.h"
|
||||
#include "Physics/System/SHPhysicsSystem.h"
|
||||
|
||||
|
@ -186,20 +186,20 @@ namespace SHADE
|
|||
|
||||
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
|
||||
|
||||
//auto result = physicsSystem->Raycast(pivot.ray );
|
||||
//if (result && result.distance < pivot.GetArmLength())
|
||||
//{
|
||||
//
|
||||
// SHVec3 newOffset = SHVec3{ 0.0f,0.0f, result.distance * 0.8f };
|
||||
// newOffset = SHVec3::RotateX(newOffset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
|
||||
// newOffset = SHVec3::RotateY(newOffset, (SHMath::DegreesToRadians(pivot.GetYaw())));
|
||||
// pivot.offset = newOffset;
|
||||
// //SHLOG_INFO("CAMERA COLLISION HIT, {}", result.distance);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// //SHLOG_INFO("CAMERA COLLISION CANT HIT CAMERA");
|
||||
//}
|
||||
auto result = physicsSystem->Raycast(pivot.ray );
|
||||
if (result && result.distance < pivot.GetArmLength())
|
||||
{
|
||||
|
||||
SHVec3 newOffset = SHVec3{ 0.0f,0.0f, result.distance * 0.8f };
|
||||
newOffset = SHVec3::RotateX(newOffset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
|
||||
newOffset = SHVec3::RotateY(newOffset, (SHMath::DegreesToRadians(pivot.GetYaw())));
|
||||
pivot.offset = newOffset;
|
||||
//SHLOG_INFO("CAMERA COLLISION HIT, {}", result.distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
//SHLOG_INFO("CAMERA COLLISION CANT HIT CAMERA");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ namespace SHADE
|
|||
|
||||
//SHSceneNode* parentNode = entityVec[eIndex]->GetSceneNode()->GetParent();
|
||||
|
||||
//SHSceneGraph::removeChild(parentNode,entityVec[eIndex].get());
|
||||
//SHSceneGraph::RemoveChild(parentNode,entityVec[eIndex].get());
|
||||
|
||||
//TODO remove from parent and recursively delete child.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHColliderTagPanel.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -15,7 +15,7 @@ namespace SHADE
|
|||
ImGui::TableNextRow();
|
||||
ImGui::PushID("CollisionTagNames");
|
||||
|
||||
for (int i = SHCollisionTag::NUM_LAYERS; i >= 1; --i)
|
||||
for (int i = SHCollisionTag::NUM_LAYERS; i >= 0; --i)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
if(i == SHCollisionTag::NUM_LAYERS) continue;
|
||||
|
@ -29,7 +29,7 @@ namespace SHADE
|
|||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopID();
|
||||
for (int i = 0; i < SHCollisionTag::NUM_LAYERS - 1; ++i)
|
||||
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
|
||||
{
|
||||
std::string tagName = SHCollisionTagMatrix::GetTagName(i);
|
||||
auto tag = SHCollisionTagMatrix::GetTag(i);
|
||||
|
@ -53,8 +53,8 @@ namespace SHADE
|
|||
tagName2 = std::to_string(idx);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if(i == idx)
|
||||
continue;
|
||||
//if(i == idx)
|
||||
// continue;
|
||||
std::string label = std::format("##{} vs {}", tagName, tagName2);
|
||||
SHEditorWidgets::CheckBox(label, [tag, &idx]{return tag->GetLayerState(idx);}, [tag, i, idx](bool const& value){tag->SetLayerState(idx, value); SHCollisionTagMatrix::GetTag(idx)->SetLayerState(i, value);}, label.substr(2));
|
||||
}
|
||||
|
|
|
@ -57,9 +57,13 @@ namespace SHADE
|
|||
skipFrame = false;
|
||||
return;
|
||||
}
|
||||
DrawMenuBar();
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
DrawMenuBar();
|
||||
if(wasFilterChanged && !filter.empty())
|
||||
{
|
||||
filterHighlightedEntities.clear();
|
||||
filterOpenEntities.clear();
|
||||
}
|
||||
if (const auto root = sceneGraph.GetRoot())
|
||||
{
|
||||
auto const& children = root->GetChildren();
|
||||
|
@ -67,7 +71,13 @@ namespace SHADE
|
|||
for (const auto child : children)
|
||||
{
|
||||
if (child)
|
||||
{
|
||||
if(wasFilterChanged && !filter.empty())
|
||||
{
|
||||
EntityFilterCheck(child);
|
||||
}
|
||||
RecursivelyDrawEntityNode(child);
|
||||
}
|
||||
if (skipFrame)
|
||||
{
|
||||
ImGui::End();
|
||||
|
@ -177,9 +187,10 @@ namespace SHADE
|
|||
|
||||
void SHHierarchyPanel::DrawHierarchyPanelFilter() noexcept
|
||||
{
|
||||
wasFilterChanged = false;
|
||||
if(ImGui::InputTextWithHint("##hierarchyPanelFilter", "Filter", &filter))
|
||||
{
|
||||
|
||||
wasFilterChanged = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button("x"))
|
||||
|
@ -204,24 +215,65 @@ namespace SHADE
|
|||
{
|
||||
result |= SHComponentManager::HasComponent<SHTransformComponent>(eid);
|
||||
}
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHColliderComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRigidBodyComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraArmComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRenderable>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHLightComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTextRenderableComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHUIComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHButtonComponent>().get_name().data(), filter) != std::string::npos;
|
||||
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCanvasComponent>().get_name().data(), filter) != std::string::npos;
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHColliderComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHColliderComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRigidBodyComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHRigidBodyComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHCameraComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraArmComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHCameraArmComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRenderable>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHRenderable>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHLightComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHLightComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTextRenderableComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHTextRenderableComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHUIComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHUIComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHButtonComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHButtonComponent>(eid);
|
||||
}
|
||||
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCanvasComponent>().get_name().data(), filter) != std::string::npos)
|
||||
{
|
||||
result |= SHComponentManager::HasComponent<SHCanvasComponent>(eid);
|
||||
}
|
||||
|
||||
//std::vector<SHSceneNode*> const& children = entityNode->GetChildren();
|
||||
if(result)
|
||||
{
|
||||
filterHighlightedEntities.push_back(eid);
|
||||
}
|
||||
|
||||
//for (auto const& child : children)
|
||||
//{
|
||||
// result |= EntityFilterCheck(child);
|
||||
//}
|
||||
std::vector<SHSceneNode*> const& children = entityNode->GetChildren();
|
||||
|
||||
bool open = false;
|
||||
for (auto const& child : children)
|
||||
{
|
||||
open |= EntityFilterCheck(child);
|
||||
}
|
||||
result |= open;
|
||||
|
||||
if(open)
|
||||
{
|
||||
filterOpenEntities.push_back(eid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -245,31 +297,27 @@ namespace SHADE
|
|||
|
||||
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
||||
|
||||
bool highlighted = false;
|
||||
//if(!filter.empty())
|
||||
//{
|
||||
// highlighted = EntityFilterCheck(currentNode);
|
||||
// if (highlighted)
|
||||
// {
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||
//
|
||||
// ImGui::SetNextItemOpen(true);
|
||||
//
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//}
|
||||
bool highlighted = false, open = false;
|
||||
if(!filter.empty())
|
||||
{
|
||||
highlighted = (std::ranges::find(filterHighlightedEntities, eid) != filterHighlightedEntities.end());
|
||||
if(open = std::ranges::find(filterOpenEntities, eid) != filterOpenEntities.end())
|
||||
{
|
||||
ImGui::SetNextItemOpen(true);
|
||||
}
|
||||
|
||||
if(!open && !highlighted)
|
||||
{
|
||||
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, highlighted ? highlightedColor : ImVec4(0.5f, 0.5f, 0.5f, 1.f ));
|
||||
}
|
||||
|
||||
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||
|
||||
|
||||
//Draw Node
|
||||
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(eid), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
||||
|
||||
if (highlighted)
|
||||
if(!filter.empty())
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ namespace SHADE
|
|||
std::string filter;
|
||||
bool isAnyNodeSelected = false;
|
||||
EntityID scrollTo = MAX_EID;
|
||||
std::vector<EntityID> draggingEntities;
|
||||
std::vector<EntityID> draggingEntities, filterOpenEntities, filterHighlightedEntities;
|
||||
bool wasFilterChanged = false;
|
||||
|
||||
};//class SHHierarchyPanel
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
#include "Physics/Interface/SHColliderComponent.h"
|
||||
#include "Reflection/SHReflectionMetadata.h"
|
||||
#include "Resource/SHResourceManager.h"
|
||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
||||
#include "Serialization/SHSerializationHelper.hpp"
|
||||
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||
#include "SHInspectorCommands.h"
|
||||
#include "Physics/Collision/SHCompositeCollider.h"
|
||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
||||
#include "Animation/SHAnimatorComponent.h"
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename T>
|
||||
|
@ -256,34 +257,31 @@ namespace SHADE
|
|||
|
||||
if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields
|
||||
{
|
||||
SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetIsGravityEnabled(value);}, "Whether Gravity is enabled for this body");
|
||||
SHEditorWidgets::DragFloat("Gravity Scale", [component] { return component->GetGravityScale(); }, [component](float const& value) { component->SetGravityScale(value); }, "Per-object Gravity Scale", 0.1f, 0.0f);
|
||||
|
||||
SHEditorWidgets::CheckBox("Auto Mass", [component]{return component->GetAutoMass();}, [component](bool const& value){component->SetAutoMass(value);}, "If mass should be automatically computed. Setting mass will turn this off.");
|
||||
SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass");
|
||||
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", 0.1f, 0.0f);
|
||||
SHEditorWidgets::DragFloat("Angular Drag", [component] {return component->GetAngularDrag(); }, [component](float const& value) {component->SetAngularDrag(value); }, "Angular Drag", 0.1f, 0.0f);
|
||||
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); }, "If the position between frames should be interpolated.");
|
||||
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");
|
||||
ImGui::PushID("FreezePos");
|
||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Stops any displacement along the X-axis."); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Stops any displacement along the Y-axis."); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Stops any displacement along the Z-axis.");
|
||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezePositionX(); }, [component](bool const& value) {component->SetFreezePositionX(value); }, "Freeze Position - X"); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezePositionY(); }, [component](bool const& value) {component->SetFreezePositionY(value); }, "Freeze Position - Y"); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezePositionZ(); }, [component](bool const& value) {component->SetFreezePositionZ(value); }, "Freeze Position - Z");
|
||||
ImGui::PopID();
|
||||
|
||||
|
||||
SHEditorWidgets::TextLabel("Freeze Rotation");
|
||||
ImGui::PushID("FreezeRot");
|
||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Stops any rotation about the X-axis."); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Stops any rotation about the Y-axis."); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Stops any rotation about the Z-axis.");
|
||||
SHEditorWidgets::CheckBox("X", [component] {return component->GetFreezeRotationX(); }, [component](bool const& value) {component->SetFreezeRotationX(value); }, "Freeze Rotation - X"); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Y", [component] {return component->GetFreezeRotationY(); }, [component](bool const& value) {component->SetFreezeRotationY(value); }, "Freeze Rotation - Y"); ImGui::SameLine();
|
||||
SHEditorWidgets::CheckBox("Z", [component] {return component->GetFreezeRotationZ(); }, [component](bool const& value) {component->SetFreezeRotationZ(value); }, "Freeze Rotation - Z");
|
||||
ImGui::PopID();
|
||||
|
||||
SHEditorWidgets::EndPanel();
|
||||
|
@ -292,15 +290,9 @@ namespace SHADE
|
|||
//Debug Info (Read-Only)
|
||||
if(ImGui::CollapsingHeader("Debug Information", ImGuiTreeNodeFlags_DefaultOpen))//Dynamic or Kinematic only fields
|
||||
{
|
||||
SHEditorWidgets::DragFloat("Mass", [component] { return component->GetMass(); }, [](float value){}, "Mass", 0.1f, 0.0f, std::numeric_limits<float>::infinity(), "%.3f", ImGuiSliderFlags_ReadOnly);
|
||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [component] {return component->GetPosition(); }, [](SHVec3 const& value) {}, false, "Position", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" }, [component]
|
||||
{
|
||||
// Convert it to degrees...
|
||||
auto rot = component->GetRotation();
|
||||
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||
rot[i] = SHMath::RadiansToDegrees(rot[i]);
|
||||
return rot;
|
||||
}, [](SHVec3 const& value) {}, false, "Rotation", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||
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);
|
||||
|
@ -310,7 +302,7 @@ namespace SHADE
|
|||
{
|
||||
SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly);
|
||||
SHEditorWidgets::DragVec3("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->IsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep");
|
||||
SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,67 +334,64 @@ namespace SHADE
|
|||
{
|
||||
DrawContextMenu(component);
|
||||
|
||||
SHEditorWidgets::CheckBox("Draw Colliders", [component] { return component->GetDebugDrawState(); }, [component](bool value) { component->SetDebugDrawState(value); });
|
||||
|
||||
auto* collisionShapes = component->GetCollisionShapes();
|
||||
int const size = collisionShapes ? static_cast<int>(collisionShapes->size()) : 0;
|
||||
ImGui::BeginChild("Collision Shapes", { 0.0f, collisionShapes->empty() ? 1.0f : 250.0f }, true);
|
||||
auto& colliders = component->GetCollisionShapes();
|
||||
int const size = static_cast<int>(colliders.size());
|
||||
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
||||
std::optional<int> colliderToDelete{ std::nullopt };
|
||||
for (int i{}; i < size; ++i)
|
||||
{
|
||||
ImGui::PushID(i);
|
||||
SHCollisionShape* shape = component->GetCollisionShape(i);
|
||||
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
||||
auto cursorPos = ImGui::GetCursorPos();
|
||||
|
||||
//collider->IsTrigger
|
||||
if (shape->GetType() == SHCollisionShape::Type::BOX)
|
||||
|
||||
if (collider->GetType() == SHCollisionShape::Type::BOX)
|
||||
{
|
||||
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||
|
||||
auto* box = reinterpret_cast<SHBox*>(shape);
|
||||
const auto* BOX = reinterpret_cast<const SHBox*>(collider->GetShape());
|
||||
SHEditorWidgets::DragVec3
|
||||
(
|
||||
"Half Extents", { "X", "Y", "Z" },
|
||||
[box] { return box->GetRelativeExtents(); },
|
||||
[box](SHVec3 const& vec) { box->SetRelativeExtents(vec); });
|
||||
[BOX] { return BOX->GetRelativeExtents(); },
|
||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||
}
|
||||
else if (shape->GetType() == SHCollisionShape::Type::SPHERE)
|
||||
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
|
||||
{
|
||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||
auto* sphere = reinterpret_cast<SHSphere*>(shape);
|
||||
const auto* SPHERE = reinterpret_cast<const SHSphere*>(collider->GetShape());
|
||||
SHEditorWidgets::DragFloat
|
||||
(
|
||||
"Radius",
|
||||
[sphere] { return sphere->GetRelativeRadius(); },
|
||||
[sphere](float const& value) { sphere->SetRelativeRadius(value); });
|
||||
[SPHERE] { return SPHERE->GetRelativeRadius(); },
|
||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||
}
|
||||
else if (shape->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
SHEditorWidgets::CheckBox("Is Trigger", [shape] { return shape->IsTrigger(); }, [shape](bool value) { shape->SetIsTrigger(value); });
|
||||
SHEditorWidgets::ComboBox("Tag", collisionTagNames, [shape]{return SHCollisionTagMatrix::GetTagIndex(shape->GetCollisionTag().GetName());}, [shape](int const& value){shape->SetCollisionTag(SHCollisionTagMatrix::GetTag(value));});
|
||||
|
||||
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
|
||||
SHEditorWidgets::ComboBox("Tag", collisionTagNames, [collider]{return SHCollisionTagMatrix::GetTagIndex(collider->GetCollisionTag().GetName());}, [collider](int const& value){collider->SetCollisionTag(SHCollisionTagMatrix::GetTag(value));});
|
||||
if(ImGui::CollapsingHeader("Physics Material"))
|
||||
{
|
||||
SHEditorWidgets::DragFloat("Friction", [shape] { return shape->GetFriction(); }, [shape](float value) { shape->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
|
||||
SHEditorWidgets::DragFloat("Bounciness", [shape] { return shape->GetBounciness(); }, [shape](float value) { shape->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
|
||||
SHEditorWidgets::DragFloat("Mass Density", [shape] { return shape->GetDensity(); }, [shape](float value) { shape->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
|
||||
SHEditorWidgets::DragFloat("Friction", [collider] { return collider->GetFriction(); }, [collider](float value) { collider->SetFriction(value); }, "Friction", 0.05f, 0.0f, 1.0f);
|
||||
SHEditorWidgets::DragFloat("Bounciness", [collider] { return collider->GetBounciness(); }, [collider](float value) { collider->SetBounciness(value); }, "Bounciness", 0.05f, 0.0f, 1.0f);
|
||||
SHEditorWidgets::DragFloat("Mass Density", [collider] { return collider->GetDensity(); }, [collider](float value) { collider->SetDensity(value); }, "Mass Density", 0.1f, 0.0f);
|
||||
}
|
||||
|
||||
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&shape] {return shape->GetPositionOffset(); }, [&shape](SHVec3 const& vec) {shape->SetPositionOffset(vec); });
|
||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||
SHEditorWidgets::DragVec3("Rotation", { "X", "Y", "Z" },
|
||||
[&shape]
|
||||
[&collider]
|
||||
{
|
||||
auto offset = shape->GetRotationOffset();
|
||||
auto offset = collider->GetRotationOffset();
|
||||
return offset;
|
||||
},
|
||||
[&shape](SHVec3 const& vec)
|
||||
[&collider](SHVec3 const& vec)
|
||||
{
|
||||
shape->SetRotationOffset(vec);
|
||||
collider->SetRotationOffset(vec);
|
||||
}, true);
|
||||
SHEditorWidgets::EndPanel();
|
||||
}
|
||||
|
@ -417,24 +406,21 @@ namespace SHADE
|
|||
}
|
||||
if (colliderToDelete.has_value())
|
||||
{
|
||||
component->GetCollider()->RemoveCollisionShape(colliderToDelete.value());
|
||||
component->RemoveCollider(colliderToDelete.value());
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// TODO: Handle differences between composite & hull collider
|
||||
if (ImGui::BeginMenu("Add Collider"))
|
||||
{
|
||||
int newColl = -1;
|
||||
|
||||
if (ImGui::Selectable("Box Collider"))
|
||||
{
|
||||
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
|
||||
compositeCollider->AddBoxCollisionShape(SHVec3::One);
|
||||
newColl = component->AddBoundingBox();
|
||||
}
|
||||
if (ImGui::Selectable("Sphere Collider"))
|
||||
{
|
||||
auto* compositeCollider = dynamic_cast<SHCompositeCollider* const>(component->GetCollider());
|
||||
compositeCollider->AddSphereCollisionShape(1.0f);
|
||||
newColl = component->AddBoundingSphere();
|
||||
}
|
||||
|
||||
//No idea why this doesn't work
|
||||
|
@ -590,4 +576,60 @@ namespace SHADE
|
|||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
template<>
|
||||
static void DrawComponent(SHAnimatorComponent* component)
|
||||
{
|
||||
if (!component)
|
||||
return;
|
||||
ImGui::PushID(SHFamilyID<SHComponent>::GetID<SHAnimatorComponent>());
|
||||
const auto componentType = rttr::type::get(*component);
|
||||
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);
|
||||
Handle<SHRig> const& rig = component->GetRig();
|
||||
const auto RIG_NAME = rig ? SHResourceManager::GetAssetName<SHRig>(rig).value_or("") : "";
|
||||
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Rig", RIG_NAME, [component]()
|
||||
{
|
||||
Handle<SHRig> const& rig = component->GetRig();
|
||||
return SHResourceManager::GetAssetID<SHRig>(rig).value_or(0);
|
||||
},
|
||||
[component](AssetID const& id)
|
||||
{
|
||||
if (SHAssetManager::GetType(id) != AssetType::MODEL)
|
||||
{
|
||||
SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!")
|
||||
return;
|
||||
}
|
||||
component->SetRig(SHResourceManager::LoadOrGet<SHRig>(id));
|
||||
SHResourceManager::FinaliseChanges();
|
||||
}, SHDragDrop::DRAG_RESOURCE);
|
||||
|
||||
Handle<SHAnimationClip> const& clip = component->GetCurrentClip();
|
||||
const auto CLIP_NAME = clip ? SHResourceManager::GetAssetName<SHAnimationClip>(clip).value_or("") : "";
|
||||
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Clip", CLIP_NAME,
|
||||
[component]()
|
||||
{
|
||||
Handle<SHAnimationClip> const& clip = component->GetCurrentClip();
|
||||
return SHResourceManager::GetAssetID<SHAnimationClip>(clip).value_or(0);
|
||||
},
|
||||
[component](AssetID const& id)
|
||||
{
|
||||
if (SHAssetManager::GetType(id) != AssetType::MODEL)
|
||||
{
|
||||
SHLOG_WARNING("Attempted to assign non mesh asset to Renderable Mesh property!")
|
||||
return;
|
||||
}
|
||||
component->SetClip(SHResourceManager::LoadOrGet<SHAnimationClip>(id));
|
||||
}, SHDragDrop::DRAG_RESOURCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawContextMenu(component);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename Component>
|
||||
void EnsureComponent(EntityID eid)
|
||||
{
|
||||
if(SHComponentManager::GetComponent_s<Component>(eid) == nullptr)
|
||||
SHComponentManager::AddComponent<Component>(eid);
|
||||
}
|
||||
|
||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
bool DrawAddComponentButton(EntityID const& eid)
|
||||
{
|
||||
|
@ -49,9 +56,13 @@ namespace SHADE
|
|||
return selected;
|
||||
}
|
||||
|
||||
template <typename ComponentType, typename EnforcedComponent, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true, std::enable_if_t<std::is_base_of_v<SHComponent, EnforcedComponent>, bool> = true>
|
||||
template <typename ComponentType, typename ... EnforcedComponents>
|
||||
bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid)
|
||||
{
|
||||
// Only make sure components are passed here
|
||||
static_assert(std::is_base_of_v<SHComponent, ComponentType>, "");
|
||||
//(static_assert(std::is_base_of_v<SHComponent, EnforcedComponents>, ""), ...);
|
||||
|
||||
bool selected = false;
|
||||
if (!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||
{
|
||||
|
@ -59,9 +70,8 @@ namespace SHADE
|
|||
|
||||
if(selected = ImGui::Selectable(std::format("Add {}", componentName).data()); selected)
|
||||
{
|
||||
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
|
||||
SHComponentManager::AddComponent<EnforcedComponent>(eid);
|
||||
|
||||
// Ensure that all required components are present
|
||||
(EnsureComponent<EnforcedComponents>(eid), ...);
|
||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||
}
|
||||
if(ImGui::IsItemHovered())
|
||||
|
@ -70,9 +80,8 @@ namespace SHADE
|
|||
ImGui::Text("Adds", componentName); ImGui::SameLine();
|
||||
ImGui::TextColored(ImGuiColors::green, "%s", componentName); ImGui::SameLine();
|
||||
ImGui::Text("to this entity", componentName);
|
||||
ImGui::Text("Adds"); ImGui::SameLine();
|
||||
ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponent>().get_name().data()); ImGui::SameLine();
|
||||
ImGui::Text("if the entity does not already have it");
|
||||
ImGui::Text("Adds the following components if the entity does not already have it: ");
|
||||
(ImGui::TextColored(ImGuiColors::red, "%s", rttr::type::get<EnforcedComponents>().get_name().data()), ...);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +127,10 @@ namespace SHADE
|
|||
{
|
||||
DrawComponent(renderableComponent);
|
||||
}
|
||||
if (auto animatorComponent = SHComponentManager::GetComponent_s<SHAnimatorComponent>(eid))
|
||||
{
|
||||
DrawComponent(animatorComponent);
|
||||
}
|
||||
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||
{
|
||||
DrawComponent(colliderComponent);
|
||||
|
@ -179,6 +192,7 @@ namespace SHADE
|
|||
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
|
||||
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
|
||||
DrawAddComponentWithEnforcedComponentButton<SHTextRenderableComponent, SHTransformComponent>(eid);
|
||||
DrawAddComponentWithEnforcedComponentButton<SHAnimatorComponent, SHTransformComponent, SHRenderable>(eid);
|
||||
|
||||
|
||||
ImGui::EndMenu();
|
||||
|
|
|
@ -201,8 +201,8 @@ namespace SHADE
|
|||
// Get interface for the shader combination
|
||||
auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface
|
||||
(
|
||||
mappings.at(SHPredefinedDescriptorTypes::MATERIALS),
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
|
||||
mappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA
|
||||
);
|
||||
if (!interface)
|
||||
return;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "Serialization/SHSerialization.h"
|
||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||
#include "Physics/System/SHPhysicsDebugDrawSystem.h"
|
||||
|
||||
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||
|
||||
|
@ -89,7 +88,6 @@ namespace SHADE
|
|||
DrawThemeMenu();
|
||||
DrawLayoutMenu();
|
||||
DrawApplicationConfig();
|
||||
DrawPhysicsSettings();
|
||||
|
||||
std::string const sceneName{std::format("Current Scene: {}",SHSceneManager::GetSceneName().data())};
|
||||
auto const size = ImGui::CalcTextSize(sceneName.data());
|
||||
|
@ -306,32 +304,4 @@ namespace SHADE
|
|||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void SHEditorMenuBar::DrawPhysicsSettings() noexcept
|
||||
{
|
||||
if (ImGui::BeginMenu("Physics Settings"))
|
||||
{
|
||||
if (auto* physicsDebugDraw = SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>())
|
||||
{
|
||||
bool drawColliders = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS);
|
||||
if (ImGui::Checkbox("Draw Colliders", &drawColliders))
|
||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS, drawColliders);
|
||||
|
||||
bool drawContactPoints = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS);
|
||||
if (ImGui::Checkbox("Draw Contact Points", &drawContactPoints))
|
||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS, drawContactPoints);
|
||||
|
||||
bool drawRays = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS);
|
||||
if (ImGui::Checkbox("Draw Rays", &drawRays))
|
||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||
|
||||
bool drawBroadphase = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE);
|
||||
if (ImGui::Checkbox("Draw Broadphase", &drawBroadphase))
|
||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE, drawBroadphase);
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace SHADE
|
|||
void DrawThemeMenu() noexcept;
|
||||
void DrawLayoutMenu() noexcept;
|
||||
void DrawApplicationConfig() noexcept;
|
||||
void DrawPhysicsSettings() noexcept;
|
||||
|
||||
float menuBarHeight = 20.0f;
|
||||
std::vector<std::filesystem::path> layoutPaths;
|
||||
|
|
|
@ -106,8 +106,8 @@ namespace SHADE
|
|||
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHInputBindingsPanel>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||
|
||||
|
|
|
@ -24,6 +24,4 @@ constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
|
|||
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
|
||||
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
|
||||
constexpr SHEventIdentifier SH_BUTTON_CLICK_EVENT { 18 };
|
||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 19 };
|
||||
|
||||
|
||||
|
|
|
@ -105,6 +105,12 @@ namespace SHADE
|
|||
std::vector<SHAsset> assets;
|
||||
|
||||
// Get all subfolders/files in this current folder
|
||||
if (!std::filesystem::exists(std::filesystem::path(folder->path)))
|
||||
{
|
||||
SHLOG_WARNING("[Asset Manager] Path to build directory does not exist!: {}", folder->path);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto& dirEntry : std::filesystem::directory_iterator(folder->path))
|
||||
{
|
||||
auto path = dirEntry.path();
|
||||
|
|
|
@ -29,24 +29,29 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "UI/SHUIComponent.h"
|
||||
#include "Animation/SHAnimatorComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* SHBatch - Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* SHBatch - Constructors/Destructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHBatch::SHBatch(Handle<SHVkPipeline> pipeline)
|
||||
: pipeline{ pipeline }
|
||||
{
|
||||
if (!pipeline)
|
||||
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
|
||||
|
||||
// Check the pipeline and flag it depending on whether or not it is animated
|
||||
isAnimated = checkIfIsAnimatedPipeline(pipeline);
|
||||
|
||||
// Mark all as dirty
|
||||
setAllDirtyFlags();
|
||||
}
|
||||
|
||||
SHBatch::SHBatch(SHBatch&& rhs)
|
||||
: device { rhs.device }
|
||||
, isAnimated { rhs.isAnimated }
|
||||
, pipeline { rhs.pipeline }
|
||||
, referencedMatInstances { std::move(rhs.referencedMatInstances) }
|
||||
, matBufferDirty { std::move(rhs.matBufferDirty) }
|
||||
|
@ -59,18 +64,24 @@ namespace SHADE
|
|||
, matPropsDataSize { rhs.matPropsDataSize }
|
||||
, singleMatPropAlignedSize { rhs.singleMatPropAlignedSize }
|
||||
, singleMatPropSize { rhs.singleMatPropSize }
|
||||
, boneMatrixData { std::move(rhs.boneMatrixData) }
|
||||
, boneMatrixIndices { std::move(rhs.boneMatrixIndices) }
|
||||
, isCPUBuffersDirty { rhs.isCPUBuffersDirty }
|
||||
, drawDataBuffer { rhs.drawDataBuffer }
|
||||
, transformDataBuffer { rhs.transformDataBuffer }
|
||||
, instancedIntegerBuffer { rhs.instancedIntegerBuffer }
|
||||
, matPropsBuffer { rhs.matPropsBuffer }
|
||||
, matPropsDescSet { rhs.matPropsDescSet }
|
||||
, boneMatrixBuffer { rhs.boneMatrixBuffer }
|
||||
, boneMatrixFirstIndexBuffer { rhs.boneMatrixFirstIndexBuffer }
|
||||
, instanceDataDescSet { rhs.instanceDataDescSet }
|
||||
{
|
||||
rhs.drawDataBuffer = {};
|
||||
rhs.transformDataBuffer = {};
|
||||
rhs.instancedIntegerBuffer = {};
|
||||
rhs.matPropsBuffer = {};
|
||||
rhs.matPropsDescSet = {};
|
||||
rhs.boneMatrixBuffer = {};
|
||||
rhs.boneMatrixFirstIndexBuffer = {};
|
||||
rhs.instanceDataDescSet = {};
|
||||
}
|
||||
|
||||
SHBatch& SHBatch::operator=(SHBatch&& rhs)
|
||||
|
@ -79,6 +90,7 @@ namespace SHADE
|
|||
return *this;
|
||||
|
||||
device = rhs.device ;
|
||||
isAnimated = rhs.isAnimated ;
|
||||
pipeline = rhs.pipeline ;
|
||||
referencedMatInstances = std::move(rhs.referencedMatInstances);
|
||||
matBufferDirty = std::move(rhs.matBufferDirty) ;
|
||||
|
@ -91,19 +103,25 @@ namespace SHADE
|
|||
matPropsDataSize = rhs.matPropsDataSize ;
|
||||
singleMatPropAlignedSize = rhs.singleMatPropAlignedSize ;
|
||||
singleMatPropSize = rhs.singleMatPropSize ;
|
||||
boneMatrixData = std::move(rhs.boneMatrixData) ;
|
||||
boneMatrixIndices = std::move(rhs.boneMatrixIndices) ;
|
||||
isCPUBuffersDirty = rhs.isCPUBuffersDirty ;
|
||||
drawDataBuffer = rhs.drawDataBuffer ;
|
||||
transformDataBuffer = rhs.transformDataBuffer ;
|
||||
instancedIntegerBuffer = rhs.instancedIntegerBuffer ;
|
||||
matPropsBuffer = rhs.matPropsBuffer ;
|
||||
matPropsDescSet = rhs.matPropsDescSet ;
|
||||
boneMatrixBuffer = rhs.boneMatrixBuffer ;
|
||||
boneMatrixFirstIndexBuffer = rhs.boneMatrixFirstIndexBuffer ;
|
||||
instanceDataDescSet = rhs.instanceDataDescSet ;
|
||||
|
||||
// Unset values
|
||||
rhs.drawDataBuffer = {};
|
||||
rhs.transformDataBuffer = {};
|
||||
rhs.instancedIntegerBuffer = {};
|
||||
rhs.matPropsBuffer = {};
|
||||
rhs.matPropsDescSet = {};
|
||||
rhs.boneMatrixBuffer = {};
|
||||
rhs.boneMatrixFirstIndexBuffer = {};
|
||||
rhs.instanceDataDescSet = {};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -121,11 +139,14 @@ namespace SHADE
|
|||
instancedIntegerBuffer[i].Free();
|
||||
if (matPropsBuffer[i])
|
||||
matPropsBuffer[i].Free();
|
||||
if (matPropsDescSet[i])
|
||||
matPropsDescSet[i].Free();
|
||||
if (instanceDataDescSet[i])
|
||||
instanceDataDescSet[i].Free();
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* SHBatch - Usage Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHBatch::Add(const SHRenderable* renderable)
|
||||
{
|
||||
// Ignore if null
|
||||
|
@ -285,7 +306,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Transfer to GPU
|
||||
rebuildMaterialBuffers(frameIndex, descPool);
|
||||
rebuildDescriptorSetBuffers(frameIndex, descPool);
|
||||
|
||||
// This frame is updated
|
||||
matBufferDirty[frameIndex] = false;
|
||||
|
@ -366,14 +387,79 @@ namespace SHADE
|
|||
{
|
||||
rendId,
|
||||
renderable->GetLightLayer()
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Transfer to GPU
|
||||
if (instancedIntegerBuffer[frameIndex] && !drawData.empty())
|
||||
instancedIntegerBuffer[frameIndex]->WriteToMemory(instancedIntegerData.data(), static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)), 0, 0);
|
||||
}
|
||||
|
||||
void SHBatch::UpdateAnimationBuffer(uint32_t frameIndex)
|
||||
{
|
||||
// Ignore if not animated batch
|
||||
if (!isAnimated)
|
||||
return;
|
||||
|
||||
// Frame Index check
|
||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||
{
|
||||
SHLOG_WARNING("[SHBatch] Attempted to update animation buffers with an invalid frame index.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset Animation Matrix Data
|
||||
boneMatrixData.clear();
|
||||
boneMatrixIndices.clear();
|
||||
|
||||
// Add the first identity matrix into the bone matrix data
|
||||
boneMatrixData.emplace_back(SHMatrix::Identity); // This kills the GPU
|
||||
|
||||
// Populate on the CPU
|
||||
for (auto& subBatch : subBatches)
|
||||
for (auto rendId : subBatch.Renderables)
|
||||
{
|
||||
// Get resources
|
||||
auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId);
|
||||
auto renderable = SHComponentManager::GetComponent<SHRenderable>(rendId);
|
||||
auto mesh = renderable->GetMesh();
|
||||
|
||||
// Mark start
|
||||
boneMatrixIndices.emplace_back(static_cast<uint32_t>(boneMatrixData.size()));
|
||||
|
||||
// Add matrices
|
||||
const int BONE_COUNT = static_cast<int>(mesh->BoneCount);
|
||||
int extraMatricesToAdd = BONE_COUNT;
|
||||
if (animator)
|
||||
{
|
||||
// Add matrices
|
||||
const auto& MATRICES = animator->GetBoneMatrices();
|
||||
if (MATRICES.size() <= BONE_COUNT)
|
||||
{
|
||||
boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend());
|
||||
extraMatricesToAdd = std::max({0, BONE_COUNT - static_cast<int>(MATRICES.size())});
|
||||
}
|
||||
}
|
||||
|
||||
// If we need to patch up with more matrices, add it
|
||||
if (extraMatricesToAdd > 0)
|
||||
{
|
||||
boneMatrixData.insert(boneMatrixData.end(), extraMatricesToAdd, SHMatrix::Identity);
|
||||
}
|
||||
}
|
||||
|
||||
// Update GPU Buffers
|
||||
if (!boneMatrixIndices.empty())
|
||||
{
|
||||
const uint32_t BMI_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
(
|
||||
device, boneMatrixFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BMI_DATA_BYTES,
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
"Batch Instance Bone Matrix First Index Buffer"
|
||||
);
|
||||
}
|
||||
rebuildBoneMatrixDescSetBuffer(frameIndex);
|
||||
}
|
||||
|
||||
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
|
||||
|
@ -410,14 +496,23 @@ namespace SHADE
|
|||
// - EID data
|
||||
instancedIntegerData.reserve(numTotalElements);
|
||||
instancedIntegerData.clear();
|
||||
// - Bone Data
|
||||
if (isAnimated)
|
||||
{
|
||||
boneMatrixData.clear();
|
||||
boneMatrixIndices.clear();
|
||||
boneMatrixIndices.reserve(numTotalElements);
|
||||
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
// Add the first identity matrix into the bone matrix data
|
||||
boneMatrixData.emplace_back(SHMatrix::Identity);
|
||||
}
|
||||
|
||||
// - Material Properties Data
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
||||
(
|
||||
descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
vk::ShaderStageFlagBits::eFragment
|
||||
);
|
||||
const bool EMPTY_MAT_PROPS = !SHADER_INFO;
|
||||
|
@ -503,9 +598,36 @@ namespace SHADE
|
|||
{
|
||||
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
|
||||
}
|
||||
//propsCurrPtr += singleMatPropAlignedSize;
|
||||
propsCurrPtr += singleMatPropSize;
|
||||
}
|
||||
|
||||
// Bone Data
|
||||
if (isAnimated)
|
||||
{
|
||||
// Mark start
|
||||
boneMatrixIndices.emplace_back(static_cast<uint32_t>(boneMatrixData.size()));
|
||||
|
||||
auto animator = SHComponentManager::GetComponent_s<SHAnimatorComponent>(rendId);
|
||||
auto mesh = renderable->GetMesh();
|
||||
const int BONE_COUNT = static_cast<int>(mesh->BoneCount);
|
||||
int extraMatricesToAdd = BONE_COUNT;
|
||||
if (animator)
|
||||
{
|
||||
// Add matrices
|
||||
const auto& MATRICES = animator->GetBoneMatrices();
|
||||
if (MATRICES.size() <= BONE_COUNT)
|
||||
{
|
||||
boneMatrixData.insert(boneMatrixData.end(), MATRICES.cbegin(), MATRICES.cend());
|
||||
extraMatricesToAdd = std::max({0, BONE_COUNT - static_cast<int>(MATRICES.size())});
|
||||
}
|
||||
}
|
||||
|
||||
// If we need to patch up with more matrices, add it
|
||||
if (extraMatricesToAdd > 0)
|
||||
{
|
||||
boneMatrixData.insert(boneMatrixData.end(), extraMatricesToAdd, SHMatrix::Identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -540,8 +662,19 @@ namespace SHADE
|
|||
BuffUsage::eVertexBuffer,
|
||||
"Batch Instance Data Buffer"
|
||||
);
|
||||
// - Material Properties Buffer
|
||||
rebuildMaterialBuffers(frameIndex, descPool);
|
||||
// - Bone Matrix Indices
|
||||
if (isAnimated && !boneMatrixIndices.empty())
|
||||
{
|
||||
const uint32_t BMI_DATA_BYTES = static_cast<uint32_t>(boneMatrixIndices.size() * sizeof(uint32_t));
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
(
|
||||
device, boneMatrixFirstIndexBuffer[frameIndex], boneMatrixIndices.data(), BMI_DATA_BYTES,
|
||||
BuffUsage::eVertexBuffer,
|
||||
"Batch Instance Bone Matrix First Index Buffer"
|
||||
);
|
||||
}
|
||||
// - Material and bone buffers/descriptor sets
|
||||
rebuildDescriptorSetBuffers(frameIndex, descPool);
|
||||
}
|
||||
|
||||
// Mark this frame as no longer dirty
|
||||
|
@ -551,7 +684,7 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* SHBatch - Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/)
|
||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline)
|
||||
{
|
||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||
{
|
||||
|
@ -564,7 +697,11 @@ namespace SHADE
|
|||
return;
|
||||
|
||||
// Bind all required objects before drawing
|
||||
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
||||
std::vector<uint32_t> dynamicOffset{ 0 };
|
||||
if (isAnimated && !boneMatrixData.empty())
|
||||
{
|
||||
dynamicOffset.emplace_back(0);
|
||||
}
|
||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||
|
||||
if (bindBatchPipeline)
|
||||
|
@ -572,16 +709,24 @@ namespace SHADE
|
|||
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||
if (matPropsDescSet[frameIndex])
|
||||
if (isAnimated && boneMatrixFirstIndexBuffer[frameIndex])
|
||||
{
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, boneMatrixFirstIndexBuffer[frameIndex], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: Bind the transform buffer instead since we won't use it anyways, but we must bind something
|
||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::BONE_MATRIX_FIRST_INDEX, transformDataBuffer[frameIndex], 0);
|
||||
}
|
||||
|
||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
if (instanceDataDescSet[frameIndex])
|
||||
{
|
||||
cmdBuffer->BindDescriptorSet
|
||||
(
|
||||
matPropsDescSet[frameIndex],
|
||||
instanceDataDescSet[frameIndex],
|
||||
SH_PIPELINE_TYPE::GRAPHICS,
|
||||
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||
descMappings.at(SHPredefinedDescriptorTypes::MATERIALS),
|
||||
descMappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
dynamicOffset
|
||||
);
|
||||
}
|
||||
|
@ -624,49 +769,128 @@ namespace SHADE
|
|||
isCPUBuffersDirty = true;
|
||||
}
|
||||
|
||||
void SHBatch::rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||
void SHBatch::rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||
{
|
||||
if (matPropsData && !drawData.empty())
|
||||
{
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
(
|
||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||
vk::BufferUsageFlagBits::eStorageBuffer,
|
||||
"Batch Material Data"
|
||||
);
|
||||
// Using Declarations and constants
|
||||
using BuffUsage = vk::BufferUsageFlagBits;
|
||||
using PreDefDescLayoutType = SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes;
|
||||
|
||||
if (!matPropsDescSet[frameIndex])
|
||||
|
||||
/* Create Descriptor Sets if Needed */
|
||||
PreDefDescLayoutType layoutTypes = {};
|
||||
if (matPropsData)
|
||||
{
|
||||
matPropsDescSet[frameIndex] = descPool->Allocate
|
||||
layoutTypes = PreDefDescLayoutType::MATERIALS;
|
||||
}
|
||||
if (!boneMatrixData.empty())
|
||||
{
|
||||
layoutTypes = PreDefDescLayoutType::MATERIAL_AND_BONES;
|
||||
}
|
||||
|
||||
const bool MUST_BUILD_BONE_DESC = isAnimated && !boneMatrixData.empty();
|
||||
|
||||
if (matPropsData || MUST_BUILD_BONE_DESC)
|
||||
{
|
||||
// Make sure that we have a descriptor set if we don't already have one
|
||||
if (!instanceDataDescSet[frameIndex])
|
||||
{
|
||||
instanceDataDescSet[frameIndex] = descPool->Allocate
|
||||
(
|
||||
SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS),
|
||||
SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(layoutTypes),
|
||||
{ 0 }
|
||||
);
|
||||
#ifdef _DEBUG
|
||||
const auto& DESC_SETS = matPropsDescSet[frameIndex]->GetVkHandle();
|
||||
const auto& DESC_SETS = instanceDataDescSet[frameIndex]->GetVkHandle();
|
||||
for (auto descSet : DESC_SETS)
|
||||
{
|
||||
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, descSet, "[Descriptor Set] Batch Material Data");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
|
||||
/* Material Data */
|
||||
if (matPropsData && !drawData.empty())
|
||||
{
|
||||
// Update GPU buffer
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
(
|
||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||
BuffUsage::eStorageBuffer,
|
||||
"Batch Material Data"
|
||||
);
|
||||
|
||||
// Update descriptor set buffer
|
||||
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
|
||||
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||
instanceDataDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||
(
|
||||
MATERIAL_DESC_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
bufferList,
|
||||
0, static_cast<uint32_t>(matPropsDataSize)
|
||||
);
|
||||
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||
|
||||
// Update the descriptor set buffer
|
||||
instanceDataDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||
(
|
||||
MATERIAL_DESC_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA
|
||||
);
|
||||
}
|
||||
|
||||
/* Animation Bone Data */
|
||||
if (MUST_BUILD_BONE_DESC)
|
||||
{
|
||||
rebuildBoneMatrixDescSetBuffer(frameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SHBatch::rebuildBoneMatrixDescSetBuffer(uint32_t frameIndex)
|
||||
{
|
||||
using BuffUsage = vk::BufferUsageFlagBits;
|
||||
// Update GPU Buffers
|
||||
const uint32_t BONE_MTX_DATA_BYTES = static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix));
|
||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||
(
|
||||
device, boneMatrixBuffer[frameIndex], boneMatrixData.data(), BONE_MTX_DATA_BYTES,
|
||||
BuffUsage::eStorageBuffer,
|
||||
"Batch Bone Matrix Buffer"
|
||||
);
|
||||
|
||||
// Update descriptor set buffer
|
||||
std::array<Handle<SHVkBuffer>, 1> bufferList = { boneMatrixBuffer[frameIndex] };
|
||||
instanceDataDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||
(
|
||||
MATERIAL_DESC_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
||||
bufferList,
|
||||
0,
|
||||
static_cast<uint32_t>(boneMatrixData.size() * sizeof(SHMatrix))
|
||||
);
|
||||
|
||||
// Update the descriptor set buffer
|
||||
instanceDataDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||
(
|
||||
MATERIAL_DESC_SET_INDEX,
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA
|
||||
);
|
||||
}
|
||||
|
||||
bool SHBatch::checkIfIsAnimatedPipeline(Handle<SHVkPipeline> pipeline)
|
||||
{
|
||||
if (!pipeline || !pipeline->GetPipelineLayout())
|
||||
return false;
|
||||
|
||||
// Grab the pipeline descriptor set layouts
|
||||
auto pipelineDescLayouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
|
||||
|
||||
// Check if they contain the material and bones layout, that indicates it is
|
||||
using GfxPreDef = SHGraphicsPredefinedData;
|
||||
using GfxPreDefType = GfxPreDef::PredefinedDescSetLayoutTypes;
|
||||
const Handle<SHVkDescriptorSetLayout> BONE_DESC_SET_LAYOUT = GfxPreDef::GetPredefinedDescSetLayouts(GfxPreDefType::MATERIAL_AND_BONES)[0];
|
||||
return std::find_if(pipelineDescLayouts.begin(), pipelineDescLayouts.end(), [BONE_DESC_SET_LAYOUT](Handle<SHVkDescriptorSetLayout> layout)
|
||||
{
|
||||
return BONE_DESC_SET_LAYOUT == layout;
|
||||
}) != pipelineDescLayouts.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
class SHVkBuffer;
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkPipeline;
|
||||
|
@ -40,36 +40,36 @@ namespace SHADE
|
|||
class SHVkDescriptorSetGroup;
|
||||
class SHVkDescriptorPool;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/***********************************************************************************/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*************************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Describes a segment of the sub batch operation.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
/*************************************************************************************/
|
||||
struct SHSubBatch
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHMesh> Mesh;
|
||||
std::unordered_set<EntityID> Renderables;
|
||||
};
|
||||
/***********************************************************************************/
|
||||
/*************************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Describes a segment of the sub batch operation.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
/*************************************************************************************/
|
||||
class SHBatch
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructor/Destructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHBatch(Handle<SHVkPipeline> pipeline);
|
||||
SHBatch(const SHBatch&) = delete;
|
||||
SHBatch(SHBatch&& rhs);
|
||||
|
@ -77,39 +77,48 @@ namespace SHADE
|
|||
SHBatch& operator=(SHBatch&& rhs);
|
||||
~SHBatch();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Add(const SHRenderable* renderable);
|
||||
void Remove(const SHRenderable* renderable);
|
||||
void Clear();
|
||||
void UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
||||
void UpdateAnimationBuffer(uint32_t frameIndex);
|
||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex);
|
||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true);
|
||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Handle<SHVkPipeline> GetPipeline() const noexcept { return pipeline; };
|
||||
bool IsEmpty() const noexcept { return subBatches.empty(); }
|
||||
Handle<SHVkBuffer> GetTransformBuffer(uint32_t frameIndex) const noexcept;
|
||||
Handle<SHVkBuffer> GetMDIBuffer(uint32_t frameIndex) const noexcept;
|
||||
bool IsAnimated() const noexcept { return isAnimated; }
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definition */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
using TripleBool = std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||
using TripleDescSet = std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constants */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
// Resources
|
||||
Handle<SHVkLogicalDevice> device;
|
||||
// Config
|
||||
bool isAnimated; // Whether the material supports animation
|
||||
// Batch Properties
|
||||
Handle<SHVkPipeline> pipeline;
|
||||
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||
|
@ -125,18 +134,25 @@ namespace SHADE
|
|||
Byte matPropsDataSize = 0;
|
||||
Byte singleMatPropAlignedSize = 0;
|
||||
Byte singleMatPropSize = 0;
|
||||
std::vector<SHMatrix> boneMatrixData; // 0th element is always an identity matrix
|
||||
std::vector<uint32_t> boneMatrixIndices;
|
||||
bool isCPUBuffersDirty = true;
|
||||
// GPU Buffers
|
||||
TripleBuffer drawDataBuffer;
|
||||
TripleBuffer transformDataBuffer;
|
||||
TripleBuffer instancedIntegerBuffer;
|
||||
TripleBuffer matPropsBuffer;
|
||||
TripleDescSet matPropsDescSet;
|
||||
TripleBuffer boneMatrixBuffer;
|
||||
TripleBuffer boneMatrixFirstIndexBuffer; // Instanced buffer, indicates where the first bone matrix is
|
||||
TripleDescSet instanceDataDescSet;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void setAllDirtyFlags();
|
||||
void rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void rebuildDescriptorSetBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void rebuildBoneMatrixDescSetBuffer(uint32_t frameIndex);
|
||||
static bool checkIfIsAnimatedPipeline(Handle<SHVkPipeline> pipeline);
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace SHADE
|
|||
{
|
||||
batch.UpdateMaterialBuffer(frameIndex, descPool);
|
||||
batch.UpdateTransformBuffer(frameIndex);
|
||||
batch.UpdateAnimationBuffer(frameIndex);
|
||||
batch.UpdateInstancedIntegerBuffer(frameIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,18 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsPredefinedData::InitDescMappings(void) noexcept
|
||||
{
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings
|
||||
({
|
||||
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||
{SHPredefinedDescriptorTypes::CAMERA, 1},
|
||||
{SHPredefinedDescriptorTypes::MATERIALS, 2},
|
||||
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
|
||||
});
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings
|
||||
({
|
||||
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
|
||||
{SHPredefinedDescriptorTypes::CAMERA, 1},
|
||||
{SHPredefinedDescriptorTypes::PER_INSTANCE_ANIM_BATCH, 2},
|
||||
});
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descMappings.AddMappings
|
||||
|
@ -50,9 +56,13 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||
{
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts });
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts });
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descSetLayouts });
|
||||
for (int i = 0; i < SYSTEM_TYPE_COUNT; ++i)
|
||||
{
|
||||
perSystemData[i].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy
|
||||
(
|
||||
SHPipelineLayoutParamsDummy { perSystemData[i].descSetLayouts }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -124,8 +134,8 @@ namespace SHADE
|
|||
SHVkDescriptorSetLayout::Binding materialDataBinding
|
||||
{
|
||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
.Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
.DescriptorCount = 1,
|
||||
};
|
||||
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding });
|
||||
|
@ -166,12 +176,24 @@ namespace SHADE
|
|||
Handle<SHVkDescriptorSetLayout> shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding });
|
||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps");
|
||||
|
||||
// For per instance data (transforms, materials, etc.)
|
||||
SHVkDescriptorSetLayout::Binding boneDataBinding
|
||||
{
|
||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eVertex,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::PER_INST_BONE_DATA,
|
||||
.DescriptorCount = 1,
|
||||
};
|
||||
Handle<SHVkDescriptorSetLayout> materialBoneDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding, boneDataBinding });
|
||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialBoneDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material and Bone Globals");
|
||||
|
||||
predefinedLayouts.push_back(staticGlobalLayout);
|
||||
predefinedLayouts.push_back(lightDataDescSetLayout);
|
||||
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
||||
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
||||
predefinedLayouts.push_back(fontDataDescSetLayout);
|
||||
predefinedLayouts.push_back(shadowMapDescLayout);
|
||||
predefinedLayouts.push_back(materialBoneDataPerInstanceLayout);
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||
(
|
||||
|
@ -180,6 +202,13 @@ namespace SHADE
|
|||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS
|
||||
);
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||
(
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIAL_AND_BONES
|
||||
);
|
||||
|
||||
perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||
(
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
|
||||
|
@ -197,12 +226,15 @@ namespace SHADE
|
|||
|
||||
void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept
|
||||
{
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Normals at binding 2
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
|
||||
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute positions at binding 0
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // Attribute UVs at binding 1
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute Normals at binding 2
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute Tangents at binding 3
|
||||
defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Instanced Transform at binding 4 - 7 (4 slots)
|
||||
defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::UINT32_4D) }); // Attribute bone indices at index 9
|
||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Attribute bone weights at index 10
|
||||
defaultVertexInputState.AddBinding(true , true , { SHVertexAttribute(SHAttribFormat::UINT32_1D) }); // Instance bone matrix first index at index 11
|
||||
|
||||
shadowMapVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D)});
|
||||
shadowMapVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }, 4, 4); // Transform at binding 4 - 7 (4 slots)
|
||||
|
@ -256,12 +288,24 @@ namespace SHADE
|
|||
return static_cast<SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes>(static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs));
|
||||
}
|
||||
|
||||
SHADE::SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& operator|=(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept
|
||||
{
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator&(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept
|
||||
{
|
||||
return static_cast<SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes>(static_cast<uint64_t>(lhs) & static_cast<uint64_t>(rhs));
|
||||
|
||||
}
|
||||
|
||||
SHADE::SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& operator&=(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept
|
||||
{
|
||||
lhs = lhs & rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
//SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetBatchingSystemData(void) noexcept
|
||||
//{
|
||||
// return batchingSystemData;
|
||||
|
|
|
@ -23,21 +23,24 @@ namespace SHADE
|
|||
// This enum is mainly to initialize a bit field to retrieve bit fields from SHPRedefinedData
|
||||
enum class PredefinedDescSetLayoutTypes : uint64_t
|
||||
{
|
||||
STATIC_DATA = 0x01,
|
||||
LIGHTS = 0x02,
|
||||
CAMERA = 0x04,
|
||||
MATERIALS = 0x08,
|
||||
FONT = 0x10,
|
||||
SHADOW = 0x20,
|
||||
STATIC_DATA = 0b00000001,
|
||||
LIGHTS = 0b00000010,
|
||||
CAMERA = 0b00000100,
|
||||
MATERIALS = 0b00001000,
|
||||
FONT = 0b00010000,
|
||||
SHADOW = 0b00100000,
|
||||
MATERIAL_AND_BONES = 0b01000000
|
||||
};
|
||||
|
||||
enum class SystemType
|
||||
{
|
||||
BATCHING = 0,
|
||||
BATCHING_ANIM,
|
||||
TEXT_RENDERING,
|
||||
RENDER_GRAPH_NODE_COMPUTE,
|
||||
NUM_TYPES
|
||||
};
|
||||
static constexpr int SYSTEM_TYPE_COUNT = static_cast<int>(SystemType::NUM_TYPES);
|
||||
|
||||
struct PerSystem
|
||||
{
|
||||
|
@ -103,5 +106,7 @@ namespace SHADE
|
|||
|
||||
};
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator| (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& operator|=(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator& (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
|
||||
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& operator&=(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes& lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ namespace SHADE
|
|||
STATIC_DATA,
|
||||
LIGHTS,
|
||||
CAMERA,
|
||||
MATERIALS,
|
||||
PER_INSTANCE_BATCH,
|
||||
PER_INSTANCE_ANIM_BATCH,
|
||||
FONT,
|
||||
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
||||
RENDER_GRAPH_RESOURCE,
|
||||
|
|
|
@ -14,7 +14,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// STL Includes
|
||||
#include <algorithm>
|
||||
// Project Includes
|
||||
#include "Assets/Asset Types/SHModelAsset.h"
|
||||
#include "Assets/Asset Types/Models/SHModelAsset.h"
|
||||
#include "../Meshes/SHPrimitiveGenerator.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "SHGraphicsSystem.h"
|
||||
|
|
|
@ -161,7 +161,15 @@ namespace SHADE
|
|||
DescriptorSet binding for per instance material values.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
|
||||
static constexpr uint32_t PER_INST_MATERIAL_DATA = 0;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
DescriptorSet binding for per instance bone values.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t PER_INST_BONE_DATA = 1;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
@ -191,6 +199,14 @@ namespace SHADE
|
|||
static constexpr uint32_t SHADOW_MAP_IMAGE_SAMPLER_DATA = 0;
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Descriptor set binding for bone matrix data.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BONE_MATRIX_DATA = 1;
|
||||
};
|
||||
|
||||
struct VertexBufferBindings
|
||||
|
@ -237,6 +253,27 @@ namespace SHADE
|
|||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t INTEGER_DATA = 5;
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Vertex buffer bindings for the bone indices buffer.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BONE_INDICES = 6;
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Vertex buffer bindings for the bone weights buffer.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BONE_WEIGHTS = 7;
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Vertex buffer bindings for the bone matrix first index buffer.
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8;
|
||||
|
||||
static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0;
|
||||
static constexpr uint32_t GLYPH_INDEX = 1;
|
||||
|
|
|
@ -127,15 +127,16 @@ namespace SHADE
|
|||
|
||||
SHFreetypeInstance::Init();
|
||||
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
|
||||
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
|
||||
//SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl", false);
|
||||
|
||||
// Load Built In Shaders
|
||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||
static constexpr AssetID VS_ANIM = 47911992; animtVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_ANIM);
|
||||
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
|
||||
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
|
||||
|
@ -450,6 +451,12 @@ namespace SHADE
|
|||
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write")
|
||||
);
|
||||
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||
defaultAnimMaterial = AddMaterial
|
||||
(
|
||||
animtVertShader, defaultFragShader,
|
||||
renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
||||
);
|
||||
defaultAnimMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -525,6 +532,8 @@ namespace SHADE
|
|||
std::make_pair(meshLibrary.GetVertexTexCoordsBuffer(), SHGraphicsConstants::VertexBufferBindings::TEX_COORD),
|
||||
std::make_pair(meshLibrary.GetVertexNormalsBuffer(), SHGraphicsConstants::VertexBufferBindings::NORMAL),
|
||||
std::make_pair(meshLibrary.GetVertexTangentsBuffer(), SHGraphicsConstants::VertexBufferBindings::TANGENT),
|
||||
std::make_pair(meshLibrary.GetVertexBoneIndicesBuffer(), SHGraphicsConstants::VertexBufferBindings::BONE_INDICES),
|
||||
std::make_pair(meshLibrary.GetVertexBoneWeightsBuffer(), SHGraphicsConstants::VertexBufferBindings::BONE_WEIGHTS),
|
||||
std::make_pair(meshLibrary.GetIndexBuffer(), 0),
|
||||
};
|
||||
|
||||
|
@ -568,14 +577,14 @@ namespace SHADE
|
|||
#endif
|
||||
}
|
||||
|
||||
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
|
||||
{
|
||||
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||
for (auto& comp : lightComps)
|
||||
{
|
||||
comp.SetEnableShadow(true);
|
||||
}
|
||||
}
|
||||
//if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
|
||||
//{
|
||||
// auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||
// for (auto& comp : lightComps)
|
||||
// {
|
||||
// comp.SetEnableShadow(true);
|
||||
// }
|
||||
//}
|
||||
|
||||
renderGraph->Begin(frameIndex);
|
||||
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
||||
|
@ -800,7 +809,12 @@ namespace SHADE
|
|||
rasterState.cull_mode = vk::CullModeFlagBits::eBack;
|
||||
|
||||
tempLibrary.Init(device);
|
||||
tempLibrary.CreateGraphicsPipelines({ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass, SHGraphicsPredefinedData::GetShadowMapViState(), rasterState);
|
||||
tempLibrary.CreateGraphicsPipelines
|
||||
(
|
||||
{ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass,
|
||||
SHGraphicsPredefinedData::SystemType::BATCHING,
|
||||
SHGraphicsPredefinedData::GetShadowMapViState(), rasterState
|
||||
);
|
||||
shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} });
|
||||
}
|
||||
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||
|
@ -865,9 +879,9 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Mesh Registration Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices)
|
||||
SHADE::Handle<SHADE::SHMesh> SHGraphicsSystem::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices, const SHMesh::VertexBoneIndices* const boneIndices, const SHMesh::VertexWeights* const boneWeights, uint32_t boneCount)
|
||||
{
|
||||
return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, indexCount, indices);
|
||||
return meshLibrary.AddMesh(vertexCount, positions, texCoords, tangents, normals, boneIndices, boneWeights, indexCount, indices, boneCount);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::RemoveMesh(Handle<SHMesh> mesh)
|
||||
|
|
|
@ -230,7 +230,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices);
|
||||
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices, const SHMesh::VertexBoneIndices* const boneIndices = nullptr, const SHMesh::VertexWeights* const boneWeights = nullptr, uint32_t boneCount = 0);
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -455,6 +455,7 @@ namespace SHADE
|
|||
|
||||
// Built-In Shaders
|
||||
Handle<SHVkShaderModule> defaultVertShader;
|
||||
Handle<SHVkShaderModule> animtVertShader;
|
||||
Handle<SHVkShaderModule> defaultFragShader;
|
||||
Handle<SHVkShaderModule> debugVertShader;
|
||||
Handle<SHVkShaderModule> debugFragShader;
|
||||
|
@ -473,6 +474,7 @@ namespace SHADE
|
|||
|
||||
// Built-In Materials
|
||||
Handle<SHMaterial> defaultMaterial;
|
||||
Handle<SHMaterial> defaultAnimMaterial;
|
||||
Handle<SHVkPipeline> debugDrawPipeline;
|
||||
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
||||
Handle<SHVkPipeline> debugDrawLineMeshPipeline;
|
||||
|
|
|
@ -100,9 +100,9 @@ namespace SHADE
|
|||
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||
return pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
||||
(
|
||||
mappings.at (SHPredefinedDescriptorTypes::MATERIALS),
|
||||
mappings.at (SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
vk::ShaderStageFlagBits::eFragment
|
||||
);
|
||||
}
|
||||
|
|
|
@ -81,9 +81,9 @@ namespace SHADE
|
|||
{
|
||||
return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface
|
||||
(
|
||||
SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING).at(SHPredefinedDescriptorTypes::MATERIALS),
|
||||
SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING).at(SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH),
|
||||
//SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||
SHGraphicsConstants::DescriptorSetBindings::PER_INST_MATERIAL_DATA,
|
||||
vk::ShaderStageFlagBits::eFragment
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,16 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
SHADE::Handle<SHADE::SHMesh> SHMeshLibrary::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices)
|
||||
SHADE::Handle<SHADE::SHMesh> SHMeshLibrary::AddMesh
|
||||
(
|
||||
uint32_t vertexCount, const SHMesh::VertexPosition* const positions,
|
||||
const SHMesh::VertexTexCoord* const texCoords,
|
||||
const SHMesh::VertexTangent* const tangents,
|
||||
const SHMesh::VertexNormal* const normals,
|
||||
const SHMesh::VertexBoneIndices* const boneIndices,
|
||||
const SHMesh::VertexWeights* const boneWeights,
|
||||
uint32_t indexCount, const SHMesh::Index* const indices,
|
||||
uint32_t boneCount)
|
||||
{
|
||||
isDirty = true;
|
||||
|
||||
|
@ -32,8 +41,11 @@ namespace SHADE
|
|||
texCoords,
|
||||
tangents,
|
||||
normals,
|
||||
boneIndices,
|
||||
boneWeights,
|
||||
indexCount,
|
||||
indices,
|
||||
boneCount,
|
||||
handle
|
||||
});
|
||||
return handle;
|
||||
|
@ -83,6 +95,8 @@ namespace SHADE
|
|||
vertTexCoordStorage.erase(vertTexCoordStorage.begin() + nextVertInsertPoint, vertTexCoordStorage.begin() + mesh->FirstVertex);
|
||||
vertTangentStorage.erase(vertTangentStorage.begin() + nextVertInsertPoint, vertTangentStorage.begin() + mesh->FirstVertex);
|
||||
vertNormalStorage.erase(vertNormalStorage.begin() + nextVertInsertPoint, vertNormalStorage.begin() + mesh->FirstVertex);
|
||||
vertBoneIdxStorage.erase(vertBoneIdxStorage.begin() + nextVertInsertPoint, vertBoneIdxStorage.begin() + mesh->FirstVertex);
|
||||
vertBoneWeightStorage.erase(vertBoneWeightStorage.begin() + nextVertInsertPoint, vertBoneWeightStorage.begin() + mesh->FirstVertex);
|
||||
// - Update mesh data
|
||||
mesh->FirstVertex = nextVertInsertPoint;
|
||||
|
||||
|
@ -114,6 +128,8 @@ namespace SHADE
|
|||
vertTexCoordStorage.reserve(newVertElems);
|
||||
vertTangentStorage.reserve(newVertElems);
|
||||
vertNormalStorage.reserve(newVertElems);
|
||||
vertBoneIdxStorage.reserve(newVertElems);
|
||||
vertBoneWeightStorage.reserve(newVertElems);
|
||||
indexStorage.reserve(newIdxElems);
|
||||
// - Append new data
|
||||
for (auto& addJob : meshAddJobs)
|
||||
|
@ -126,6 +142,7 @@ namespace SHADE
|
|||
.VertexCount = static_cast<uint32_t>(addJob.VertexCount),
|
||||
.FirstIndex = static_cast<uint32_t>(indexStorage.size()),
|
||||
.IndexCount = static_cast<uint32_t>(addJob.IndexCount),
|
||||
.BoneCount = addJob.BoneCount
|
||||
};
|
||||
|
||||
// Copy into storage
|
||||
|
@ -149,6 +166,32 @@ namespace SHADE
|
|||
vertNormalStorage.end(),
|
||||
addJob.VertexNormals, addJob.VertexNormals + addJob.VertexCount
|
||||
);
|
||||
if (addJob.VertexBoneIndices)
|
||||
{
|
||||
vertBoneIdxStorage.insert
|
||||
(
|
||||
vertBoneIdxStorage.end(),
|
||||
addJob.VertexBoneIndices, addJob.VertexBoneIndices + addJob.VertexCount
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertBoneIdxStorage.resize(vertBoneIdxStorage.size() + addJob.VertexCount);
|
||||
}
|
||||
if (addJob.VertexBoneWeights)
|
||||
{
|
||||
vertBoneWeightStorage.insert
|
||||
(
|
||||
vertBoneWeightStorage.end(),
|
||||
addJob.VertexBoneWeights, addJob.VertexBoneWeights + addJob.VertexCount
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto OG_SIZE = vertBoneWeightStorage.size();
|
||||
vertBoneWeightStorage.resize(vertBoneWeightStorage.size() + addJob.VertexCount);
|
||||
std::fill_n(vertBoneWeightStorage.begin() + OG_SIZE, addJob.VertexCount, SHVec4(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
indexStorage.insert
|
||||
(
|
||||
indexStorage.end(),
|
||||
|
@ -192,6 +235,28 @@ namespace SHADE
|
|||
BuffUsage::eVertexBuffer,
|
||||
"Mesh Library Vertex Normals"
|
||||
);
|
||||
if (!vertBoneIdxStorage.empty())
|
||||
{
|
||||
SHVkUtil::EnsureBufferAndCopyData
|
||||
(
|
||||
device, cmdBuffer, vertBoneIdxBuffer,
|
||||
vertBoneIdxStorage.data(),
|
||||
static_cast<uint32_t>(vertBoneIdxStorage.size()) * sizeof(SHMesh::VertexBoneIndices),
|
||||
BuffUsage::eVertexBuffer,
|
||||
"Mesh Library Vertex Bone Indices"
|
||||
);
|
||||
}
|
||||
if (!vertBoneWeightStorage.empty())
|
||||
{
|
||||
SHVkUtil::EnsureBufferAndCopyData
|
||||
(
|
||||
device, cmdBuffer, vertBoneWeightBuffer,
|
||||
vertBoneWeightStorage.data(),
|
||||
static_cast<uint32_t>(vertBoneWeightStorage.size()) * sizeof(SHMesh::VertexWeights),
|
||||
BuffUsage::eVertexBuffer,
|
||||
"Mesh Library Vertex Bone Weights"
|
||||
);
|
||||
}
|
||||
SHVkUtil::EnsureBufferAndCopyData
|
||||
(
|
||||
device, cmdBuffer, indexBuffer,
|
||||
|
|
|
@ -19,6 +19,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Resource/SHResourceLibrary.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Math/Vector/SHVec4U.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -49,6 +51,8 @@ namespace SHADE
|
|||
using VertexTexCoord = SHVec2;
|
||||
using VertexTangent = SHVec3;
|
||||
using VertexNormal = SHVec3;
|
||||
using VertexBoneIndices = SHVec4U;
|
||||
using VertexWeights = SHVec4;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
|
@ -57,6 +61,7 @@ namespace SHADE
|
|||
uint32_t VertexCount;
|
||||
uint32_t FirstIndex;
|
||||
uint32_t IndexCount;
|
||||
uint32_t BoneCount;
|
||||
};
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
|
@ -105,7 +110,14 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/*******************************************************************************/
|
||||
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices);
|
||||
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions,
|
||||
const SHMesh::VertexTexCoord* const texCoords,
|
||||
const SHMesh::VertexTangent* const tangents,
|
||||
const SHMesh::VertexNormal* const normals,
|
||||
const SHMesh::VertexBoneIndices* const boneIndices,
|
||||
const SHMesh::VertexWeights* const boneWeights,
|
||||
uint32_t indexCount, const SHMesh::Index* const indices,
|
||||
uint32_t boneCount);
|
||||
/*******************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -144,7 +156,9 @@ namespace SHADE
|
|||
Handle<SHVkBuffer> GetVertexTexCoordsBuffer() const noexcept { return vertTexCoordBuffer; }
|
||||
Handle<SHVkBuffer> GetVertexTangentsBuffer() const noexcept { return vertTangentBuffer; }
|
||||
Handle<SHVkBuffer> GetVertexNormalsBuffer() const noexcept { return vertNormalBuffer; }
|
||||
Handle<SHVkBuffer> GetIndexBuffer() const { return indexBuffer; }
|
||||
Handle<SHVkBuffer> GetVertexBoneIndicesBuffer() const noexcept { return vertBoneIdxBuffer; }
|
||||
Handle<SHVkBuffer> GetVertexBoneWeightsBuffer() const noexcept { return vertBoneWeightBuffer; }
|
||||
Handle<SHVkBuffer> GetIndexBuffer() const noexcept { return indexBuffer; }
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -157,8 +171,11 @@ namespace SHADE
|
|||
const SHMesh::VertexTexCoord* VertexTexCoords = nullptr;
|
||||
const SHMesh::VertexTangent* VertexTangents = nullptr;
|
||||
const SHMesh::VertexNormal* VertexNormals = nullptr;
|
||||
const SHMesh::VertexBoneIndices* VertexBoneIndices = nullptr;
|
||||
const SHMesh::VertexWeights* VertexBoneWeights = nullptr;
|
||||
uint32_t IndexCount = 0;
|
||||
const SHMesh::Index* Indices = nullptr;
|
||||
uint32_t BoneCount = 0;
|
||||
Handle<SHMesh> Handle;
|
||||
};
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -168,19 +185,23 @@ namespace SHADE
|
|||
std::vector<MeshAddJob> meshAddJobs;
|
||||
std::vector<Handle<SHMesh>> meshRemoveJobs;
|
||||
// Tracking
|
||||
SHResourceLibrary<SHMesh> meshes{};
|
||||
SHResourceLibrary<SHMesh> meshes;
|
||||
std::vector<Handle<SHMesh>> meshOrder;
|
||||
// CPU Storage
|
||||
std::vector<SHMesh::VertexPosition> vertPosStorage;
|
||||
std::vector<SHMesh::VertexTexCoord> vertTexCoordStorage;
|
||||
std::vector<SHMesh::VertexTangent> vertTangentStorage;
|
||||
std::vector<SHMesh::VertexNormal> vertNormalStorage;
|
||||
std::vector<SHMesh::VertexBoneIndices> vertBoneIdxStorage; // Must be in multiples of 4
|
||||
std::vector<SHMesh::VertexWeights> vertBoneWeightStorage;
|
||||
std::vector<SHMesh::Index> indexStorage;
|
||||
// GPU Storage
|
||||
Handle<SHVkBuffer> vertPosBuffer{};
|
||||
Handle<SHVkBuffer> vertTexCoordBuffer{};
|
||||
Handle<SHVkBuffer> vertTangentBuffer{};
|
||||
Handle<SHVkBuffer> vertNormalBuffer{};
|
||||
Handle<SHVkBuffer> vertBoneIdxBuffer{};
|
||||
Handle<SHVkBuffer> vertBoneWeightBuffer{};
|
||||
Handle<SHVkBuffer> indexBuffer{};
|
||||
// Flags
|
||||
bool isDirty = true;
|
||||
|
|
|
@ -25,18 +25,18 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHMeshData SHPrimitiveGenerator::cubeMesh;
|
||||
SHMeshData SHPrimitiveGenerator::sphereMesh;
|
||||
SHMeshData SHPrimitiveGenerator::lineCubeMesh;
|
||||
SHMeshData SHPrimitiveGenerator::lineCircleMesh;
|
||||
SHMeshData SHPrimitiveGenerator::lineCapsuleCapMesh;
|
||||
SHMeshAsset SHPrimitiveGenerator::cubeMesh;
|
||||
SHMeshAsset SHPrimitiveGenerator::sphereMesh;
|
||||
SHMeshAsset SHPrimitiveGenerator::lineCubeMesh;
|
||||
SHMeshAsset SHPrimitiveGenerator::lineCircleMesh;
|
||||
SHMeshAsset SHPrimitiveGenerator::lineCapsuleCapMesh;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Primitive Generation Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHMeshData SHPrimitiveGenerator::Cube() noexcept
|
||||
SHMeshAsset SHPrimitiveGenerator::Cube() noexcept
|
||||
{
|
||||
SHMeshData mesh;
|
||||
SHMeshAsset mesh;
|
||||
|
||||
mesh.VertexPositions =
|
||||
{
|
||||
|
@ -221,9 +221,9 @@ namespace SHADE
|
|||
return addMeshDataTo(cubeMesh, gfxSystem);
|
||||
}
|
||||
|
||||
SHMeshData SHPrimitiveGenerator::Sphere() noexcept
|
||||
SHMeshAsset SHPrimitiveGenerator::Sphere() noexcept
|
||||
{
|
||||
SHMeshData meshData;
|
||||
SHMeshAsset meshData;
|
||||
|
||||
const int LAT_SLICES = 12;
|
||||
const int LONG_SLICES = 12;
|
||||
|
@ -288,9 +288,9 @@ namespace SHADE
|
|||
return addMeshDataTo(sphereMesh, gfxSystem);
|
||||
}
|
||||
|
||||
SHMeshData SHPrimitiveGenerator::LineCube() noexcept
|
||||
SHMeshAsset SHPrimitiveGenerator::LineCube() noexcept
|
||||
{
|
||||
SHMeshData mesh;
|
||||
SHMeshAsset mesh;
|
||||
|
||||
mesh.VertexPositions =
|
||||
{
|
||||
|
@ -347,9 +347,9 @@ namespace SHADE
|
|||
return addMeshDataTo(lineCubeMesh, gfxSystem);
|
||||
}
|
||||
|
||||
SHMeshData SHPrimitiveGenerator::LineCircle() noexcept
|
||||
SHMeshAsset SHPrimitiveGenerator::LineCircle() noexcept
|
||||
{
|
||||
SHMeshData mesh;
|
||||
SHMeshAsset mesh;
|
||||
|
||||
// Generate points of the circle
|
||||
static constexpr int SPLITS = 36;
|
||||
|
@ -393,9 +393,9 @@ namespace SHADE
|
|||
return addMeshDataTo(lineCircleMesh, gfxSystem);
|
||||
}
|
||||
|
||||
SHADE::SHMeshData SHPrimitiveGenerator::LineCapsuleCap() noexcept
|
||||
SHMeshAsset SHPrimitiveGenerator::LineCapsuleCap() noexcept
|
||||
{
|
||||
SHMeshData mesh;
|
||||
SHMeshAsset mesh;
|
||||
|
||||
// Have multiple semi-circles for the cap
|
||||
static constexpr int SPLITS = 36;
|
||||
|
@ -454,7 +454,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept
|
||||
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshAsset& meshData, SHMeshLibrary& meshLibrary) noexcept
|
||||
{
|
||||
return meshLibrary.AddMesh
|
||||
(
|
||||
|
@ -463,12 +463,15 @@ namespace SHADE
|
|||
meshData.VertexTexCoords.data(),
|
||||
meshData.VertexTangents.data(),
|
||||
meshData.VertexNormals.data(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
static_cast<uint32_t>(meshData.Indices.size()),
|
||||
meshData.Indices.data()
|
||||
meshData.Indices.data(),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept
|
||||
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshAsset& meshData, SHGraphicsSystem& gfxSystem) noexcept
|
||||
{
|
||||
return gfxSystem.AddMesh
|
||||
(
|
||||
|
|
|
@ -12,10 +12,11 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Math/SHMath.h"
|
||||
#include "Assets/Asset Types/SHModelAsset.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||
#include "SH_API.h"
|
||||
#include "Math/SHMath.h"
|
||||
#include "Assets/Asset Types/Models/SHModelAsset.h"
|
||||
#include "Assets/Asset Types/Models/SHMeshAsset.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMeshLibrary.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -47,13 +48,13 @@ namespace SHADE
|
|||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Produces a cube and stores the data in a SHMeshData object.
|
||||
Produces a cube and stores the data in a SHMeshAsset object.
|
||||
|
||||
\return
|
||||
SHMeshData object containing vertex data for the cube.
|
||||
SHMeshAsset object containing vertex data for the cube.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData Cube() noexcept;
|
||||
[[nodiscard]] static SHMeshAsset Cube() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -83,13 +84,13 @@ namespace SHADE
|
|||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
Produces a sphere and stores the data in a SHMeshData object.
|
||||
Produces a sphere and stores the data in a SHMeshAsset object.
|
||||
|
||||
\return
|
||||
SHMeshData object containing vertex data for the sphere.
|
||||
SHMeshAsset object containing vertex data for the sphere.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData Sphere() noexcept;
|
||||
[[nodiscard]] static SHMeshAsset Sphere() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -120,13 +121,13 @@ namespace SHADE
|
|||
/*!
|
||||
\brief
|
||||
Produces a cube that is comprised only of lines with no diagonal lines and store
|
||||
the data in a SHMeshData object.
|
||||
the data in a SHMeshAsset object.
|
||||
|
||||
\return
|
||||
SHMeshData object containing vertex data for the line cube.
|
||||
SHMeshAsset object containing vertex data for the line cube.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData LineCube() noexcept;
|
||||
[[nodiscard]] static SHMeshAsset LineCube() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -158,13 +159,13 @@ namespace SHADE
|
|||
/*!
|
||||
\brief
|
||||
Produces a circle that is comprised only of lines with no diagonal lines and
|
||||
store the data in a SHMeshData object.
|
||||
store the data in a SHMeshAsset object.
|
||||
|
||||
\return
|
||||
SHMeshData object containing vertex data for the line circle.
|
||||
SHMeshAsset object containing vertex data for the line circle.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData LineCircle() noexcept;
|
||||
[[nodiscard]] static SHMeshAsset LineCircle() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -204,7 +205,7 @@ namespace SHADE
|
|||
SHMeshData object containing vertex data for the line circle.
|
||||
*/
|
||||
/***********************************************************************************/
|
||||
[[nodiscard]] static SHMeshData LineCapsuleCap() noexcept;
|
||||
[[nodiscard]] static SHMeshAsset LineCapsuleCap() noexcept;
|
||||
/***********************************************************************************/
|
||||
/*!
|
||||
\brief
|
||||
|
@ -239,16 +240,16 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept;
|
||||
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept;
|
||||
static Handle<SHMesh> addMeshDataTo(const SHMeshAsset& meshData, SHMeshLibrary& meshLibrary) noexcept;
|
||||
static Handle<SHMesh> addMeshDataTo(const SHMeshAsset& meshData, SHGraphicsSystem& gfxSystem) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static SHMeshData cubeMesh;
|
||||
static SHMeshData sphereMesh;
|
||||
static SHMeshData lineCubeMesh;
|
||||
static SHMeshData lineCircleMesh;
|
||||
static SHMeshData lineCapsuleCapMesh;
|
||||
static SHMeshAsset cubeMesh;
|
||||
static SHMeshAsset sphereMesh;
|
||||
static SHMeshAsset lineCubeMesh;
|
||||
static SHMeshAsset lineCircleMesh;
|
||||
static SHMeshAsset lineCapsuleCapMesh;
|
||||
};
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
namespace SHADE
|
||||
{
|
||||
|
||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHVertexInputState const& viState/* = SHGraphicsPredefinedData::GetDefaultViState()*/, SHRasterizationState const& rasterState) noexcept
|
||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHGraphicsPredefinedData::SystemType systemType, SHVertexInputState const& viState, SHRasterizationState const& rasterState) noexcept
|
||||
{
|
||||
std::vector<Handle<SHVkShaderModule>> modules{};
|
||||
if (vsFsPair.first)
|
||||
|
@ -17,8 +17,8 @@ namespace SHADE
|
|||
|
||||
SHPipelineLayoutParams params
|
||||
{
|
||||
.shaderModules = std::move(modules),
|
||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(systemType).descSetLayouts
|
||||
};
|
||||
|
||||
// Create the pipeline layout
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
|||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||
Handle<SHVkRenderpass> renderpass,
|
||||
Handle<SHSubpass> subpass,
|
||||
SHGraphicsPredefinedData::SystemType systemType,
|
||||
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState(),
|
||||
SHRasterizationState const& rasterState = SHRasterizationState{}
|
||||
) noexcept;
|
||||
|
|
|
@ -689,11 +689,37 @@ namespace SHADE
|
|||
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair);
|
||||
if (!pipeline)
|
||||
{
|
||||
// default to batching system type
|
||||
SHGraphicsPredefinedData::SystemType systemType{ SHGraphicsPredefinedData::SystemType::BATCHING };
|
||||
auto const& REFLECTED_SETS = vsFsPair.first->GetReflectedData().GetDescriptorBindingInfo().GetReflectedSets();
|
||||
|
||||
// look for animation set binding in the shader (set 2 binding 1)
|
||||
for (auto const& set : REFLECTED_SETS)
|
||||
{
|
||||
auto const mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING_ANIM);
|
||||
|
||||
// Look for set 2
|
||||
if (set->set == mappings.at(SHPredefinedDescriptorTypes::PER_INSTANCE_ANIM_BATCH))
|
||||
{
|
||||
for (int i = 0; i < set->binding_count; i++)
|
||||
{
|
||||
// look for binding 1. if found use BATCHING_ANIM system type
|
||||
if (set->bindings[i]->binding == SHGraphicsConstants::DescriptorSetBindings::BONE_MATRIX_DATA)
|
||||
{
|
||||
systemType = SHGraphicsPredefinedData::SystemType::BATCHING_ANIM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pipeline = pipelineLibrary.CreateGraphicsPipelines
|
||||
(
|
||||
vsFsPair,
|
||||
renderpass,
|
||||
subpass
|
||||
subpass,
|
||||
systemType
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
/****************************************************************************************
|
||||
* \file SHAABB.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DirectXCollision.h>
|
||||
|
||||
// Project Headers
|
||||
#include "Math/SHRay.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates a 3D Axis-Aligned Bounding Box.
|
||||
*/
|
||||
class SH_API SHAABB : private DirectX::BoundingBox
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
static constexpr size_t NUM_VERTICES = 8;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
~SHAABB () noexcept = default;
|
||||
|
||||
SHAABB () noexcept;
|
||||
SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept;
|
||||
SHAABB (const SHAABB& rhs) noexcept;
|
||||
SHAABB (SHAABB&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHAABB& operator= (const SHAABB& rhs) noexcept;
|
||||
SHAABB& operator= (SHAABB&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetExtents () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||
void SetExtents (const SHVec3& newHalfExtents) noexcept;
|
||||
void SetMin (const SHVec3& min) noexcept;
|
||||
void SetMax (const SHVec3& max) noexcept;
|
||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Checks if a point is inside the aabb.
|
||||
* @param point
|
||||
* The point to check.
|
||||
* @return
|
||||
* True if the point is inside the aabb.
|
||||
*/
|
||||
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Casts a ray against the aabb.
|
||||
* @param ray
|
||||
* The ray to cast.
|
||||
* @return
|
||||
* The result of the raycast. <br/>
|
||||
* See the corresponding header for the contents of the raycast result object.
|
||||
*/
|
||||
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Checks if an entire other aabb is contained by this aabb.
|
||||
* @param rhs
|
||||
* The aabb to check.
|
||||
* @return
|
||||
* True if the other sphere is completely contained by this aabb.
|
||||
*/
|
||||
[[nodiscard]] bool Contains (const SHAABB& rhs) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculates the volume of the aabb.
|
||||
*/
|
||||
[[nodiscard]] float Volume () const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Calculates the surface area of the aabb.
|
||||
*/
|
||||
[[nodiscard]] float SurfaceArea () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Combines two aabbs to form a larger aabb.
|
||||
* If one aabb is completely contained by the other, the result is the larger aabb.
|
||||
* @return
|
||||
* The combined aabb.
|
||||
*/
|
||||
[[nodiscard]] static SHAABB Combine (const SHAABB& lhs, const SHAABB& rhs) noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Checks if two aabbs are intersecting.
|
||||
* @return
|
||||
* True if they are intersecting.
|
||||
*/
|
||||
[[nodiscard]] static bool Intersect (const SHAABB& lhs, const SHAABB& rhs) noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Builds a single aabb from multiple aabbs.
|
||||
* @param spheres
|
||||
* The set of aabbs to build from.
|
||||
* @param numSpheres
|
||||
* The number of aabbs in the set to build from.
|
||||
* @return
|
||||
* An aabb that contains all the spheres in the set.
|
||||
*/
|
||||
[[nodiscard]] static SHAABB BuildFromBoxes (const SHAABB* boxes, size_t numBoxes) noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Builds a aabb from a set of vertices.
|
||||
* @param vertices
|
||||
* The vertices to build a aabb from.
|
||||
* @param numVertices
|
||||
* The number of vertices in the set to build from.
|
||||
* @param stride
|
||||
* The stride between each vertex, in the instance there is data in between each
|
||||
* vertex that does not define the geometry of the object.
|
||||
* @return
|
||||
* An aabb that contains all the vertices in the set.
|
||||
*/
|
||||
[[nodiscard]] static SHAABB BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SHADE
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************************
|
||||
* \file SHAABB.cpp
|
||||
* \file SHBox.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
|
||||
*
|
||||
|
@ -11,7 +11,7 @@
|
|||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHAABB.h"
|
||||
#include "SHBox.h"
|
||||
// Project Headers
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "Math/SHRay.h"
|
||||
|
@ -24,52 +24,75 @@ namespace SHADE
|
|||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHAABB::SHAABB() noexcept
|
||||
SHBox::SHBox() noexcept
|
||||
: RelativeExtents { SHVec3::One }
|
||||
{
|
||||
Extents = SHVec3::One * 0.5f;
|
||||
type = Type::BOX;
|
||||
}
|
||||
|
||||
SHAABB::SHAABB(const SHVec3& c, const SHVec3& hE) noexcept
|
||||
SHBox::SHBox(const SHVec3& c, const SHVec3& hE) noexcept
|
||||
: RelativeExtents { SHVec3::One }
|
||||
{
|
||||
type = Type::BOX;
|
||||
|
||||
Center = c;
|
||||
Extents = hE;
|
||||
}
|
||||
|
||||
|
||||
SHAABB::SHAABB(const SHAABB& rhs) noexcept
|
||||
SHBox::SHBox(const SHBox& rhs) noexcept
|
||||
{
|
||||
if (this == &rhs)
|
||||
return;
|
||||
|
||||
type = Type::BOX;
|
||||
|
||||
Center = rhs.Center;
|
||||
Extents = rhs.Extents;
|
||||
RelativeExtents = rhs.RelativeExtents;
|
||||
}
|
||||
|
||||
SHAABB::SHAABB(SHAABB&& rhs) noexcept
|
||||
SHBox::SHBox(SHBox&& rhs) noexcept
|
||||
{
|
||||
type = Type::BOX;
|
||||
|
||||
Center = rhs.Center;
|
||||
Extents = rhs.Extents;
|
||||
RelativeExtents = rhs.RelativeExtents;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Operator Overload Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHAABB& SHAABB::operator=(const SHAABB& rhs) noexcept
|
||||
SHBox& SHBox::operator=(const SHBox& rhs) noexcept
|
||||
{
|
||||
if (this != &rhs)
|
||||
if (rhs.type != Type::BOX)
|
||||
{
|
||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||
}
|
||||
else if (this != &rhs)
|
||||
{
|
||||
Center = rhs.Center;
|
||||
Extents = rhs.Extents;
|
||||
RelativeExtents = rhs.RelativeExtents;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SHAABB& SHAABB::operator=(SHAABB&& rhs) noexcept
|
||||
SHBox& SHBox::operator=(SHBox&& rhs) noexcept
|
||||
{
|
||||
if (rhs.type != Type::BOX)
|
||||
{
|
||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||
}
|
||||
else
|
||||
{
|
||||
Center = rhs.Center;
|
||||
Extents = rhs.Extents;
|
||||
RelativeExtents = rhs.RelativeExtents;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -78,22 +101,27 @@ namespace SHADE
|
|||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHVec3 SHAABB::GetCenter() const noexcept
|
||||
SHVec3 SHBox::GetCenter() const noexcept
|
||||
{
|
||||
return Center;
|
||||
}
|
||||
|
||||
SHVec3 SHAABB::GetExtents() const noexcept
|
||||
SHVec3 SHBox::GetWorldExtents() const noexcept
|
||||
{
|
||||
return Extents;
|
||||
}
|
||||
|
||||
SHVec3 SHAABB::GetMin() const noexcept
|
||||
const SHVec3& SHBox::GetRelativeExtents() const noexcept
|
||||
{
|
||||
return RelativeExtents;
|
||||
}
|
||||
|
||||
SHVec3 SHBox::GetMin() const noexcept
|
||||
{
|
||||
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
|
||||
}
|
||||
|
||||
SHVec3 SHAABB::GetMax() const noexcept
|
||||
SHVec3 SHBox::GetMax() const noexcept
|
||||
{
|
||||
return SHVec3{ Center.x + Extents.x, Center.y + Extents.y, Center.z + Extents.z };
|
||||
}
|
||||
|
@ -102,17 +130,22 @@ namespace SHADE
|
|||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHAABB::SetCenter(const SHVec3& newCenter) noexcept
|
||||
void SHBox::SetCenter(const SHVec3& newCenter) noexcept
|
||||
{
|
||||
Center = newCenter;
|
||||
}
|
||||
|
||||
void SHAABB::SetExtents(const SHVec3& newHalfExtents) noexcept
|
||||
void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
||||
{
|
||||
Extents = newHalfExtents;
|
||||
Extents = newWorldExtents;
|
||||
}
|
||||
|
||||
void SHAABB::SetMin(const SHVec3& min) noexcept
|
||||
void SHBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
|
||||
{
|
||||
RelativeExtents = newRelativeExtents;
|
||||
}
|
||||
|
||||
void SHBox::SetMin(const SHVec3& min) noexcept
|
||||
{
|
||||
const SHVec3 MAX = GetMax();
|
||||
|
||||
|
@ -120,7 +153,7 @@ namespace SHADE
|
|||
Extents = SHVec3::Abs((MAX - min) * 0.5f);
|
||||
}
|
||||
|
||||
void SHAABB::SetMax(const SHVec3& max) noexcept
|
||||
void SHBox::SetMax(const SHVec3& max) noexcept
|
||||
{
|
||||
const SHVec3 MIN = GetMin();
|
||||
|
||||
|
@ -128,13 +161,13 @@ namespace SHADE
|
|||
Extents = SHVec3::Abs((max - MIN) * 0.5f);
|
||||
}
|
||||
|
||||
void SHAABB::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
|
||||
void SHBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
|
||||
{
|
||||
Center = SHVec3::Lerp(min, max, 0.5f);
|
||||
Extents = SHVec3::Abs((max - min) * 0.5f);
|
||||
}
|
||||
|
||||
std::vector<SHVec3> SHAABB::GetVertices() const noexcept
|
||||
std::vector<SHVec3> SHBox::GetVertices() const noexcept
|
||||
{
|
||||
std::vector<SHVec3> vertices{ 8 };
|
||||
GetCorners(vertices.data());
|
||||
|
@ -145,12 +178,12 @@ namespace SHADE
|
|||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHAABB::TestPoint(const SHVec3& point) const noexcept
|
||||
bool SHBox::TestPoint(const SHVec3& point) const noexcept
|
||||
{
|
||||
return BoundingBox::Contains(point);
|
||||
}
|
||||
|
||||
SHRaycastResult SHAABB::Raycast(const SHRay& ray) const noexcept
|
||||
SHRaycastResult SHBox::Raycast(const SHRay& ray) const noexcept
|
||||
{
|
||||
SHRaycastResult result;
|
||||
|
||||
|
@ -159,24 +192,22 @@ namespace SHADE
|
|||
{
|
||||
result.position = ray.position + ray.direction * result.distance;
|
||||
result.angle = SHVec3::Angle(ray.position, result.position);
|
||||
|
||||
// TODO: Compute normal
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SHAABB::Contains(const SHAABB& rhs) const noexcept
|
||||
bool SHBox::Contains(const SHBox& rhs) const noexcept
|
||||
{
|
||||
return BoundingBox::Contains(rhs) == CONTAINS;
|
||||
return BoundingBox::Contains(rhs);
|
||||
}
|
||||
|
||||
float SHAABB::Volume() const noexcept
|
||||
float SHBox::Volume() const noexcept
|
||||
{
|
||||
return 8.0f * (Extents.x * Extents.y * Extents.z);
|
||||
}
|
||||
|
||||
float SHAABB::SurfaceArea() const noexcept
|
||||
float SHBox::SurfaceArea() const noexcept
|
||||
{
|
||||
return 8.0f * ((Extents.x * Extents.y)
|
||||
+ (Extents.x * Extents.z)
|
||||
|
@ -187,21 +218,21 @@ namespace SHADE
|
|||
/* Static Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHAABB SHAABB::Combine(const SHAABB& lhs, const SHAABB& rhs) noexcept
|
||||
SHBox SHBox::Combine(const SHBox& lhs, const SHBox& rhs) noexcept
|
||||
{
|
||||
SHAABB result;
|
||||
SHBox result;
|
||||
CreateMerged(result, lhs, rhs);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SHAABB::Intersect(const SHAABB& lhs, const SHAABB& rhs) noexcept
|
||||
bool SHBox::Intersect(const SHBox& lhs, const SHBox& rhs) noexcept
|
||||
{
|
||||
return lhs.Intersects(rhs);
|
||||
}
|
||||
|
||||
SHAABB SHAABB::BuildFromBoxes(const SHAABB* boxes, size_t numBoxes) noexcept
|
||||
SHBox SHBox::BuildFromBoxes(const SHBox* boxes, size_t numBoxes) noexcept
|
||||
{
|
||||
SHAABB result;
|
||||
SHBox result;
|
||||
|
||||
for (size_t i = 1; i < numBoxes; ++i)
|
||||
CreateMerged(result, boxes[i - 1], boxes[i]);
|
||||
|
@ -209,9 +240,9 @@ namespace SHADE
|
|||
return result;
|
||||
}
|
||||
|
||||
SHAABB SHAABB::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
||||
SHBox SHBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
||||
{
|
||||
SHAABB result;
|
||||
SHBox result;
|
||||
CreateFromPoints(result, numVertices, vertices, stride);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/****************************************************************************************
|
||||
* \file SHBox.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DirectXCollision.h>
|
||||
|
||||
// Project Headers
|
||||
#include "SHShape.h"
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SH_API SHBox : public SHShape,
|
||||
private DirectX::BoundingBox
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
static constexpr size_t NUM_VERTICES = 8;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
~SHBox () override = default;
|
||||
|
||||
SHBox () noexcept;
|
||||
SHBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
|
||||
SHBox (const SHBox& rhs) noexcept;
|
||||
SHBox (SHBox&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHBox& operator= (const SHBox& rhs) noexcept;
|
||||
SHBox& operator= (SHBox&& rhs) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
||||
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
||||
void SetMin (const SHVec3& min) noexcept;
|
||||
void SetMax (const SHVec3& max) noexcept;
|
||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
||||
[[nodiscard]] SHRaycastResult Raycast(const SHRay& ray) const noexcept override;
|
||||
|
||||
[[nodiscard]] bool Contains (const SHBox& rhs) const noexcept;
|
||||
[[nodiscard]] float Volume () const noexcept;
|
||||
[[nodiscard]] float SurfaceArea () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] static SHBox Combine (const SHBox& lhs, const SHBox& rhs) noexcept;
|
||||
[[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept;
|
||||
[[nodiscard]] static SHBox BuildFromBoxes (const SHBox* boxes, size_t numBoxes) noexcept;
|
||||
[[nodiscard]] static SHBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHVec3 RelativeExtents;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SHADE
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPlane.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for a plane.
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
****************************************************************************************/
|
||||
|
||||
#include <SHpch.h>
|
||||
|
||||
#include <DirectXMath.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHPlane.h"
|
||||
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "Math/SHMathHelpers.h"
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHPlane::SHPlane() noexcept
|
||||
: planeEquation { SHVec3::One }
|
||||
{
|
||||
planeEquation.w = 0.0f;
|
||||
}
|
||||
|
||||
SHPlane::SHPlane(const SHVec3& point, const SHVec3& normal) noexcept
|
||||
{
|
||||
XMStoreFloat4(&planeEquation, XMPlaneFromPointNormal(point, normal));
|
||||
}
|
||||
|
||||
SHPlane::SHPlane(float a, float b, float c, float d) noexcept
|
||||
: planeEquation { a, b, c, d }
|
||||
{}
|
||||
|
||||
SHPlane::SHPlane(const SHVec3& normal, float distance) noexcept
|
||||
: planeEquation { normal }
|
||||
{
|
||||
planeEquation.w = distance;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Operator Overload Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHPlane::operator==(const SHPlane& rhs) const noexcept
|
||||
{
|
||||
return XMPlaneEqual(planeEquation, rhs.planeEquation);
|
||||
}
|
||||
|
||||
bool SHPlane::operator!=(const SHPlane& rhs) const noexcept
|
||||
{
|
||||
return XMPlaneNotEqual(planeEquation, rhs.planeEquation);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHVec3 SHPlane::GetNormal() const noexcept
|
||||
{
|
||||
return SHVec3{ planeEquation.x, planeEquation.y, planeEquation.z };
|
||||
}
|
||||
|
||||
float SHPlane::GetDistance() const noexcept
|
||||
{
|
||||
return planeEquation.w;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHPlane::SetNormal(const SHVec3& normal) noexcept
|
||||
{
|
||||
planeEquation.x = normal.x;
|
||||
planeEquation.y = normal.y;
|
||||
planeEquation.z = normal.z;
|
||||
}
|
||||
|
||||
void SHPlane::SetDistance(float distance) noexcept
|
||||
{
|
||||
planeEquation.w = distance;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHPlane::TestPoint(const SHVec3& point) const noexcept
|
||||
{
|
||||
const float DISTANCE = SignedDistance(point);
|
||||
return SHMath::CompareFloat(DISTANCE, 0.0f);
|
||||
}
|
||||
|
||||
SHRaycastResult SHPlane::Raycast(const SHRay& ray) const noexcept
|
||||
{
|
||||
SHRaycastResult result;
|
||||
|
||||
const SHVec3 N = GetNormal();
|
||||
|
||||
// Check if ray is parallel to plane
|
||||
const float N_DOT_D = N.Dot(ray.direction);
|
||||
if (SHMath::CompareFloat(N_DOT_D, 0.0f))
|
||||
{
|
||||
result.hit = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
const float DIST = (planeEquation.w - N.Dot(ray.position)) / N_DOT_D;
|
||||
if (DIST < 0.0f || !SHMath::CompareFloat(DIST, 0.0f))
|
||||
{
|
||||
result.hit = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.hit = true;
|
||||
result.distance = DIST;
|
||||
result.position = ray.position + ray.direction * DIST;
|
||||
result.angle = SHVec3::Angle(ray.position, result.position);
|
||||
|
||||
// The normal is either the plane's normal or the reverse if the ray came from below
|
||||
result.normal = N_DOT_D < 0.0f ? -N : N;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float SHPlane::SignedDistance(const SHVec3& point) const noexcept
|
||||
{
|
||||
return XMVectorGetX(XMPlaneDotCoord(planeEquation, point));
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -1,121 +0,0 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPlane.h
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Interface for a plane.
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Project Headers
|
||||
#include "Math/SHRay.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates a 3D plane in point-normal form.
|
||||
*/
|
||||
class SH_API SHPlane
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors & Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
~SHPlane () noexcept = default;
|
||||
SHPlane (const SHPlane& rhs) noexcept = default;
|
||||
SHPlane (SHPlane&& rhs) noexcept = default;
|
||||
|
||||
SHPlane () noexcept;
|
||||
SHPlane (const SHVec3& point, const SHVec3& normal) noexcept;
|
||||
SHPlane (float a, float b, float c, float d) noexcept;
|
||||
SHPlane (const SHVec3& normal, float distance) noexcept;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHPlane& operator= (const SHPlane& rhs) noexcept = default;
|
||||
SHPlane& operator= (SHPlane&& rhs) noexcept = default;
|
||||
|
||||
bool operator== (const SHPlane& rhs) const noexcept;
|
||||
bool operator!= (const SHPlane& rhs) const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] SHVec3 GetNormal () const noexcept;
|
||||
[[nodiscard]] float GetDistance () const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetNormal (const SHVec3& normal) noexcept;
|
||||
void SetDistance (float distance) noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Checks if a point is on the plane.
|
||||
* @param point
|
||||
* The point to check.
|
||||
* @return
|
||||
* True if the point is on the plane.
|
||||
*/
|
||||
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Casts a ray against the plane.
|
||||
* @param ray
|
||||
* The ray to cast.
|
||||
* @return
|
||||
* The result of the raycast. <br/>
|
||||
* See the corresponding header for the contents of the raycast result object.
|
||||
*/
|
||||
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Gets the signed distance from a point to the plane.
|
||||
* @param point
|
||||
* The point to check.
|
||||
* @return
|
||||
* The signed distance of the point to a plane. <br/>
|
||||
* If the signed distance is negative, the point is behind the plane. <br/>
|
||||
* If the signed distance is zero, the point is on the plane. <br/>
|
||||
* If the signed distance is positive, the point is in front of the plane. <br/>
|
||||
*/
|
||||
[[nodiscard]] float SignedDistance (const SHVec3& point) const noexcept;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Static Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Transform plane
|
||||
* Intersection Tests
|
||||
*/
|
||||
|
||||
private:
|
||||
|
||||
SHVec4 planeEquation;
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************************
|
||||
* \file SHCapsuleVsCapsule.cpp
|
||||
* \file SHShape.cpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for the Detecting Collisions between two capsules
|
||||
* \brief Implementation for a shape.
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
|
@ -11,25 +11,25 @@
|
|||
#include <SHpch.h>
|
||||
|
||||
// Primary Header
|
||||
#include "SHCollision.h"
|
||||
|
||||
// Project Headers
|
||||
#include "Math/SHMathHelpers.h"
|
||||
#include "SHShape.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Public Member Functions Definitions */
|
||||
/* Constructors & Destructor Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHCollision::CapsuleVsCapsule(const SHCollisionShape& A, const SHCollisionShape& B) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SHShape::SHShape()
|
||||
: type { Type::NONE }
|
||||
{}
|
||||
|
||||
bool SHCollision::CapsuleVsCapsule(SHManifold& manifold, const SHCollisionShape& A, const SHCollisionShape& B) noexcept
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHShape::Type SHShape::GetType() const noexcept
|
||||
{
|
||||
return false;
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue