Merge branch 'main' into PlayerController
This commit is contained in:
commit
4f9015995c
|
@ -50,7 +50,7 @@
|
||||||
Colliders:
|
Colliders:
|
||||||
- Is Trigger: false
|
- Is Trigger: false
|
||||||
Type: Box
|
Type: Box
|
||||||
Half Extents: {x: 24.7399445, y: 0.25, z: 8.75}
|
Half Extents: {x: 1, y: 1, z: 1}
|
||||||
Friction: 0.400000006
|
Friction: 0.400000006
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
|
@ -90,23 +90,7 @@
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
Scripts:
|
Scripts: ~
|
||||||
- Type: PlayerController
|
|
||||||
drag: 2
|
|
||||||
currentState: 0
|
|
||||||
maxMoveVel: 2
|
|
||||||
moveForce: 50
|
|
||||||
sprintMultiplier: 2
|
|
||||||
rotationFactorPerFrame: 1
|
|
||||||
maxJumpHeight: 4
|
|
||||||
maxJumpTime: 0.75
|
|
||||||
fallMultipler: 2
|
|
||||||
lightMultiper: 0.75
|
|
||||||
mediumMultiper: 0.5
|
|
||||||
heavyMultiper: 0.25
|
|
||||||
- Type: PickAndThrow
|
|
||||||
throwForce: [200, 300, 200]
|
|
||||||
item: 5
|
|
||||||
- EID: 3
|
- EID: 3
|
||||||
Name: Default
|
Name: Default
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
@ -126,12 +110,7 @@
|
||||||
Translate: {x: 0, y: 0, z: 0}
|
Translate: {x: 0, y: 0, z: 0}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
Scripts:
|
Scripts: ~
|
||||||
- Type: SHADE_Scripting.ThirdPersonCamera
|
|
||||||
armLength: 2
|
|
||||||
turnSpeedPitch: 0.300000012
|
|
||||||
turnSpeedYaw: 0.5
|
|
||||||
pitchClamp: 45
|
|
||||||
- EID: 9
|
- EID: 9
|
||||||
Name: Default
|
Name: Default
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
@ -145,6 +124,67 @@
|
||||||
Mesh: 144838771
|
Mesh: 144838771
|
||||||
Material: 123745521
|
Material: 123745521
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
|
- EID: 6
|
||||||
|
Name: AI
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: -8, y: -2, z: 2.5}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
RigidBody Component:
|
||||||
|
Type: Dynamic
|
||||||
|
Mass: 1
|
||||||
|
Drag: 0
|
||||||
|
Angular Drag: 0
|
||||||
|
Use Gravity: true
|
||||||
|
Interpolate: false
|
||||||
|
Freeze Position X: false
|
||||||
|
Freeze Position Y: false
|
||||||
|
Freeze Position Z: false
|
||||||
|
Freeze Rotation X: true
|
||||||
|
Freeze Rotation Y: true
|
||||||
|
Freeze Rotation Z: true
|
||||||
|
Collider Component:
|
||||||
|
Colliders:
|
||||||
|
- Is Trigger: false
|
||||||
|
Type: Box
|
||||||
|
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
|
||||||
|
Friction: 0.400000006
|
||||||
|
Bounciness: 0
|
||||||
|
Density: 1
|
||||||
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 7
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -16.8647861, z: -14.039052}
|
||||||
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
|
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 149697411
|
||||||
|
Material: 126974645
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 8
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Light Component:
|
||||||
|
Position: {x: 0, y: 0, z: 0}
|
||||||
|
Type: Ambient
|
||||||
|
Direction: {x: 0, y: 0, z: 1}
|
||||||
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
|
Layer: 4294967295
|
||||||
|
Strength: 0.25
|
||||||
|
Scripts: ~
|
||||||
- EID: 5
|
- EID: 5
|
||||||
Name: item
|
Name: item
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
@ -186,77 +226,4 @@
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
Scripts:
|
|
||||||
- Type: Item
|
|
||||||
currCategory: 0
|
|
||||||
- EID: 6
|
|
||||||
Name: AI
|
|
||||||
IsActive: true
|
|
||||||
NumberOfChildren: 0
|
|
||||||
Components:
|
|
||||||
Transform Component:
|
|
||||||
Translate: {x: -8, y: -2, z: 2.5}
|
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
|
||||||
Renderable Component:
|
|
||||||
Mesh: 149697411
|
|
||||||
Material: 126974645
|
|
||||||
RigidBody Component:
|
|
||||||
Type: Dynamic
|
|
||||||
Mass: 1
|
|
||||||
Drag: 0
|
|
||||||
Angular Drag: 0
|
|
||||||
Use Gravity: true
|
|
||||||
Interpolate: false
|
|
||||||
Freeze Position X: false
|
|
||||||
Freeze Position Y: false
|
|
||||||
Freeze Position Z: false
|
|
||||||
Freeze Rotation X: true
|
|
||||||
Freeze Rotation Y: true
|
|
||||||
Freeze Rotation Z: true
|
|
||||||
Collider Component:
|
|
||||||
Colliders:
|
|
||||||
- Is Trigger: false
|
|
||||||
Type: Box
|
|
||||||
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
|
|
||||||
Friction: 0.400000006
|
|
||||||
Bounciness: 0
|
|
||||||
Density: 1
|
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
|
||||||
Scripts:
|
|
||||||
- Type: AIPrototype
|
|
||||||
movementForceMultiplier: 100
|
|
||||||
patrolSpeed: 0.400000006
|
|
||||||
chaseSpeed: 0.800000012
|
|
||||||
distanceToCapture: 1.20000005
|
|
||||||
distanceToStartChase: 2
|
|
||||||
distanceToEndChase: 2.5
|
|
||||||
- EID: 7
|
|
||||||
Name: Default
|
|
||||||
IsActive: true
|
|
||||||
NumberOfChildren: 0
|
|
||||||
Components:
|
|
||||||
Transform Component:
|
|
||||||
Translate: {x: 0, y: -16.8647861, z: -14.039052}
|
|
||||||
Rotate: {x: -0, y: 0, z: -0}
|
|
||||||
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
|
|
||||||
Renderable Component:
|
|
||||||
Mesh: 149697411
|
|
||||||
Material: 126974645
|
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 8
|
|
||||||
Name: Default
|
|
||||||
IsActive: true
|
|
||||||
NumberOfChildren: 0
|
|
||||||
Components:
|
|
||||||
Light Component:
|
|
||||||
Position: {x: 0, y: 0, z: 0}
|
|
||||||
Type: Ambient
|
|
||||||
Direction: {x: 0, y: 0, z: 1}
|
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
|
||||||
Layer: 4294967295
|
|
||||||
Strength: 0.25
|
|
||||||
Scripts:
|
|
||||||
- Type: PickAndThrow
|
|
||||||
throwForce: [100, 200, 100]
|
|
||||||
item: 1
|
|
|
@ -27,6 +27,11 @@ public class RaccoonShowcase : Script
|
||||||
Debug.LogError("Transform is NULL!");
|
Debug.LogError("Transform is NULL!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var child in Owner)
|
||||||
|
{
|
||||||
|
Debug.Log(child.Name);
|
||||||
|
}
|
||||||
|
|
||||||
originalScale = Transform.LocalScale.z;
|
originalScale = Transform.LocalScale.z;
|
||||||
}
|
}
|
||||||
protected override void update()
|
protected override void update()
|
||||||
|
@ -36,4 +41,10 @@ public class RaccoonShowcase : Script
|
||||||
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
||||||
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void onDrawGizmos()
|
||||||
|
{
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f));
|
||||||
|
Gizmos.DrawLine(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 0.0f), Color.Red);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -106,6 +106,7 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Sandbox
|
||||||
|
|
||||||
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
auto* floorBox = floorCollider.AddBoundingBox();
|
floorCollider.AddBoundingBox();
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
@ -114,8 +114,8 @@ namespace Sandbox
|
||||||
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
|
||||||
|
|
||||||
racoonCollider.AddBoundingBox();
|
racoonCollider.AddBoundingBox();
|
||||||
racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
|
||||||
racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
|
||||||
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
|
||||||
|
@ -140,13 +140,13 @@ namespace Sandbox
|
||||||
|
|
||||||
itemCollider.AddBoundingBox();
|
itemCollider.AddBoundingBox();
|
||||||
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
|
||||||
itemCollider.GetCollider(1).SetIsTrigger(true);
|
itemCollider.GetCollisionShape(1).SetIsTrigger(true);
|
||||||
|
|
||||||
itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
itemRigidBody.SetInterpolate(false);
|
itemRigidBody.SetInterpolate(false);
|
||||||
itemRigidBody.SetFreezeRotationX(true);
|
itemRigidBody.SetFreezeRotationX(true);
|
||||||
|
@ -168,8 +168,8 @@ namespace Sandbox
|
||||||
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
|
||||||
|
|
||||||
AICollider.AddBoundingBox();
|
AICollider.AddBoundingBox();
|
||||||
AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
|
||||||
AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
|
||||||
|
|
||||||
AIRigidBody.SetInterpolate(false);
|
AIRigidBody.SetInterpolate(false);
|
||||||
AIRigidBody.SetFreezeRotationX(true);
|
AIRigidBody.SetFreezeRotationX(true);
|
||||||
|
|
|
@ -51,6 +51,7 @@ enum class AssetType : AssetTypeMeta
|
||||||
SCENE,
|
SCENE,
|
||||||
PREFAB,
|
PREFAB,
|
||||||
MATERIAL,
|
MATERIAL,
|
||||||
|
SCRIPT,
|
||||||
MESH,
|
MESH,
|
||||||
MAX_COUNT
|
MAX_COUNT
|
||||||
};
|
};
|
||||||
|
@ -91,12 +92,12 @@ constexpr std::string_view EXTENSIONS[] = {
|
||||||
AUDIO_EXTENSION,
|
AUDIO_EXTENSION,
|
||||||
SHADER_EXTENSION,
|
SHADER_EXTENSION,
|
||||||
SHADER_BUILT_IN_EXTENSION,
|
SHADER_BUILT_IN_EXTENSION,
|
||||||
MATERIAL_EXTENSION,
|
TEXTURE_EXTENSION,
|
||||||
TEXTURE_EXTENSION,
|
|
||||||
MODEL_EXTENSION,
|
MODEL_EXTENSION,
|
||||||
SCRIPT_EXTENSION,
|
SCENE_EXTENSION,
|
||||||
SCENE_EXTENSION,
|
|
||||||
PREFAB_EXTENSION,
|
PREFAB_EXTENSION,
|
||||||
|
MATERIAL_EXTENSION,
|
||||||
|
SCRIPT_EXTENSION,
|
||||||
AUDIO_WAV_EXTENSION,
|
AUDIO_WAV_EXTENSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
|
void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept
|
||||||
{
|
{
|
||||||
if (!std::filesystem::exists(path))
|
if (!std::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
|
@ -360,10 +360,12 @@ namespace SHADE
|
||||||
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
|
||||||
modelPath += MODEL_EXTENSION;
|
modelPath += MODEL_EXTENSION;
|
||||||
newPath = modelPath;
|
newPath = modelPath;
|
||||||
|
|
||||||
GenerateNewMeta(newPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (genMeta)
|
||||||
|
{
|
||||||
|
GenerateNewMeta(newPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
FolderPointer SHAssetManager::GetRootFolder() noexcept
|
||||||
|
@ -371,6 +373,13 @@ namespace SHADE
|
||||||
return folderRoot;
|
return folderRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::RefreshDirectory() noexcept
|
||||||
|
{
|
||||||
|
SHFileSystem::DestroyDirectory(folderRoot);
|
||||||
|
assetCollection.clear();
|
||||||
|
BuildAssetCollection();
|
||||||
|
}
|
||||||
|
|
||||||
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
||||||
{
|
{
|
||||||
for (auto const& e : EXTENSIONS)
|
for (auto const& e : EXTENSIONS)
|
||||||
|
|
|
@ -87,9 +87,10 @@ namespace SHADE
|
||||||
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
|
||||||
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
|
||||||
|
|
||||||
static void CompileAsset(AssetPath const& path) noexcept;
|
static void CompileAsset(AssetPath const& path, bool genMeta) noexcept;
|
||||||
|
|
||||||
static FolderPointer GetRootFolder() noexcept;
|
static FolderPointer GetRootFolder() noexcept;
|
||||||
|
static void RefreshDirectory() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <FMOD/fmod_studio.hpp>
|
#include <FMOD/fmod_studio.hpp>
|
||||||
#include <SDL_keyboard.h>
|
#include <SDL_keyboard.h>
|
||||||
|
|
||||||
|
const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHAudioSystem::SHAudioSystem()
|
SHAudioSystem::SHAudioSystem()
|
||||||
|
@ -79,10 +81,10 @@ namespace SHADE
|
||||||
//SHResourceManager::LoadAllAudio(system, soundList);
|
//SHResourceManager::LoadAllAudio(system, soundList);
|
||||||
|
|
||||||
|
|
||||||
LoadBank("../../Assets/Audio/Master.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
|
||||||
LoadBank("../../Assets/Audio/Master.strings.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
|
||||||
//LoadBank("../../Assets/Audio/Music.bank");
|
//LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data());
|
||||||
LoadBank("../../Assets/Audio/footsteps.bank");
|
LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data());
|
||||||
|
|
||||||
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
||||||
//clip->Play();
|
//clip->Play();
|
||||||
|
|
|
@ -419,7 +419,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Execute()
|
void SHEntityParentCommand::Execute()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].newParentEID == MAX_EID)
|
if (entityParentData[eid].newParentEID == MAX_EID)
|
||||||
|
@ -431,7 +431,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHEntityParentCommand::Undo()
|
void SHEntityParentCommand::Undo()
|
||||||
{
|
{
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
if (entityParentData[eid].oldParentEID == MAX_EID)
|
if (entityParentData[eid].oldParentEID == MAX_EID)
|
||||||
|
|
|
@ -224,9 +224,6 @@ namespace SHADE
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get transform component for extrapolating relative sizes
|
|
||||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
|
|
||||||
|
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -234,46 +231,39 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
auto& colliders = component->GetColliders();
|
auto& colliders = component->GetCollisionShapes();
|
||||||
int const size = static_cast<int>(colliders.size());
|
int const size = static_cast<int>(colliders.size());
|
||||||
ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
|
||||||
std::optional<int> colliderToDelete{ std::nullopt };
|
std::optional<int> colliderToDelete{ std::nullopt };
|
||||||
for (int i{}; i < size; ++i)
|
for (int i{}; i < size; ++i)
|
||||||
{
|
{
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
SHCollider* collider = &component->GetCollider(i);
|
SHCollisionShape* collider = &component->GetCollisionShape(i);
|
||||||
auto cursorPos = ImGui::GetCursorPos();
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
//collider->IsTrigger
|
//collider->IsTrigger
|
||||||
|
|
||||||
if (collider->GetType() == SHCollider::Type::BOX)
|
if (collider->GetType() == SHCollisionShape::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
|
||||||
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
(
|
(
|
||||||
"Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
|
[box] { return box->GetRelativeExtents(); },
|
||||||
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::SPHERE)
|
else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
|
|
||||||
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[sphere, transformComponent]
|
[sphere] { return sphere->GetRelativeRadius(); },
|
||||||
{
|
|
||||||
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
|
||||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
|
||||||
return (sphere->GetRadius() / MAX_SCALE) * 2.0f;
|
|
||||||
},
|
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Serialization/Configurations/SHConfigurationManager.h"
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
@ -43,8 +46,7 @@ namespace SHADE
|
||||||
void SHEditorMenuBar::Init()
|
void SHEditorMenuBar::Init()
|
||||||
{
|
{
|
||||||
SHEditorWindow::Init();
|
SHEditorWindow::Init();
|
||||||
constexpr std::string_view path = "../../Assets/Editor/Layouts";
|
for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
|
||||||
for(auto const& entry : std::filesystem::directory_iterator(path))
|
|
||||||
{
|
{
|
||||||
layoutPaths.push_back(entry.path());
|
layoutPaths.push_back(entry.path());
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ RTTR_REGISTRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" };
|
||||||
|
const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" };
|
||||||
|
const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"};
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -106,7 +110,7 @@ namespace SHADE
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
io->IniFilename = USER_LAYOUT_PATH.data();
|
||||||
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
InitLayout();
|
InitLayout();
|
||||||
|
|
||||||
|
@ -236,20 +240,20 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if(!std::filesystem::exists(io->IniFilename))
|
if(!std::filesystem::exists(io->IniFilename))
|
||||||
{
|
{
|
||||||
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename);
|
std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename);
|
||||||
}
|
}
|
||||||
//eventually load preferred layout here
|
//eventually load preferred layout here
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::InitFonts() noexcept
|
void SHEditor::InitFonts() noexcept
|
||||||
{
|
{
|
||||||
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path
|
||||||
|
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
|
||||||
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
|
||||||
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
|
||||||
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
|
constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
|
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
|
||||||
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
|
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
|
||||||
|
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "SHFileSystem.h"
|
#include "SHFileSystem.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "Assets/SHAssetMetaHandler.h"
|
#include "Assets/SHAssetMetaHandler.h"
|
||||||
|
|
||||||
|
@ -24,23 +25,37 @@ namespace SHADE
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
|
bool SHFileSystem::IsCompilable(std::string ext) noexcept
|
||||||
|
{
|
||||||
|
for (auto const& external : EXTERNALS)
|
||||||
|
{
|
||||||
|
if (ext == external)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
|
||||||
{
|
{
|
||||||
std::queue<FolderPointer> folderQueue;
|
std::stack<FolderPointer> folderStack;
|
||||||
root = new SHFolder("root");
|
root = new SHFolder("root");
|
||||||
root->path = path;
|
root->path = path;
|
||||||
folderQueue.push(root);
|
folderStack.push(root);
|
||||||
|
|
||||||
while (!folderQueue.empty())
|
while (!folderStack.empty())
|
||||||
{
|
{
|
||||||
auto const folder = folderQueue.front();
|
auto const folder = folderStack.top();
|
||||||
folderQueue.pop();
|
folderStack.pop();
|
||||||
|
|
||||||
std::vector<SHAsset> assets;
|
std::vector<SHAsset> assets;
|
||||||
|
|
||||||
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
|
for (auto& dirEntry : std::filesystem::directory_iterator(folder->path))
|
||||||
{
|
{
|
||||||
auto const& path = dirEntry.path();
|
auto path = dirEntry.path();
|
||||||
|
path.make_preferred();
|
||||||
if (!dirEntry.is_directory())
|
if (!dirEntry.is_directory())
|
||||||
{
|
{
|
||||||
if (path.extension().string() == META_EXTENSION)
|
if (path.extension().string() == META_EXTENSION)
|
||||||
|
@ -55,14 +70,15 @@ namespace SHADE
|
||||||
path.stem().string(),
|
path.stem().string(),
|
||||||
path.string(),
|
path.string(),
|
||||||
path.extension().string(),
|
path.extension().string(),
|
||||||
nullptr
|
nullptr,
|
||||||
|
IsCompilable(path.extension().string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
||||||
folderQueue.push(newFolder);
|
folderStack.push(newFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& asset : assets)
|
for (auto const& asset : assets)
|
||||||
|
@ -72,11 +88,34 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (file.name == asset.name)
|
if (file.name == asset.name)
|
||||||
{
|
{
|
||||||
file.assetMeta = &assetCollection[asset.id];
|
AssetPath path{ file.path };
|
||||||
break;
|
if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
|
||||||
|
{
|
||||||
|
file.assetMeta = &assetCollection[asset.id];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHFileSystem::DestroyDirectory(FolderPointer root) noexcept
|
||||||
|
{
|
||||||
|
std::stack<FolderPointer> folderStack;
|
||||||
|
folderStack.push(root);
|
||||||
|
|
||||||
|
while(!folderStack.empty())
|
||||||
|
{
|
||||||
|
auto const folder = folderStack.top();
|
||||||
|
folderStack.pop();
|
||||||
|
|
||||||
|
for (auto const& ptr : folder->subFolders)
|
||||||
|
{
|
||||||
|
folderStack.push(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete folder;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
|
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
|
||||||
|
static void DestroyDirectory(FolderPointer root) noexcept;
|
||||||
private:
|
private:
|
||||||
static bool DeleteFolder(FolderPointer location) noexcept;
|
static bool DeleteFolder(FolderPointer location) noexcept;
|
||||||
|
static bool IsCompilable(std::string ext) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -33,6 +33,7 @@ namespace SHADE
|
||||||
FilePath path;
|
FilePath path;
|
||||||
FileExt ext;
|
FileExt ext;
|
||||||
SHAsset const* assetMeta;
|
SHAsset const* assetMeta;
|
||||||
|
bool compilable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHFolder
|
class SHFolder
|
||||||
|
|
|
@ -323,7 +323,7 @@ namespace SHADE
|
||||||
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
|
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
|
||||||
for (const auto& idx : SPHERE.Indices)
|
for (const auto& idx : SPHERE.Indices)
|
||||||
{
|
{
|
||||||
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
|
spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
||||||
|
|
|
@ -25,11 +25,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox() noexcept
|
SHBoundingBox::SHBoundingBox() noexcept
|
||||||
|
: RelativeExtents { SHVec3::One }
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
|
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
|
||||||
|
: RelativeExtents { SHVec3::One }
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
|
@ -45,16 +47,18 @@ namespace SHADE
|
||||||
|
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
|
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -69,8 +73,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if (this != &rhs)
|
else if (this != &rhs)
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -84,8 +89,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
RelativeExtents = rhs.RelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,11 +106,16 @@ namespace SHADE
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept
|
SHVec3 SHBoundingBox::GetWorldExtents() const noexcept
|
||||||
{
|
{
|
||||||
return Extents;
|
return Extents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept
|
||||||
|
{
|
||||||
|
return RelativeExtents;
|
||||||
|
}
|
||||||
|
|
||||||
SHVec3 SHBoundingBox::GetMin() const noexcept
|
SHVec3 SHBoundingBox::GetMin() const noexcept
|
||||||
{
|
{
|
||||||
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
|
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
|
||||||
|
@ -124,9 +135,14 @@ namespace SHADE
|
||||||
Center = newCenter;
|
Center = newCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept
|
void SHBoundingBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
||||||
{
|
{
|
||||||
Extents = newHalfExtents;
|
Extents = newWorldExtents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoundingBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
|
||||||
|
{
|
||||||
|
RelativeExtents = newRelativeExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingBox::SetMin(const SHVec3& min) noexcept
|
void SHBoundingBox::SetMin(const SHVec3& min) noexcept
|
||||||
|
|
|
@ -54,21 +54,23 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept;
|
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||||
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||||
void SetHalfExtents (const SHVec3& newHalfExtents) noexcept;
|
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
||||||
void SetMin (const SHVec3& min) noexcept;
|
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
||||||
void SetMax (const SHVec3& max) noexcept;
|
void SetMin (const SHVec3& min) noexcept;
|
||||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
void SetMax (const SHVec3& max) noexcept;
|
||||||
|
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -89,6 +91,13 @@ namespace SHADE
|
||||||
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
|
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
|
||||||
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
|
||||||
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHVec3 RelativeExtents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,13 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere() noexcept
|
SHBoundingSphere::SHBoundingSphere() noexcept
|
||||||
|
: RelativeRadius { 1.0f }
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
|
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
|
||||||
|
: RelativeRadius { 1.0f }
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
|
@ -44,16 +46,18 @@ namespace SHADE
|
||||||
|
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
|
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -68,8 +72,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else if (this != &rhs)
|
else if (this != &rhs)
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -83,8 +88,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Radius = rhs.Radius;
|
Radius = rhs.Radius;
|
||||||
|
RelativeRadius = rhs.RelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -99,11 +105,16 @@ namespace SHADE
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHBoundingSphere::GetRadius() const noexcept
|
float SHBoundingSphere::GetWorldRadius() const noexcept
|
||||||
{
|
{
|
||||||
return Radius;
|
return Radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float SHBoundingSphere::GetRelativeRadius() const noexcept
|
||||||
|
{
|
||||||
|
return RelativeRadius;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -113,9 +124,14 @@ namespace SHADE
|
||||||
Center = center;
|
Center = center;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBoundingSphere::SetRadius(float radius) noexcept
|
void SHBoundingSphere::SetWorldRadius(float newWorldRadius) noexcept
|
||||||
{
|
{
|
||||||
Radius = radius;
|
Radius = newWorldRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoundingSphere::SetRelativeRadius(float newRelativeRadius) noexcept
|
||||||
|
{
|
||||||
|
RelativeRadius = newRelativeRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -48,15 +48,17 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] float GetRadius () const noexcept;
|
[[nodiscard]] float GetWorldRadius () const noexcept;
|
||||||
|
[[nodiscard]] float GetRelativeRadius () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetCenter (const SHVec3& center) noexcept;
|
void SetCenter (const SHVec3& center) noexcept;
|
||||||
void SetRadius (float radius) noexcept;
|
void SetWorldRadius (float newWorldRadius) noexcept;
|
||||||
|
void SetRelativeRadius (float newRelativeRadius) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -79,5 +81,12 @@ namespace SHADE
|
||||||
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
|
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
|
||||||
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
float RelativeRadius;
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
|
@ -231,12 +231,12 @@ namespace SHADE
|
||||||
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);
|
||||||
|
|
||||||
// Set the orientation
|
// Set the orientation
|
||||||
// Wrap rotations between -360 and 360 and convert to radians
|
// Wrap rotations between -720 and 720 and convert to radians
|
||||||
SHVec3 worldRotRad, localRotRad;
|
SHVec3 worldRotRad, localRotRad;
|
||||||
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
for (size_t i = 0; i < SHVec3::SIZE; ++i)
|
||||||
{
|
{
|
||||||
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
worldRotRad[i] = SHMath::Wrap(tf.worldRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI);
|
||||||
localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -SHMath::TWO_PI, SHMath::TWO_PI);
|
localRotRad[i] = SHMath::Wrap(tf.localRotation[i], -2.0f * SHMath::TWO_PI, 2.0f * SHMath::TWO_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
|
tf.world.orientation = SHQuaternion::FromEuler(worldRotRad);
|
||||||
|
|
|
@ -48,17 +48,22 @@ namespace SHADE
|
||||||
return orientation.ToEuler();
|
return orientation.ToEuler();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHColliderComponent::Colliders& SHColliderComponent::GetColliders() const noexcept
|
const SHVec3& SHColliderComponent::GetScale() const noexcept
|
||||||
{
|
{
|
||||||
return colliders;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider& SHColliderComponent::GetCollider(int index)
|
const SHColliderComponent::CollisionShapes& SHColliderComponent::GetCollisionShapes() const noexcept
|
||||||
{
|
{
|
||||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
return collisionShapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHCollisionShape& SHColliderComponent::GetCollisionShape(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
throw std::invalid_argument("Out-of-range access!");
|
||||||
|
|
||||||
return colliders[index];
|
return collisionShapes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -75,39 +80,74 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept
|
void SHColliderComponent::RecomputeCollisionShapes() noexcept
|
||||||
|
{
|
||||||
|
for (auto& collisionShape : collisionShapes)
|
||||||
|
{
|
||||||
|
switch (collisionShape.GetType())
|
||||||
|
{
|
||||||
|
case SHCollisionShape::Type::BOX:
|
||||||
|
{
|
||||||
|
auto* box = reinterpret_cast<SHBoundingBox*>(collisionShape.GetShape());
|
||||||
|
const SHVec3& RELATIVE_EXTENTS = box->GetRelativeExtents();
|
||||||
|
|
||||||
|
// Recompute world extents based on new scale and fixed relative extents
|
||||||
|
const SHVec3 WORLD_EXTENTS = RELATIVE_EXTENTS * (scale * 0.5f);
|
||||||
|
box->SetWorldExtents(WORLD_EXTENTS);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case SHCollisionShape::Type::SPHERE:
|
||||||
|
{
|
||||||
|
auto* sphere = reinterpret_cast<SHBoundingSphere*>(collisionShape.GetShape());
|
||||||
|
const float RELATIVE_RADIUS = sphere->GetRelativeRadius();
|
||||||
|
|
||||||
|
// Recompute world radius based on new scale and fixed radius
|
||||||
|
const float MAX_SCALE = SHMath::Max({ scale.x, scale.y, scale.z });
|
||||||
|
const float WORLD_RADIUS = RELATIVE_RADIUS * MAX_SCALE * 0.5f;
|
||||||
|
sphere->SetWorldRadius(WORLD_RADIUS);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset, const SHVec3& rotOffset) noexcept
|
||||||
{
|
{
|
||||||
if (!system)
|
if (!system)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
|
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
|
||||||
return nullptr;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto TYPE = SHCollider::Type::BOX;
|
static constexpr auto TYPE = SHCollisionShape::Type::BOX;
|
||||||
|
|
||||||
auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
|
auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE });
|
||||||
|
|
||||||
collider.entityID = GetEID();
|
collider.entityID = GetEID();
|
||||||
collider.SetPositionOffset(posOffset);
|
collider.SetPositionOffset(posOffset);
|
||||||
|
collider.SetRotationOffset(rotOffset);
|
||||||
collider.SetBoundingBox(halfExtents);
|
collider.SetBoundingBox(halfExtents);
|
||||||
|
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
system->AddCollisionShape(GetEID(), &collider);
|
system->AddCollisionShape(GetEID(), &collider);
|
||||||
|
|
||||||
return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
return static_cast<int>(collisionShapes.size()) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
|
int SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
|
||||||
{
|
{
|
||||||
if (!system)
|
if (!system)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
|
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
|
||||||
return nullptr;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto TYPE = SHCollider::Type::SPHERE;
|
static constexpr auto TYPE = SHCollisionShape::Type::SPHERE;
|
||||||
|
|
||||||
auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
|
auto& collider = collisionShapes.emplace_back(SHCollisionShape{ GetEID(), TYPE });
|
||||||
|
|
||||||
collider.entityID = GetEID();
|
collider.entityID = GetEID();
|
||||||
collider.SetPositionOffset(posOffset);
|
collider.SetPositionOffset(posOffset);
|
||||||
|
@ -116,17 +156,17 @@ namespace SHADE
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
system->AddCollisionShape(GetEID(), &collider);
|
system->AddCollisionShape(GetEID(), &collider);
|
||||||
|
|
||||||
return reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
return static_cast<int>(collisionShapes.size()) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHColliderComponent::RemoveCollider(int index)
|
void SHColliderComponent::RemoveCollider(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || static_cast<size_t>(index) >= colliders.size())
|
if (index < 0 || static_cast<size_t>(index) >= collisionShapes.size())
|
||||||
throw std::invalid_argument("Out-of-range access!");
|
throw std::invalid_argument("Out-of-range access!");
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
auto it = colliders.begin();
|
auto it = collisionShapes.begin();
|
||||||
for (; it != colliders.end(); ++it)
|
for (; it != collisionShapes.end(); ++it)
|
||||||
{
|
{
|
||||||
if (idx == index)
|
if (idx == index)
|
||||||
break;
|
break;
|
||||||
|
@ -134,7 +174,7 @@ namespace SHADE
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
it = colliders.erase(it);
|
it = collisionShapes.erase(it);
|
||||||
|
|
||||||
// Notify Physics System
|
// Notify Physics System
|
||||||
if (!system)
|
if (!system)
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Physics/SHCollider.h"
|
#include "Physics/SHCollisionShape.h"
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
using Colliders = std::vector<SHCollider>;
|
using CollisionShapes = std::vector<SHCollisionShape>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -67,26 +67,29 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] bool HasChanged () const noexcept;
|
[[nodiscard]] bool HasChanged () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
[[nodiscard]] const SHVec3& GetPosition () const noexcept;
|
||||||
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
[[nodiscard]] SHVec3 GetRotation () const noexcept;
|
||||||
|
[[nodiscard]] const SHVec3& GetScale () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const Colliders& GetColliders () const noexcept;
|
[[nodiscard]] const CollisionShapes& GetCollisionShapes() const noexcept;
|
||||||
[[nodiscard]] SHCollider& GetCollider (int index);
|
[[nodiscard]] SHCollisionShape& GetCollisionShape (int index);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void OnCreate () override;
|
void OnCreate () override;
|
||||||
void OnDestroy () override;
|
void OnDestroy () override;
|
||||||
|
|
||||||
void RemoveCollider (int index);
|
void RecomputeCollisionShapes () noexcept;
|
||||||
|
|
||||||
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
void RemoveCollider (int index);
|
||||||
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
|
||||||
|
int AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero) noexcept;
|
||||||
|
int AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -98,7 +101,8 @@ namespace SHADE
|
||||||
|
|
||||||
SHVec3 position;
|
SHVec3 position;
|
||||||
SHQuaternion orientation;
|
SHQuaternion orientation;
|
||||||
Colliders colliders;
|
SHVec3 scale;
|
||||||
|
CollisionShapes collisionShapes;
|
||||||
|
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
|
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHCollider.h"
|
#include "SHCollisionShape.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -25,7 +25,7 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
SHCollisionShape::SHCollisionShape(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
|
||||||
: type { colliderType }
|
: type { colliderType }
|
||||||
, entityID { eid }
|
, entityID { eid }
|
||||||
, isTrigger { false }
|
, isTrigger { false }
|
||||||
|
@ -49,7 +49,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(const SHCollider& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(const SHCollisionShape& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -61,7 +61,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::SHCollider(SHCollider&& rhs) noexcept
|
SHCollisionShape::SHCollisionShape(SHCollisionShape&& rhs) noexcept
|
||||||
: type { rhs.type}
|
: type { rhs.type}
|
||||||
, entityID { rhs.entityID }
|
, entityID { rhs.entityID }
|
||||||
, isTrigger { rhs.isTrigger }
|
, isTrigger { rhs.isTrigger }
|
||||||
|
@ -73,7 +73,7 @@ namespace SHADE
|
||||||
CopyShape(rhs.shape);
|
CopyShape(rhs.shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::~SHCollider() noexcept
|
SHCollisionShape::~SHCollisionShape() noexcept
|
||||||
{
|
{
|
||||||
shape = nullptr;
|
shape = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ namespace SHADE
|
||||||
/* Operator Overload Definitions */
|
/* Operator Overload Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(const SHCollisionShape& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,7 +100,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
|
SHCollisionShape& SHCollisionShape::operator=(SHCollisionShape&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = rhs.type;
|
type = rhs.type;
|
||||||
entityID = rhs.entityID;
|
entityID = rhs.entityID;
|
||||||
|
@ -119,52 +119,52 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHCollider::HasChanged() const noexcept
|
bool SHCollisionShape::HasChanged() const noexcept
|
||||||
{
|
{
|
||||||
return dirty;
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHCollider::IsTrigger() const noexcept
|
bool SHCollisionShape::IsTrigger() const noexcept
|
||||||
{
|
{
|
||||||
return isTrigger;
|
return isTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollider::Type SHCollider::GetType() const noexcept
|
SHCollisionShape::Type SHCollisionShape::GetType() const noexcept
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetFriction() const noexcept
|
float SHCollisionShape::GetFriction() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetFriction();
|
return material.GetFriction();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetBounciness() const noexcept
|
float SHCollisionShape::GetBounciness() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetBounciness();
|
return material.GetBounciness();
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHCollider::GetDensity() const noexcept
|
float SHCollisionShape::GetDensity() const noexcept
|
||||||
{
|
{
|
||||||
return material.GetDensity();
|
return material.GetDensity();
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept
|
const SHPhysicsMaterial& SHCollisionShape::GetMaterial() const noexcept
|
||||||
{
|
{
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetPositionOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetPositionOffset() const noexcept
|
||||||
{
|
{
|
||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHVec3& SHCollider::GetRotationOffset() const noexcept
|
const SHVec3& SHCollisionShape::GetRotationOffset() const noexcept
|
||||||
{
|
{
|
||||||
return rotationOffset;
|
return rotationOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHShape* SHCollider::GetShape() noexcept
|
SHShape* SHCollisionShape::GetShape() noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
return shape;
|
return shape;
|
||||||
|
@ -174,93 +174,80 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::SetBoundingBox(const SHVec3& halfExtents)
|
void SHCollisionShape::SetBoundingBox(const SHVec3& halfExtents)
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
// Set the half extents relative to transform
|
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
|
||||||
SHVec3 worldHalfExtents = halfExtents;
|
// Set the half extents relative to world scale
|
||||||
|
const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
if (type != Type::BOX)
|
||||||
if (transformComponent != nullptr)
|
|
||||||
worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f);
|
|
||||||
|
|
||||||
if (type == Type::BOX)
|
|
||||||
{
|
|
||||||
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
|
||||||
box->SetHalfExtents(worldHalfExtents);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::BOX;
|
||||||
|
|
||||||
delete shape;
|
delete shape;
|
||||||
shape = new SHBoundingBox{ positionOffset, worldHalfExtents };
|
shape = new SHBoundingBox{ positionOffset, WORLD_EXTENTS };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
|
||||||
|
box->SetWorldExtents(WORLD_EXTENTS);
|
||||||
|
box->SetRelativeExtents(halfExtents);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBoundingSphere(float radius)
|
void SHCollisionShape::SetBoundingSphere(float radius)
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
// Set the radius relative to transform
|
const auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
|
||||||
float worldRadius = radius;
|
// Set the radius relative to world scale
|
||||||
|
const SHVec3 WORLD_SCALE = colliderComponent->GetScale();
|
||||||
|
const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z });
|
||||||
|
const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f;
|
||||||
|
|
||||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
if (type != Type::SPHERE)
|
||||||
if (transformComponent != nullptr)
|
|
||||||
{
|
|
||||||
const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
|
||||||
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
|
||||||
|
|
||||||
worldRadius *= MAX_SCALE * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type::SPHERE)
|
|
||||||
{
|
|
||||||
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
|
|
||||||
sphere->SetRadius(worldRadius);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
type = Type::SPHERE;
|
type = Type::SPHERE;
|
||||||
|
|
||||||
delete shape;
|
delete shape;
|
||||||
shape = new SHBoundingSphere{ positionOffset, worldRadius };
|
shape = new SHBoundingSphere{ positionOffset, WORLD_RADIUS };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
|
||||||
|
sphere->SetWorldRadius(WORLD_RADIUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetIsTrigger(bool trigger) noexcept
|
void SHCollisionShape::SetIsTrigger(bool trigger) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
isTrigger = trigger;
|
isTrigger = trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetFriction(float friction) noexcept
|
void SHCollisionShape::SetFriction(float friction) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetFriction(friction);
|
material.SetFriction(friction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetBounciness(float bounciness) noexcept
|
void SHCollisionShape::SetBounciness(float bounciness) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetBounciness(bounciness);
|
material.SetBounciness(bounciness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetDensity(float density) noexcept
|
void SHCollisionShape::SetDensity(float density) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material.SetDensity(density);
|
material.SetDensity(density);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
material = newMaterial;
|
material = newMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
|
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
positionOffset = posOffset;
|
positionOffset = posOffset;
|
||||||
|
@ -281,7 +268,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
void SHCollisionShape::SetRotationOffset(const SHVec3& rotOffset) noexcept
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
rotationOffset = rotOffset;
|
rotationOffset = rotOffset;
|
||||||
|
@ -291,7 +278,7 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHCollider::CopyShape(const SHShape* rhs)
|
void SHCollisionShape::CopyShape(const SHShape* rhs)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -299,14 +286,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
|
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
|
||||||
|
|
||||||
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() };
|
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetWorldExtents() };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::SPHERE:
|
case Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
|
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
|
||||||
|
|
||||||
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() };
|
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetWorldRadius() };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -320,14 +307,14 @@ RTTR_REGISTRATION
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
registration::enumeration<SHCollider::Type>("Collider Type")
|
registration::enumeration<SHCollisionShape::Type>("Collider Type")
|
||||||
(
|
(
|
||||||
value("Box", SHCollider::Type::BOX),
|
value("Box", SHCollisionShape::Type::BOX),
|
||||||
value("Sphere", SHCollider::Type::SPHERE)
|
value("Sphere", SHCollisionShape::Type::SPHERE)
|
||||||
// TODO(Diren): Add More Shapes
|
// TODO(Diren): Add More Shapes
|
||||||
);
|
);
|
||||||
|
|
||||||
registration::class_<SHCollider>("Collider")
|
registration::class_<SHCollisionShape>("Collider")
|
||||||
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset)
|
.property("Position Offset", &SHCollisionShape::GetPositionOffset, &SHCollisionShape::SetPositionOffset)
|
||||||
.property("Rotation Offset", &SHCollider::GetRotationOffset, &SHCollider::SetRotationOffset) (metadata(META::angleInRad, true));
|
.property("Rotation Offset", &SHCollisionShape::GetRotationOffset, &SHCollisionShape::SetRotationOffset) (metadata(META::angleInRad, true));
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHCollider
|
class SH_API SHCollisionShape
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -51,18 +51,18 @@ namespace SHADE
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
|
SHCollisionShape (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
|
||||||
|
|
||||||
SHCollider (const SHCollider& rhs) noexcept;
|
SHCollisionShape (const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider (SHCollider&& rhs) noexcept;
|
SHCollisionShape (SHCollisionShape&& rhs) noexcept;
|
||||||
~SHCollider () noexcept;
|
~SHCollisionShape () noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHCollider& operator=(const SHCollider& rhs) noexcept;
|
SHCollisionShape& operator=(const SHCollisionShape& rhs) noexcept;
|
||||||
SHCollider& operator=(SHCollider&& rhs) noexcept;
|
SHCollisionShape& operator=(SHCollisionShape&& rhs) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
|
@ -128,24 +128,24 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int SHPhysicsObject::AddCollider(SHCollider* collider)
|
int SHPhysicsObject::AddCollider(SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
const rp3d::Transform OFFSETS{ collider->GetPositionOffset(), collider->GetRotationOffset() };
|
||||||
|
|
||||||
switch (collider->GetType())
|
switch (collider->GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
|
||||||
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
|
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetWorldExtents());
|
||||||
|
|
||||||
rp3dBody->addCollider(newBox, OFFSETS);
|
rp3dBody->addCollider(newBox, OFFSETS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
|
||||||
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
|
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetWorldRadius());
|
||||||
|
|
||||||
rp3dBody->addCollider(newSphere, OFFSETS);
|
rp3dBody->addCollider(newSphere, OFFSETS);
|
||||||
break;
|
break;
|
||||||
|
@ -173,7 +173,7 @@ namespace SHADE
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto& collider : c->colliders)
|
for (auto& collider : c->collisionShapes)
|
||||||
{
|
{
|
||||||
if (!collider.dirty)
|
if (!collider.dirty)
|
||||||
continue;
|
continue;
|
||||||
|
@ -188,21 +188,21 @@ namespace SHADE
|
||||||
|
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||||
|
|
||||||
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
|
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
|
||||||
rp3dBoxShape->setHalfExtents(box->GetHalfExtents());
|
rp3dBoxShape->setHalfExtents(box->GetWorldExtents());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
||||||
|
|
||||||
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
|
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
|
||||||
rp3dSphereShape->setRadius(sphere->GetRadius());
|
rp3dSphereShape->setRadius(sphere->GetWorldRadius());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int AddCollider (SHCollider* collider);
|
int AddCollider (SHCollisionShape* collider);
|
||||||
void RemoveCollider (int index);
|
void RemoveCollider (int index);
|
||||||
|
|
||||||
void SyncColliders (SHColliderComponent* c) const noexcept;
|
void SyncColliders (SHColliderComponent* c) const noexcept;
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace SHADE
|
||||||
factory.destroyPhysicsWorld(world);
|
factory.destroyPhysicsWorld(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
|
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollisionShape* collider)
|
||||||
{
|
{
|
||||||
auto* physicsObject = GetPhysicsObject(entityID);
|
auto* physicsObject = GetPhysicsObject(entityID);
|
||||||
|
|
||||||
|
@ -395,6 +395,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
const auto WORLD_ROT = transformComponent->GetWorldOrientation();
|
const auto WORLD_ROT = transformComponent->GetWorldOrientation();
|
||||||
|
const auto WORLD_SCL = transformComponent->GetWorldScale();
|
||||||
|
|
||||||
physicsObject.SetPosition(WORLD_POS);
|
physicsObject.SetPosition(WORLD_POS);
|
||||||
physicsObject.SetOrientation(WORLD_ROT);
|
physicsObject.SetOrientation(WORLD_ROT);
|
||||||
|
@ -409,8 +410,11 @@ namespace SHADE
|
||||||
|
|
||||||
if (colliderComponent)
|
if (colliderComponent)
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
colliderComponent->position = WORLD_POS;
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
colliderComponent->scale = WORLD_SCL;
|
||||||
|
|
||||||
|
colliderComponent->RecomputeCollisionShapes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,7 +609,6 @@ namespace SHADE
|
||||||
|
|
||||||
if (rigidBodyComponent != nullptr)
|
if (rigidBodyComponent != nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -658,8 +661,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
||||||
{
|
{
|
||||||
const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0];
|
const bool ENTITY_MATCH = (e.ids[0] == collisionEvent.ids[0] && e.ids[1] == collisionEvent.ids[1])
|
||||||
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1];
|
|| (e.ids[0] == collisionEvent.ids[1] && e.ids[1] == collisionEvent.ids[0]);
|
||||||
|
const bool COLLIDERS_MATCH = (e.ids[2] == collisionEvent.ids[2] && e.ids[3] == collisionEvent.ids[3])
|
||||||
|
|| (e.ids[2] == collisionEvent.ids[3] && e.ids[3] == collisionEvent.ids[2]);
|
||||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -734,7 +739,7 @@ namespace SHADE
|
||||||
// Add collision shapes back into the body
|
// Add collision shapes back into the body
|
||||||
if (colliderComponent != nullptr)
|
if (colliderComponent != nullptr)
|
||||||
{
|
{
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,8 +748,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
|
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
|
||||||
|
|
||||||
colliderComponent->position = transformComponent->GetWorldPosition();
|
colliderComponent->position = transformComponent->GetWorldPosition();
|
||||||
colliderComponent->orientation = transformComponent->GetWorldOrientation();
|
colliderComponent->orientation = transformComponent->GetWorldOrientation();
|
||||||
|
colliderComponent->scale = transformComponent->GetWorldScale();
|
||||||
|
|
||||||
if (physicsObject->rp3dBody == nullptr)
|
if (physicsObject->rp3dBody == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -755,7 +761,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Collision Shapes
|
// Add Collision Shapes
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -800,7 +806,7 @@ namespace SHADE
|
||||||
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
|
||||||
);
|
);
|
||||||
|
|
||||||
for (auto& collider : colliderComponent->colliders)
|
for (auto& collider : colliderComponent->collisionShapes)
|
||||||
physicsObject->AddCollider(&collider);
|
physicsObject->AddCollider(&collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace SHADE
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () override;
|
void Exit () override;
|
||||||
|
|
||||||
void AddCollisionShape (EntityID entityID, SHCollider* collider);
|
void AddCollisionShape (EntityID entityID, SHCollisionShape* collider);
|
||||||
void RemoveCollisionShape (EntityID entityID, int index);
|
void RemoveCollisionShape (EntityID entityID, int index);
|
||||||
|
|
||||||
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
void onContact (const rp3d::CollisionCallback::CallbackData& callbackData) override;
|
||||||
|
@ -183,24 +183,24 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||||
|
|
||||||
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||||
void SyncTransforms () noexcept;
|
void SyncTransforms () noexcept;
|
||||||
|
|
||||||
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||||
void ClearInvalidCollisions () noexcept;
|
void ClearInvalidCollisions () noexcept;
|
||||||
|
|
||||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||||
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
SHEventHandle ResetWorld (SHEventPtr editorStopEvent);
|
||||||
|
|
||||||
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||||
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||||
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
||||||
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,14 @@ namespace SHADE
|
||||||
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
return SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ids[ENTITY_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderA() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderA() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollider(ids[COLLIDER_A]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_A])->GetCollisionShape(ids[COLLIDER_A]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHCollider* SHCollisionEvent::GetColliderB() const noexcept
|
const SHCollisionShape* SHCollisionEvent::GetColliderB() const noexcept
|
||||||
{
|
{
|
||||||
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollider(ids[COLLIDER_B]);
|
return &SHComponentManager::GetComponent<SHColliderComponent>(ids[ENTITY_B])->GetCollisionShape(ids[COLLIDER_B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
SHCollisionEvent::State SHCollisionEvent::GetCollisionState() const noexcept
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
struct SHPhysicsColliderAddedEvent
|
struct SHPhysicsColliderAddedEvent
|
||||||
{
|
{
|
||||||
EntityID entityID;
|
EntityID entityID;
|
||||||
SHCollider::Type colliderType;
|
SHCollisionShape::Type colliderType;
|
||||||
int colliderIndex;
|
int colliderIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ namespace SHADE
|
||||||
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
[[nodiscard]] EntityID GetEntityB () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyA () const noexcept;
|
||||||
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
[[nodiscard]] const SHRigidBodyComponent* GetRigidBodyB () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderA () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderA () const noexcept;
|
||||||
[[nodiscard]] const SHCollider* GetColliderB () const noexcept;
|
[[nodiscard]] const SHCollisionShape* GetColliderB () const noexcept;
|
||||||
[[nodiscard]] State GetCollisionState () const noexcept;
|
[[nodiscard]] State GetCollisionState () const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHSceneGraph.cpp
|
* \file SHSceneGraph.cpp
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Implementation for a Scene Graph & Scene Nodes.
|
* \brief Implementation for a Scene Graph.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -16,8 +16,6 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Tools/SHLogger.h"
|
|
||||||
#include "Tools/SHException.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -25,56 +23,6 @@ namespace SHADE
|
||||||
/* Constructors & Destructor Definitions */
|
/* Constructors & Destructor Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
|
|
||||||
: active { true }
|
|
||||||
, entityID { eid }
|
|
||||||
, parent { parent }
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
|
|
||||||
: active { rhs.active }
|
|
||||||
, entityID { rhs.entityID }
|
|
||||||
, parent { rhs.parent }
|
|
||||||
{
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
|
|
||||||
: active { rhs.active }
|
|
||||||
, entityID { rhs.entityID }
|
|
||||||
, parent { rhs.parent }
|
|
||||||
{
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept
|
|
||||||
{
|
|
||||||
if (this == &rhs)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
active = rhs.active;
|
|
||||||
entityID = rhs.entityID;
|
|
||||||
parent = rhs.parent;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
|
|
||||||
{
|
|
||||||
active = rhs.active;
|
|
||||||
entityID = rhs.entityID;
|
|
||||||
parent = rhs.parent;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneGraph::SHSceneGraph() noexcept
|
SHSceneGraph::SHSceneGraph() noexcept
|
||||||
: root { nullptr }
|
: root { nullptr }
|
||||||
{
|
{
|
||||||
|
@ -110,56 +58,6 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool SHSceneNode::IsActive() const noexcept
|
|
||||||
{
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityID SHSceneNode::GetEntityID() const noexcept
|
|
||||||
{
|
|
||||||
return entityID;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
|
||||||
{
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
|
||||||
{
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error handling
|
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (children.empty())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Entity {} has no children!", entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
// Find child
|
|
||||||
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
|
||||||
|
|
||||||
const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH);
|
|
||||||
if (CHILD_ITER == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *CHILD_ITER;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
||||||
{
|
{
|
||||||
if (root != nullptr)
|
if (root != nullptr)
|
||||||
|
@ -313,41 +211,7 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* newParent) noexcept
|
||||||
{
|
|
||||||
if (parentNode == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
parent->RemoveChild(this);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle self assignment
|
|
||||||
if (parent && parentNode->entityID == parent->entityID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (parent)
|
|
||||||
parent->RemoveChild(this);
|
|
||||||
|
|
||||||
parent = parentNode;
|
|
||||||
// Update parent's children
|
|
||||||
parent->AddChild(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneNode::SetActive(bool newActiveState) noexcept
|
|
||||||
{
|
|
||||||
active = newActiveState;
|
|
||||||
|
|
||||||
for (auto* child : children)
|
|
||||||
{
|
|
||||||
SetActive(newActiveState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Error Handling
|
// Error Handling
|
||||||
|
@ -369,30 +233,31 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
.node = NODE_ITER->second
|
.node = NODE_ITER->second
|
||||||
, .oldParent = NODE_ITER->second->GetParent()
|
, .oldParent = NODE_ITER->second->GetParent()
|
||||||
, .newParent = parent ? parent : root
|
, .newParent = newParent ? newParent : root
|
||||||
};
|
};
|
||||||
|
|
||||||
if (parent == nullptr)
|
if (newParent == nullptr)
|
||||||
parent = root;
|
newParent = root;
|
||||||
|
|
||||||
NODE_ITER->second->SetParent(parent);
|
ChangeParent(NODE_ITER->second, newParent);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, EntityID newParent) noexcept
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Error Handling
|
// Error Handling
|
||||||
|
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SHEntityManager::IsValidEID(parent))
|
if (!SHEntityManager::IsValidEID(newParent))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID)
|
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,10 +268,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PARENT_ITER = entityNodeMap.find(parent);
|
auto PARENT_ITER = entityNodeMap.find(newParent);
|
||||||
if (PARENT_ITER == entityNodeMap.end())
|
if (PARENT_ITER == entityNodeMap.end())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
@ -419,7 +284,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
currentNode->SetParent(PARENT_ITER->second);
|
ChangeParent(currentNode, PARENT_ITER->second);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||||
}
|
}
|
||||||
|
@ -428,84 +293,6 @@ namespace SHADE
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (newChild == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
if (newChild->parent)
|
|
||||||
newChild->parent->RemoveChild(newChild);
|
|
||||||
|
|
||||||
newChild->parent = this;
|
|
||||||
children.emplace_back(newChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Entity {} is invalid!", childID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node)
|
|
||||||
{
|
|
||||||
return node->GetEntityID() == childID;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (childIter == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*childIter)->parent = nullptr;
|
|
||||||
childIter = children.erase(childIter);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
|
|
||||||
{
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Error Handling
|
|
||||||
if (childToRemove == nullptr)
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
auto childIter = std::find(children.begin(), children.end(), childToRemove);
|
|
||||||
if (childIter == children.end())
|
|
||||||
{
|
|
||||||
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childToRemove->entityID, entityID)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
childIter = children.erase(childIter);
|
|
||||||
childToRemove->parent = nullptr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSceneNode::RemoveAllChildren() noexcept
|
|
||||||
{
|
|
||||||
for (const auto child : children)
|
|
||||||
child->parent = nullptr;
|
|
||||||
|
|
||||||
children.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
@ -528,13 +315,12 @@ namespace SHADE
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
{
|
{
|
||||||
// Specific handling for root to avoid a warning when removing a non-existent child
|
// Specific handling for root to avoid a warning when removing a non-existent child
|
||||||
parent = root;
|
|
||||||
newNode->parent = root;
|
newNode->parent = root;
|
||||||
root->children.emplace_back(newNode);
|
root->children.emplace_back(newNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newNode->SetParent(parent);
|
ChangeParent(newNode, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
@ -542,6 +328,8 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
|
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -554,12 +342,12 @@ namespace SHADE
|
||||||
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
|
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
SHSceneNode* parent = currentNode->GetParent();
|
if (currentNode->parent != nullptr)
|
||||||
if (parent != nullptr)
|
RemoveChild(currentNode->parent, currentNode);
|
||||||
parent->RemoveChild(currentNode);
|
|
||||||
|
|
||||||
ReleaseNode(currentNode);
|
ReleaseNode(currentNode);
|
||||||
return true;
|
return true;
|
||||||
|
@ -568,9 +356,8 @@ namespace SHADE
|
||||||
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
|
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
|
||||||
{
|
{
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
SHSceneNode* parent = nodeToRemove->GetParent();
|
if (nodeToRemove->parent != nullptr)
|
||||||
if (parent != nullptr)
|
RemoveChild(nodeToRemove->parent, nodeToRemove);
|
||||||
parent->RemoveChild(nodeToRemove);
|
|
||||||
|
|
||||||
ReleaseNode(nodeToRemove);
|
ReleaseNode(nodeToRemove);
|
||||||
return true;
|
return true;
|
||||||
|
@ -582,6 +369,91 @@ namespace SHADE
|
||||||
ReleaseNode(node);
|
ReleaseNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||||
|
if (NODE_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
// Handle self-checks
|
||||||
|
if (NODE_ITER->second == targetNode)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} cannot be a child of itself!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for a matching target until the root
|
||||||
|
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
|
||||||
|
while (CURRENT_TARGET != root)
|
||||||
|
{
|
||||||
|
if (CURRENT_TARGET == targetNode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CURRENT_TARGET = CURRENT_TARGET->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHSceneGraph::IsChildOf(EntityID entityID, EntityID targetID) noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SHEntityManager::IsValidEID(targetID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} is invalid!", targetID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NODE_ITER = entityNodeMap.find(entityID);
|
||||||
|
if (NODE_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto TARGET_ITER = entityNodeMap.find(targetID);
|
||||||
|
if (TARGET_ITER == entityNodeMap.end())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
|
||||||
|
while (CURRENT_TARGET != root)
|
||||||
|
{
|
||||||
|
if (CURRENT_TARGET == TARGET_ITER->second)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CURRENT_TARGET = CURRENT_TARGET->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
||||||
{
|
{
|
||||||
TraverseAndInvokeFunction(root, function);
|
TraverseAndInvokeFunction(root, function);
|
||||||
|
@ -594,11 +466,6 @@ namespace SHADE
|
||||||
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
||||||
{
|
{
|
||||||
SHSceneNode* newNode = new SHSceneNode{entityID};
|
SHSceneNode* newNode = new SHSceneNode{entityID};
|
||||||
|
|
||||||
//#ifdef _DEBUG
|
|
||||||
// SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
entityNodeMap.emplace(entityID, newNode);
|
entityNodeMap.emplace(entityID, newNode);
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
@ -608,19 +475,81 @@ namespace SHADE
|
||||||
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
|
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
|
||||||
|
|
||||||
// Remove parent's reference to this node if there is a parent
|
// Remove parent's reference to this node if there is a parent
|
||||||
if (node->GetParent() != nullptr)
|
if (node->parent != nullptr)
|
||||||
node->GetParent()->RemoveChild(node);
|
RemoveChild(node->parent, node);
|
||||||
|
|
||||||
// Remove child's references to this node. Children end up as floating nodes.
|
// Remove child's references to this node. Children end up as floating nodes.
|
||||||
for (auto* child : node->GetChildren())
|
for (auto* child : node->GetChildren())
|
||||||
{
|
{
|
||||||
child->SetParent(nullptr);
|
ChangeParent(child, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityNodeMap.erase(node->GetEntityID());
|
entityNodeMap.erase(node->GetEntityID());
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent)
|
||||||
|
{
|
||||||
|
// Handle self assignment
|
||||||
|
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove child
|
||||||
|
if (node->parent)
|
||||||
|
RemoveChild(node->parent, node);
|
||||||
|
|
||||||
|
if (newParent == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Removing Entity {}'s parent", node->entityID)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->parent = newParent;
|
||||||
|
// Update parent's children
|
||||||
|
AddChild(newParent, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::AddChild(SHSceneNode* node, SHSceneNode* newChild)
|
||||||
|
{
|
||||||
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
|
SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
|
||||||
|
|
||||||
|
if (newChild->parent)
|
||||||
|
RemoveChild(newChild->parent, newChild);
|
||||||
|
|
||||||
|
newChild->parent = node;
|
||||||
|
node->children.emplace_back(newChild);
|
||||||
|
|
||||||
|
const SHSceneGraphAddChildEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.parent = node
|
||||||
|
, .childAdded = newChild
|
||||||
|
};
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphAddChildEvent>(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove)
|
||||||
|
{
|
||||||
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
|
SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!")
|
||||||
|
|
||||||
|
auto childIter = std::find(node->children.begin(), node->children.end(), childToRemove);
|
||||||
|
if (childIter == node->children.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
childIter = node->children.erase(childIter);
|
||||||
|
childToRemove->parent = nullptr;
|
||||||
|
|
||||||
|
const SHSceneGraphRemoveChildEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.parent = node
|
||||||
|
, .childRemoved = childToRemove
|
||||||
|
};
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneGraphRemoveChildEvent>(EVENT_DATA, SH_SCENEGRAPH_REMOVE_CHILD_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
||||||
{
|
{
|
||||||
for (auto* child : node->children)
|
for (auto* child : node->children)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHSceneGraph.h
|
* \file SHSceneGraph.h
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Interface for a Scene Graph & Scene Nodes.
|
* \brief Interface for a Scene Graph.
|
||||||
*
|
*
|
||||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
* disclosure of this file or its contents without the prior written consent
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
@ -15,81 +15,15 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Entity/SHEntity.h"
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "SHSceneNode.h"
|
||||||
|
#include "SHSceneGraphEvents.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Forward Declarations */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SHSceneGraph;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class SH_API SHSceneNode
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Friends */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
friend class SHSceneGraph;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
~SHSceneNode () = default;
|
|
||||||
|
|
||||||
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
|
|
||||||
SHSceneNode (const SHSceneNode& rhs) noexcept;
|
|
||||||
SHSceneNode (SHSceneNode&& rhs) noexcept;
|
|
||||||
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
|
|
||||||
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Getter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsActive () const noexcept;
|
|
||||||
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
|
||||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
|
||||||
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Setter Functions */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void SetParent (SHSceneNode* parentNode) noexcept;
|
|
||||||
void SetActive (bool newActiveState) noexcept;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void AddChild (SHSceneNode* newChild) noexcept;
|
|
||||||
|
|
||||||
bool RemoveChild (EntityID childID) noexcept;
|
|
||||||
bool RemoveChild (SHSceneNode* childToRemove) noexcept;
|
|
||||||
|
|
||||||
void RemoveAllChildren () noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Data Members */
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
bool active;
|
|
||||||
EntityID entityID;
|
|
||||||
SHSceneNode* parent;
|
|
||||||
std::vector<SHSceneNode*> children;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SH_API SHSceneGraph
|
class SH_API SHSceneGraph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -130,19 +64,22 @@ namespace SHADE
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept;
|
void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
|
||||||
void SetParent (EntityID entityID, EntityID parent) const noexcept;
|
void SetParent (EntityID entityID, EntityID newParent) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
||||||
bool RemoveNode (EntityID entityID) noexcept;
|
bool RemoveNode (EntityID entityID) noexcept;
|
||||||
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
||||||
void Reset () noexcept;
|
void Reset () noexcept;
|
||||||
|
|
||||||
void Traverse (const UnaryFunction& function) const;
|
bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept;
|
||||||
|
bool IsChildOf (EntityID entityID, EntityID targetID) noexcept;
|
||||||
|
|
||||||
|
void Traverse (const UnaryFunction& function) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -156,20 +93,14 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode* AllocateNode (EntityID entityID);
|
SHSceneNode* AllocateNode (EntityID entityID);
|
||||||
void ReleaseNode (SHSceneNode* node) noexcept;
|
void ReleaseNode (SHSceneNode* node) noexcept;
|
||||||
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
void ChangeParent (SHSceneNode* node, SHSceneNode* newParent);
|
||||||
/* Event Data Definitions */
|
void AddChild (SHSceneNode* node, SHSceneNode* newChild);
|
||||||
/*-----------------------------------------------------------------------------------*/
|
void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove);
|
||||||
|
|
||||||
struct SHSceneGraphChangeParentEvent
|
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
||||||
{
|
|
||||||
SHSceneNode* node;
|
|
||||||
SHSceneNode* oldParent;
|
|
||||||
SHSceneNode* newParent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -0,0 +1,41 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneGraphEvents.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for Scene Graph Events.
|
||||||
|
*
|
||||||
|
* \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 "SHSceneNode.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Event Data Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct SHSceneGraphChangeParentEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* node;
|
||||||
|
SHSceneNode* oldParent;
|
||||||
|
SHSceneNode* newParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHSceneGraphAddChildEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* parent;
|
||||||
|
SHSceneNode* childAdded;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHSceneGraphRemoveChildEvent
|
||||||
|
{
|
||||||
|
SHSceneNode* parent;
|
||||||
|
SHSceneNode* childRemoved;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,143 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneNode.c[[
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for a Scene Node.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||||
|
* disclosure of this file or its contents without the prior written consent
|
||||||
|
* of DigiPen Institute of Technology is prohibited.
|
||||||
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#include <SHpch.h>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHSceneNode.h"
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
|
||||||
|
: active { true }
|
||||||
|
, entityID { eid }
|
||||||
|
, parent { parent }
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
|
||||||
|
: active { rhs.active }
|
||||||
|
, entityID { rhs.entityID }
|
||||||
|
, parent { rhs.parent }
|
||||||
|
{
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
|
||||||
|
: active { rhs.active }
|
||||||
|
, entityID { rhs.entityID }
|
||||||
|
, parent { rhs.parent }
|
||||||
|
{
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
active = rhs.active;
|
||||||
|
entityID = rhs.entityID;
|
||||||
|
parent = rhs.parent;
|
||||||
|
|
||||||
|
children.clear();
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
|
||||||
|
{
|
||||||
|
active = rhs.active;
|
||||||
|
entityID = rhs.entityID;
|
||||||
|
parent = rhs.parent;
|
||||||
|
|
||||||
|
children.clear();
|
||||||
|
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHSceneNode::IsActive() const noexcept
|
||||||
|
{
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityID SHSceneNode::GetEntityID() const noexcept
|
||||||
|
{
|
||||||
|
return entityID;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
||||||
|
{
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
||||||
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
|
if (!SHEntityManager::IsValidEID(childID))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.empty())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} has no children!", entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
// Find child
|
||||||
|
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
||||||
|
|
||||||
|
const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH);
|
||||||
|
if (CHILD_ITER == children.end())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *CHILD_ITER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHSceneNode::SetActive(bool newActiveState) noexcept
|
||||||
|
{
|
||||||
|
active = newActiveState;
|
||||||
|
|
||||||
|
for (auto* child : children)
|
||||||
|
{
|
||||||
|
SetActive(newActiveState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,82 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHSceneNode.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a Scene Node.
|
||||||
|
*
|
||||||
|
* \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 <vector>
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "SHSceneGraph.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class SHSceneGraph;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class SH_API SHSceneNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Friends */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
friend class SHSceneGraph;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
~SHSceneNode () = default;
|
||||||
|
|
||||||
|
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
|
||||||
|
SHSceneNode (const SHSceneNode& rhs) noexcept;
|
||||||
|
SHSceneNode (SHSceneNode&& rhs) noexcept;
|
||||||
|
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
|
||||||
|
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsActive () const noexcept;
|
||||||
|
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
||||||
|
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
||||||
|
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetActive (bool newActiveState) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
EntityID entityID;
|
||||||
|
SHSceneNode* parent;
|
||||||
|
std::vector<SHSceneNode*> children;
|
||||||
|
};
|
||||||
|
} // namespace SHADE
|
||||||
|
|
|
@ -26,13 +26,15 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
#include "Physics/SHPhysicsSystem.h"
|
#include "Physics/SHPhysicsSystem.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Static Definitions */
|
/* Static Definitions */
|
||||||
/*----------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------*/
|
||||||
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
||||||
const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder";
|
const std::string SHScriptEngine::CSPROJ_DIR = std::string(ASSET_ROOT) + "/Scripts";
|
||||||
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
|
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -262,18 +264,18 @@ namespace SHADE
|
||||||
</ItemGroup>\n\
|
</ItemGroup>\n\
|
||||||
<ItemGroup>\n\
|
<ItemGroup>\n\
|
||||||
<Reference Include=\"SHADE_Managed\">\n\
|
<Reference Include=\"SHADE_Managed\">\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
|
||||||
</Reference>\n\
|
</Reference>\n\
|
||||||
<Reference Include=\"SHADE_CSharp\">\n\
|
<Reference Include=\"SHADE_CSharp\">\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\
|
||||||
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\
|
<HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\
|
||||||
</Reference>\n\
|
</Reference>\n\
|
||||||
</ItemGroup>\n\
|
</ItemGroup>\n\
|
||||||
</Project>";
|
</Project>";
|
||||||
|
|
||||||
// Attempt to create the file
|
// Attempt to create the file
|
||||||
std::ofstream file(path);
|
std::ofstream file(path, std::ios::out | std::ios::trunc);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
throw std::runtime_error("Unable to create CsProj file!");
|
throw std::runtime_error("Unable to create CsProj file!");
|
||||||
|
|
||||||
|
@ -316,6 +318,20 @@ namespace SHADE
|
||||||
return eventData->handle;
|
return eventData->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHScriptEngine::onSceneNodeChildrenAdded(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphAddChildEvent>*>(eventPtr.get());
|
||||||
|
csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID());
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHScriptEngine::onSceneNodeChildrenRemoved(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphRemoveChildEvent>*>(eventPtr.get());
|
||||||
|
csSceneNodeChildrenChanged(eventData->data->parent->GetEntityID());
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -380,6 +396,12 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
"ExecuteLateUpdate"
|
"ExecuteLateUpdate"
|
||||||
);
|
);
|
||||||
|
csScriptsExecuteDrawGizmos = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteOnDrawGizmos"
|
||||||
|
);
|
||||||
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
csScriptsExecutePhysicsEvents = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
(
|
(
|
||||||
DEFAULT_CSHARP_LIB_NAME,
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
@ -434,6 +456,12 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".Collider",
|
DEFAULT_CSHARP_NAMESPACE + ".Collider",
|
||||||
"OnCollisionShapeRemoved"
|
"OnCollisionShapeRemoved"
|
||||||
);
|
);
|
||||||
|
csSceneNodeChildrenChanged = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ChildListCache",
|
||||||
|
"OnChildrenChanged"
|
||||||
|
);
|
||||||
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
||||||
(
|
(
|
||||||
DEFAULT_CSHARP_LIB_NAME,
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
@ -456,6 +484,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHScriptEngine::registerEvents()
|
void SHScriptEngine::registerEvents()
|
||||||
{
|
{
|
||||||
|
/* Entity */
|
||||||
// Register for entity destroyed event
|
// Register for entity destroyed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedEventReceiver
|
||||||
{
|
{
|
||||||
|
@ -463,26 +492,39 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
|
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
|
||||||
|
|
||||||
|
/* Colliders */
|
||||||
// Register for collider added event
|
// Register for collider added event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderAdded)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderAdded)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addedColliderEventReceiver));
|
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_ADDED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addedColliderEventReceiver));
|
||||||
|
|
||||||
// Register for collider removed event
|
// Register for collider removed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderRemoved)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderRemoved)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderEventReceiver));
|
SHEventManager::SubscribeTo(SH_PHYSICS_COLLIDER_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderEventReceiver));
|
||||||
|
|
||||||
// Register for collider component removed event
|
// Register for collider component removed event
|
||||||
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderComponentEventReceiver
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedColliderComponentEventReceiver
|
||||||
{
|
{
|
||||||
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderComponentRemoved)
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onColliderComponentRemoved)
|
||||||
};
|
};
|
||||||
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver));
|
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver));
|
||||||
|
|
||||||
|
/* SceneGraph */
|
||||||
|
// Register for SceneNode child added event
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addChildEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneNodeChildrenAdded)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_ADD_CHILD_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(addChildEventReceiver));
|
||||||
|
// Register for SceneNode child removed event
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removeChildEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneNodeChildrenRemoved)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_SCENEGRAPH_REMOVE_CHILD_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removeChildEventReceiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
||||||
|
|
|
@ -55,6 +55,12 @@ namespace SHADE
|
||||||
LateUpdateRoutine();
|
LateUpdateRoutine();
|
||||||
void Execute(double dt) noexcept override final;
|
void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
|
class SH_API GizmosDrawRoutine final : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GizmosDrawRoutine();
|
||||||
|
void Execute(double dt) noexcept override final;
|
||||||
|
};
|
||||||
class SH_API FrameCleanUpRoutine final : public SHSystemRoutine
|
class SH_API FrameCleanUpRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -250,6 +256,7 @@ namespace SHADE
|
||||||
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteFixedUpdate = nullptr;
|
||||||
CsFuncPtr csScriptsExecuteUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteUpdate = nullptr;
|
||||||
CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
|
CsFuncPtr csScriptsExecuteLateUpdate = nullptr;
|
||||||
|
CsFuncPtr csScriptsExecuteDrawGizmos = nullptr;
|
||||||
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
|
CsFuncPtr csScriptsExecutePhysicsEvents = nullptr;
|
||||||
CsFuncPtr csScriptsFrameCleanUp = nullptr;
|
CsFuncPtr csScriptsFrameCleanUp = nullptr;
|
||||||
CsScriptManipFuncPtr csScriptsAdd = nullptr;
|
CsScriptManipFuncPtr csScriptsAdd = nullptr;
|
||||||
|
@ -260,6 +267,7 @@ namespace SHADE
|
||||||
// - Events
|
// - Events
|
||||||
CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
|
CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
|
||||||
CsEventRelayFuncPtr csColliderOnRemoved = nullptr;
|
CsEventRelayFuncPtr csColliderOnRemoved = nullptr;
|
||||||
|
CsEventRelayFuncPtr csSceneNodeChildrenChanged = nullptr;
|
||||||
// - Editor
|
// - Editor
|
||||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||||
CsFuncPtr csEditorUndo = nullptr;
|
CsFuncPtr csEditorUndo = nullptr;
|
||||||
|
@ -272,6 +280,8 @@ namespace SHADE
|
||||||
SHEventHandle onColliderAdded(SHEventPtr eventPtr);
|
SHEventHandle onColliderAdded(SHEventPtr eventPtr);
|
||||||
SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
|
SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
|
||||||
SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr);
|
SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr);
|
||||||
|
SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr);
|
||||||
|
SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -50,6 +50,17 @@ namespace SHADE
|
||||||
reinterpret_cast<SHScriptEngine*>(system)->csScriptsExecuteLateUpdate();
|
reinterpret_cast<SHScriptEngine*>(system)->csScriptsExecuteLateUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* System Routine Functions - GizmosDrawRoutine */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHScriptEngine::GizmosDrawRoutine::GizmosDrawRoutine()
|
||||||
|
: SHSystemRoutine("Script Engine Gizmos Draw", true)
|
||||||
|
{}
|
||||||
|
void SHScriptEngine::GizmosDrawRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
reinterpret_cast<SHScriptEngine*>(system)->csScriptsExecuteDrawGizmos();
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* System Routine Functions - FrameCleanUpRoutine */
|
/* System Routine Functions - FrameCleanUpRoutine */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace SHADE
|
||||||
class SH_API SHConfigurationManager
|
class SH_API SHConfigurationManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr std::string_view applicationConfigPath{"../../Assets/Application.SHConfig"};
|
static inline std::string applicationConfigPath{ std::string(ASSET_ROOT) + "/Application.SHConfig"};
|
||||||
static constexpr std::string_view editorConfigPath{"../../Assets/Editor/Editor.SHConfig"};
|
static inline std::string editorConfigPath{ std::string(ASSET_ROOT) + "/Editor/Editor.SHConfig"};
|
||||||
|
|
||||||
static void SaveApplicationConfig();
|
static void SaveApplicationConfig();
|
||||||
static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr);
|
static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Math/Geometry/SHBoundingBox.h"
|
#include "Math/Geometry/SHBoundingBox.h"
|
||||||
#include "Math/Geometry/SHBoundingSphere.h"
|
#include "Math/Geometry/SHBoundingSphere.h"
|
||||||
#include "Physics/SHCollider.h"
|
#include "Physics/SHCollisionShape.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
#include "Math/Vector/SHVec2.h"
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
@ -101,7 +101,7 @@ namespace YAML
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<SHCollider>
|
struct convert<SHCollisionShape>
|
||||||
{
|
{
|
||||||
static constexpr const char* IsTrigger = "Is Trigger";
|
static constexpr const char* IsTrigger = "Is Trigger";
|
||||||
|
|
||||||
|
@ -114,33 +114,33 @@ namespace YAML
|
||||||
static constexpr const char* Density = "Density";
|
static constexpr const char* Density = "Density";
|
||||||
static constexpr const char* PositionOffset = "Position Offset";
|
static constexpr const char* PositionOffset = "Position Offset";
|
||||||
|
|
||||||
static Node encode(SHCollider& rhs)
|
static Node encode(SHCollisionShape& rhs)
|
||||||
{
|
{
|
||||||
Node node;
|
Node node;
|
||||||
|
|
||||||
node[IsTrigger] = rhs.IsTrigger();
|
node[IsTrigger] = rhs.IsTrigger();
|
||||||
|
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
SHCollider::Type colliderType = rhs.GetType();
|
SHCollisionShape::Type colliderType = rhs.GetType();
|
||||||
|
|
||||||
node[Type] = enumAlign.value_to_name(colliderType).data();
|
node[Type] = enumAlign.value_to_name(colliderType).data();
|
||||||
|
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
auto const bb = reinterpret_cast<SHBoundingBox*>(rhs.GetShape());
|
||||||
node[HalfExtents] = bb->GetHalfExtents();
|
node[HalfExtents] = bb->GetRelativeExtents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
auto const bs = reinterpret_cast<SHBoundingSphere*>(rhs.GetShape());
|
||||||
node[Radius] = bs->GetRadius();
|
node[Radius] = bs->GetRelativeRadius();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,33 +151,33 @@ namespace YAML
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
static bool decode(Node const& node, SHCollider& rhs)
|
static bool decode(Node const& node, SHCollisionShape& rhs)
|
||||||
{
|
{
|
||||||
if (node[IsTrigger].IsDefined())
|
if (node[IsTrigger].IsDefined())
|
||||||
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
rhs.SetIsTrigger(node[IsTrigger].as<bool>());
|
||||||
if (!node[Type].IsDefined())
|
if (!node[Type].IsDefined())
|
||||||
return false;
|
return false;
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
bool ok;
|
bool ok;
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
const SHCollisionShape::Type colliderType = enumAlign.name_to_value(node[Type].as<std::string>()).convert<SHCollisionShape::Type>(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
if (node[HalfExtents].IsDefined())
|
if (node[HalfExtents].IsDefined())
|
||||||
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>() * 2.0f);
|
rhs.SetBoundingBox(node[HalfExtents].as<SHVec3>());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
if (node[Radius].IsDefined())
|
if (node[Radius].IsDefined())
|
||||||
rhs.SetBoundingSphere(node[Radius].as<float>());
|
rhs.SetBoundingSphere(node[Radius].as<float>());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
if (node[Friction].IsDefined())
|
if (node[Friction].IsDefined())
|
||||||
|
@ -200,12 +200,12 @@ namespace YAML
|
||||||
static Node encode(SHColliderComponent& rhs)
|
static Node encode(SHColliderComponent& rhs)
|
||||||
{
|
{
|
||||||
Node node, collidersNode;
|
Node node, collidersNode;
|
||||||
auto const& colliders = rhs.GetColliders();
|
auto const& colliders = rhs.GetCollisionShapes();
|
||||||
int const numColliders = static_cast<int>(colliders.size());
|
int const numColliders = static_cast<int>(colliders.size());
|
||||||
for (int i = 0; i < numColliders; ++i)
|
for (int i = 0; i < numColliders; ++i)
|
||||||
{
|
{
|
||||||
auto& collider = rhs.GetCollider(i);
|
auto& collider = rhs.GetCollisionShape(i);
|
||||||
Node colliderNode = convert<SHCollider>::encode(collider);
|
Node colliderNode = convert<SHCollisionShape>::encode(collider);
|
||||||
if (colliderNode.IsDefined())
|
if (colliderNode.IsDefined())
|
||||||
collidersNode[i] = colliderNode;
|
collidersNode[i] = colliderNode;
|
||||||
}
|
}
|
||||||
|
@ -219,21 +219,21 @@ namespace YAML
|
||||||
int numColliders{};
|
int numColliders{};
|
||||||
for (auto const& colliderNode : node[Colliders])
|
for (auto const& colliderNode : node[Colliders])
|
||||||
{
|
{
|
||||||
rttr::type const shapeRttrType = rttr::type::get<SHCollider::Type>();
|
rttr::type const shapeRttrType = rttr::type::get<SHCollisionShape::Type>();
|
||||||
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
rttr::enumeration const enumAlign = shapeRttrType.get_enumeration();
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
const SHCollider::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollider>::Type].as<std::string>()).convert<SHCollider::Type>(&ok);
|
const SHCollisionShape::Type colliderType = enumAlign.name_to_value(colliderNode[convert<SHCollisionShape>::Type].as<std::string>()).convert<SHCollisionShape::Type>(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (colliderType)
|
switch (colliderType)
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX: rhs.AddBoundingBox(); break;
|
case SHCollisionShape::Type::BOX: rhs.AddBoundingBox(); break;
|
||||||
case SHCollider::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
case SHCollisionShape::Type::SPHERE: rhs.AddBoundingSphere(); break;
|
||||||
case SHCollider::Type::CAPSULE: break;
|
case SHCollisionShape::Type::CAPSULE: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
YAML::convert<SHCollider>::decode(colliderNode, rhs.GetCollider(numColliders++));
|
YAML::convert<SHCollisionShape>::decode(colliderNode, rhs.GetCollisionShape(numColliders++));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -55,11 +55,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
Vector3 BoxCollider::HalfExtents::get()
|
Vector3 BoxCollider::HalfExtents::get()
|
||||||
{
|
{
|
||||||
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents());
|
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetWorldExtents());
|
||||||
}
|
}
|
||||||
void BoxCollider::HalfExtents::set(Vector3 value)
|
void BoxCollider::HalfExtents::set(Vector3 value)
|
||||||
{
|
{
|
||||||
getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value));
|
getNativeBoundObject<SHBoundingBox>().SetWorldExtents(Convert::ToNative(value));
|
||||||
}
|
}
|
||||||
Vector3 BoxCollider::Min::get()
|
Vector3 BoxCollider::Min::get()
|
||||||
{
|
{
|
||||||
|
@ -103,11 +103,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
float SphereCollider::Radius::get()
|
float SphereCollider::Radius::get()
|
||||||
{
|
{
|
||||||
return getNativeBoundObject<SHBoundingSphere>().GetRadius();
|
return getNativeBoundObject<SHBoundingSphere>().GetWorldRadius();
|
||||||
}
|
}
|
||||||
void SphereCollider::Radius::set(float value)
|
void SphereCollider::Radius::set(float value)
|
||||||
{
|
{
|
||||||
getNativeBoundObject<SHBoundingSphere>().SetRadius(value);
|
getNativeBoundObject<SHBoundingSphere>().SetWorldRadius(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -150,7 +150,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
int Collider::CollisionShapeCount::get()
|
int Collider::CollisionShapeCount::get()
|
||||||
{
|
{
|
||||||
return static_cast<int>(GetNativeComponent()->GetColliders().size());
|
return static_cast<int>(GetNativeComponent()->GetCollisionShapes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -230,18 +230,18 @@ namespace SHADE
|
||||||
|
|
||||||
// Populate the list
|
// Populate the list
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& collider : GetNativeComponent()->GetColliders())
|
for (const auto& collider : GetNativeComponent()->GetCollisionShapes())
|
||||||
{
|
{
|
||||||
CollisionShape^ bound = nullptr;
|
CollisionShape^ bound = nullptr;
|
||||||
switch (collider.GetType())
|
switch (collider.GetType())
|
||||||
{
|
{
|
||||||
case SHCollider::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
bound = gcnew BoxCollider(i, Owner.GetEntity());
|
bound = gcnew BoxCollider(i, Owner.GetEntity());
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
bound = gcnew SphereCollider(i, Owner.GetEntity());
|
bound = gcnew SphereCollider(i, Owner.GetEntity());
|
||||||
break;
|
break;
|
||||||
case SHCollider::Type::CAPSULE:
|
case SHCollisionShape::Type::CAPSULE:
|
||||||
// TODO
|
// TODO
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -27,11 +27,11 @@ namespace SHADE
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto& bounds = collider->GetCollider(arrayIndex);
|
auto& shape = collider->GetCollisionShape(arrayIndex);
|
||||||
if (bounds.GetType() != SHCollider::Type::BOX)
|
if (shape.GetType() != SHCollisionShape::Type::BOX)
|
||||||
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
|
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
|
||||||
|
|
||||||
return reinterpret_cast<CollisionShapeType&>(bounds);
|
return reinterpret_cast<CollisionShapeType&>(shape);
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument&)
|
catch (std::invalid_argument&)
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all Scripts of the specified type from this GameObject.
|
/// Removes all Scripts of the specified type from this GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of PLushieScripts to remove.</typeparam>
|
/// <typeparam name="T">Type of Scripts to remove.</typeparam>
|
||||||
generic<typename T> where T : ref class, Script
|
generic<typename T> where T : ref class, Script
|
||||||
void RemoveScript();
|
void RemoveScript();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Light.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 8, 2022
|
||||||
|
\brief Contains the definition of the functions of the managed Light class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Headers
|
||||||
|
#include "SHpch.h"
|
||||||
|
// Primary Header
|
||||||
|
#include "Light.hxx"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Light::Light(Entity entity)
|
||||||
|
: Component(entity)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Vector3 Light::Position::get()
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(GetNativeComponent()->GetPosition());
|
||||||
|
}
|
||||||
|
void Light::Position::set(Vector3 value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetPosition(Convert::ToNative(value));
|
||||||
|
}
|
||||||
|
Light::Type Light::LightType::get()
|
||||||
|
{
|
||||||
|
return static_cast<Type>(GetNativeComponent()->GetType());
|
||||||
|
}
|
||||||
|
void Light::LightType::set(Light::Type value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetType(static_cast<SH_LIGHT_TYPE>(value));
|
||||||
|
}
|
||||||
|
Vector3 Light::Direction::get()
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(GetNativeComponent()->GetDirection());
|
||||||
|
}
|
||||||
|
void Light::Direction::set(Vector3 value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetDirection(Convert::ToNative(value));
|
||||||
|
}
|
||||||
|
Color Light::Color::get()
|
||||||
|
{
|
||||||
|
return Convert::ToCLI(SHColour(GetNativeComponent()->GetColor()));
|
||||||
|
}
|
||||||
|
void Light::Color::set(SHADE::Color value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetColor(Convert::ToNative(value));
|
||||||
|
}
|
||||||
|
System::UInt32 Light::CullingMask::get()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->GetCullingMask();
|
||||||
|
}
|
||||||
|
void Light::CullingMask::set(System::UInt32 value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetCullingMask(value);
|
||||||
|
}
|
||||||
|
float Light::Strength::get()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->GetStrength();
|
||||||
|
}
|
||||||
|
void Light::Strength::set(float value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetStrength(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Light.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 8, 2022
|
||||||
|
\brief Contains the definition of the managed Light class with the declaration
|
||||||
|
of functions for working with it.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
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 "Components/Component.hxx"
|
||||||
|
#include "Math/Vector3.hxx"
|
||||||
|
// External Dependencies
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// CLR version of the SHADE Engine's SHLightComponent.
|
||||||
|
/// </summary>
|
||||||
|
public ref class Light : public Component<SHLightComponent>
|
||||||
|
{
|
||||||
|
internal:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a Light Component that represents a native Light component tied to
|
||||||
|
/// the specified Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">Entity that this Component will be tied to.</param>
|
||||||
|
Light(Entity entity);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constants */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Supported types of the Light Component.
|
||||||
|
/// </summary>
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Light applied uniformly across the scene at a specified direction.
|
||||||
|
/// </summary>
|
||||||
|
Directional,
|
||||||
|
/// <summary>
|
||||||
|
/// Light that originates from a certain point in all directions.
|
||||||
|
/// Not implemented yet.
|
||||||
|
/// </summary>
|
||||||
|
Point,
|
||||||
|
/// <summary>
|
||||||
|
/// Light that originates from a certain point within a angle.
|
||||||
|
/// Not implemented yet.
|
||||||
|
/// </summary>
|
||||||
|
Spot,
|
||||||
|
/// <summary>
|
||||||
|
/// Light applied to all objects. Has no source point.
|
||||||
|
/// </summary>
|
||||||
|
Ambient
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Position of the light. Only works for Point Light (unimplemented).
|
||||||
|
/// </summary>
|
||||||
|
[System::ObsoleteAttribute("Not implemented yet.", true)]
|
||||||
|
property Vector3 Position
|
||||||
|
{
|
||||||
|
Vector3 get();
|
||||||
|
void set(Vector3 val);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Type of lighting that this Light component will apply onto the scene.
|
||||||
|
/// </summary>
|
||||||
|
property Type LightType
|
||||||
|
{
|
||||||
|
Type get();
|
||||||
|
void set(Type val);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Direction of the light. Only applicable for Directional Lights.
|
||||||
|
/// </summary>
|
||||||
|
property Vector3 Direction
|
||||||
|
{
|
||||||
|
Vector3 get();
|
||||||
|
void set(Vector3 val);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Colour of the Light.
|
||||||
|
/// </summary>
|
||||||
|
property SHADE::Color Color
|
||||||
|
{
|
||||||
|
SHADE::Color get();
|
||||||
|
void set(SHADE::Color val);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Culling mask that is used to control what types of Materials would be
|
||||||
|
/// affected by this Light.
|
||||||
|
/// </summary>
|
||||||
|
property System::UInt32 CullingMask
|
||||||
|
{
|
||||||
|
System::UInt32 get();
|
||||||
|
void set(System::UInt32 val);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Intensity of the Light
|
||||||
|
/// </summary>
|
||||||
|
property float Strength
|
||||||
|
{
|
||||||
|
float get();
|
||||||
|
void set(float val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -414,19 +414,10 @@ namespace SHADE
|
||||||
generic<typename Attribute>
|
generic<typename Attribute>
|
||||||
Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field)
|
Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field)
|
||||||
{
|
{
|
||||||
array<System::Object^>^ attributes = field->GetCustomAttributes(true);
|
array<System::Object^>^ attributes = field->GetCustomAttributes(Attribute::typeid, false);
|
||||||
for each (System::Object^ attrib in attributes)
|
if (attributes->Length > 0)
|
||||||
{
|
{
|
||||||
try
|
return safe_cast<Attribute>(attributes[0]);
|
||||||
{
|
|
||||||
Attribute attribute = safe_cast<Attribute>(attrib);
|
|
||||||
if (attribute != nullptr)
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
catch (System::InvalidCastException^)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Failed to find
|
// Failed to find
|
||||||
return Attribute{};
|
return Attribute{};
|
||||||
|
|
|
@ -39,10 +39,10 @@ namespace SHADE
|
||||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||||
static void RenderScriptsInInspector(Entity entity);
|
static void RenderScriptsInInspector(Entity entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
/// Renders a dropdown button that allows for the addition of Scripts onto the
|
||||||
/// onto the specified Entity.
|
/// specified Entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
/// <param name="entity">The Entity to add Scripts to.</param>
|
||||||
static void RenderScriptAddButton(Entity entity);
|
static void RenderScriptAddButton(Entity entity);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file ChildListCache.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 11, 2022
|
||||||
|
\brief Contains the definition of the functions for the ChildListCache managed
|
||||||
|
class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Headers
|
||||||
|
#include "SHpch.h"
|
||||||
|
// Primary Header
|
||||||
|
#include "ChildListCache.hxx"
|
||||||
|
// External Dependencies
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
// Project Headers
|
||||||
|
#include "Utility/Debug.hxx"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
ChildListCache::ChildEnumerable^ ChildListCache::GetChildList(Entity entity)
|
||||||
|
{
|
||||||
|
// Ignore if invalid
|
||||||
|
if (entity == MAX_EID)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Check if in cache
|
||||||
|
if (cachedLists->ContainsKey(entity))
|
||||||
|
return cachedLists[entity];
|
||||||
|
|
||||||
|
// Grab the native child list
|
||||||
|
auto node = GameObject(entity).GetSceneNode();
|
||||||
|
if (!node || node->GetChildren().empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Otherwise
|
||||||
|
// - Create the list
|
||||||
|
ChildList^ list = gcnew ChildList();
|
||||||
|
updateChildList(list, node);
|
||||||
|
// - Cache it
|
||||||
|
cachedLists[entity] = list;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChildListCache::UpdateChildList(Entity entity)
|
||||||
|
{
|
||||||
|
// Ignore if invalid
|
||||||
|
if (entity == MAX_EID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if in cache
|
||||||
|
if (!cachedLists->ContainsKey(entity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Update
|
||||||
|
updateChildList(cachedLists[entity], GameObject(entity).GetSceneNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Event Handling Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void ChildListCache::OnChildrenChanged(EntityID entity)
|
||||||
|
{
|
||||||
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
UpdateChildList(entity);
|
||||||
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ChildListCache")
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void ChildListCache::updateChildList(ChildList^ list, const SHSceneNode* sceneNode)
|
||||||
|
{
|
||||||
|
list->Clear();
|
||||||
|
for (auto node : sceneNode->GetChildren())
|
||||||
|
{
|
||||||
|
list->Add(GameObject(node->GetEntityID()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file ChildListCache.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 11, 2022
|
||||||
|
\brief Contains the definition of the ChildListCache managed class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
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 "GameObject.hxx"
|
||||||
|
|
||||||
|
namespace SHADE { }
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
class SHSceneNode;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Static class that caches all the lists of children for GameObjects.
|
||||||
|
/// </summary>
|
||||||
|
private ref class ChildListCache abstract sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
using ChildList = System::Collections::Generic::List<GameObject>;
|
||||||
|
using ChildEnumerable = System::Collections::Generic::IEnumerable<GameObject>;
|
||||||
|
using ListMap = System::Collections::Generic::Dictionary<Entity, ChildList^>;
|
||||||
|
|
||||||
|
internal:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Static Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the children list for the specified Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Enumerable read only list of an Entity's children. Null if entity is invalid
|
||||||
|
/// or there are no children.
|
||||||
|
/// </returns>
|
||||||
|
static ChildEnumerable^ GetChildList(Entity entity);
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the children list for the specified Entity if it exists.
|
||||||
|
/// </summary>
|
||||||
|
static void UpdateChildList(Entity entity);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Event Handling Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// To be
|
||||||
|
/// </summary>
|
||||||
|
static void OnChildrenChanged(EntityID entity);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Static Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static ListMap^ cachedLists = gcnew ListMap();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static void updateChildList(ChildList^ list, const SHSceneNode* sceneNode);
|
||||||
|
};
|
||||||
|
}
|
|
@ -22,8 +22,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// External Dependencies
|
// External Dependencies
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Physics\Components\SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
#include "Physics\Components\SHRigidBodyComponent.h"
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Scene/SHSceneGraph.h"
|
#include "Scene/SHSceneGraph.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
|
@ -31,10 +31,11 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Utility/Convert.hxx"
|
#include "Utility/Convert.hxx"
|
||||||
#include "Utility/Debug.hxx"
|
#include "Utility/Debug.hxx"
|
||||||
#include "Components/Transform.hxx"
|
#include "Components/Transform.hxx"
|
||||||
#include "Components\RigidBody.hxx"
|
#include "Components/RigidBody.hxx"
|
||||||
#include "Components\Collider.hxx"
|
#include "Components/Collider.hxx"
|
||||||
#include "Components/Camera.hxx"
|
#include "Components/Camera.hxx"
|
||||||
#include "Components/CameraArm.hxx"
|
#include "Components/CameraArm.hxx"
|
||||||
|
#include "Components/Light.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -252,6 +253,7 @@ namespace SHADE
|
||||||
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
||||||
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
||||||
componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>());
|
componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>());
|
||||||
|
componentMap.Add(createComponentSet<SHLightComponent, Light>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Static class that contains the functions for interfacing with the core
|
/// Static class that contains the functions for interfacing with the core
|
||||||
/// PlushieEngine written in C++ for managing the lifecycle of managed code.
|
/// SHADE Engine written in C++ for managing the lifecycle of managed code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private ref class EngineInterface abstract sealed
|
private ref class EngineInterface abstract sealed
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Utility/Convert.hxx"
|
#include "Utility/Convert.hxx"
|
||||||
#include "Scripts/ScriptStore.hxx"
|
#include "Scripts/ScriptStore.hxx"
|
||||||
#include "Utility/Debug.hxx"
|
#include "Utility/Debug.hxx"
|
||||||
|
#include "ChildListCache.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -87,30 +88,43 @@ namespace SHADE
|
||||||
throw gcnew System::NullReferenceException();
|
throw gcnew System::NullReferenceException();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
GameObject^ GameObject::Parent::get()
|
GameObject GameObject::Parent::get()
|
||||||
{
|
{
|
||||||
if (!valid)
|
if (!valid)
|
||||||
throw gcnew System::NullReferenceException();
|
throw gcnew System::NullReferenceException();
|
||||||
|
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||||
|
|
||||||
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||||
if (NODE == nullptr)
|
if (NODE == nullptr)
|
||||||
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||||
|
|
||||||
const auto* PARENT = NODE->GetParent();
|
const auto* PARENT = NODE->GetParent();
|
||||||
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
|
return PARENT != ROOT ? GameObject(PARENT->GetEntityID()) : GameObject();
|
||||||
}
|
}
|
||||||
void GameObject::Parent::set(GameObject^ newParent)
|
void GameObject::Parent::set(GameObject newParent)
|
||||||
{
|
{
|
||||||
if (!valid)
|
if (!valid)
|
||||||
throw gcnew System::NullReferenceException();
|
throw gcnew System::NullReferenceException();
|
||||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
if (newParent == nullptr)
|
if (newParent)
|
||||||
SCENE_GRAPH.SetParent(entity, nullptr);
|
SCENE_GRAPH.SetParent(entity, newParent.EntityId);
|
||||||
else
|
else
|
||||||
SCENE_GRAPH.SetParent(entity, newParent->EntityId);
|
SCENE_GRAPH.SetParent(entity, nullptr);
|
||||||
|
}
|
||||||
|
int GameObject::ChildCount::get()
|
||||||
|
{
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
|
||||||
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||||
|
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||||
|
if (NODE == nullptr)
|
||||||
|
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||||
|
|
||||||
|
return static_cast<int>(NODE->GetChildren().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -215,6 +229,90 @@ namespace SHADE
|
||||||
ScriptStore::RemoveScript<T>(entity);
|
ScriptStore::RemoveScript<T>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Scene Graph Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void GameObject::DetachChildren()
|
||||||
|
{
|
||||||
|
// Validity Checks
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
auto node = GetSceneNode();
|
||||||
|
if (!node)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
|
||||||
|
// Unparent all children to the root
|
||||||
|
for (auto child : node->GetChildren())
|
||||||
|
{
|
||||||
|
SHSceneManager::GetCurrentSceneGraph().SetParent(child->GetEntityID(), nullptr);
|
||||||
|
}
|
||||||
|
ChildListCache::UpdateChildList(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject GameObject::GetChild(int index)
|
||||||
|
{
|
||||||
|
// Validity Checks
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
auto node = GetSceneNode();
|
||||||
|
if (!node)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
|
||||||
|
auto child = node->GetChild(index);
|
||||||
|
return child ? GameObject(child->GetEntityID()) : GameObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
System::Collections::Generic::IEnumerable<GameObject>^ GameObject::GetChildren()
|
||||||
|
{
|
||||||
|
// Validity Checks
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
return ChildListCache::GetChildList(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameObject::GetSiblingIndex()
|
||||||
|
{
|
||||||
|
throw gcnew System::NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameObject::IsChildOf(GameObject gameObj)
|
||||||
|
{
|
||||||
|
// Search parents recursively
|
||||||
|
auto node = GetSceneNode();
|
||||||
|
while (node != nullptr)
|
||||||
|
{
|
||||||
|
if (node->GetEntityID() == gameObj.entity)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Go up higher
|
||||||
|
node = node->GetParent();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::SetAsFirstSibling()
|
||||||
|
{
|
||||||
|
throw gcnew System::NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::SetAsLastSibling()
|
||||||
|
{
|
||||||
|
throw gcnew System::NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::SetSiblingIndex(int index)
|
||||||
|
{
|
||||||
|
throw gcnew System::NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
GameObject::operator bool(GameObject gameObj)
|
||||||
|
{
|
||||||
|
return gameObj.valid;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -245,11 +343,15 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Helper Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
GameObject::operator bool(GameObject gameObj)
|
SHSceneNode* GameObject::GetSceneNode()
|
||||||
{
|
{
|
||||||
return gameObj.valid;
|
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||||
|
if (!ROOT)
|
||||||
|
return nullptr;
|
||||||
|
return SCENE_GRAPH.GetNode(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -290,4 +392,21 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* IEnummerable */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
System::Collections::Generic::IEnumerator<GameObject>^ GameObject::GetEnumerator()
|
||||||
|
{
|
||||||
|
System::Collections::Generic::IEnumerable<GameObject>^ childList = GetChildren();
|
||||||
|
if (childList == nullptr)
|
||||||
|
return System::Linq::Enumerable::Empty<GameObject>()->GetEnumerator();
|
||||||
|
else
|
||||||
|
return childList->GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
System::Collections::IEnumerator^ GameObject::GetEnumeratorNonGeneric()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Forward Declarations */
|
/* Forward Declarations */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
ref class Script;
|
ref class Script;
|
||||||
ref class BaseComponent;
|
ref class BaseComponent;
|
||||||
|
@ -32,8 +32,9 @@ namespace SHADE
|
||||||
/// Lightweight object for an Entity that allows for easy access to Component and
|
/// Lightweight object for an Entity that allows for easy access to Component and
|
||||||
/// Script operations.
|
/// Script operations.
|
||||||
/// Can be set to a invalid/null GameObject by default construction.
|
/// Can be set to a invalid/null GameObject by default construction.
|
||||||
|
/// Can also be iterated to access children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public value class GameObject : public System::IEquatable<GameObject>
|
public value class GameObject : public System::IEquatable<GameObject>, public System::Collections::Generic::IEnumerable<GameObject>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -97,10 +98,17 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The parent entity for this GameObject.
|
/// The parent entity for this GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
property GameObject^ Parent
|
property GameObject Parent
|
||||||
{
|
{
|
||||||
GameObject^ get();
|
GameObject get();
|
||||||
void set(GameObject^);
|
void set(GameObject);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Number of Children held by this GameObject
|
||||||
|
/// </summary>
|
||||||
|
property int ChildCount
|
||||||
|
{
|
||||||
|
int get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -122,7 +130,6 @@ namespace SHADE
|
||||||
/// </param>
|
/// </param>
|
||||||
void SetActive(bool active);
|
void SetActive(bool active);
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Component Access Functions */
|
/* Component Access Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -210,10 +217,86 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all Scripts of the specified type from this GameObject.
|
/// Removes all Scripts of the specified type from this GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of PLushieScripts to remove.</typeparam>
|
/// <typeparam name="T">Type of Scripts to remove.</typeparam>
|
||||||
generic<typename T> where T : ref class, Script
|
generic<typename T> where T : ref class, Script
|
||||||
void RemoveScript();
|
void RemoveScript();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Scene Graph Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Unparents all children. Useful if you want to destroy the root of a hierarchy
|
||||||
|
/// without destroying the children.
|
||||||
|
/// </summary>
|
||||||
|
void DetachChildren();
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a child by index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Index of the child GameObject to retrieve.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Handle to the GameObject if the index is valid. Invalid GameObject otherwise.
|
||||||
|
/// </returns>
|
||||||
|
GameObject GetChild(int index);
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a cached enumerable container of child GameObjects of this
|
||||||
|
/// GameObject.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Enumerable container of child GameObjects of this GameObject. Null if
|
||||||
|
/// ChildCount is 0.
|
||||||
|
/// </returns>
|
||||||
|
System::Collections::Generic::IEnumerable<GameObject>^ GetChildren();
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sibling index. Use GetSiblingIndex to find out the GameObject’s
|
||||||
|
/// place in this hierarchy. When the sibling index of a GameObject is changed,
|
||||||
|
/// its order in the Hierarchy window will also change.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Index of this GameObject among the parent GameObject's children.
|
||||||
|
/// </returns>
|
||||||
|
[System::ObsoleteAttribute("Not yet implemented.", true)]
|
||||||
|
int GetSiblingIndex();
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this GameObject a direct or indirect child of the specified
|
||||||
|
/// GameObject.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// True if this GameObject is a child, deep child (child of a child) or
|
||||||
|
/// identical to this GameObject, otherwise false.
|
||||||
|
/// </returns>
|
||||||
|
bool IsChildOf(GameObject gameObj);
|
||||||
|
/// <summary>
|
||||||
|
/// Move the GameObject to the start of the parent GameObject's children list.
|
||||||
|
/// </summary>
|
||||||
|
[System::ObsoleteAttribute("Not yet implemented.", true)]
|
||||||
|
void SetAsFirstSibling();
|
||||||
|
/// <summary>
|
||||||
|
/// Move the GameObject to the end of the parent GameObject's children list.
|
||||||
|
/// </summary>
|
||||||
|
[System::ObsoleteAttribute("Not yet implemented.", true)]
|
||||||
|
void SetAsLastSibling();
|
||||||
|
/// <summary>
|
||||||
|
/// Move the GameObject to the specified position in the parent GameObject's
|
||||||
|
/// children list. An existing object at that position if any, will be pushed
|
||||||
|
/// to the next index (existing element will be at index + 1).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">
|
||||||
|
/// Position to place this GameObject at in the hierarchy. Clamped to between
|
||||||
|
/// [0, parent.ChildCount].
|
||||||
|
/// </param>
|
||||||
|
[System::ObsoleteAttribute("Not yet implemented.", true)]
|
||||||
|
void SetSiblingIndex(int index);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Implicit conversion operator to enable checking if a GameObject is valid.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObj">GameObjects to check.</param>
|
||||||
|
/// <returns>True if the GameObject is valid.</returns>
|
||||||
|
static operator bool(GameObject gameObj);
|
||||||
|
|
||||||
internal:
|
internal:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
|
@ -249,13 +332,13 @@ namespace SHADE
|
||||||
SHEntity& GetNativeEntity();
|
SHEntity& GetNativeEntity();
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implicit conversion operator to enable checking if a GameObject is valid.
|
/// Retrieves the SceneNode for this GameObject's referenced entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gameObj">GameObjects to check.</param>
|
/// <returns>Pointer to the SceneNode for this GameObject..</returns>
|
||||||
static operator bool(GameObject gameObj);
|
SHSceneNode* GetSceneNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -304,6 +387,14 @@ namespace SHADE
|
||||||
/// <param name="rhs">Another GameObject to check with.</param>
|
/// <param name="rhs">Another GameObject to check with.</param>
|
||||||
/// <returns>True if both Components are different.</returns>
|
/// <returns>True if both Components are different.</returns>
|
||||||
static bool operator!=(GameObject lhs, GameObject rhs);
|
static bool operator!=(GameObject lhs, GameObject rhs);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* IEnummerable */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <inheritdoc/>
|
||||||
|
System::Collections::Generic::IEnumerator<GameObject>^ GetEnumerator() override;
|
||||||
|
/// <inheritdoc/>
|
||||||
|
System::Collections::IEnumerator^ GetEnumeratorNonGeneric() override = System::Collections::IEnumerable::GetEnumerator;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,95 +25,85 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Properties */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A static class that contains a set of default Colors.
|
/// Pure black.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ref class Defaults abstract sealed
|
static property Color Black
|
||||||
{
|
{
|
||||||
public:
|
Color get() { return Color(0.0f, 0.0f, 0.0f); }
|
||||||
/*-------------------------------------------------------------------------*/
|
}
|
||||||
/* Properties */
|
/// <summary>
|
||||||
/*-------------------------------------------------------------------------*/
|
/// Light Gray, lighter than gray.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure black.
|
static property Color LightGray
|
||||||
/// </summary>
|
{
|
||||||
static property Color Black
|
Color get() { return Color(0.827451f, 0.827451f, 0.827451f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.0f, 0.0f, 0.0f); }
|
/// <summary>
|
||||||
}
|
/// Gray, halfway between black and white.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Light Gray, lighter than gray.
|
static property Color Gray
|
||||||
/// </summary>
|
{
|
||||||
static property Color LightGray
|
Color get() { return Color(0.5f, 0.5f, 0.5f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.827451f, 0.827451f, 0.827451f); }
|
/// <summary>
|
||||||
}
|
/// Dark Gray, darker than gray.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Gray, halfway between black and white.
|
static property Color DarkGray
|
||||||
/// </summary>
|
{
|
||||||
static property Color Gray
|
Color get() { return Color(0.622f, 0.622f, 0.622f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.5f, 0.5f, 0.5f); }
|
/// <summary>
|
||||||
}
|
/// Pure white.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Dark Gray, darker than gray.
|
static property Color White
|
||||||
/// </summary>
|
{
|
||||||
static property Color DarkGray
|
Color get() { return Color(1.0f, 1.0f, 1.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.622f, 0.622f, 0.622f); }
|
/// <summary>
|
||||||
}
|
/// Pure red.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure white.
|
static property Color Red
|
||||||
/// </summary>
|
{
|
||||||
static property Color White
|
Color get() { return Color(1.0f, 0.0f, 0.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(1.0f, 1.0f, 1.0f); }
|
/// <summary>
|
||||||
}
|
/// Pure green.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure red.
|
static property Color Green
|
||||||
/// </summary>
|
{
|
||||||
static property Color Red
|
Color get() { return Color(0.0f, 1.0f, 0.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(1.0f, 0.0f, 0.0f); }
|
/// <summary>
|
||||||
}
|
/// Pure blue.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure green.
|
static property Color Blue
|
||||||
/// </summary>
|
{
|
||||||
static property Color Green
|
Color get() { return Color(0.0f, 0.0f, 1.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.0f, 1.0f, 0.0f); }
|
/// <summary>
|
||||||
}
|
/// Pure cyan, mix of pure green and blue.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure blue.
|
static property Color Cyan
|
||||||
/// </summary>
|
{
|
||||||
static property Color Blue
|
Color get() { return Color(0.0f, 1.0f, 1.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.0f, 0.0f, 1.0f); }
|
/// <summary>
|
||||||
}
|
/// Pure magenta, mix of pure red and blue.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure cyan, mix of pure green and blue.
|
static property Color Magenta
|
||||||
/// </summary>
|
{
|
||||||
static property Color Cyan
|
Color get() { return Color(1.0f, 0.0f, 1.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(0.0f, 1.0f, 1.0f); }
|
/// <summary>
|
||||||
}
|
/// Pure yellow, mix of pure red and green.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Pure magenta, mix of pure red and blue.
|
static property Color Yellow
|
||||||
/// </summary>
|
{
|
||||||
static property Color Magenta
|
Color get() { return Color(1.0f, 1.0f, 0.0f); }
|
||||||
{
|
}
|
||||||
Color get() { return Color(1.0f, 0.0f, 1.0f); }
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Pure yellow, mix of pure red and green.
|
|
||||||
/// </summary>
|
|
||||||
static property Color Yellow
|
|
||||||
{
|
|
||||||
Color get() { return Color(1.0f, 1.0f, 0.0f); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
|
|
|
@ -276,4 +276,4 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
} // namespace PlushieAPI::Mathematics
|
}
|
||||||
|
|
|
@ -294,4 +294,4 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return Vector3(vec);
|
return Vector3(vec);
|
||||||
}
|
}
|
||||||
} // namespace PlushieAPI::Mathematics
|
}
|
||||||
|
|
|
@ -439,4 +439,5 @@ namespace SHADE
|
||||||
/// <param name="vec">Vector2 to convert from.</param>
|
/// <param name="vec">Vector2 to convert from.</param>
|
||||||
static explicit operator Vector3(Vector2 vec);
|
static explicit operator Vector3(Vector2 vec);
|
||||||
};
|
};
|
||||||
} // namespace PlushieAPI::Mathematics
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Oct 28, 2021
|
\date Oct 28, 2021
|
||||||
\brief Contains the definition of the functions for the PlushieScript managed
|
\brief Contains the definition of the functions for the Script managed class.
|
||||||
class.
|
|
||||||
|
|
||||||
Note: This file is written in C++17/CLI.
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
@ -140,6 +139,13 @@ namespace SHADE
|
||||||
lateUpdate();
|
lateUpdate();
|
||||||
SAFE_NATIVE_CALL_END(this)
|
SAFE_NATIVE_CALL_END(this)
|
||||||
}
|
}
|
||||||
|
void Script::OnDrawGizmos()
|
||||||
|
{
|
||||||
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
OnGizmosDrawOverriden = true;
|
||||||
|
onDrawGizmos();
|
||||||
|
SAFE_NATIVE_CALL_END(this)
|
||||||
|
}
|
||||||
void Script::OnDestroy()
|
void Script::OnDestroy()
|
||||||
{
|
{
|
||||||
SAFE_NATIVE_CALL_BEGIN
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
@ -194,6 +200,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
Script::Script(GameObject gameObj)
|
Script::Script(GameObject gameObj)
|
||||||
: owner { gameObj }
|
: owner { gameObj }
|
||||||
|
, OnGizmosDrawOverriden { false }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -210,6 +217,10 @@ namespace SHADE
|
||||||
void Script::fixedUpdate() {}
|
void Script::fixedUpdate() {}
|
||||||
void Script::update() {}
|
void Script::update() {}
|
||||||
void Script::lateUpdate() {}
|
void Script::lateUpdate() {}
|
||||||
|
void Script::onDrawGizmos()
|
||||||
|
{
|
||||||
|
OnGizmosDrawOverriden = false;
|
||||||
|
}
|
||||||
void Script::onDestroy() {}
|
void Script::onDestroy() {}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -164,6 +164,14 @@ namespace SHADE
|
||||||
static operator bool(Script^ s);
|
static operator bool(Script^ s);
|
||||||
|
|
||||||
internal:
|
internal:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the OnGizmosDraw function was overridden.
|
||||||
|
/// </summary>
|
||||||
|
bool OnGizmosDrawOverriden;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* "All-Time" Lifecycle Functions */
|
/* "All-Time" Lifecycle Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -208,6 +216,11 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void LateUpdate();
|
void LateUpdate();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Used to call onDrawGizmos(). This should be called just before rendering
|
||||||
|
/// the scene. This will only be called when working in the editor.
|
||||||
|
/// </summary>
|
||||||
|
void OnDrawGizmos();
|
||||||
|
/// <summary>
|
||||||
/// Used to call onDestroy(). This should be called at the end of the frame
|
/// Used to call onDestroy(). This should be called at the end of the frame
|
||||||
/// where the attached GameObject or this script is destroyed directly or
|
/// where the attached GameObject or this script is destroyed directly or
|
||||||
/// indirectly due to destruction of the owner.
|
/// indirectly due to destruction of the owner.
|
||||||
|
@ -308,6 +321,10 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
virtual void lateUpdate();
|
virtual void lateUpdate();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Called every frame just before rendering but only if working in the editor.
|
||||||
|
/// </summary>
|
||||||
|
virtual void onDrawGizmos();
|
||||||
|
/// <summary>
|
||||||
/// Called just before the end of the frame where the attached GameObject or
|
/// Called just before the end of the frame where the attached GameObject or
|
||||||
/// this script is destroyed directly or indirectly due to destruction of the
|
/// this script is destroyed directly or indirectly due to destruction of the
|
||||||
/// owner.
|
/// owner.
|
||||||
|
|
|
@ -478,6 +478,24 @@ namespace SHADE
|
||||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptStore::ExecuteOnDrawGizmos()
|
||||||
|
{
|
||||||
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
for each (System::Collections::Generic::KeyValuePair<Entity, ScriptList^> entity in scripts)
|
||||||
|
{
|
||||||
|
// Check active state
|
||||||
|
if (!isEntityActive(entity.Key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Update each script
|
||||||
|
for each (Script^ script in entity.Value)
|
||||||
|
{
|
||||||
|
script->OnDrawGizmos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptStore::ExecuteCollisionFunctions()
|
void ScriptStore::ExecuteCollisionFunctions()
|
||||||
{
|
{
|
||||||
SAFE_NATIVE_CALL_BEGIN
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// Type of script to add.
|
/// Type of script to add.
|
||||||
/// This needs to be a default constructable PlushieScript.
|
/// This needs to be a default constructable Script.
|
||||||
/// </typeparam>
|
/// </typeparam>
|
||||||
/// <param name="entity">The entity to add a script to.</param>
|
/// <param name="entity">The entity to add a script to.</param>
|
||||||
/// <returns>Reference to the script added.</returns>
|
/// <returns>Reference to the script added.</returns>
|
||||||
|
@ -234,6 +234,10 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void ExecuteLateUpdate();
|
static void ExecuteLateUpdate();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Executes OnDrawGizmos() for all scripts.
|
||||||
|
/// </summary>
|
||||||
|
static void ExecuteOnDrawGizmos();
|
||||||
|
/// <summary>
|
||||||
/// Executes OnCollision*() and OnTrigger*() for all scripts.
|
/// Executes OnCollision*() and OnTrigger*() for all scripts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void ExecuteCollisionFunctions();
|
static void ExecuteCollisionFunctions();
|
||||||
|
|
|
@ -72,6 +72,16 @@ namespace SHADE
|
||||||
return Ray(ToCLI(vec.position), ToCLI(vec.direction));
|
return Ray(ToCLI(vec.position), ToCLI(vec.direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHColour Convert::ToNative(Color col)
|
||||||
|
{
|
||||||
|
return SHColour(col.r, col.g, col.b, col.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color Convert::ToCLI(const SHColour& vec)
|
||||||
|
{
|
||||||
|
return Color(vec.x, vec.y, vec.z, vec.w);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* String Conversions */
|
/* String Conversions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -29,6 +29,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Math/Quaternion.hxx"
|
#include "Math/Quaternion.hxx"
|
||||||
#include "Math/Ray.hxx"
|
#include "Math/Ray.hxx"
|
||||||
#include "Engine/GenericHandle.hxx"
|
#include "Engine/GenericHandle.hxx"
|
||||||
|
#include "Math/SHColour.h"
|
||||||
|
#include "Graphics/Color.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -104,6 +106,17 @@ namespace SHADE
|
||||||
/// <param name="vec">The native Vector2 to convert from.</param>
|
/// <param name="vec">The native Vector2 to convert from.</param>
|
||||||
/// <returns>Managed copy of a native Vector2.</returns>
|
/// <returns>Managed copy of a native Vector2.</returns>
|
||||||
static Ray ToCLI(const SHRay& vec);
|
static Ray ToCLI(const SHRay& vec);
|
||||||
|
/// Converts from a managed Color to a native Colour.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec">The managed Color to convert from.</param>
|
||||||
|
/// <returns>Native copy of a managed Color.</returns>
|
||||||
|
static SHColour ToNative(Color col);
|
||||||
|
/// <summary>
|
||||||
|
/// Converts from a native Colour to a managed Color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec">The native Colour to convert from.</param>
|
||||||
|
/// <returns>Managed copy of a native Colour.</returns>
|
||||||
|
static Color ToCLI(const SHColour& vec);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* String Conversions */
|
/* String Conversions */
|
||||||
|
|
|
@ -33,4 +33,4 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} // namespace PlushieAPI
|
}
|
||||||
|
|
|
@ -36,4 +36,4 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
System::Reflection::Assembly^ Load(System::Reflection::AssemblyName^ assemblyName) override;
|
System::Reflection::Assembly^ Load(System::Reflection::AssemblyName^ assemblyName) override;
|
||||||
};
|
};
|
||||||
} // namespace PlushieAPI
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Gizmos.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 8, 2022
|
||||||
|
\brief Contains the definition of the functions for the Convert managed static
|
||||||
|
class.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Headers
|
||||||
|
#include "SHpch.h"
|
||||||
|
// Primary Header
|
||||||
|
#include "Gizmos.hxx"
|
||||||
|
#include "Convert.hxx"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
// External Dependencies
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Public Properties */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Color Gizmos::Color::get()
|
||||||
|
{
|
||||||
|
return defaultColor;
|
||||||
|
}
|
||||||
|
void Gizmos::Color::set(SHADE::Color color)
|
||||||
|
{
|
||||||
|
defaultColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Debug Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void Gizmos::DrawLine(Vector3 from, Vector3 to)
|
||||||
|
{
|
||||||
|
DrawLine(from, to, defaultColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmos::DrawLine(Vector3 from, Vector3 to, SHADE::Color color)
|
||||||
|
{
|
||||||
|
SHDebugDraw::Line(Convert::ToNative(color), Convert::ToNative(from), Convert::ToNative(to));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents)
|
||||||
|
{
|
||||||
|
DrawWireCube(center, extents, defaultColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmos::DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color)
|
||||||
|
{
|
||||||
|
SHDebugDraw::Cube(Convert::ToNative(color), Convert::ToNative(center), Convert::ToNative(extents));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmos::DrawWireSphere(Vector3 center, float radius)
|
||||||
|
{
|
||||||
|
DrawWireSphere(center, radius, defaultColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmos::DrawWireSphere(Vector3 center, float radius, SHADE::Color color)
|
||||||
|
{
|
||||||
|
SHDebugDraw::Sphere(Convert::ToNative(color), Convert::ToNative(center), radius);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file Gizmos.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 8, 2022
|
||||||
|
\brief Contains the definition of the Gizmos static class and the
|
||||||
|
declaration of its functions.
|
||||||
|
|
||||||
|
Note: This file is written in C++17/CLI.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Project Includes
|
||||||
|
#include "Math/Vector3.hxx"
|
||||||
|
#include "Graphics/Color.hxx"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functions for implementing debug drawing.
|
||||||
|
/// </summary>
|
||||||
|
public value class Gizmos abstract sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Public Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Default colour that will be used for drawing debug primitives if the color
|
||||||
|
/// parameter is not specified.
|
||||||
|
/// </summary>
|
||||||
|
static property Color Color
|
||||||
|
{
|
||||||
|
SHADE::Color get();
|
||||||
|
void set(SHADE::Color color);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Debug Draw Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a line between two points in world space.
|
||||||
|
/// Uses <see cref="Gizmos.Color">Color</see> to render.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">First point of the line.</param>
|
||||||
|
/// <param name="to">Second point of the line.</param>
|
||||||
|
static void DrawLine(Vector3 from, Vector3 to);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a line between two points in world space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="from">First point of the line.</param>
|
||||||
|
/// <param name="to">Second point of the line.</param>
|
||||||
|
/// <param name="color">Colour of the line.</param>
|
||||||
|
static void DrawLine(Vector3 from, Vector3 to, SHADE::Color color);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe cube centered around the position specified in world
|
||||||
|
/// space.
|
||||||
|
/// Uses <see cref="Gizmos.Color">Color</see> to render.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center">Position where the cube wil be centered at.</param>
|
||||||
|
/// <param name="extents">Size of the rendered cube.</param>
|
||||||
|
static void DrawWireCube(Vector3 center, Vector3 extents);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe cube centered around the position specified in world
|
||||||
|
/// space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center">Position where the cube wil be centered at.</param>
|
||||||
|
/// <param name="extents">Size of the rendered cube.</param>
|
||||||
|
/// <param name="color">Colour of the cube.</param>
|
||||||
|
static void DrawWireCube(Vector3 center, Vector3 extents, SHADE::Color color);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe sphere centered around the position specified in world
|
||||||
|
/// space.
|
||||||
|
/// Uses <see cref="Gizmos.Color">Color</see> to render.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center">Position where the sphere wil be centered at.</param>
|
||||||
|
/// <param name="radius">Radius of the rendered sphere.</param>
|
||||||
|
static void DrawWireSphere(Vector3 center, float radius);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe sphere centered around the position specified in world
|
||||||
|
/// space.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="center">Position where the sphere wil be centered at.</param>
|
||||||
|
/// <param name="radius">Radius of the rendered sphere.</param>
|
||||||
|
/// <param name="color">Colour of the sphere.</param>
|
||||||
|
static void DrawWireSphere(Vector3 center, float radius, SHADE::Color color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static SHADE::Color defaultColor = SHADE::Color::White;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue