Merge remote-tracking branch 'origin/main' into SP3-1-Rendering

This commit is contained in:
Brandon Mak 2022-09-16 14:08:36 +08:00
commit eb975d96c6
114 changed files with 11798 additions and 1175 deletions

5
.gitignore vendored
View File

@ -353,4 +353,9 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Generated Files
[Dd]ependencies/
*.vcxproj
*.vcxproj.filters
*.sln
*.csproj

View File

@ -8,34 +8,36 @@ echo "A - All"
echo "B - VMA"
echo "C - msdf"
echo "D - assimp"
echo "E - ktx"
echo "F - spdlog"
echo "G - reactphysics3d"
echo "H - imgui"
echo "I - imguizmo"
echo "J - imnodes"
echo "K - tracy"
echo "L - RTTR"
echo "M - yamlcpp"
echo "E - spdlog"
echo "F - reactphysics3d"
echo "G - imgui"
echo "H - imguizmo"
echo "I - imnodes"
echo "J - tracy"
echo "K - RTTR"
echo "L - yamlcpp"
echo "M - SDL"
echo "N - dotnet"
echo ---------------------------------------------------
echo.
choice /C ABCDEFGHIJKLM /T 10 /D A
choice /C ABCDEFGHIJKLMN /T 10 /D A
set _e=%ERRORLEVEL%
if %_e%==1 goto VMA
if %_e%==2 goto VMA
if %_e%==3 goto MSDF
if %_e%==4 goto assimp
if %_e%==5 goto ktx
if %_e%==6 goto spdlog
if %_e%==7 goto reactphysics3d
if %_e%==8 goto imgui
if %_e%==9 goto imguizmo
if %_e%==10 goto imnodes
if %_e%==11 goto tracy
if %_e%==12 goto RTTR
if %_e%==13 goto yamlcpp
if %_e%==5 goto spdlog
if %_e%==6 goto reactphysics3d
if %_e%==7 goto imgui
if %_e%==8 goto imguizmo
if %_e%==9 goto imnodes
if %_e%==10 goto tracy
if %_e%==11 goto RTTR
if %_e%==12 goto yamlcpp
if %_e%==13 goto SDL
if %_e%==14 goto dotnet
:VMA
echo -----------------------VMA----------------------------
@ -53,60 +55,87 @@ if %_e%==3 (goto :done) else (goto :assimp)
echo -----------------------assimp----------------------------
rmdir "Dependencies/assimp" /S /Q
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/assimp"
if %_e%==4 (goto :done) else (goto :ktx)
if %_e%==4 (goto :done) else (goto :spdlog)
:ktx
rmdir "Dependencies/ktx" /S /Q
echo -----------------------ktx----------------------------
git clone https://github.com/SHADE-DP/ktx.git "Dependencies/ktx"
if %_e%==5 (goto :done) else (goto :spdlog)
@REM :ktx
@REM rmdir "Dependencies/ktx" /S /Q
@REM echo -----------------------ktx----------------------------
@REM git clone https://github.com/SHADE-DP/ktx.git "Dependencies/ktx"
@REM if %_e%==5 (goto :done) else (goto :spdlog)
:spdlog
echo -----------------------spdlog----------------------------
rmdir "Dependencies/spdlog" /S /Q
git clone https://github.com/SHADE-DP/spdlog.git "Dependencies/spdlog"
if %_e%==6 (goto :done) else (goto :reactphysics3d)
if %_e%==5 (goto :done) else (goto :reactphysics3d)
:reactphysics3d
echo -----------------------reactphysics3d----------------------------
rmdir "Dependencies/reactphysics3d" /S /Q
git clone https://github.com/SHADE-DP/reactphysics3d.git "Dependencies/reactphysics3d"
if %_e%==7 (goto :done) else (goto :imgui)
if %_e%==6 (goto :done) else (goto :imgui)
:imgui
echo -----------------------imgui----------------------------
rmdir "Dependencies/imgui" /S /Q
git clone https://github.com/SHADE-DP/imgui.git "Dependencies/imgui"
if %_e%==8 (goto :done) else (goto :imguizmo)
if %_e%==7 (goto :done) else (goto :imguizmo)
:imguizmo
echo -----------------------imguizmo----------------------------
rmdir "Dependencies/imguizmo" /S /Q
git clone https://github.com/SHADE-DP/ImGuizmo.git "Dependencies/imguizmo"
if %_e%==9 (goto :done) else (goto :imnodes)
if %_e%==8 (goto :done) else (goto :imnodes)
:imnodes
echo -----------------------imnodes----------------------------
rmdir "Dependencies/imnodes" /S /Q
git clone https://github.com/SHADE-DP/imnodes.git "Dependencies/imnodes"
if %_e%==10 (goto :done) else (goto :tracy)
if %_e%==9 (goto :done) else (goto :tracy)
:tracy
echo -----------------------tracy----------------------------
rmdir "Dependencies/tracy" /S /Q
git clone https://github.com/SHADE-DP/tracy.git "Dependencies/tracy"
if %_e%==11 (goto :done) else (goto :RTTR)
if %_e%==10 (goto :done) else (goto :RTTR)
:RTTR
echo -----------------------RTTR----------------------------
rmdir "Dependencies/RTTR" /S /Q
git clone https://github.com/SHADE-DP/RTTR.git "Dependencies/RTTR"
if %_e%==12 (goto :done) else (goto :yamlcpp)
if %_e%==11 (goto :done) else (goto :yamlcpp)
:yamlcpp
echo -----------------------yamlcpp----------------------------
rmdir "Dependencies/yamlcpp" /S /Q
git clone https://github.com/SHADE-DP/yaml-cpp.git "Dependencies/yamlcpp"
if %_e%==12 (goto :done) else (goto :SDL)
:SDL
echo -----------------------SDL----------------------------
rmdir "Dependencies/SDL" /S /Q
mkdir "Dependencies/SDL/include"
mkdir "Dependencies/SDL/lib"
powershell -Command "& {wget https://github.com/libsdl-org/SDL/releases/download/release-2.24.0/SDL2-devel-2.24.0-VC.zip -OutFile "Dependencies/SDL/SDL.zip"}"
powershell -Command "& {Expand-Archive -LiteralPath Dependencies/SDL/SDL.zip -DestinationPath Dependencies/SDL/tmp}"
robocopy "Dependencies/SDL/tmp/SDL2-2.24.0/lib/x64" "Dependencies/SDL/lib/" /ns /nfl /ndl /nc /njh
robocopy "Dependencies/SDL/tmp/SDL2-2.24.0/include/" "Dependencies/SDL/include/" /ns /nfl /ndl /nc /njh
rmdir "Dependencies/SDL/tmp/" /s /q
powershell -Command "& {Remove-Item "Dependencies/SDL/SDL.zip"}"
if %_e%==13 (goto :done) else (goto :dotnet)
:dotnet
echo -----------------------dotnet----------------------------
rmdir "Dependencies/dotnet" /S /Q
mkdir "Dependencies/dotnet/include"
mkdir "Dependencies/dotnet/bin"
powershell -Command "& {wget https://raw.githubusercontent.com/dotnet/runtime/main/src/coreclr/hosts/inc/coreclrhost.h -OutFile "Dependencies/dotnet/include/coreclrhost.h"}"
powershell -Command "& {wget https://download.visualstudio.microsoft.com/download/pr/8686fa48-b378-424e-908b-afbd66d6e120/2d75d5c3574fb5d917c5a3cd3f624287/dotnet-sdk-6.0.400-win-x64.zip -OutFile "Dependencies/dotnet/dotnet.zip"}"
powershell -Command "& {Expand-Archive -LiteralPath Dependencies/dotnet/dotnet.zip -DestinationPath Dependencies/dotnet/tmp}"
robocopy "Dependencies/dotnet/tmp/shared/Microsoft.NETCore.App/6.0.8/" "Dependencies/dotnet/bin/" *.dll /ns /nfl /ndl /nc /njh
rmdir "Dependencies/dotnet/tmp/" /s /q
del "Dependencies/dotnet/dotnet.zip"
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
:done
echo DONE!

View File

@ -10,6 +10,7 @@ IncludeDir["tracy"] = "%{wks.location}/Dependencies/tracy"
IncludeDir["VMA"] = "%{wks.location}/Dependencies/VMA"
IncludeDir["yamlcpp"] = "%{wks.location}/Dependencies/yamlcpp/include"
IncludeDir["RTTR"] = "%{wks.location}/Dependencies/RTTR"
IncludeDir["ktx"] = "%{wks.location}/Dependencies/ktx"
IncludeDir["reactphysics3d"] = "%{wks.location}/Dependencies/reactphysics3d"
IncludeDir["SDL"] = "%{wks.location}/Dependencies/SDL"
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
IncludeDir["dotnet"] = "%{wks.location}/Dependencies/dotnet"

Binary file not shown.

View File

@ -1,87 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SHADE_Application", "SHADE_Application\SHADE_Application.vcxproj", "{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencies", "{53E47842-3FC8-3998-A828-34EB942B241A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImGui", "Dependencies\imgui\ImGui.vcxproj", "{C0FF640D-2C14-8DBE-F595-301E616989EF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "Dependencies\msdf\msdfgen\freetype\freetype.vcxproj", "{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msdf-atlas-gen", "Dependencies\msdf\msdf-atlas-gen.vcxproj", "{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msdfgen", "Dependencies\msdf\msdfgen\msdfgen.vcxproj", "{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reactphysics3d", "Dependencies\reactphysics3d\reactphysics3d.vcxproj", "{2ECAB41A-1A98-A820-032C-1947EF988485}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "Dependencies\spdlog\spdlog.vcxproj", "{8EAD431C-7A4F-6EF2-630A-82464F4BF542}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "Dependencies\yamlcpp\yaml-cpp.vcxproj", "{88F1A057-74BE-FB62-9DD7-E90A890331F1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SHADE_Engine", "SHADE_Engine\SHADE_Engine.vcxproj", "{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}"
ProjectSection(ProjectDependencies) = postProject
{88F1A057-74BE-FB62-9DD7-E90A890331F1} = {88F1A057-74BE-FB62-9DD7-E90A890331F1}
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA} = {8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6} = {38BD587B-248B-4C81-0D1F-BDA7F98B28E6}
{2ECAB41A-1A98-A820-032C-1947EF988485} = {2ECAB41A-1A98-A820-032C-1947EF988485}
{C0FF640D-2C14-8DBE-F595-301E616989EF} = {C0FF640D-2C14-8DBE-F595-301E616989EF}
{8EAD431C-7A4F-6EF2-630A-82464F4BF542} = {8EAD431C-7A4F-6EF2-630A-82464F4BF542}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Debug|x64.ActiveCfg = Debug|x64
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Debug|x64.Build.0 = Debug|x64
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Release|x64.ActiveCfg = Release|x64
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Release|x64.Build.0 = Release|x64
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Debug|x64.ActiveCfg = Debug|x64
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Debug|x64.Build.0 = Debug|x64
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Release|x64.ActiveCfg = Release|x64
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Release|x64.Build.0 = Release|x64
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Debug|x64.ActiveCfg = Debug|x64
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Debug|x64.Build.0 = Debug|x64
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Release|x64.ActiveCfg = Release|x64
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Release|x64.Build.0 = Release|x64
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Debug|x64.ActiveCfg = Debug|x64
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Debug|x64.Build.0 = Debug|x64
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Release|x64.ActiveCfg = Release|x64
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Release|x64.Build.0 = Release|x64
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Debug|x64.ActiveCfg = Debug|x64
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Debug|x64.Build.0 = Debug|x64
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Release|x64.ActiveCfg = Release|x64
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Release|x64.Build.0 = Release|x64
{2ECAB41A-1A98-A820-032C-1947EF988485}.Debug|x64.ActiveCfg = Debug|x64
{2ECAB41A-1A98-A820-032C-1947EF988485}.Debug|x64.Build.0 = Debug|x64
{2ECAB41A-1A98-A820-032C-1947EF988485}.Release|x64.ActiveCfg = Release|x64
{2ECAB41A-1A98-A820-032C-1947EF988485}.Release|x64.Build.0 = Release|x64
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Debug|x64.ActiveCfg = Debug|x64
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Debug|x64.Build.0 = Debug|x64
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Release|x64.ActiveCfg = Release|x64
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Release|x64.Build.0 = Release|x64
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Debug|x64.ActiveCfg = Debug|x64
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Debug|x64.Build.0 = Debug|x64
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Release|x64.ActiveCfg = Release|x64
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Release|x64.Build.0 = Release|x64
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Debug|x64.ActiveCfg = Debug|x64
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Debug|x64.Build.0 = Debug|x64
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Release|x64.ActiveCfg = Release|x64
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C0FF640D-2C14-8DBE-F595-301E616989EF} = {53E47842-3FC8-3998-A828-34EB942B241A}
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71} = {53E47842-3FC8-3998-A828-34EB942B241A}
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6} = {53E47842-3FC8-3998-A828-34EB942B241A}
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA} = {53E47842-3FC8-3998-A828-34EB942B241A}
{2ECAB41A-1A98-A820-032C-1947EF988485} = {53E47842-3FC8-3998-A828-34EB942B241A}
{8EAD431C-7A4F-6EF2-630A-82464F4BF542} = {53E47842-3FC8-3998-A828-34EB942B241A}
{88F1A057-74BE-FB62-9DD7-E90A890331F1} = {53E47842-3FC8-3998-A828-34EB942B241A}
EndGlobalSection
EndGlobal

View File

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}</ProjectGuid>
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SHADE_Application</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\Debug_x86_64\SHADE_Application\</OutDir>
<IntDir>bin-int\Debug_x86_64\SHADE_Application\</IntDir>
<TargetName>SHADE_Application</TargetName>
<TargetExt>.exe</TargetExt>
<IncludePath>..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>bin\Release_x86_64\SHADE_Application\</OutDir>
<IntDir>bin-int\Release_x86_64\SHADE_Application\</IntDir>
<TargetName>SHADE_Application</TargetName>
<TargetExt>.exe</TargetExt>
<IncludePath>..\Dependencies\spdlog\include;$(VULKAN_SDK)\include;..\Dependencies\VMA\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>SBpch.h</PrecompiledHeaderFile>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>SBpch.h</PrecompiledHeaderFile>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>NOMINMAX;_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\SHADE_Engine\src;src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\Application\SBApplication.h" />
<ClInclude Include="src\SBpch.h" />
<ClInclude Include="src\Scenes\SBTestScene.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Application\SBApplication.cpp" />
<ClCompile Include="src\SBpch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\Scenes\SBTestScene.cpp" />
<ClCompile Include="src\WinMain.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SHADE_Engine\SHADE_Engine.vcxproj">
<Project>{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Application">
<UniqueIdentifier>{D9DE78AF-4594-F1A4-CE88-EB7B3A3DE8A8}</UniqueIdentifier>
</Filter>
<Filter Include="Scenes">
<UniqueIdentifier>{86EEB3D0-7290-DEA6-5B4B-F2FA478C65F7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Application\SBApplication.h">
<Filter>Application</Filter>
</ClInclude>
<ClInclude Include="src\SBpch.h" />
<ClInclude Include="src\Scenes\SBTestScene.h">
<Filter>Scenes</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Application\SBApplication.cpp">
<Filter>Application</Filter>
</ClCompile>
<ClCompile Include="src\SBpch.cpp" />
<ClCompile Include="src\Scenes\SBTestScene.cpp">
<Filter>Scenes</Filter>
</ClCompile>
<ClCompile Include="src\WinMain.cpp" />
</ItemGroup>
</Project>

View File

@ -1,13 +1,13 @@
project "SHADE_Application"
kind "WindowedApp"
language "C++"
cppdialect "C++latest"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
cppdialect "C++20"
targetdir (outputdir)
objdir (interdir)
systemversion "latest"
pchheader "SBpch.h"
pchsource "%{prj.location}/src/SBpch.cpp"
staticruntime "on"
staticruntime "off"
entrypoint "wWinMainCRTStartup"
system ("windows")
@ -15,7 +15,7 @@ project "SHADE_Application"
{
"%{prj.location}/src/**.h",
"%{prj.location}/src/**.hpp",
"%{prj.location}/src/**.c",
"%{prj.location}/src/**.c",
"%{prj.location}/src/**.cpp",
"%{prj.location}/src/**.glsl",
}
@ -23,7 +23,9 @@ project "SHADE_Application"
includedirs
{
"../SHADE_Engine/src",
"src"
"src",
"%{IncludeDir.dotnet}/include",
"%{IncludeDir.SDL}/include",
}
externalincludedirs
@ -43,11 +45,16 @@ project "SHADE_Application"
links
{
"SHADE_Engine"
"SHADE_Engine",
"SHADE_Managed",
"SDL2.lib",
"SDL2main.lib"
}
postbuildcommands
libdirs
{
"%{IncludeDir.spdlog}/lib",
"%{IncludeDir.SDL}/lib",
}
defines
@ -55,6 +62,11 @@ project "SHADE_Application"
"NOMINMAX"
}
disablewarnings
{
"4251"
}
warnings 'Extra'
filter "configurations:Debug"

View File

@ -8,9 +8,15 @@
//#include "Scenes/SBEditorScene.h"
#endif // SHEDITOR
#include "Tools/SHLogger.h"
#include "Tools/SHFileUtilties.h"
#include <chrono>
#include <ratio>
#include <ctime>
#include <SDL.h>
#include "Scripting/SHScriptEngine.h"
namespace Sandbox
{
@ -23,11 +29,15 @@ namespace Sandbox
_In_ INT nCmdShow
)
{
// Set working directory
SHADE::SHFileUtilities::SetWorkDirToExecDir();
SDL_Init(SDL_INIT_VIDEO);
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>("Graphics System");
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem("Graphics System"));
graphicsSystem->SetWindow(&window);
SDL_CreateWindowFrom(window.GetHWND());
SHADE::SHSystemManager::Init();
#ifdef SHEDITOR
@ -35,6 +45,8 @@ namespace Sandbox
#else
#endif
// Set up scripting
SHADE::SHScriptEngine::Init();
}
void SBApplication::Update(void)
@ -61,9 +73,9 @@ namespace Sandbox
void SBApplication::Exit(void)
{
//SHADE::SHEditor::Exit();
SHADE::SHScriptEngine::Exit();
SHADE::SHSystemManager::Exit();
SDL_DestroyWindow(sdlWindow);
#ifdef SHEDITOR
#else
#endif

View File

@ -2,6 +2,7 @@
#define SB_APPLICATION_H
#include <Graphics/Windowing/SHWindow.h>
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include <SDL_video.h>
//using namespace SHADE;
namespace Sandbox
@ -10,6 +11,7 @@ namespace Sandbox
{
private:
SHADE::SHWindow window;
SDL_Window* sdlWindow;
//SHAppConfig config;
public:
SBApplication() = default;

View File

@ -26,15 +26,15 @@ INT WINAPI wWinMain
)
{
const SHADE::SHLogger::Config LOGGER_CONFIG{ .directoryPath = "./logs/" };
SHADE::SHLogger::Initialise(LOGGER_CONFIG);
auto logger = SHADE::SHLogger::Initialise(LOGGER_CONFIG);
try
{
#ifndef SHEDITOR
//ShowWindow(::GetConsoleWindow(), SW_HIDE);
#endif
#endif
SHLOG_INFO("sup")
SHLOG_REGISTER(logger)
SHADE::SHEngine::Run<Sandbox::SBApplication>(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

View File

@ -1,280 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}</ProjectGuid>
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SHADE_Engine</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>bin\Debug_x86_64\SHADE_Engine\</OutDir>
<IntDir>bin-int\Debug_x86_64\SHADE_Engine\</IntDir>
<TargetName>SHADE_Engine</TargetName>
<TargetExt>.lib</TargetExt>
<IncludePath>..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>bin\Release_x86_64\SHADE_Engine\</OutDir>
<IntDir>bin-int\Release_x86_64\SHADE_Engine\</IntDir>
<TargetName>SHADE_Engine</TargetName>
<TargetExt>.lib</TargetExt>
<IncludePath>..\Dependencies\assimp\include;..\Dependencies\imgui;..\Dependencies\imguizmo;..\Dependencies\imnodes;..\Dependencies\msdf;..\Dependencies\msdf\msdfgen;..\Dependencies\spdlog\include;..\Dependencies\tracy;..\Dependencies\VMA\include;..\Dependencies\yamlcpp\include;..\Dependencies\ktx\include;..\Dependencies\RTTR\include;..\Dependencies\reactphysics3d\include;$(VULKAN_SDK)\include;$(VULKAN_SDK)\Source\SPIRV-Reflect;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>SHpch.h</PrecompiledHeaderFile>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>_LIB;_GLFW_INCLUDE_NONE;MSDFGEN_USE_CPP11;NOMINMAX;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>vulkan-1.lib;assimp-vc142-mtd.lib;ktxd.lib;librttr_core_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>libs;$(VULKAN_SDK)\Lib;..\Dependencies\assimp\lib\Debug;..\Dependencies\assimp\lib\Release;..\Dependencies\RTTR\lib;..\Dependencies\ktx\lib\Debug;..\Dependencies\ktx\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>SHpch.h</PrecompiledHeaderFile>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>_LIB;_GLFW_INCLUDE_NONE;MSDFGEN_USE_CPP11;NOMINMAX;_RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpplatest</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalDependencies>vulkan-1.lib;assimp-vc142-mt.lib;ktx.lib;librttr_core.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>libs;$(VULKAN_SDK)\Lib;..\Dependencies\assimp\lib\Debug;..\Dependencies\assimp\lib\Release;..\Dependencies\RTTR\lib;..\Dependencies\ktx\lib\Debug;..\Dependencies\ktx\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponent.h" />
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponentGroup.h" />
<ClInclude Include="src\Engine\ECS_Base\Entity\SHEntity.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHFamily.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHHandleGenerator.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseBase.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSet.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSetContainer.h" />
<ClInclude Include="src\Engine\ECS_Base\SHECSMacros.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHComponentManager.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHEntityManager.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHSystem.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHSystemManager.h" />
<ClInclude Include="src\Engine\SHEngine.h" />
<ClInclude Include="src\Graphics\Buffers\SHVkBuffer.h" />
<ClInclude Include="src\Graphics\Commands\SHCommandPoolResetMode.h" />
<ClInclude Include="src\Graphics\Commands\SHVkCommandBuffer.h" />
<ClInclude Include="src\Graphics\Commands\SHVkCommandPool.h" />
<ClInclude Include="src\Graphics\Debugging\SHValidationLayersQuery.h" />
<ClInclude Include="src\Graphics\Debugging\SHVkDebugMessenger.h" />
<ClInclude Include="src\Graphics\Debugging\SHVulkanDebugUtil.h" />
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolManager.h" />
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.h" />
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.h" />
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorPool.h" />
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.h" />
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.h" />
<ClInclude Include="src\Graphics\Devices\SHVkLogicalDevice.h" />
<ClInclude Include="src\Graphics\Devices\SHVkPhysicalDevice.h" />
<ClInclude Include="src\Graphics\Devices\SHVkPhysicalDeviceLibrary.h" />
<ClInclude Include="src\Graphics\Framebuffer\SHVkFramebuffer.h" />
<ClInclude Include="src\Graphics\Images\SHImageViewDetails.h" />
<ClInclude Include="src\Graphics\Images\SHVkImage.h" />
<ClInclude Include="src\Graphics\Images\SHVkImageView.h" />
<ClInclude Include="src\Graphics\Images\SHVkSampler.h" />
<ClInclude Include="src\Graphics\Instance\SHVkInstance.h" />
<ClInclude Include="src\Graphics\MiddleEnd\Interface\SHGraphicsSystem.h" />
<ClInclude Include="src\Graphics\MiddleEnd\Interface\SHRenderTarget.h" />
<ClInclude Include="src\Graphics\MiddleEnd\PerFrame\SHPerFrameData.h" />
<ClInclude Include="src\Graphics\MiddleEnd\PerFrame\SHRenderContext.h" />
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderModuleLibrary.h" />
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderSourceLibrary.h" />
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderType.h" />
<ClInclude Include="src\Graphics\Pipeline\SHPipelineLayoutParams.h" />
<ClInclude Include="src\Graphics\Pipeline\SHPipelineState.h" />
<ClInclude Include="src\Graphics\Pipeline\SHPipelineType.h" />
<ClInclude Include="src\Graphics\Pipeline\SHPushConstantInterface.h" />
<ClInclude Include="src\Graphics\Pipeline\SHVkPipeline.h" />
<ClInclude Include="src\Graphics\Pipeline\SHVkPipelineLayout.h" />
<ClInclude Include="src\Graphics\Queues\SHVkQueue.h" />
<ClInclude Include="src\Graphics\RenderGraph\SHRenderGraph.h" />
<ClInclude Include="src\Graphics\Renderpass\SHVkAttachDescGen.h" />
<ClInclude Include="src\Graphics\Renderpass\SHVkAttachment.h" />
<ClInclude Include="src\Graphics\Renderpass\SHVkRenderpass.h" />
<ClInclude Include="src\Graphics\Renderpass\SHVkSubpassDescription.h" />
<ClInclude Include="src\Graphics\Renderpass\SHVkSubpassParams.h" />
<ClInclude Include="src\Graphics\SHVkUtil.h" />
<ClInclude Include="src\Graphics\SHVulkanDefines.h" />
<ClInclude Include="src\Graphics\SHVulkanIncludes.h" />
<ClInclude Include="src\Graphics\Shaders\BlockInterface\SHShaderBlockInterface.h" />
<ClInclude Include="src\Graphics\Shaders\SHShaderReflected.h" />
<ClInclude Include="src\Graphics\Shaders\SHVkShaderModule.h" />
<ClInclude Include="src\Graphics\Shaders\spirv-reflect\spirv_reflect.h" />
<ClInclude Include="src\Graphics\Swapchain\SHSwapchainParams.h" />
<ClInclude Include="src\Graphics\Swapchain\SHVkSwapchain.h" />
<ClInclude Include="src\Graphics\Synchronization\SHVkFence.h" />
<ClInclude Include="src\Graphics\Synchronization\SHVkSemaphore.h" />
<ClInclude Include="src\Graphics\VertexDescriptors\SHVertexAttribute.h" />
<ClInclude Include="src\Graphics\Windowing\SHWindow.h" />
<ClInclude Include="src\Graphics\Windowing\SHWindowMap.h" />
<ClInclude Include="src\Graphics\Windowing\Surface\SHVkSurface.h" />
<ClInclude Include="src\Meta\SHIsDetected.h" />
<ClInclude Include="src\Resource\Handle.h" />
<ClInclude Include="src\Resource\Handle.hpp" />
<ClInclude Include="src\Resource\ResourceLibrary.h" />
<ClInclude Include="src\Resource\ResourceLibrary.hpp" />
<ClInclude Include="src\Resource\SparseSet.h" />
<ClInclude Include="src\Resource\SparseSet.hpp" />
<ClInclude Include="src\SHpch.h" />
<ClInclude Include="src\Scene\SHScene.h" />
<ClInclude Include="src\Scene\SHSceneManager.h" />
<ClInclude Include="src\Tools\SHException.h" />
<ClInclude Include="src\Tools\SHExceptionHandler.h" />
<ClInclude Include="src\Tools\SHLogger.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponent.cpp" />
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponentGroup.cpp" />
<ClCompile Include="src\Engine\ECS_Base\Entity\SHEntity.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHComponentManager.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHEntityManager.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHSystemManager.cpp" />
<ClCompile Include="src\Engine\SHEngine.cpp" />
<ClCompile Include="src\Graphics\Buffers\SHVkBuffer.cpp" />
<ClCompile Include="src\Graphics\Commands\SHVkCommandBuffer.cpp" />
<ClCompile Include="src\Graphics\Commands\SHVkCommandPool.cpp" />
<ClCompile Include="src\Graphics\Debugging\SHValidationLayersQuery.cpp" />
<ClCompile Include="src\Graphics\Debugging\SHVkDebugMessenger.cpp" />
<ClCompile Include="src\Graphics\Debugging\SHVulkanDebugUtil.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolManager.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorPool.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.cpp" />
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.cpp" />
<ClCompile Include="src\Graphics\Devices\SHVkLogicalDevice.cpp" />
<ClCompile Include="src\Graphics\Devices\SHVkPhysicalDevice.cpp" />
<ClCompile Include="src\Graphics\Devices\SHVkPhysicalDeviceLibrary.cpp" />
<ClCompile Include="src\Graphics\Framebuffer\SHVkFramebuffer.cpp" />
<ClCompile Include="src\Graphics\Images\SHVkImage.cpp" />
<ClCompile Include="src\Graphics\Images\SHVkImageView.cpp" />
<ClCompile Include="src\Graphics\Images\SHVkSampler.cpp" />
<ClCompile Include="src\Graphics\Instance\SHVkInstance.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\Interface\SHGraphicsSystem.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\Interface\SHRenderTarget.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\PerFrame\SHPerFrameData.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\PerFrame\SHRenderContext.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\Shaders\SHShaderModuleLibrary.cpp" />
<ClCompile Include="src\Graphics\MiddleEnd\Shaders\SHShaderSourceLibrary.cpp" />
<ClCompile Include="src\Graphics\Pipeline\SHPipelineState.cpp" />
<ClCompile Include="src\Graphics\Pipeline\SHPushConstantInterface.cpp" />
<ClCompile Include="src\Graphics\Pipeline\SHVkPipeline.cpp" />
<ClCompile Include="src\Graphics\Pipeline\SHVkPipelineLayout.cpp" />
<ClCompile Include="src\Graphics\Queues\SHVkQueue.cpp" />
<ClCompile Include="src\Graphics\RenderGraph\SHRenderGraph.cpp" />
<ClCompile Include="src\Graphics\Renderpass\SHVkAttachDescGen.cpp" />
<ClCompile Include="src\Graphics\Renderpass\SHVkRenderpass.cpp" />
<ClCompile Include="src\Graphics\Renderpass\SHVkSubpassParams.cpp" />
<ClCompile Include="src\Graphics\SHVkUtil.cpp" />
<ClCompile Include="src\Graphics\SHVulkanIncludes.cpp" />
<ClCompile Include="src\Graphics\Shaders\BlockInterface\SHShaderBlockInterface.cpp" />
<ClCompile Include="src\Graphics\Shaders\SHShaderReflected.cpp" />
<ClCompile Include="src\Graphics\Shaders\SHVkShaderModule.cpp" />
<ClCompile Include="src\Graphics\Shaders\spirv-reflect\spirv_reflect.cpp" />
<ClCompile Include="src\Graphics\Swapchain\SHVkSwapchain.cpp" />
<ClCompile Include="src\Graphics\Synchronization\SHVkFence.cpp" />
<ClCompile Include="src\Graphics\Synchronization\SHVkSemaphore.cpp" />
<ClCompile Include="src\Graphics\VertexDescriptors\SHVertexAttribute.cpp" />
<ClCompile Include="src\Graphics\Windowing\SHWIndowMap.cpp" />
<ClCompile Include="src\Graphics\Windowing\SHWindow.cpp" />
<ClCompile Include="src\Graphics\Windowing\Surface\SHVkSurface.cpp" />
<ClCompile Include="src\Resource\ResourceLibrary.cpp" />
<ClCompile Include="src\SHpch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\Scene\SHSceneManager.cpp" />
<ClCompile Include="src\Tools\SHException.cpp" />
<ClCompile Include="src\Tools\SHExceptionHandler.cpp" />
<ClCompile Include="src\Tools\SHLogger.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dependencies\yamlcpp\yaml-cpp.vcxproj">
<Project>{88F1A057-74BE-FB62-9DD7-E90A890331F1}</Project>
</ProjectReference>
<ProjectReference Include="..\Dependencies\msdf\msdfgen\msdfgen.vcxproj">
<Project>{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}</Project>
</ProjectReference>
<ProjectReference Include="..\Dependencies\msdf\msdf-atlas-gen.vcxproj">
<Project>{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}</Project>
</ProjectReference>
<ProjectReference Include="..\Dependencies\reactphysics3d\reactphysics3d.vcxproj">
<Project>{2ECAB41A-1A98-A820-032C-1947EF988485}</Project>
</ProjectReference>
<ProjectReference Include="..\Dependencies\imgui\ImGui.vcxproj">
<Project>{C0FF640D-2C14-8DBE-F595-301E616989EF}</Project>
</ProjectReference>
<ProjectReference Include="..\Dependencies\spdlog\spdlog.vcxproj">
<Project>{8EAD431C-7A4F-6EF2-630A-82464F4BF542}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,545 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Engine">
<UniqueIdentifier>{DBC7D3B0-C769-FE86-B024-12DB9C6585D7}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base">
<UniqueIdentifier>{7FF59BF8-EB80-09BD-F491-8CB1609C65BD}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\Components">
<UniqueIdentifier>{340D0110-201D-ADE0-89D6-11FF75059C79}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\Entity">
<UniqueIdentifier>{EBFC8BDC-D7F6-B42E-C063-4B3FACFC1A9B}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\General">
<UniqueIdentifier>{6CD692F2-D80D-DB89-E117-3FAD4DCE0183}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\System">
<UniqueIdentifier>{B3E3FAFD-9FDD-2350-884A-BA6074E389BC}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics">
<UniqueIdentifier>{1653CE33-0220-293F-2B39-17E717655ECD}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Buffers">
<UniqueIdentifier>{92C817CE-7EC1-3620-A7F3-1BA5934B162C}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Commands">
<UniqueIdentifier>{17C745C0-83DD-4356-CC54-CF7738AA14DE}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Debugging">
<UniqueIdentifier>{51443AC7-3D28-FB1C-A688-F56F928BE59E}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Descriptors">
<UniqueIdentifier>{573A6CF2-43C9-F5BB-ECE7-09B7D8550662}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Devices">
<UniqueIdentifier>{08DBDC43-F4D3-FB95-1D06-E11A095EDBA1}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Framebuffer">
<UniqueIdentifier>{4AD5CA42-3664-540C-DF82-6807CBF064B2}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Images">
<UniqueIdentifier>{FB5EE099-67EA-4D5E-70FB-D052DC05AA5E}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Instance">
<UniqueIdentifier>{BA26540B-263D-52A1-6FB4-DDC2DB092329}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\MiddleEnd">
<UniqueIdentifier>{4B204703-3704-0859-A064-02AC8C67F2DA}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\MiddleEnd\Interface">
<UniqueIdentifier>{EBA1D3FF-D75C-C3AB-8014-3CF66CAE0D3C}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\MiddleEnd\PerFrame">
<UniqueIdentifier>{8CDBA7C9-F8E8-D5AF-81CF-D19AEDDBA166}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\MiddleEnd\Shaders">
<UniqueIdentifier>{2460C057-1070-6C28-7929-D14665585BC1}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Pipeline">
<UniqueIdentifier>{FBD334F8-67EA-328E-B061-BEAF1CB70316}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Queues">
<UniqueIdentifier>{1DD51CAD-8960-8A71-9271-0D66FE7BE671}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\RenderGraph">
<UniqueIdentifier>{57DAB30C-4369-3DD6-EC87-51D1D8F54D7C}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Renderpass">
<UniqueIdentifier>{9C0DAFD9-086F-8CE7-91DC-D299FD3CC3A6}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Shaders">
<UniqueIdentifier>{EF2D07CC-DB26-261E-0459-0BA3F0B0052A}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Shaders\BlockInterface">
<UniqueIdentifier>{3AEF06DD-A6D2-151D-AFD5-43591B38DC6D}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Shaders\spirv-reflect">
<UniqueIdentifier>{245F5AB0-1085-2417-F9CA-A9E2E58F49E3}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Swapchain">
<UniqueIdentifier>{03DB39DE-EFBE-FA33-581F-F5864422E5B5}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Synchronization">
<UniqueIdentifier>{576DF841-4392-47C2-6CDD-2C52586146E0}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\VertexDescriptors">
<UniqueIdentifier>{75F29FE5-6102-4CB6-CABB-B0D4B6EA3A4F}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Windowing">
<UniqueIdentifier>{5BAB2A92-478F-EBE7-B0EF-E53A9CF2D569}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics\Windowing\Surface">
<UniqueIdentifier>{B3B14D12-9FC1-F9E2-087B-5E01F4A9E87B}</UniqueIdentifier>
</Filter>
<Filter Include="Meta">
<UniqueIdentifier>{AC05897C-983C-8A0D-4129-70102D3F060F}</UniqueIdentifier>
</Filter>
<Filter Include="Resource">
<UniqueIdentifier>{ED6CDF9B-D939-3AA7-0253-284FEE7E6F35}</UniqueIdentifier>
</Filter>
<Filter Include="Scene">
<UniqueIdentifier>{B3F7140E-1F0C-3DBF-E88D-E01E546139F0}</UniqueIdentifier>
</Filter>
<Filter Include="Tools">
<UniqueIdentifier>{16CF2D0E-82E3-55BF-4B65-F91EB73852F0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponent.h">
<Filter>Engine\ECS_Base\Components</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponentGroup.h">
<Filter>Engine\ECS_Base\Components</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\Entity\SHEntity.h">
<Filter>Engine\ECS_Base\Entity</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHFamily.h">
<Filter>Engine\ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHHandleGenerator.h">
<Filter>Engine\ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseBase.h">
<Filter>Engine\ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSet.h">
<Filter>Engine\ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSetContainer.h">
<Filter>Engine\ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\SHECSMacros.h">
<Filter>Engine\ECS_Base</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHComponentManager.h">
<Filter>Engine\ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHEntityManager.h">
<Filter>Engine\ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHSystem.h">
<Filter>Engine\ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHSystemManager.h">
<Filter>Engine\ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\SHEngine.h">
<Filter>Engine</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Buffers\SHVkBuffer.h">
<Filter>Graphics\Buffers</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Commands\SHCommandPoolResetMode.h">
<Filter>Graphics\Commands</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Commands\SHVkCommandBuffer.h">
<Filter>Graphics\Commands</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Commands\SHVkCommandPool.h">
<Filter>Graphics\Commands</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Debugging\SHValidationLayersQuery.h">
<Filter>Graphics\Debugging</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Debugging\SHVkDebugMessenger.h">
<Filter>Graphics\Debugging</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Debugging\SHVulkanDebugUtil.h">
<Filter>Graphics\Debugging</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolManager.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorPool.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.h">
<Filter>Graphics\Descriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Devices\SHVkLogicalDevice.h">
<Filter>Graphics\Devices</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Devices\SHVkPhysicalDevice.h">
<Filter>Graphics\Devices</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Devices\SHVkPhysicalDeviceLibrary.h">
<Filter>Graphics\Devices</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Framebuffer\SHVkFramebuffer.h">
<Filter>Graphics\Framebuffer</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Images\SHImageViewDetails.h">
<Filter>Graphics\Images</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Images\SHVkImage.h">
<Filter>Graphics\Images</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Images\SHVkImageView.h">
<Filter>Graphics\Images</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Images\SHVkSampler.h">
<Filter>Graphics\Images</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Instance\SHVkInstance.h">
<Filter>Graphics\Instance</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\Interface\SHGraphicsSystem.h">
<Filter>Graphics\MiddleEnd\Interface</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\Interface\SHRenderTarget.h">
<Filter>Graphics\MiddleEnd\Interface</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\PerFrame\SHPerFrameData.h">
<Filter>Graphics\MiddleEnd\PerFrame</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\PerFrame\SHRenderContext.h">
<Filter>Graphics\MiddleEnd\PerFrame</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderModuleLibrary.h">
<Filter>Graphics\MiddleEnd\Shaders</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderSourceLibrary.h">
<Filter>Graphics\MiddleEnd\Shaders</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\MiddleEnd\Shaders\SHShaderType.h">
<Filter>Graphics\MiddleEnd\Shaders</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHPipelineLayoutParams.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHPipelineState.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHPipelineType.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHPushConstantInterface.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHVkPipeline.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Pipeline\SHVkPipelineLayout.h">
<Filter>Graphics\Pipeline</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Queues\SHVkQueue.h">
<Filter>Graphics\Queues</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\RenderGraph\SHRenderGraph.h">
<Filter>Graphics\RenderGraph</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Renderpass\SHVkAttachDescGen.h">
<Filter>Graphics\Renderpass</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Renderpass\SHVkAttachment.h">
<Filter>Graphics\Renderpass</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Renderpass\SHVkRenderpass.h">
<Filter>Graphics\Renderpass</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Renderpass\SHVkSubpassDescription.h">
<Filter>Graphics\Renderpass</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Renderpass\SHVkSubpassParams.h">
<Filter>Graphics\Renderpass</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\SHVkUtil.h">
<Filter>Graphics</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\SHVulkanDefines.h">
<Filter>Graphics</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\SHVulkanIncludes.h">
<Filter>Graphics</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Shaders\BlockInterface\SHShaderBlockInterface.h">
<Filter>Graphics\Shaders\BlockInterface</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Shaders\SHShaderReflected.h">
<Filter>Graphics\Shaders</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Shaders\SHVkShaderModule.h">
<Filter>Graphics\Shaders</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Shaders\spirv-reflect\spirv_reflect.h">
<Filter>Graphics\Shaders\spirv-reflect</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Swapchain\SHSwapchainParams.h">
<Filter>Graphics\Swapchain</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Swapchain\SHVkSwapchain.h">
<Filter>Graphics\Swapchain</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Synchronization\SHVkFence.h">
<Filter>Graphics\Synchronization</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Synchronization\SHVkSemaphore.h">
<Filter>Graphics\Synchronization</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\VertexDescriptors\SHVertexAttribute.h">
<Filter>Graphics\VertexDescriptors</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Windowing\SHWindow.h">
<Filter>Graphics\Windowing</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Windowing\SHWindowMap.h">
<Filter>Graphics\Windowing</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Windowing\Surface\SHVkSurface.h">
<Filter>Graphics\Windowing\Surface</Filter>
</ClInclude>
<ClInclude Include="src\Meta\SHIsDetected.h">
<Filter>Meta</Filter>
</ClInclude>
<ClInclude Include="src\Resource\Handle.h">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\Resource\Handle.hpp">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\Resource\ResourceLibrary.h">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\Resource\ResourceLibrary.hpp">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\Resource\SparseSet.h">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\Resource\SparseSet.hpp">
<Filter>Resource</Filter>
</ClInclude>
<ClInclude Include="src\SHpch.h" />
<ClInclude Include="src\Scene\SHScene.h">
<Filter>Scene</Filter>
</ClInclude>
<ClInclude Include="src\Scene\SHSceneManager.h">
<Filter>Scene</Filter>
</ClInclude>
<ClInclude Include="src\Tools\SHException.h">
<Filter>Tools</Filter>
</ClInclude>
<ClInclude Include="src\Tools\SHExceptionHandler.h">
<Filter>Tools</Filter>
</ClInclude>
<ClInclude Include="src\Tools\SHLogger.h">
<Filter>Tools</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponent.cpp">
<Filter>Engine\ECS_Base\Components</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponentGroup.cpp">
<Filter>Engine\ECS_Base\Components</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\Entity\SHEntity.cpp">
<Filter>Engine\ECS_Base\Entity</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHComponentManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHEntityManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHSystemManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\SHEngine.cpp">
<Filter>Engine</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Buffers\SHVkBuffer.cpp">
<Filter>Graphics\Buffers</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Commands\SHVkCommandBuffer.cpp">
<Filter>Graphics\Commands</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Commands\SHVkCommandPool.cpp">
<Filter>Graphics\Commands</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Debugging\SHValidationLayersQuery.cpp">
<Filter>Graphics\Debugging</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Debugging\SHVkDebugMessenger.cpp">
<Filter>Graphics\Debugging</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Debugging\SHVulkanDebugUtil.cpp">
<Filter>Graphics\Debugging</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolManager.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorPoolStorage.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHDescriptorSetUpdater.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorPool.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetGroup.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Descriptors\SHVkDescriptorSetLayout.cpp">
<Filter>Graphics\Descriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Devices\SHVkLogicalDevice.cpp">
<Filter>Graphics\Devices</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Devices\SHVkPhysicalDevice.cpp">
<Filter>Graphics\Devices</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Devices\SHVkPhysicalDeviceLibrary.cpp">
<Filter>Graphics\Devices</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Framebuffer\SHVkFramebuffer.cpp">
<Filter>Graphics\Framebuffer</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Images\SHVkImage.cpp">
<Filter>Graphics\Images</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Images\SHVkImageView.cpp">
<Filter>Graphics\Images</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Images\SHVkSampler.cpp">
<Filter>Graphics\Images</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Instance\SHVkInstance.cpp">
<Filter>Graphics\Instance</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\Interface\SHGraphicsSystem.cpp">
<Filter>Graphics\MiddleEnd\Interface</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\Interface\SHRenderTarget.cpp">
<Filter>Graphics\MiddleEnd\Interface</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\PerFrame\SHPerFrameData.cpp">
<Filter>Graphics\MiddleEnd\PerFrame</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\PerFrame\SHRenderContext.cpp">
<Filter>Graphics\MiddleEnd\PerFrame</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\Shaders\SHShaderModuleLibrary.cpp">
<Filter>Graphics\MiddleEnd\Shaders</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\MiddleEnd\Shaders\SHShaderSourceLibrary.cpp">
<Filter>Graphics\MiddleEnd\Shaders</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Pipeline\SHPipelineState.cpp">
<Filter>Graphics\Pipeline</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Pipeline\SHPushConstantInterface.cpp">
<Filter>Graphics\Pipeline</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Pipeline\SHVkPipeline.cpp">
<Filter>Graphics\Pipeline</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Pipeline\SHVkPipelineLayout.cpp">
<Filter>Graphics\Pipeline</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Queues\SHVkQueue.cpp">
<Filter>Graphics\Queues</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\RenderGraph\SHRenderGraph.cpp">
<Filter>Graphics\RenderGraph</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Renderpass\SHVkAttachDescGen.cpp">
<Filter>Graphics\Renderpass</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Renderpass\SHVkRenderpass.cpp">
<Filter>Graphics\Renderpass</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Renderpass\SHVkSubpassParams.cpp">
<Filter>Graphics\Renderpass</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\SHVkUtil.cpp">
<Filter>Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\SHVulkanIncludes.cpp">
<Filter>Graphics</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Shaders\BlockInterface\SHShaderBlockInterface.cpp">
<Filter>Graphics\Shaders\BlockInterface</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Shaders\SHShaderReflected.cpp">
<Filter>Graphics\Shaders</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Shaders\SHVkShaderModule.cpp">
<Filter>Graphics\Shaders</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Shaders\spirv-reflect\spirv_reflect.cpp">
<Filter>Graphics\Shaders\spirv-reflect</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Swapchain\SHVkSwapchain.cpp">
<Filter>Graphics\Swapchain</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Synchronization\SHVkFence.cpp">
<Filter>Graphics\Synchronization</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Synchronization\SHVkSemaphore.cpp">
<Filter>Graphics\Synchronization</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\VertexDescriptors\SHVertexAttribute.cpp">
<Filter>Graphics\VertexDescriptors</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Windowing\SHWIndowMap.cpp">
<Filter>Graphics\Windowing</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Windowing\SHWindow.cpp">
<Filter>Graphics\Windowing</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Windowing\Surface\SHVkSurface.cpp">
<Filter>Graphics\Windowing\Surface</Filter>
</ClCompile>
<ClCompile Include="src\Resource\ResourceLibrary.cpp">
<Filter>Resource</Filter>
</ClCompile>
<ClCompile Include="src\SHpch.cpp" />
<ClCompile Include="src\Scene\SHSceneManager.cpp">
<Filter>Scene</Filter>
</ClCompile>
<ClCompile Include="src\Tools\SHException.cpp">
<Filter>Tools</Filter>
</ClCompile>
<ClCompile Include="src\Tools\SHExceptionHandler.cpp">
<Filter>Tools</Filter>
</ClCompile>
<ClCompile Include="src\Tools\SHLogger.cpp">
<Filter>Tools</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,13 +1,13 @@
project "SHADE_Engine"
kind "StaticLib"
kind "SharedLib"
language "C++"
cppdialect "C++latest"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
cppdialect "C++20"
targetdir (outputdir)
objdir (interdir)
systemversion "latest"
pchheader "SHpch.h"
pchsource "%{prj.location}/src/SHpch.cpp"
staticruntime "on"
staticruntime "off"
files
{
@ -35,11 +35,12 @@ project "SHADE_Engine"
"%{IncludeDir.tracy}",
"%{IncludeDir.VMA}/include",
"%{IncludeDir.yamlcpp}",
"%{IncludeDir.ktx}/include",
"%{IncludeDir.SDL}/include",
"%{IncludeDir.RTTR}/include",
"%{IncludeDir.reactphysics3d}/include",
"%{IncludeDir.VULKAN}/include",
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
"%{IncludeDir.dotnet}/include",
}
externalwarnings "Off"
@ -51,8 +52,8 @@ project "SHADE_Engine"
"%{IncludeDir.assimp}/lib/Debug",
"%{IncludeDir.assimp}/lib/Release",
"%{IncludeDir.RTTR}/lib",
"%{IncludeDir.ktx}/lib/Debug",
"%{IncludeDir.ktx}/lib/Release",
"%{IncludeDir.SDL}/lib",
"%{IncludeDir.spdlog}/lib"
}
links
@ -62,8 +63,16 @@ project "SHADE_Engine"
"msdf-atlas-gen",
"reactphysics3d",
"imgui",
"spdlog",
"vulkan-1.lib"
"vulkan-1.lib",
"SDL2.lib",
"SDL2main.lib",
"shaderc_shared.lib",
"shlwapi.lib"
}
disablewarnings
{
"4251"
}
defines
@ -71,7 +80,8 @@ project "SHADE_Engine"
"_LIB",
"_GLFW_INCLUDE_NONE",
"MSDFGEN_USE_CPP11",
"NOMINMAX"
"NOMINMAX",
"SH_API_EXPORT"
}
flags
@ -86,7 +96,13 @@ project "SHADE_Engine"
"msdf-atlas-gen",
"reactphysics3d",
"imgui",
"spdlog",
}
postbuildcommands
{
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}/bin\" \"$(OutDir)\"",
"xcopy /r /y /q \"%{IncludeDir.SDL}/lib/SDL2.dll\" \"$(OutDir)\"",
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}/bin\" \"$(OutDir)\""
}
warnings 'Extra'
@ -94,11 +110,11 @@ project "SHADE_Engine"
filter "configurations:Debug"
symbols "On"
defines {"_DEBUG"}
links{"assimp-vc142-mtd.lib", "ktxd.lib", "librttr_core_d.lib"}
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
filter "configurations:Release"
optimize "On"
defines{"_RELEASE"}
links{"assimp-vc142-mt.lib", "ktx.lib", "librttr_core.lib"}
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}

View File

@ -0,0 +1,28 @@
/************************************************************************************//*!
\file SHCommonTypes.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 8, 2022
\brief Contains the definitions of type alias for commonly used units for
clarity and convenience.
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
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Type used to mark a value that is supposed to represent a size in bytes.
*/
/***********************************************************************************/
using Byte = size_t;
}

View File

@ -14,13 +14,14 @@
#include "SHpch.h"
#include "../SHECSMacros.h"
#include "SH_API.h"
namespace SHADE
{
class SHComponentManager;
class SHComponent
class SH_API SHComponent
{
friend SHComponentManager;

View File

@ -28,7 +28,7 @@ namespace SHADE
//SHEntityManager::RemoveEntity(this->entityID);
}
EntityID SHEntity::GetEID() noexcept
EntityID SHEntity::GetEID() const noexcept
{
return this->entityID;
}

View File

@ -15,6 +15,7 @@
#include "../Components/SHComponent.h"
#include "../System/SHComponentManager.h"
//#include "../../Scene/SHSceneNode.h"
#include "SH_API.h"
@ -23,7 +24,7 @@ namespace SHADE
class SHComponentManager;
class SHEntityManager;
class SHEntity
class SH_API SHEntity
{
public:
@ -77,7 +78,7 @@ namespace SHADE
* \return uint32_t
* The entityID of this Entity object.
***************************************************************************/
EntityID GetEID() noexcept;
EntityID GetEID() const noexcept;
/*!*************************************************************************
* \brief Set the Active object

View File

@ -19,13 +19,14 @@
#include "../Components/SHComponent.h"
#include "../Components/SHComponentGroup.h"
//#include "Scene/SHSceneNode.h"
#include "SH_API.h"
#include <cassert>
namespace SHADE
{
class SHComponentManager
class SH_API SHComponentManager
{
private:
@ -34,7 +35,7 @@ namespace SHADE
//The Container of all Componentgroups
static std::vector<SHComponentGroup> componentGroups;
friend class SHSceneNode;
friend struct SHSceneNode;

View File

@ -22,11 +22,12 @@
#include "../Components/SHComponent.h"
#include "../General/SHHandleGenerator.h"
#include "../SHECSMacros.h"
#include "SH_API.h"
namespace SHADE
{
class SHEntityManager
class SH_API SHEntityManager
{
private:
static std::vector<std::unique_ptr<SHEntity>> entityVec;

View File

@ -0,0 +1,22 @@
/******************************************************************************
* \file SHEvent.h
* \author Loh Xiao Qi
* \brief Event class declaration
*
* \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 "SHEventDefines.h"
namespace SHADE
{
struct SHEvent
{
SHEventIdentifier type;
SHEventDataPtr dataPtr;
SHEventHandle handle;
};
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "SHpch.h"
typedef uint32_t SHEventIdentifier;
typedef uint32_t SHEventHandle;
typedef void* SHEventDataPtr;
//Add your event identifiers here:
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};

View File

@ -0,0 +1,107 @@
/******************************************************************************
* \file SHEventManager.cpp
* \author Loh Xiao Qi
* \brief Function Implmentations for SHEventManager
*
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
* or disclosure of this file or its contents without the prior
* written consent of Digipen Institute of Technology is prohibited
******************************************************************************/
#include "SHpch.h"
#include "SHEventManager.h"
namespace SHADE
{
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
std::unordered_map<SHEventHandle, SHEventDataPtr> SHEventManager::dataEventMap;
SHEventHandle SHEventManager::handleCounter{ 0 };
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Templated type for every type of event
* \brief Receives event from the listeners.
****************************************************************************/
void SHEventManager::CatchEvent(SHEvent event)
{
// Do something with the event
Broadcast(event);
}
/****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed
* into event manager to be called when events are broadcasted.
* \param SHEventIdentifier - package type that corresponding subscriber is
* subscribing to.
* \brief Links a function pointer from a subscriber to a particular
* package type
****************************************************************************/
void SHEventManager::SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
RegisterReceiverToType(pkgType, receiver);
}
template<typename T>
T* SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
{
SHEventDataPtr ptr = new std::byte[sizeof(data)];
std::memcpy(ptr, &data, sizeof(data));
CatchEvent(
{
eventType,
ptr,
handleCounter++
}
);
return reinterpret_cast<T*>(ptr);
}
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
void SHEventManager::RegisterReceiverToType(
SHEventIdentifier pkgType, ReceiverPtr receiver)
{
if (packageReceiverRegistry.contains(pkgType))
{
packageReceiverRegistry[pkgType].emplace_back(receiver);
}
else
{
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
}
}
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
void SHEventManager::Broadcast(SHEvent const& event)
{
ResponseVec& receivers{ packageReceiverRegistry[event.type] };
for (auto& receiver : receivers)
{
receiver->Receive(event);
}
//auto& funcs{ ackageReceiverRegistry[event.GetType()] };
//for (auto func : funcs)
//{
// func(event.GetData());
//}
}
}

View File

@ -0,0 +1,116 @@
/******************************************************************************
* \file SHEventManager.h
* \author Loh Xiao Qi
* \brief Class declaration for event manager.
*
* \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 "SHEvent.h"
#include "SHEventReceiver.h"
#include <unordered_map>
#include <functional>
/******************************************************************************
INSTRUCTIONS FOR USE:
On broadcaster side:
1. Create a struct/class to contain the data that you would need to send
in the event.
2. Create unique event identifier in SHEventDefines.h, follow the example
provided.
3. When ready to send the event, call
SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER);
Headers required: SHEventManager.h
On Receiver side:
1. Create a function with the signature:
SHEventHandle FunctionName(SHEvent);
2. In the init function of the class, copy the below in and replace the
necessary:
std::shared_ptr<SHEventReceiverSpec<ReceiverClass>> thisReceiver{
std::make_shared<SHEventReceiverSpec<ReceiverClass>>(this, &ReceiverClass::ReceiveFunction)
};
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
SHEventManager::SubscribeTo(EVENT_IDENTIFIER, receiver);
ReceiverClass is the class that the receiver is in. E.g., SHPhysicsSystem
3. Note: The EventIdentifier should match all that is defined in
SHEventDefines.h so check there. When the receiver catches the event, it
needs to know the struct that the broadcaster is using to cast the void*
properly.
Headers required: SHEventManager.h, SHEventReceiver.h
If you have any questions/suggestions for improvement lmk.
******************************************************************************/
namespace SHADE
{
using ResponseFunction = std::function<SHEventHandle(SHEvent)>;
using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
using ResponseVec = std::vector<ReceiverPtr>;
using StaticResponseVec = std::vector<ResponseFunction>;
using EventManagerListener = std::function<void(SHEvent)>;
class SHEventManager
{
public:
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Templated type for every type of event
* \brief Receives event from the listeners.
****************************************************************************/
static void CatchEvent(SHEvent);
/****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed
* into event manager to be called when events are broadcasted.
* \param SHPackageType - package type that corresponding subscriber is
* subscribing to.
* \brief Links a function pointer from a subscriber to a particular
* package type
****************************************************************************/
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
template<typename T>
static T* BroadcastEvent(T data, SHEventIdentifier eventType);
private:
// Registry for broadcasters and subscribers
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
static std::unordered_map<SHEventHandle, SHEventDataPtr> dataEventMap;
static SHEventHandle handleCounter;
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
static void Broadcast(SHEvent const&);
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
static void RegisterReceiverToType(SHEventIdentifier, ReceiverPtr);
};
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "SHEvent.h"
namespace SHADE
{
class SHEventReceiver
{
private:
public:
virtual void Receive(SHEvent) = 0;
};
template<typename T>
class SHEventReceiverSpec : public SHEventReceiver
{
private:
T* object;
SHEventHandle(T::*callback)(SHEvent);
public:
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventDataPtr))
:SHEventReceiver(), object{ obj }, callback{ cb }
{
}
void Receive(SHEvent evt) override
{
(object->*callback)(evt);
}
};
}

View File

@ -0,0 +1,134 @@
/*********************************************************************
* \file SHFramerateController.cpp
* \author Ryan Wang Nian Jing
* \brief Definition for functions of the framerate controller
* Handles changing of scenes and manages loop (timestep, etc.)
*
* \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 <chrono>
#include <cassert>
#include <SHpch.h>
#include "SHFramerateController.h"
#include "../Tools/SHLogger.h"
namespace SHADE
{
//Init statics
double SHFramerateController::fixedTimestep = 0.01;
SHScene* SHFramerateController::previousScene = nullptr;
SHScene* SHFramerateController::currentScene = nullptr;
SHScene* SHFramerateController::nextScene = nullptr;
bool SHFramerateController::toRestart = false;
bool SHFramerateController::toQuit = false;
//Scene manager loop
void SHFramerateController::Run(SHScene* firstScene)
{
if (firstScene == nullptr)
{
SHLOG_ERROR("Do not pass a nullptr as the firstScene");
return;
}
//Set quit and restart flags to false
toQuit = false;
toRestart = false;
//Set the first scene to run
previousScene = firstScene;
currentScene = firstScene;
nextScene = firstScene;
while (!toQuit)
{
if (toRestart)
{
//Restart current scene
currentScene = previousScene;
nextScene = previousScene;
toRestart = false;
}
else
{
//Move to a new scene
currentScene->Load();
}
//Call init function of current scene
currentScene->Init();
//Have an initial value
//This frame time will fluctuate
//SHOULD be larger than the fixed timestep
//TODO this might need to be changed
double variableLastFrameTime = fixedTimestep;
//Time accumulator for meshing between fixed and variable timesteps
double accumulator = 0.0;
//Start state loop
while (currentScene == nextScene && !toQuit && !toRestart)
{
//Use of new STL timing functions
//https://en.cppreference.com/w/cpp/chrono
std::chrono::duration<double> deltaTime;
auto startTime = std::chrono::high_resolution_clock::now();
//Whittle down the accumulator by continuously simulating
for (; accumulator > fixedTimestep; accumulator -= fixedTimestep)
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//TODO change to double
currentScene->Update((float)fixedTimestep);
}
//Interpolation
//Manage the alpha value well
//https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
//Key points:
//1) Any time you add or subtract floats of widely varying
// magnitudes, you need to watch for loss of precision
//2) Sometimes using double instead of float is the correct
// solution, but often a more stable algorithm is more important
//3) calcT() should probably use double (to give sufficient
// precision after many hours of gameplay)
//TODO awaiting approval to use this
//double alpha = accumulator / fixedTimestep;
//assert alpha does not go out of range
currentScene->Render();
auto endTime = std::chrono::high_resolution_clock::now();
deltaTime = endTime - startTime;
variableLastFrameTime = deltaTime.count();
//Increase accumulator
accumulator += variableLastFrameTime;
}
//Free once out of scene loop
currentScene->Free();
//Check if not to restart state
//If so, unload
if (!toRestart) currentScene->Unload();
//Shift forward scenes
previousScene = currentScene;
currentScene = nextScene;
}
}
}

View File

@ -0,0 +1,62 @@
/*********************************************************************
* \file SHFramerateController.h
* \author Ryan Wang Nian Jing
* \brief Declaration for the framerate controller
* Handles changing of scenes and manages loop (timestep, etc.)
*
* \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.
*********************************************************************/
#ifndef SH_FRAMERATECONTROLLER_H
#define SH_FRAMERATECONTROLLER_H
#pragma once
#include "../Scene/SHScene.h"
namespace SHADE
{
class SHFramerateController
{
private:
//scene pointers
static SHScene* previousScene;
static SHScene* currentScene;
static SHScene* nextScene;
//Flags
//Whether the flag has been raised for the game to be quit
static bool toQuit;
//Whether the flag has been raised for the current scene to restart
static bool toRestart;
public:
//Fixed timestep value for physics. Default at 1/100th of a second.
//Should be lower than the variable refresh rate
static double fixedTimestep;
//Scene Manager Loop
//This loop is vital to the game because it runs for as long as the game
//runs. Before entering, initialise vital systems for game. After exiting,
//free these vital systems before finishing the main() function and
//terminating the game
//Parameter of firstScene is what scene the game should start with
static void Run(SHScene* firstScene);
//Set the flag to restart the current game scene
static inline void RestartScene() { toRestart = true; }
//Set the flag to halt running of the scene manager and quit the game
static inline void QuitGame() { toQuit = true; }
//Set the next scene to be excuted
//This will tell the scene manager to
//halt execution of the current scene and prepare
//execution of the next
static inline void SetNextScene(SHScene* const next) { nextScene = next; }
};
}
#endif

View File

@ -0,0 +1,135 @@
#include "SHpch.h"
#include "SHFileSystem.h"
#include "fileapi.h"
#include <filesystem>
#include <cassert>
#include <queue>
namespace SHADE
{
char const FOLDER_MAX_COUNT {15};
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders;
FolderPointer SHFileSystem::root {nullptr};
SHFolder::SHFolder(FolderHandle id, FolderName name)
:id{ id }, name{ name }, subFolders(0), folded{ false }, path{""}
{
}
FolderLocation SHFileSystem::CreateNewFolderHere(FolderName name, FolderLocation here) noexcept
{
if (here == 0)
{
if (!folders.contains(0))
{
folders[0] = std::make_unique<SHFolder>(0, "root");
}
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
auto const location = static_cast<FolderLocation>(count);
CreateFolder(folders[0]->path, here, location, name);
return location;
}
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
FolderHandle location = here;
location <<= FOLDER_BIT_ALLOCATE;
location |= count;
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
CreateFolder(folders[0]->path, here, location, name);
return location;
}
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
{
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
for (auto const& subFolder : folders[location->id]->subFolders)
{
DeleteFolder(subFolder);
}
RemoveDirectoryA(folders[location->id]->path.c_str());
return true;
}
void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
{
std::queue<FolderPointer> folderQueue;
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
while (!folderQueue.empty())
{
auto folder = folderQueue.front();
folderQueue.pop();
FolderCounter count = 0;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
{
if (!dirEntry.is_directory())
{
continue;
}
FolderLocation location = folder->id;
location <<= FOLDER_BIT_ALLOCATE;
location |= ++count;
std::string name = dirEntry.path().string();
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
FolderPointer newFolder{ RegisterFolder(
dirEntry.path().string(),
folder->id,
location,
name)
};
folderQueue.push(newFolder);
folder->subFolders.push_back(newFolder);
}
}
}
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
{
assert(
CreateDirectoryA(path.c_str(), nullptr),
"Failed to create folder\n"
);
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return folders[location].get();
}
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
namespace SHADE
{
class SHFolder;
typedef unsigned char FolderCounter;
typedef unsigned char FileCounter;
typedef uint64_t FolderLocation;
typedef uint64_t FolderHandle;
typedef std::string FolderName;
typedef std::string FolderPath;
typedef SHFolder* FolderPointer;
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
constexpr char FOLDER_MAX_DEPTH{ 16 };
class SHFolder
{
public:
SHFolder(FolderHandle id, FolderName name);
FolderHandle id;
FolderName name;
std::vector<FolderPointer> subFolders;
bool folded;
private:
FolderPath path;
friend class SHFileSystem;
};
class SHFileSystem
{
public:
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
static bool DeleteFolder(FolderPointer location) noexcept;
static void StartupFillDirectories(FolderPath path) noexcept;
private:
static FolderPointer root;
static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders;
static FolderPointer CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
};
}

View File

@ -21,7 +21,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/SHVulkanIncludes.h"
#include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
#include "Engine/ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystem.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
namespace SHADE

View File

@ -5,6 +5,7 @@
#include <functional>
#include <unordered_map>
#include "SHWindowMap.h"
#include "SH_API.h"
namespace SHADE
{
@ -67,7 +68,7 @@ namespace SHADE
std::string icoPath = "";
};
class SHWindow
class SH_API SHWindow
{
public:
using SHVec2 = std::pair<uint32_t, uint32_t>;

View File

@ -0,0 +1,9 @@
#pragma once
#include "SHMathHelpers.h"
#include "Vector/SHVec2.h"
#include "Vector/SHVec3.h"
#include "Vector/SHVec4.h"
#include "SHMatrix.h"

View File

@ -0,0 +1,34 @@
/****************************************************************************************
* \file SHMathHelpers.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for various mathematical helper functions.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#include <SHpch.h>
#include <chrono>
// Primary Header
#include "SHMathHelpers.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
std::default_random_engine SHMath::rng;
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHMath::Initialise()
{
const unsigned SEED = static_cast<unsigned>(std::chrono::system_clock::now().time_since_epoch().count());
rng.seed(SEED);
}
}

View File

@ -0,0 +1,100 @@
/****************************************************************************************
* \file SHMathHelpers.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for various mathematical helper functions.
*
* \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 <type_traits>
#include <numeric>
#include <numbers>
#include <random>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Concepts */
/*-----------------------------------------------------------------------------------*/
template <typename T>
concept IsArithmetic = std::is_arithmetic_v<T>;
template <typename T>
concept IsIntegral = std::is_integral_v<T>;
template <typename T>
concept IsFloatingPoint = std::is_floating_point_v<T>;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHMath
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
/** Standard Epsilon value for comparing Single-Precision Floating-Point values. */
static constexpr float EPSILON = 0.001f;
/** Single-Precision Floating-Point value of infinity */
static constexpr float INF = std::numeric_limits<float>::infinity();
static constexpr float PI = std::numbers::pi_v<float>;
static constexpr float HALF_PI = PI * 0.5f;
static constexpr float TWO_PI = 2.0f * PI;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
static void Initialise ();
template <IsArithmetic T>
[[nodiscard]] static constexpr T DegreesToRadians (T angleInDeg);
template <IsArithmetic T>
[[nodiscard]] static constexpr T RadiansToDegrees (T angleInRad);
template <IsArithmetic T>
[[nodiscard]] static T Lerp (T a, T b, T alpha);
template <IsArithmetic T>
[[nodiscard]] static T ClampedLerp (T a, T b, T alpha, T alphaMin, T alphaMax);
template <IsArithmetic T>
[[nodiscard]] static T Wrap (T value, T min, T max);
template <IsArithmetic T = float>
[[nodiscard]] static T GenerateRandomNumber (T lowerBound = 0, T upperBound = 1);
/**
* @brief Compares two floating-point values for equality within given tolerances.
* @tparam T A floating-point type
* @param lhs A floating-point value.
* @param rhs A floating-point value.
* @param absTolerance The absolute tolerance to compare the values for equality.
* @param relTolerance The relative tolerance for comparing large values for equality.
* @returns True if the values are equal within the specified tolerances.
*/
template <IsFloatingPoint T = float>
[[nodiscard]] static bool CompareFloat (T lhs, T rhs, T absTolerance = EPSILON, T relTolerance = EPSILON);
private:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static std::default_random_engine rng;
};
} // namespace SHADE
#include "SHMathHelpers.hpp"

View File

@ -0,0 +1,90 @@
/****************************************************************************************
* \file SHMathHelpers.hpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for various templated mathematical helper functions.
*
* \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
// Primary Header
#include "SHMathHelpers.h"
#include <cmath>
#include <algorithm>
// TODOs (Diren): Include pch?
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Function Members Definitions */
/*-----------------------------------------------------------------------------------*/
template <IsArithmetic T>
constexpr T SHMath::DegreesToRadians(T angleInDeg)
{
return angleInDeg * static_cast<T>(PI / 180.0f);
}
template <IsArithmetic T>
constexpr T SHMath::RadiansToDegrees(T angleInRad)
{
return angleInRad * static_cast<T>(180.0f / PI);
}
template <IsArithmetic T>
T SHMath::Lerp(T a, T b, T alpha)
{
return a + alpha * (b - a);
}
template <IsArithmetic T>
T SHMath::ClampedLerp(T a, T b, T alpha, T alphaMin, T alphaMax)
{
const T T_ACTUAL = std::clamp(alpha, alphaMin, alphaMax);
return a + T_ACTUAL * (b - a);
}
template <IsArithmetic T>
T SHMath::Wrap(T value, T min, T max)
{
while (value < min)
{
value = max - (min - value);
}
while (value > max)
{
value = min + (value - max);
}
return value;
}
template <IsArithmetic T>
T SHMath::GenerateRandomNumber(T lowerBound, T upperBound)
{
if constexpr (IsIntegral<T>)
{
std::uniform_int_distribution<T> distribution(lowerBound, upperBound);
return distribution(rng);
}
if constexpr (IsFloatingPoint<T>)
{
std::uniform_real_distribution<T> distribution(lowerBound, upperBound);
return distribution(rng);
}
}
template <IsFloatingPoint T>
bool CompareFloat(T lhs, T rhs, T absTolerance, T relTolerance)
{
return std::fabs(lhs - rhs) <= std::max(absTolerance, relTolerance * std::max(abs(lhs), abs(rhs)));
}
} // namespace SHADE

View File

@ -0,0 +1,601 @@
/****************************************************************************************
* \file SHMatrix.hpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Matrix.
*
* \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 "SHMatrix.h"
#include "Vector/SHVec2.h"
#include "Vector/SHVec3.h"
#include "Vector/SHVec4.h"
#include "SHQuaternion.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHMatrix SHMatrix::Identity
{
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHMatrix::SHMatrix() noexcept
: XMFLOAT4X4
(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
)
{}
SHMatrix::SHMatrix
(
const SHVec4& r0, const SHVec4& r1,
const SHVec4& r2, const SHVec4& r3
) noexcept
: XMFLOAT4X4
(
r0.x, r0.y, r0.z, r0.w,
r1.x, r1.y, r1.z, r1.w,
r2.x, r2.y, r2.z, r2.w,
r3.x, r3.y, r3.z, r3.w
)
{}
SHMatrix::SHMatrix
(
float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33
) noexcept
: XMFLOAT4X4
(
m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33
)
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHMatrix& SHMatrix::operator+=(const SHMatrix& rhs) noexcept
{
return *this = *this + rhs;
}
SHMatrix& SHMatrix::operator-=(const SHMatrix& rhs) noexcept
{
return *this = *this - rhs;
}
SHMatrix& SHMatrix::operator*=(const SHMatrix& rhs) noexcept
{
return *this = *this * rhs;
}
SHMatrix& SHMatrix::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHMatrix& SHMatrix::operator/=(const SHMatrix& rhs) noexcept
{
return *this = *this / rhs;
}
SHMatrix& SHMatrix::operator/=(float rhs) noexcept
{
return *this = *this / rhs;
}
SHMatrix SHMatrix::operator+(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorAdd(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorAdd(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorAdd(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorAdd(L4, R4));
return result;
}
SHMatrix SHMatrix::operator-(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorSubtract(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorSubtract(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorSubtract(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorSubtract(L4, R4));
return result;
}
SHMatrix SHMatrix::operator-() const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorNegate(L1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorNegate(L2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorNegate(L3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorNegate(L4));
return result;
}
SHMatrix SHMatrix::operator*(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMMATRIX M1 = XMLoadFloat4x4(this);
const XMMATRIX M2 = XMLoadFloat4x4(&rhs);
XMStoreFloat4x4(&result, XMMatrixMultiply(M1, M2));
return result;
}
SHVec3 SHMatrix::operator*(const SHVec3& rhs) const noexcept
{
return SHVec3::Transform(rhs, *this);
}
SHVec4 SHMatrix::operator*(const SHVec4& rhs) const noexcept
{
return SHVec4::Transform3D(rhs, *this);
}
SHMatrix SHMatrix::operator*(float rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorScale(L1, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorScale(L2, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorScale(L3, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorScale(L4, rhs));
return result;
}
SHMatrix SHMatrix::operator/(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorDivide(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorDivide(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorDivide(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorDivide(L4, R4));
return result;
}
SHMatrix SHMatrix::operator/(float rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const float INV_RHS = 1.0f / rhs;
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorScale(L1, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorScale(L2, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorScale(L3, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorScale(L4, INV_RHS));
return result;
}
bool SHMatrix::operator==(const SHMatrix& rhs) const noexcept
{
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
return
(
XMVector4Equal(L1, R1)
&& XMVector4Equal(L2, R2)
&& XMVector4Equal(L3, R4)
&& XMVector4Equal(L4, R4)
) != 0;
}
bool SHMatrix::operator!=(const SHMatrix& rhs) const noexcept
{
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
return
(
XMVector4NotEqual(L1, R1)
|| XMVector4NotEqual(L2, R2)
|| XMVector4NotEqual(L3, R4)
|| XMVector4NotEqual(L4, R4)
) != 0;
}
SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept
{
return rhs * lhs;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHMatrix::Transpose() noexcept
{
const XMMATRIX M = XMLoadFloat4x4(this);
XMStoreFloat4x4(this, XMMatrixTranspose(M));
}
void SHMatrix::Invert() noexcept
{
const XMMATRIX M = XMLoadFloat4x4(this);
XMStoreFloat4x4(this, XMMatrixInverse(nullptr, M));
}
float SHMatrix::Determinant() const noexcept
{
const XMMATRIX M = XMLoadFloat4x4(this);
return XMVectorGetX(XMMatrixDeterminant(M));
}
std::string SHMatrix::ToString() const noexcept
{
std::stringstream ss;
ss << std::fixed << std::setprecision(3);
ss << "| " << _11 << ", " << _12 << ", " << _13 << ", " << _14 << " |\n";
ss << "| " << _21 << ", " << _22 << ", " << _23 << ", " << _24 << " |\n";
ss << "| " << _31 << ", " << _32 << ", " << _33 << ", " << _34 << " |\n";
ss << "| " << _41 << ", " << _42 << ", " << _43 << ", " << _44 << " |";
return ss.str();
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHMatrix SHMatrix::Transpose(const SHMatrix& matrix) noexcept
{
SHMatrix result;
const XMMATRIX M = XMLoadFloat4x4(&matrix);
XMStoreFloat4x4(&result, XMMatrixTranspose(M));
return result;
}
SHMatrix SHMatrix::Inverse(const SHMatrix& matrix) noexcept
{
SHMatrix result;
const XMMATRIX M = XMLoadFloat4x4(&matrix);
XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, M));
return result;
}
SHMatrix SHMatrix::Translate(float x, float y, float z) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixTranslation(x, y, z));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Translate(const SHVec3& pos) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Rotate(const SHVec3& axis, float angleInRad) noexcept
{
SHMatrix result;
const XMVECTOR A = XMLoadFloat3(&axis);
XMStoreFloat4x4(&result, XMMatrixRotationAxis(A, angleInRad));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Rotate(float yaw, float pitch, float roll) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Rotate(const SHVec3& eulerAngles) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(eulerAngles.x, eulerAngles.y, eulerAngles.z));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Rotate(const SHQuaternion& q) noexcept
{
SHMatrix result;
const XMVECTOR Q = XMLoadFloat4(&q);
XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(Q));
result.Transpose();
return result;
}
SHMatrix SHMatrix::RotateX(float angleInRad) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad));
result.Transpose();
return result;
}
SHMatrix SHMatrix::RotateY(float angleInRad) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad));
result.Transpose();
return result;
}
SHMatrix SHMatrix::RotateZ(float angleInRad) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad));
result.Transpose();
return result;
}
SHMatrix SHMatrix::Scale(float uniformScaleFactor) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor));
return result;
}
SHMatrix SHMatrix::Scale(float x, float y, float z) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z));
return result;
}
SHMatrix SHMatrix::Scale(const SHVec3& scale) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixScaling(scale.x, scale.y, scale.z));
return result;
}
SHMatrix SHMatrix::LookAtRH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept
{
SHMatrix result;
const XMVECTOR EYE = XMLoadFloat3(&eye);
const XMVECTOR TGT = XMLoadFloat3(&target);
const XMVECTOR UP = XMLoadFloat3(&up);
XMStoreFloat4x4(&result, XMMatrixLookAtRH(EYE, TGT, UP));
result.Transpose();
return result;
}
SHMatrix SHMatrix::LookAtLH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept
{
SHMatrix result;
const XMVECTOR EYE = XMLoadFloat3(&eye);
const XMVECTOR TGT = XMLoadFloat3(&target);
const XMVECTOR UP = XMLoadFloat3(&up);
XMStoreFloat4x4(&result, XMMatrixLookAtLH(EYE, TGT, UP));
result.Transpose();
return result;
}
SHMatrix SHMatrix::CamToWorldRH(const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept
{
SHMatrix result;
const SHVec3 FWD_HAT = SHVec3::Normalise(-forward);
const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT));
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT));
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._21), Y_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._31), Z_HAT);
result._41 = pos.x;
result._42 = pos.y;
result._43 = pos.z;
result.Transpose();
return result;
}
SHMatrix SHMatrix::CamToWorldLH(const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept
{
SHMatrix result;
const SHVec3 FWD_HAT = SHVec3::Normalise(forward);
const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT));
const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT));
const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._11), X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._21), Y_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._31), Z_HAT);
result._41 = pos.x;
result._42 = pos.x;
result._43 = pos.x;
result.Transpose();
return result;
}
SHMatrix SHMatrix::PerspectiveFovRH(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane));
result.Transpose();
return result;
}
SHMatrix SHMatrix::PerspectiveFovLH(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixPerspectiveFovLH(fov, aspectRatio, nearPlane, farPlane));
result.Transpose();
return result;
}
SHMatrix SHMatrix::PerspectiveRH(float width, float height, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane));
result.Transpose();
return result;
}
SHMatrix SHMatrix::PerspectiveLH(float width, float height, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixPerspectiveLH(width, height, nearPlane, farPlane));
result.Transpose();
return result;
}
SHMatrix SHMatrix::OrthographicRH(float width, float height, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixOrthographicRH(width, height, nearPlane, farPlane));
result.Transpose();
return result;
}
SHMatrix SHMatrix::OrthographicLH(float width, float height, float nearPlane, float farPlane) noexcept
{
SHMatrix result;
XMStoreFloat4x4(&result, XMMatrixOrthographicLH(width, height, nearPlane, farPlane));
result.Transpose();
return result;
}
} // namespace SHADE

View File

@ -0,0 +1,144 @@
/****************************************************************************************
* \file SHMatrix.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Matrix.
*
* \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 <DirectXMath.h>
#include <string>
#include "Vector/SHVec4.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHVec2;
class SHVec3;
class SHVec4;
class SHQuaternion;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/**
* @brief Interface for a Column-Major Row Vector 4x4 Matrix.
*/
class SHMatrix : public DirectX::XMFLOAT4X4
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t SIZE = 16U;
static constexpr size_t NUM_ROWS = 4U;
static constexpr size_t NUM_COLS = 4U;
static const SHMatrix Identity;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHMatrix (const SHMatrix& rhs) = default;
SHMatrix (SHMatrix&& rhs) = default;
~SHMatrix () = default;
SHMatrix () noexcept;
SHMatrix ( const SHVec4& r0,
const SHVec4& r1,
const SHVec4& r2,
const SHVec4& r3 = SHVec4::UnitW
) noexcept;
SHMatrix (
float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30 = 0.0f, float m31 = 0.0f, float m32 = 0.0f, float m33 = 1.0f
) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHMatrix& operator= (const SHMatrix& rhs) = default;
SHMatrix& operator= (SHMatrix&& rhs) = default;
SHMatrix& operator+= (const SHMatrix& rhs) noexcept;
SHMatrix& operator-= (const SHMatrix& rhs) noexcept;
SHMatrix& operator*= (const SHMatrix& rhs) noexcept;
SHMatrix& operator*= (float rhs) noexcept;
SHMatrix& operator/= (const SHMatrix& rhs) noexcept;
SHMatrix& operator/= (float rhs) noexcept;
SHMatrix operator+ (const SHMatrix& rhs) const noexcept;
SHMatrix operator- (const SHMatrix& rhs) const noexcept;
SHMatrix operator- () const noexcept;
SHMatrix operator* (const SHMatrix& rhs) const noexcept;
SHVec3 operator* (const SHVec3& rhs) const noexcept;
SHVec4 operator* (const SHVec4& rhs) const noexcept;
SHMatrix operator* (float rhs) const noexcept;
SHMatrix operator/ (const SHMatrix& rhs) const noexcept;
SHMatrix operator/ (float rhs) const noexcept;
bool operator== (const SHMatrix& rhs) const noexcept;
bool operator!= (const SHMatrix& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void Transpose () noexcept;
void Invert () noexcept;
[[nodiscard]] float Determinant () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHMatrix Transpose (const SHMatrix& matrix) noexcept;
[[nodiscard]] static SHMatrix Inverse (const SHMatrix& matrix) noexcept;
[[nodiscard]] static SHMatrix Translate (float x, float y, float z) noexcept;
[[nodiscard]] static SHMatrix Translate (const SHVec3& pos) noexcept;
[[nodiscard]] static SHMatrix Rotate (const SHVec3& axis, float angleInRad) noexcept;
[[nodiscard]] static SHMatrix Rotate (float yaw, float pitch, float roll) noexcept;
[[nodiscard]] static SHMatrix Rotate (const SHVec3& eulerAngles) noexcept;
[[nodiscard]] static SHMatrix Rotate (const SHQuaternion& q) noexcept;
[[nodiscard]] static SHMatrix RotateX (float angleInRad) noexcept;
[[nodiscard]] static SHMatrix RotateY (float angleInRad) noexcept;
[[nodiscard]] static SHMatrix RotateZ (float angleInRad) noexcept;
[[nodiscard]] static SHMatrix Scale (float uniformScaleFactor) noexcept;
[[nodiscard]] static SHMatrix Scale (float x, float y, float z) noexcept;
[[nodiscard]] static SHMatrix Scale (const SHVec3& scale) noexcept;
[[nodiscard]] static SHMatrix LookAtRH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix LookAtLH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix CamToWorldRH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix CamToWorldLH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept;
[[nodiscard]] static SHMatrix PerspectiveFovRH (float fov, float aspectRatio, float nearPlane, float farPlane) noexcept;
[[nodiscard]] static SHMatrix PerspectiveFovLH (float fov, float aspectRatio, float nearPlane, float farPlane) noexcept;
[[nodiscard]] static SHMatrix PerspectiveRH (float width, float height, float nearPlane, float farPlane) noexcept;
[[nodiscard]] static SHMatrix PerspectiveLH (float width, float height, float nearPlane, float farPlane) noexcept;
[[nodiscard]] static SHMatrix OrthographicRH (float width, float height, float nearPlane, float farPlane) noexcept;
[[nodiscard]] static SHMatrix OrthographicLH (float width, float height, float nearPlane, float farPlane) noexcept;
// TODO(Diren): Billboard, Shadow, Projection & Reflection
};
SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept;
} // namespace SHADE

View File

@ -0,0 +1,308 @@
/****************************************************************************************
* \file SHQuaternion.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Quaternion.
*
* \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 "SHQuaternion.h"
// Project Headers
#include "Vector/SHVec3.h"
#include "SHMatrix.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHQuaternion SHQuaternion::Identity{ 0.0f, 0.0f, 0.0f, 1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHQuaternion::SHQuaternion() noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{}
SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept
: XMFLOAT4( _x, _y, _z, _w )
{}
SHQuaternion::SHQuaternion(float yaw, float pitch, float roll) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
XMStoreFloat4(this, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll));
}
SHQuaternion::SHQuaternion(const SHVec3& eulerAngles) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
const XMVECTOR V = XMLoadFloat3(&eulerAngles);
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V));
}
SHQuaternion::SHQuaternion(const SHVec3& axis, float angleInRad) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
const XMVECTOR AXIS = XMLoadFloat3(&axis);
XMStoreFloat4(this, XMQuaternionRotationAxis(AXIS, angleInRad));
}
SHQuaternion::SHQuaternion(const SHMatrix& rotationMatrix) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
const XMMATRIX M = XMLoadFloat4x4(&rotationMatrix);
XMStoreFloat4(this, XMQuaternionRotationMatrix(M));
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHQuaternion& SHQuaternion::operator+=(const SHQuaternion& rhs) noexcept
{
return *this = *this + rhs;
}
SHQuaternion& SHQuaternion::operator-=(const SHQuaternion& rhs) noexcept
{
return *this = *this - rhs;
}
SHQuaternion& SHQuaternion::operator*=(const SHQuaternion& rhs) noexcept
{
return *this = *this * rhs;
}
SHQuaternion& SHQuaternion::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHQuaternion& SHQuaternion::operator/=(const SHQuaternion& rhs) noexcept
{
return *this = *this / rhs;
}
SHQuaternion SHQuaternion::operator+(const SHQuaternion& rhs) const noexcept
{
SHQuaternion result;
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorAdd(Q1, Q2));
return result;
}
SHQuaternion SHQuaternion::operator-(const SHQuaternion& rhs) const noexcept
{
SHQuaternion result;
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorSubtract(Q1, Q2));
return result;
}
SHQuaternion SHQuaternion::operator-() const noexcept
{
SHQuaternion result;
const XMVECTOR Q = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorNegate(Q));
return result;
}
SHQuaternion SHQuaternion::operator*(const SHQuaternion& rhs) const noexcept
{
SHQuaternion result;
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2));
return result;
}
SHQuaternion SHQuaternion::operator*(float rhs) const noexcept
{
SHQuaternion result;
const XMVECTOR Q = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(Q, rhs));
return result;
}
SHQuaternion SHQuaternion::operator/(const SHQuaternion& rhs) const noexcept
{
SHQuaternion result;
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMQuaternionInverse(XMLoadFloat4(&rhs));
XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2));
return result;
}
bool SHQuaternion::operator==(const SHQuaternion& rhs) const noexcept
{
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
return XMQuaternionEqual(Q1, Q2);
}
bool SHQuaternion::operator!=(const SHQuaternion& rhs) const noexcept
{
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
return XMQuaternionNotEqual(Q1, Q2);
}
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
{
return rhs * lhs;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHQuaternion::Invert() noexcept
{
const XMVECTOR Q = XMLoadFloat4(this);
XMStoreFloat4(this, XMQuaternionInverse(Q));
}
float SHQuaternion::Length() const noexcept
{
const XMVECTOR Q = XMLoadFloat4(this);
return XMVectorGetX(XMQuaternionLength(Q));
}
float SHQuaternion::LengthSquared() const noexcept
{
const XMVECTOR Q = XMLoadFloat4(this);
return XMVectorGetX(XMQuaternionLengthSq(Q));
}
float SHQuaternion::Dot(const SHQuaternion& rhs) const noexcept
{
const XMVECTOR Q1 = XMLoadFloat4(this);
const XMVECTOR Q2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMQuaternionDot(Q1, Q2));
}
SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept
{
SHQuaternion result;
// TODO (Diren)
return result;
}
SHVec3 SHQuaternion::ToEuler() const noexcept
{
// TODO (Diren)
return SHVec3::Zero;
}
std::string SHQuaternion::ToString() const noexcept
{
std::stringstream ss;
ss << std::fixed << std::setprecision(3);
ss << "<" << x << ", " << y << ", " << z << ", " << w <<">";
return ss.str();
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHQuaternion SHQuaternion::Normalise(const SHQuaternion& q) noexcept
{
SHQuaternion result;
const XMVECTOR Q = XMLoadFloat4(&q);
XMStoreFloat4(&result, XMQuaternionNormalize(Q));
return result;
}
SHQuaternion SHQuaternion::Conjugate(const SHQuaternion& q) noexcept
{
SHQuaternion result;
const XMVECTOR Q = XMLoadFloat4(&q);
XMStoreFloat4(&result, XMQuaternionConjugate(Q));
return result;
}
SHQuaternion SHQuaternion::Inverse(const SHQuaternion& q) noexcept
{
SHQuaternion result;
const XMVECTOR Q = XMLoadFloat4(&q);
XMStoreFloat4(&result, XMQuaternionInverse(Q));
return result;
}
float SHQuaternion::Angle(const SHQuaternion&, const SHQuaternion&) noexcept
{
// TODO (Diren)
return 0.0f;
}
SHQuaternion SHQuaternion::Lerp(const SHQuaternion&, const SHQuaternion&, float) noexcept
{
SHQuaternion result;
// TODO (Diren)
return result;
}
SHQuaternion SHQuaternion::Slerp(const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept
{
SHQuaternion result;
const XMVECTOR Q1 = XMLoadFloat4(&q1);
const XMVECTOR Q2 = XMLoadFloat4(&q2);
XMStoreFloat4(&result, XMQuaternionSlerp(Q1, Q2, t));
return result;
}
SHQuaternion SHQuaternion::Rotate(const SHVec3& , const SHVec3&) noexcept
{
SHQuaternion result;
// TODO (Diren)
return result;
}
} // namespace SHADE

View File

@ -0,0 +1,106 @@
/****************************************************************************************
* \file SHQuaternion.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Quaternion.
*
* \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 <DirectXMath.h>
#include <string>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHVec3;
class SHMatrix;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHQuaternion : public DirectX::XMFLOAT4
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static const SHQuaternion Identity;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHQuaternion (const SHQuaternion& rhs) = default;
SHQuaternion (SHQuaternion&& rhs) = default;
SHQuaternion () noexcept;
SHQuaternion (float x, float y, float z, float w) noexcept;
SHQuaternion (float yaw, float pitch, float roll) noexcept;
SHQuaternion (const SHVec3& eulerAngles) noexcept;
SHQuaternion (const SHVec3& axis, float angleInRad) noexcept;
SHQuaternion (const SHMatrix& rotationMatrix) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHQuaternion& operator= (const SHQuaternion& rhs) = default;
[[nodiscard]] SHQuaternion& operator= (SHQuaternion&& rhs) = default;
[[nodiscard]] SHQuaternion& operator+= (const SHQuaternion& rhs) noexcept;
[[nodiscard]] SHQuaternion& operator-= (const SHQuaternion& rhs) noexcept;
[[nodiscard]] SHQuaternion& operator*= (const SHQuaternion& rhs) noexcept;
[[nodiscard]] SHQuaternion& operator*= (float rhs) noexcept;
[[nodiscard]] SHQuaternion& operator/= (const SHQuaternion& rhs) noexcept;
[[nodiscard]] SHQuaternion operator+ (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] SHQuaternion operator- (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] SHQuaternion operator- () const noexcept;
[[nodiscard]] SHQuaternion operator* (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] SHQuaternion operator* (float rhs) const noexcept;
[[nodiscard]] SHQuaternion operator/ (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void Invert () noexcept;
[[nodiscard]] float Length () const noexcept;
[[nodiscard]] float LengthSquared () const noexcept;
[[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] SHQuaternion RotateTowards (const SHQuaternion& target, float maxAngleInRad) const noexcept;
[[nodiscard]] SHVec3 ToEuler () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept;
[[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept;
[[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept;
[[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept;
[[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
[[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept;
[[nodiscard]] static SHQuaternion Rotate (const SHVec3& from, const SHVec3& to) noexcept;
};
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept;
} // namespace SHADE

View File

@ -0,0 +1,460 @@
/****************************************************************************************
* \file SHVec2.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for 2D Vector.
*
* \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 "SHVec2.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec2 const SHVec2::Zero { 0.0f, 0.0f };
SHVec2 const SHVec2::One { 1.0f, 1.0f };
SHVec2 const SHVec2::Left { -1.0f, 0.0f };
SHVec2 const SHVec2::Right { 1.0f, 0.0f };
SHVec2 const SHVec2::Up { 0.0f, 1.0f };
SHVec2 const SHVec2::Down { 0.0f, -1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec2::SHVec2() noexcept
: XMFLOAT2( 0.0f, 0.0f )
{}
SHVec2::SHVec2(float _x, float _y) noexcept
: XMFLOAT2( _x, _y )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept
{
return *this = *this + rhs;
}
SHVec2& SHVec2::operator-=(const SHVec2& rhs) noexcept
{
return *this = *this - rhs;
}
SHVec2& SHVec2::operator*=(const SHVec2& rhs) noexcept
{
return *this = *this * rhs;
}
SHVec2& SHVec2::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHVec2& SHVec2::operator/=(const SHVec2& rhs) noexcept
{
return *this = *this / rhs;
}
SHVec2& SHVec2::operator/=(float rhs) noexcept
{
return *this = *this / rhs;
}
SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorAdd(V1, V2));
return result;
}
SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorSubtract(V1, V2));
return result;
}
SHVec2 SHVec2::operator-() const noexcept
{
return SHVec2{ -x, -y };
}
SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorMultiply(V1, V2));
return result;
}
SHVec2 SHVec2::operator*(float rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, rhs));
return result;
}
SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorDivide(V1, V2));
return result;
}
SHVec2 SHVec2::operator/(float rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, 1.0f / rhs));
return result;
}
bool SHVec2::operator==(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2Equal(V1, V2);
}
bool SHVec2::operator!=(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2NotEqual(V1, V2);
}
float SHVec2::operator[](int index)
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
default: return 0.0f;
}
}
float SHVec2::operator[](size_t index)
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
default: return 0.0f;
}
}
float SHVec2::operator[](int index) const
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
default: return 0.0f;
}
}
float SHVec2::operator[](size_t index) const
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
default: return 0.0f;
}
}
SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorScale(V, lhs));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
float SHVec2::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat2(this);
return XMVectorGetX(XMVector2Length(V));
}
float SHVec2::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat2(this);
return XMVectorGetX(XMVector2LengthSq(V));
}
std::string SHVec2::ToString() const noexcept
{
std::stringstream ss;
ss << std::fixed << std::setprecision(3);
ss << "<" << x << ", " << y << ">";
return ss.str();
}
float SHVec2::Dot(const SHVec2& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2Dot(V1, V2));
}
SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVector2Cross(V1, V2));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec2 SHVec2::Normalise(const SHVec2& vec2) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&vec2);
XMStoreFloat2(&result, XMVector2Normalize(V));
return result;
}
SHVec2 SHVec2::Abs(const SHVec2& vec2) noexcept
{
return SHVec2{ std::fabs(vec2.x), std::fabs(vec2.y) };
}
SHVec2 SHVec2::Min(const std::initializer_list<SHVec2>& vec2s) noexcept
{
if (vec2s.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Min value is a default SHVec2.")
return SHVec2{};
}
SHVec2 result;
XMVECTOR min = XMLoadFloat2(&(*vec2s.begin()));
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat2(&(*it));
min = XMVectorMin(min, tmp);
}
XMStoreFloat2(&result, min);
return result;
}
SHVec2 SHVec2::Max(const std::initializer_list<SHVec2>& vec2s) noexcept
{
if (vec2s.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Max value is a default SHVec2.")
return SHVec2{};
}
SHVec2 result;
XMVECTOR max = XMLoadFloat2(&(*vec2s.begin()));
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat2(&(*it));
max = XMVectorMax(max, tmp);
}
XMStoreFloat2(&result, max);
return result;
}
SHVec2 SHVec2::Clamp(const SHVec2& v, const SHVec2& vMin, const SHVec2& vMax) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMVECTOR MIN = XMLoadFloat2(&vMin);
const XMVECTOR MAX = XMLoadFloat2(&vMax);
XMStoreFloat2(&result, XMVectorClamp(V, MIN, MAX));
return result;
}
SHVec2 SHVec2::Lerp(const SHVec2& a, const SHVec2& b, float t) noexcept
{
SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(&a);
const XMVECTOR V2 = XMLoadFloat2(&b);
XMStoreFloat2(&result, XMVectorLerp(V1, V2, t));
return result;
}
SHVec2 SHVec2::ClampedLerp(const SHVec2& a, const SHVec2& b, float t, float tMin, float tMax) noexcept
{
return Lerp(a, b, std::clamp(t, tMin, tMax));
}
float SHVec2::Distance(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
return (lhs - rhs).Length();
}
float SHVec2::DistanceSquared(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
return (lhs - rhs).LengthSquared();
}
float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat2(&lhs);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2AngleBetweenVectors(V1, V2));
}
float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
return lhs.Dot(rhs);
}
SHVec2 SHVec2::Project(const SHVec2& v, const SHVec2& u) noexcept
{
SHVec2 result;
const XMVECTOR U = XMLoadFloat2(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat2(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
return result;
}
SHVec2 SHVec2::Reflect(const SHVec2& v, const SHVec2& normal) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMVECTOR N = XMLoadFloat2(&normal);
XMStoreFloat2(&result, XMVector2Reflect(V, N));
return result;
}
SHVec2 SHVec2::Rotate(const SHVec2& v, float angleInRad) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat2(&result, XMVector2Transform(V, R));
return result;
}
SHVec2 SHVec2::Transform(const SHVec2& v, const SHMatrix& transformMtx) noexcept
{
SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat2(&result, XMVector2TransformCoord(V, TF));
return result;
}
SHVec2 SHVec2::Cross(float lhs, const SHVec2& rhs) noexcept
{
SHVec2 result;
const XMFLOAT3 LHS { 0.0f, 0.0f, lhs };
const XMFLOAT3 RHS { rhs.x, rhs.y, 0.0f };
const XMVECTOR V1 = XMLoadFloat3(&LHS);
const XMVECTOR V2 = XMLoadFloat3(&RHS);
XMStoreFloat2(&result, XMVector3Cross(V1, V2));
return result;
}
SHVec2 SHVec2::Cross(const SHVec2& lhs, float rhs) noexcept
{
SHVec2 result;
const XMFLOAT3 LHS { lhs.x, lhs.y, 0.0f };
const XMFLOAT3 RHS { 0.0f, 0.0f, rhs };
const XMVECTOR V1 = XMLoadFloat3(&LHS);
const XMVECTOR V2 = XMLoadFloat3(&RHS);
XMStoreFloat2(&result, XMVector3Cross(V1, V2));
return result;
}
float SHVec2::Cross(const SHVec2& lhs, const SHVec2& rhs) noexcept
{
return (lhs.x * rhs.y) - (lhs.y * rhs.x);
}
}

View File

@ -0,0 +1,122 @@
/****************************************************************************************
* \file SHVec2.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for 2D Vector.
*
* \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 <DirectXMath.h>
#include <string>
#include <initializer_list>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMatrix;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHVec2 : public DirectX::XMFLOAT2
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t SIZE = 2U;
static const SHVec2 Zero;
static const SHVec2 One;
static const SHVec2 Left;
static const SHVec2 Right;
static const SHVec2 Up;
static const SHVec2 Down;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHVec2 (const SHVec2& rhs) = default;
SHVec2 (SHVec2&& rhs) = default;
~SHVec2 () = default;
SHVec2 () noexcept;
SHVec2 (float x, float y) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec2& operator= (const SHVec2& rhs) = default;
[[nodiscard]] SHVec2& operator= (SHVec2&& rhs) = default;
[[nodiscard]] SHVec2& operator+= (const SHVec2& rhs) noexcept;
[[nodiscard]] SHVec2& operator-= (const SHVec2& rhs) noexcept;
[[nodiscard]] SHVec2& operator*= (const SHVec2& rhs) noexcept;
[[nodiscard]] SHVec2& operator*= (float rhs) noexcept;
[[nodiscard]] SHVec2& operator/= (const SHVec2& rhs) noexcept;
[[nodiscard]] SHVec2& operator/= (float rhs) noexcept;
[[nodiscard]] SHVec2 operator+ (const SHVec2& rhs) const noexcept;
[[nodiscard]] SHVec2 operator- (const SHVec2& rhs) const noexcept;
[[nodiscard]] SHVec2 operator- () const noexcept;
[[nodiscard]] SHVec2 operator* (const SHVec2& rhs) const noexcept;
[[nodiscard]] SHVec2 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec2 operator/ (const SHVec2& rhs) const noexcept;
[[nodiscard]] SHVec2 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec2& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec2& rhs) const noexcept;
[[nodiscard]] float operator[] (int index);
[[nodiscard]] float operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] float Length () const noexcept;
[[nodiscard]] float LengthSquared () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
[[nodiscard]] float Dot (const SHVec2& rhs) const noexcept;
[[nodiscard]] SHVec2 Cross (const SHVec2& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHVec2 Normalise (const SHVec2& vec2) noexcept;
[[nodiscard]] static SHVec2 Abs (const SHVec2& vec2) noexcept;
[[nodiscard]] static SHVec2 Min (const std::initializer_list<SHVec2>& vec2s) noexcept;
[[nodiscard]] static SHVec2 Max (const std::initializer_list<SHVec2>& vec2s) noexcept;
[[nodiscard]] static SHVec2 Clamp (const SHVec2& v, const SHVec2& vMin, const SHVec2& vMax) noexcept;
[[nodiscard]] static SHVec2 Lerp (const SHVec2& a, const SHVec2& b, float t) noexcept;
[[nodiscard]] static SHVec2 ClampedLerp (const SHVec2& a, const SHVec2& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
[[nodiscard]] static float Distance (const SHVec2& lhs, const SHVec2& rhs) noexcept;
[[nodiscard]] static float DistanceSquared (const SHVec2& lhs, const SHVec2& rhs) noexcept;
[[nodiscard]] static float Angle (const SHVec2& lhs, const SHVec2& rhs) noexcept;
[[nodiscard]] static float Dot (const SHVec2& lhs, const SHVec2& rhs) noexcept;
[[nodiscard]] static SHVec2 Project (const SHVec2& v, const SHVec2& u) noexcept;
[[nodiscard]] static SHVec2 Reflect (const SHVec2& v, const SHVec2& normal) noexcept;
[[nodiscard]] static SHVec2 Rotate (const SHVec2& v, float angleInRad) noexcept;
[[nodiscard]] static SHVec2 Transform (const SHVec2& v, const SHMatrix& transformMtx) noexcept;
[[nodiscard]] static SHVec2 Cross (float lhs, const SHVec2& rhs) noexcept;
[[nodiscard]] static SHVec2 Cross (const SHVec2& lhs, float rhs) noexcept;
[[nodiscard]] static float Cross (const SHVec2& lhs, const SHVec2& rhs) noexcept;
};
SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept;
} // namespace SHADE

View File

@ -0,0 +1,477 @@
/****************************************************************************************
* \file SHVec3.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for 3D Vector.
*
* \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 "SHVec3.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f };
SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::Right { 1.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::Up { 0.0f, 1.0f, 0.0f };
SHVec3 const SHVec3::Down { 0.0f, -1.0f, 0.0f };
SHVec3 const SHVec3::Forward { 0.0f, 0.0f, 1.0f };
SHVec3 const SHVec3::Back { 0.0f, 0.0f, -1.0f };
SHVec3 const SHVec3::UnitX { 1.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::UnitY { 0.0f, 1.0f, 0.0f };
SHVec3 const SHVec3::UnitZ { 0.0f, 0.0f, 1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3::SHVec3() noexcept
: XMFLOAT3( 0.0f, 0.0f, 0.0f )
{}
SHVec3::SHVec3(float _x, float _y, float _z) noexcept
: XMFLOAT3( _x, _y, _z )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept
{
return *this = *this + rhs;
}
SHVec3& SHVec3::operator-=(const SHVec3& rhs) noexcept
{
return *this = *this - rhs;
}
SHVec3& SHVec3::operator*=(const SHVec3& rhs) noexcept
{
return *this = *this * rhs;
}
SHVec3& SHVec3::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHVec3& SHVec3::operator/=(const SHVec3& rhs) noexcept
{
return *this = *this / rhs;
}
SHVec3& SHVec3::operator/=(float rhs) noexcept
{
return *this = *this / rhs;
}
SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorAdd(V1, V2));
return result;
}
SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorSubtract(V1, V2));
return result;
}
SHVec3 SHVec3::operator-() const noexcept
{
return SHVec3{ -x, -y, -z };
}
SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorMultiply(V1, V2));
return result;
}
SHVec3 SHVec3::operator*(float rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, rhs));
return result;
}
SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorDivide(V1, V2));
return result;
}
SHVec3 SHVec3::operator/(float rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, 1.0f / rhs));
return result;
}
bool SHVec3::operator==(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3Equal(V1, V2);
}
bool SHVec3::operator!=(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3NotEqual(V1, V2);
}
float SHVec3::operator[](int index)
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: return 0.0f;
}
}
float SHVec3::operator[](size_t index)
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: return 0.0f;
}
}
float SHVec3::operator[](int index) const
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: return 0.0f;
}
}
float SHVec3::operator[](size_t index) const
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: return 0.0f;
}
}
SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorScale(V, lhs));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
float SHVec3::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat3(this);
return XMVectorGetX(XMVector3Length(V));
}
float SHVec3::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat3(this);
return XMVectorGetX(XMVector3LengthSq(V));
}
std::string SHVec3::ToString() const noexcept
{
std::stringstream ss;
ss << std::fixed << std::setprecision(3);
ss << "<" << x << ", " << y << ", " << z << ">";
return ss.str();
}
float SHVec3::Dot(const SHVec3& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
}
SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVector3Cross(V1, V2));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3 SHVec3::Normalise(const SHVec3& v) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
XMStoreFloat3(&result, XMVector3Normalize(V));
return result;
}
SHVec3 SHVec3::Abs(const SHVec3& v) noexcept
{
return SHVec3{ std::fabs(v.x), std::fabs(v.y), std::fabs(v.z) };
}
SHVec3 SHVec3::Min(const std::initializer_list<SHVec3>& vs) noexcept
{
if (vs.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Min value is a default SHVec3.")
return SHVec3{};
}
SHVec3 result;
XMVECTOR min = XMLoadFloat3(&(*vs.begin()));
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat3(&(*it));
min = XMVectorMin(min, tmp);
}
XMStoreFloat3(&result, min);
return result;
}
SHVec3 SHVec3::Max(const std::initializer_list<SHVec3>& vs) noexcept
{
if (vs.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Max value is a default SHVec3.")
return SHVec3{};
}
SHVec3 result;
XMVECTOR max = XMLoadFloat3(&(*vs.begin()));
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat3(&(*it));
max = XMVectorMax(max, tmp);
}
XMStoreFloat3(&result, max);
return result;
}
SHVec3 SHVec3::Clamp(const SHVec3& v, const SHVec3& vMin, const SHVec3& vMax) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR MIN = XMLoadFloat3(&vMin);
const XMVECTOR MAX = XMLoadFloat3(&vMax);
XMStoreFloat3(&result, XMVectorClamp(V, MIN, MAX));
return result;
}
SHVec3 SHVec3::Lerp(const SHVec3& a, const SHVec3& b, float t) noexcept
{
SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(&a);
const XMVECTOR V2 = XMLoadFloat3(&b);
XMStoreFloat3(&result, XMVectorLerp(V1, V2, t));
return result;
}
SHVec3 SHVec3::ClampedLerp(const SHVec3& a, const SHVec3& b, float t, float tMin, float tMax) noexcept
{
return Lerp(a, b, std::clamp(t, tMin, tMax));
}
float SHVec3::Distance(const SHVec3& lhs, const SHVec3& rhs) noexcept
{
return (lhs - rhs).Length();
}
float SHVec3::DistanceSquared(const SHVec3& lhs, const SHVec3& rhs) noexcept
{
return (lhs - rhs).LengthSquared();
}
float SHVec3::Angle(const SHVec3& lhs, const SHVec3& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat3(&lhs);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2));
}
float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept
{
return lhs.Dot(rhs);
}
SHVec3 SHVec3::Cross(const SHVec3& lhs, const SHVec3& rhs) noexcept
{
return lhs.Cross(rhs);
}
SHVec3 SHVec3::Project(const SHVec3& v, const SHVec3& u) noexcept
{
SHVec3 result;
const XMVECTOR U = XMLoadFloat3(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat3(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
return result;
}
SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR N = XMLoadFloat3(&normal);
XMStoreFloat3(&result, XMVector3Reflect(V, N));
return result;
}
SHVec3 SHVec3::Rotate(const SHVec3& v, const SHVec3& axis, float angleInRad) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR AXIS = XMLoadFloat3(&axis);
const XMVECTOR Q = XMQuaternionRotationAxis(AXIS, angleInRad);
XMStoreFloat3(&result, XMVector3Rotate(V, Q));
return result;
}
SHVec3 SHVec3::RotateX(const SHVec3& v, float angleInRad) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationX(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
return result;
}
SHVec3 SHVec3::RotateY(const SHVec3& v, float angleInRad) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationY(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
return result;
}
SHVec3 SHVec3::RotateZ(const SHVec3& v, float angleInRad) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R));
return result;
}
SHVec3 SHVec3::Transform(const SHVec3& v, const SHMatrix& transformMtx) noexcept
{
SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat3(&result, XMVector3TransformCoord(V, TF));
return result;
}
}

View File

@ -0,0 +1,129 @@
/****************************************************************************************
* \file SHVec3.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for 3D Vector.
*
* \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 <DirectXMath.h>
#include <string>
#include <initializer_list>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMatrix;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHVec3 : public DirectX::XMFLOAT3
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t SIZE = 3U;
static const SHVec3 Zero;
static const SHVec3 One;
static const SHVec3 Left;
static const SHVec3 Right;
static const SHVec3 Up;
static const SHVec3 Down;
static const SHVec3 Forward;
static const SHVec3 Back;
static const SHVec3 UnitX;
static const SHVec3 UnitY;
static const SHVec3 UnitZ;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHVec3 (const SHVec3& rhs) = default;
SHVec3 (SHVec3&& rhs) = default;
~SHVec3 () = default;
SHVec3 () noexcept;
SHVec3 (float x, float y, float z) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3& operator= (const SHVec3& rhs) = default;
[[nodiscard]] SHVec3& operator= (SHVec3&& rhs) = default;
[[nodiscard]] SHVec3& operator+= (const SHVec3& rhs) noexcept;
[[nodiscard]] SHVec3& operator-= (const SHVec3& rhs) noexcept;
[[nodiscard]] SHVec3& operator*= (const SHVec3& rhs) noexcept;
[[nodiscard]] SHVec3& operator*= (float rhs) noexcept;
[[nodiscard]] SHVec3& operator/= (const SHVec3& rhs) noexcept;
[[nodiscard]] SHVec3& operator/= (float rhs) noexcept;
[[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator- () const noexcept;
[[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept;
[[nodiscard]] float operator[] (int index);
[[nodiscard]] float operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] float Length () const noexcept;
[[nodiscard]] float LengthSquared () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
[[nodiscard]] float Dot (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 Cross (const SHVec3& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHVec3 Normalise (const SHVec3& v) noexcept;
[[nodiscard]] static SHVec3 Abs (const SHVec3& v) noexcept;
[[nodiscard]] static SHVec3 Min (const std::initializer_list<SHVec3>& vs) noexcept;
[[nodiscard]] static SHVec3 Max (const std::initializer_list<SHVec3>& vs) noexcept;
[[nodiscard]] static SHVec3 Clamp (const SHVec3& v, const SHVec3& vMin, const SHVec3& vMax) noexcept;
[[nodiscard]] static SHVec3 Lerp (const SHVec3& a, const SHVec3& b, float t) noexcept;
[[nodiscard]] static SHVec3 ClampedLerp (const SHVec3& a, const SHVec3& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
[[nodiscard]] static float Distance (const SHVec3& lhs, const SHVec3& rhs) noexcept;
[[nodiscard]] static float DistanceSquared (const SHVec3& lhs, const SHVec3& rhs) noexcept;
[[nodiscard]] static float Angle (const SHVec3& lhs, const SHVec3& rhs) noexcept;
[[nodiscard]] static float Dot (const SHVec3& lhs, const SHVec3& rhs) noexcept;
[[nodiscard]] static SHVec3 Cross (const SHVec3& lhs, const SHVec3& rhs) noexcept;
[[nodiscard]] static SHVec3 Project (const SHVec3& v, const SHVec3& u) noexcept;
[[nodiscard]] static SHVec3 Reflect (const SHVec3& v, const SHVec3& normal) noexcept;
[[nodiscard]] static SHVec3 Rotate (const SHVec3& v, const SHVec3& axis, float angleInRad) noexcept;
[[nodiscard]] static SHVec3 RotateX (const SHVec3& v, float angleInRad) noexcept;
[[nodiscard]] static SHVec3 RotateY (const SHVec3& v, float angleInRad) noexcept;
[[nodiscard]] static SHVec3 RotateZ (const SHVec3& v, float angleInRad) noexcept;
[[nodiscard]] static SHVec3 Transform (const SHVec3& v, const SHMatrix& transformMtx) noexcept;
};
SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept;
} // namespace SHADE

View File

@ -0,0 +1,529 @@
/****************************************************************************************
* \file SHVec4.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for 4D Vector.
*
* \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 "SHVec4.h"
// Project Headers
#include "Math/SHMatrix.h"
#include "Tools/SHLogger.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec4 const SHVec4::Zero { 0.0f, 0.0f, 0.0f, 0.0f };
SHVec4 const SHVec4::One { 1.0f, 1.0f, 1.0f, 1.0f };
SHVec4 const SHVec4::UnitX { 1.0f, 0.0f, 0.0f, 0.0f };
SHVec4 const SHVec4::UnitY { 0.0f, 1.0f, 0.0f, 0.0f };
SHVec4 const SHVec4::UnitZ { 0.0f, 0.0f, 1.0f, 0.0f };
SHVec4 const SHVec4::UnitW { 0.0f, 0.0f, 0.0f, 1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec4::SHVec4() noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f )
{}
SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept
: XMFLOAT4( _x, _y, _z, _w )
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept
{
return *this = *this + rhs;
}
SHVec4& SHVec4::operator-=(const SHVec4& rhs) noexcept
{
return *this = *this - rhs;
}
SHVec4& SHVec4::operator*=(const SHVec4& rhs) noexcept
{
return *this = *this * rhs;
}
SHVec4& SHVec4::operator*=(float rhs) noexcept
{
return *this = *this * rhs;
}
SHVec4& SHVec4::operator/=(const SHVec4& rhs) noexcept
{
return *this = *this / rhs;
}
SHVec4& SHVec4::operator/=(float rhs) noexcept
{
return *this = *this / rhs;
}
SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorAdd(V1, V2));
return result;
}
SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorSubtract(V1, V2));
return result;
}
SHVec4 SHVec4::operator-() const noexcept
{
return SHVec4{ -x, -y, -z, -w };
}
SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorMultiply(V1, V2));
return result;
}
SHVec4 SHVec4::operator*(float rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, rhs));
return result;
}
SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorDivide(V1, V2));
return result;
}
SHVec4 SHVec4::operator/(float rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, 1.0f / rhs));
return result;
}
bool SHVec4::operator==(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4Equal(V1, V2);
}
bool SHVec4::operator!=(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4NotEqual(V1, V2);
}
float SHVec4::operator[](int index)
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0.0f;
}
}
float SHVec4::operator[](size_t index)
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0.0f;
}
}
float SHVec4::operator[](int index) const
{
if (index >= SIZE || index < 0)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0.0f;
}
}
float SHVec4::operator[](size_t index) const
{
if (index >= SIZE)
throw std::invalid_argument("Index out of range!");
switch (index)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: return 0.0f;
}
}
SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorScale(V, lhs));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
float SHVec4::Length() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector4Length(V));
}
float SHVec4::Length3D() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector3Length(V));
}
float SHVec4::LengthSquared() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector4LengthSq(V));
}
float SHVec4::LengthSquared3D() const noexcept
{
const XMVECTOR V = XMLoadFloat4(this);
return XMVectorGetX(XMVector3LengthSq(V));
}
std::string SHVec4::ToString() const noexcept
{
std::stringstream ss;
ss << std::fixed << std::setprecision(3);
ss << "<" << x << ", " << y << ", " << z << ", " << w <<">";
return ss.str();
}
float SHVec4::Dot(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4Dot(V1, V2));
}
float SHVec4::Dot3D(const SHVec4& rhs) const noexcept
{
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
}
SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVector3Cross(V1, V2));
result.w = 1.0f;
return result;
}
SHVec4 SHVec4::Cross(const SHVec4& v1, const SHVec4& v2) const noexcept
{
SHVec4 result;
const XMVECTOR V3 = XMLoadFloat4(this);
const XMVECTOR V1 = XMLoadFloat4(&v1);
const XMVECTOR V2 = XMLoadFloat4(&v2);
XMStoreFloat4(&result, XMVector4Cross(V3, V1, V2));
return result;
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec4 SHVec4::Normalise(const SHVec4& v) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
XMStoreFloat4(&result, XMVector4Normalize(V));
return result;
}
SHVec4 SHVec4::Normalise3D(const SHVec4& v) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
XMStoreFloat4(&result, XMVector3Normalize(V));
result.w = 1.0f;
return result;
}
SHVec4 SHVec4::Abs(const SHVec4& v) noexcept
{
return SHVec4{ std::fabs(v.x), std::fabs(v.y), std::fabs(v.z), std::fabs(v.w) };
}
SHVec4 SHVec4::Min(const std::initializer_list<SHVec4>& vs) noexcept
{
if (vs.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Min value is a default SHVec4.")
return SHVec4{};
}
SHVec4 result;
XMVECTOR min = XMLoadFloat4(&(*vs.begin()));
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat4(&(*it));
min = XMVectorMin(min, tmp);
}
XMStoreFloat4(&result, min);
return result;
}
SHVec4 SHVec4::Max(const std::initializer_list<SHVec4>& vs) noexcept
{
if (vs.size() == 0)
{
SHLOG_WARNING("No arguments passed in! Max value is a default SHVec4.")
return SHVec4{};
}
SHVec4 result;
XMVECTOR max = XMLoadFloat4(&(*vs.begin()));
for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{
const XMVECTOR tmp = XMLoadFloat4(&(*it));
max = XMVectorMax(max, tmp);
}
XMStoreFloat4(&result, max);
return result;
}
SHVec4 SHVec4::Clamp(const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR MIN = XMLoadFloat4(&vMin);
const XMVECTOR MAX = XMLoadFloat4(&vMax);
XMStoreFloat4(&result, XMVectorClamp(V, MIN, MAX));
return result;
}
SHVec4 SHVec4::Lerp(const SHVec4& a, const SHVec4& b, float t) noexcept
{
SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(&a);
const XMVECTOR V2 = XMLoadFloat4(&b);
XMStoreFloat4(&result, XMVectorLerp(V1, V2, t));
return result;
}
SHVec4 SHVec4::ClampedLerp(const SHVec4& a, const SHVec4& b, float t, float tMin, float tMax) noexcept
{
return Lerp(a, b, std::clamp(t, tMin, tMax));
}
float SHVec4::Distance(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return (lhs - rhs).Length();
}
float SHVec4::Distance3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return (lhs - rhs).Length3D();
}
float SHVec4::DistanceSquared(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return (lhs - rhs).LengthSquared();
}
float SHVec4::DistanceSquared3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return (lhs - rhs).LengthSquared3D();
}
float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat4(&lhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4AngleBetweenVectors(V1, V2));
}
float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
const XMVECTOR V1 = XMLoadFloat4(&lhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2));
}
float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return lhs.Dot(rhs);
}
float SHVec4::Dot3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return lhs.Dot3D(rhs);
}
SHVec4 SHVec4::Cross3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{
return lhs.Cross3D(rhs);
}
SHVec4 SHVec4::Cross(const SHVec4& v1, const SHVec4& v2, const SHVec4& v3) noexcept
{
return v1.Cross(v2, v3);
}
SHVec4 SHVec4::Project(const SHVec4& v, const SHVec4& u) noexcept
{
SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
return result;
}
SHVec4 SHVec4::Project3D(const SHVec4& v, const SHVec4& u) noexcept
{
SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot3D(v, u);
const float U_LENSQ = u.LengthSquared3D();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ));
result.w = 1.0f;
return result;
}
SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector4Reflect(V, N));
result.w = 1.0f;
return result;
}
SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector3Reflect(V, N));
result.w = 1.0f;
return result;
}
SHVec4 SHVec4::Transform3D(const SHVec4& v, const SHMatrix& transformMtx) noexcept
{
SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat4(&result, XMVector3TransformCoord(V, TF));
return result;
}
}

View File

@ -0,0 +1,133 @@
/****************************************************************************************
* \file SHVec4.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for 4D Vector.
*
* \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 <DirectXMath.h>
#include <string>
#include <initializer_list>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMatrix;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHVec4 : public DirectX::XMFLOAT4
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t SIZE = 4U;
static const SHVec4 Zero;
static const SHVec4 One;
static const SHVec4 UnitX;
static const SHVec4 UnitY;
static const SHVec4 UnitZ;
static const SHVec4 UnitW;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHVec4 (const SHVec4& rhs) = default;
SHVec4 (SHVec4&& rhs) = default;
~SHVec4 () = default;
SHVec4 () noexcept;
SHVec4 (float x, float y, float z, float w) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec4& operator= (const SHVec4& rhs) = default;
[[nodiscard]] SHVec4& operator= (SHVec4&& rhs) = default;
[[nodiscard]] SHVec4& operator+= (const SHVec4& rhs) noexcept;
[[nodiscard]] SHVec4& operator-= (const SHVec4& rhs) noexcept;
[[nodiscard]] SHVec4& operator*= (const SHVec4& rhs) noexcept;
[[nodiscard]] SHVec4& operator*= (float rhs) noexcept;
[[nodiscard]] SHVec4& operator/= (const SHVec4& rhs) noexcept;
[[nodiscard]] SHVec4& operator/= (float rhs) noexcept;
[[nodiscard]] SHVec4 operator+ (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 operator- (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 operator- () const noexcept;
[[nodiscard]] SHVec4 operator* (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec4 operator/ (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec4& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec4& rhs) const noexcept;
[[nodiscard]] float operator[] (int index);
[[nodiscard]] float operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] float Length () const noexcept;
[[nodiscard]] float Length3D () const noexcept;
[[nodiscard]] float LengthSquared () const noexcept;
[[nodiscard]] float LengthSquared3D () const noexcept;
[[nodiscard]] std::string ToString () const noexcept;
[[nodiscard]] float Dot (const SHVec4& rhs) const noexcept;
[[nodiscard]] float Dot3D (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 Cross3D (const SHVec4& rhs) const noexcept;
[[nodiscard]] SHVec4 Cross (const SHVec4& v1, const SHVec4& v2) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept;
[[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept;
[[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept;
[[nodiscard]] static SHVec4 Min (const std::initializer_list<SHVec4>& vs) noexcept;
[[nodiscard]] static SHVec4 Max (const std::initializer_list<SHVec4>& vs) noexcept;
[[nodiscard]] static SHVec4 Clamp (const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept;
[[nodiscard]] static SHVec4 Lerp (const SHVec4& a, const SHVec4& b, float t) noexcept;
[[nodiscard]] static SHVec4 ClampedLerp (const SHVec4& a, const SHVec4& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept;
[[nodiscard]] static float Distance (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float Distance3D (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float DistanceSquared (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float DistanceSquared3D (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float Angle (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float Angle3D (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float Dot (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static float Dot3D (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static SHVec4 Cross3D (const SHVec4& lhs, const SHVec4& rhs) noexcept;
[[nodiscard]] static SHVec4 Cross (const SHVec4& v1, const SHVec4& v2, const SHVec4& v3) noexcept;
[[nodiscard]] static SHVec4 Project (const SHVec4& v, const SHVec4& u) noexcept;
[[nodiscard]] static SHVec4 Project3D (const SHVec4& v, const SHVec4& u) noexcept;
[[nodiscard]] static SHVec4 Reflect (const SHVec4& v, const SHVec4& normal) noexcept;
[[nodiscard]] static SHVec4 Reflect3D (const SHVec4& v, const SHVec4& normal) noexcept;
[[nodiscard]] static SHVec4 Transform3D (const SHVec4& v, const SHMatrix& transformMtx) noexcept;
};
SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept;
} // namespace SHADE

View File

@ -0,0 +1,28 @@
/************************************************************************************//*!
\file SHCommonTypes.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 8, 2022
\brief Contains the definitions of type alias for commonly used units for
clarity and convenience.
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
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Type used to mark a value that is supposed to represent a size in bytes.
*/
/***********************************************************************************/
using Byte = size_t;
}

36
SHADE_Engine/src/SH_API.h Normal file
View File

@ -0,0 +1,36 @@
/************************************************************************************//*!
\file SH_API.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 13, 2022
\brief Contains dllexport and dllimport macros for the SHADE Engine.
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
// Select the correct export system based on the compiler
#if defined SH_LIB
# define SH_API
#else
# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
# define SH_EXPORT __declspec(dllexport)
# define SH_IMPORT __declspec(dllimport)
# elif defined __GNUC__ && __GNUC__ >= 4
# define SH_EXPORT __attribute__((visibility("default")))
# define SH_IMPORT __attribute__((visibility("default")))
# else /* Unsupported compiler */
# define SH_EXPORT
# define SH_IMPORT
# endif
// Define the correct
# ifndef SH_API
# if defined SH_API_EXPORT
# define SH_API SH_EXPORT
# else
# define SH_API SH_IMPORT
# endif
# endif
#endif

View File

@ -22,8 +22,14 @@
#include <string>
#include <algorithm>
#include <array>
#include <ranges>
#include <utility>
#include <unordered_map>
#include <map>
#include <tuple>
#include <functional>
#include <sstream>
#include <iomanip>
#include <cstddef>
#include "Common/SHCommonTypes.h"

View File

@ -0,0 +1,475 @@
/****************************************************************************************
* \file SHSceneGraph.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Scene Graph & Scene Nodes.
*
* \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 "SHSceneGraph.h"
// Project Headers
#include "ECS_Base/System/SHEntityManager.h"
#include "Tools/SHLogger.h"
#include "Tools/SHException.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: isActive { true }
, entityID { eid }
, parent { parent }
{}
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: isActive { rhs.isActive }
, entityID { rhs.entityID }
, parent { rhs.parent }
{
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
}
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: isActive { rhs.isActive }
, 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;
isActive = rhs.isActive;
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
{
isActive = rhs.isActive;
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
: root { nullptr }
{}
SHSceneGraph::~SHSceneGraph() noexcept
{
SHASSERT(root != nullptr, "Unable to destroy a Scene without a root node!")
#ifdef _DEBUG
SHLOG_INFO("Destroying Scene Graph...")
#endif
// Go through the map and release all the nodes
for (auto* node : entityNodeMap | std::views::values)
ReleaseNode(node);
#ifdef _DEBUG
SHLOG_INFO("Scene Graph Destroyed Successfully!")
#endif
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
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;
}
SHSceneNode* SHSceneGraph::GetRoot() const noexcept
{
if (root != nullptr)
return root;
SHLOG_WARNING("Scene has no root object!")
return nullptr;
}
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
return nullptr;
}
return NODE_ITER->second;
}
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
return nullptr;
}
return NODE_ITER->second->GetParent();
}
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
{
// Error Handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return nullptr;
}
const auto& children = NODE_ITER->second->GetChildren();
if (children.empty())
{
SHLOG_WARNING("Entity {} has no children!", entityID)
return nullptr;
}
const auto CHILD_ITER = std::ranges::find(children.begin(), children.end(), childNode);
if (CHILD_ITER == children.end())
{
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
return nullptr;
}
return *CHILD_ITER;
}
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return nullptr;
}
return NODE_ITER->second->GetChild(childEntityID);
}
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
{
// TODO(Diren): Discuss with team best way to handle this
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return root->GetChildren();
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return root->GetChildren();
}
return NODE_ITER->second->GetChildren();
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
{
if (parentNode == nullptr)
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
if (parentNode == parent)
return;
parent = parentNode;
// Update parent's children
parent->AddChild(this);
}
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return;
}
NODE_ITER->second->SetParent(parent);
}
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
return;
}
if (!SHEntityManager::IsValidEID(parent))
{
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID)
return;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to set parent!", entityID)
return;
}
auto PARENT_ITER = entityNodeMap.find(entityID);
if (PARENT_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
return;
}
SHSceneNode* currentNode = NODE_ITER->second;
currentNode->SetParent(PARENT_ITER->second);
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
{
if (newChild == nullptr)
{
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
return;
}
children.emplace_back(newChild);
}
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
{
if (!SHEntityManager::IsValidEID(childID))
{
SHLOG_ERROR("Entity {} is invalid!", childID)
return false;
}
SHSceneNode* removedChild = nullptr;
const auto ENTITY_MATCH = [&](SHSceneNode* node)
{
if (node->GetEntityID() == childID)
{
removedChild = node;
return true;
}
return false;
};
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH);
removedChild->parent = nullptr;
return removedChild == nullptr;
}
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
{
if (childToRemove == nullptr)
{
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
return false;
}
children.end() = std::remove(children.begin(), children.end(), childToRemove);
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)
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
{
SHLOG_WARNING("Entity {} already exists in the scene!", entityID)
return NODE_ITER->second;
}
SHSceneNode* newNode = AllocateNode(entityID);
newNode->SetParent(parent);
return newNode;
}
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} does not exist in the scene!", entityID)
return false;
}
// Remove reference of current node from parent
SHSceneNode* currentNode = NODE_ITER->second;
SHSceneNode* parent = currentNode->GetParent();
if (parent != nullptr)
parent->RemoveChild(currentNode);
ReleaseNode(currentNode);
return true;
}
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
{
// Remove reference of current node from parent
SHSceneNode* parent = nodeToRemove->GetParent();
if (parent != nullptr)
parent->RemoveChild(nodeToRemove);
ReleaseNode(nodeToRemove);
return true;
}
void SHSceneGraph::Reset() noexcept
{
for (auto* node : entityNodeMap | std::views::values)
ReleaseNode(node);
}
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
{
SHSceneNode* newNode = new SHSceneNode{entityID};
#ifdef _DEBUG
SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
#endif
entityNodeMap.emplace(entityID, newNode);
return newNode;
}
void SHSceneGraph::ReleaseNode(SHSceneNode* node) noexcept
{
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
// Remove parent's reference to this node if there is a parent
if (node->GetParent() != nullptr)
node->GetParent()->RemoveChild(node);
// Remove child's references to this node. Children end up as floating nodes.
for (auto* child : node->GetChildren())
{
child->SetParent(nullptr);
}
entityNodeMap.erase(node->GetEntityID());
delete node;
}
} // namespace SHADE

View File

@ -0,0 +1,143 @@
/****************************************************************************************
* \file SHSceneGraph.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Scene Graph & Scene Nodes.
*
* \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"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHSceneNode
{
public:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
bool isActive;
/*---------------------------------------------------------------------------------*/
/* 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]] EntityID GetEntityID () const noexcept { return entityID ;}
[[nodiscard]] SHSceneNode* GetParent () const noexcept { return parent; }
[[nodiscard]] std::vector<SHSceneNode*>& GetChildren () noexcept { return children; }
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetParent (SHSceneNode* parentNode) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void AddChild (SHSceneNode* newChild) noexcept;
bool RemoveChild (EntityID childID) noexcept;
bool RemoveChild (SHSceneNode* childToRemove) noexcept;
void RemoveAllChildren () noexcept;
private:
EntityID entityID;
SHSceneNode* parent;
std::vector<SHSceneNode*> children;
};
class SHSceneGraph
{
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHSceneGraph () noexcept;
~SHSceneGraph () noexcept;
SHSceneGraph (const SHSceneGraph&) = delete;
SHSceneGraph (SHSceneGraph&&) = delete;
SHSceneGraph& operator= (const SHSceneGraph&) = delete;
SHSceneGraph& operator= (SHSceneGraph&&) = delete;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHSceneNode* GetRoot () const noexcept;
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept;
void SetParent (EntityID entityID, EntityID parent) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
bool RemoveNode (EntityID entityID) noexcept;
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* root;
EntityNodeMap entityNodeMap;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* AllocateNode (EntityID entityID);
void ReleaseNode (SHSceneNode* node) noexcept;
};
} // namespace SHADE

View File

@ -10,11 +10,11 @@
*********************************************************************/
#include "SHpch.h"
#include "SHSceneManager.h"
#include "Engine/ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/System/SHComponentManager.h"
//#include "Input/SHInputManager.h"
//#include "Engine/Rendering/Window/SHRenderingWindow.h"
#include "Engine/ECS_Base/System/SHEntityManager.h"
#include "Engine/ECS_Base/System/SHSystemManager.h"
//#include "Rendering/Window/SHRenderingWindow.h"
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/System/SHSystemManager.h"
//#include "FRC/SHFrameRateController.h"
//#include "ECS_Base/System/SHApplication.h"

View File

@ -13,7 +13,7 @@
#define SH_SCENE_MANAGER_H
#include "Engine/ECS_Base/General/SHFamily.h"
#include "ECS_Base/General/SHFamily.h"
#include "SHScene.h"
#include <functional>

View File

@ -0,0 +1,198 @@
/*************************************************************************************//*!
\file SHDotNetRuntime.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 2, 2021
\brief Contains the definition of the SHDotNetRuntime class.
Implementation of code to set up code for SHDotNetRuntime is based on the
following repository:
https://github.com/mjrousos/SampleCoreCLRHost
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//**************************************************************************************/
// Precompiled Header
#include <SHpch.h>
// Primary Header
#include "SHDotNetRuntime.h"
// Standard Library
#include <array>
// External Dependencies
#include <shlwapi.h> // PathRemoveFileSpecA
#include "Tools/SHLogger.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors/Destructor */
/*---------------------------------------------------------------------------------*/
SHDotNetRuntime::SHDotNetRuntime(bool autoInit)
{
if (autoInit)
{
Init();
}
}
SHDotNetRuntime::~SHDotNetRuntime()
{
if (IsLoaded())
{
try
{
Exit();
}
catch (std::runtime_error& e)
{
SHLOG_ERROR(e.what());
}
}
}
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void SHDotNetRuntime::Init()
{
// State checking, in case there was an unload before, we must ensure that the state is valid
if (initialised)
throw std::runtime_error("[DotNetRuntime] Failed to initialise as it was already initialised or was deinitialised into an invalid state.");
// Get the current executable directory
std::string runtimePath(MAX_PATH, '\0');
GetModuleFileNameA(nullptr, runtimePath.data(), MAX_PATH);
PathRemoveFileSpecA(runtimePath.data());
// Since PathRemoveFileSpecA() removes from data(), the size is not updated, so we must manually update it
runtimePath.resize(std::strlen(runtimePath.data()));
// Do not need to load the library if it was previously loaded
if (coreClr == nullptr)
{
// Construct the CoreCLR path
std::string coreClrPath(runtimePath); // Works
coreClrPath += "\\coreclr.dll";
// Load the CoreCLR DLL
coreClr = LoadLibraryExA(coreClrPath.c_str(), nullptr, 0);
if (!coreClr)
{
std::ostringstream oss;
oss << "[DotNetRuntime] Error #" << GetLastError() << " Failed to load CoreCLR from \"" << coreClrPath << "\"\n";
throw std::runtime_error(oss.str());
}
// Step 2: Get CoreCLR hosting functions
initializeCoreClr = getCoreClrFunctionPtr<coreclr_initialize_ptr>("coreclr_initialize");
createManagedDelegate = getCoreClrFunctionPtr<coreclr_create_delegate_ptr>("coreclr_create_delegate");
shutdownCoreClr = getCoreClrFunctionPtr<coreclr_shutdown_ptr>("coreclr_shutdown");
}
// Step 3: Construct AppDomain properties used when starting the runtime
// Construct the trusted platform assemblies (TPA) list
// This is the list of assemblies that .NET Core can load as
// trusted system assemblies (similar to the .NET Framework GAC).
// For this host (as with most), assemblies next to CoreCLR will
// be included in the TPA list
std::string tpaList = buildTpaList(runtimePath);
// Define CoreCLR properties
std::array propertyKeys =
{
"TRUSTED_PLATFORM_ASSEMBLIES", // Trusted assemblies (like the GAC)
"APP_PATHS", // Directories to probe for application assemblies
// "APP_NI_PATHS", // Directories to probe for application native images (not used in this sample)
// "NATIVE_DLL_SEARCH_DIRECTORIES", // Directories to probe for native dlls (not used in this sample)
};
std::array propertyValues =
{
tpaList.c_str(),
runtimePath.c_str()
};
// Step 4: Start the CoreCLR runtime
int result = initializeCoreClr
(
runtimePath.c_str(), // AppDomain base path
"SHADEHost", // AppDomain friendly name
static_cast<int>(propertyKeys.size()), // Property count
propertyKeys.data(), // Property names
propertyValues.data(), // Property values
&hostHandle, // Host handle
&domainId // AppDomain ID
);
// Check if intiialization of CoreCLR failed
throwIfFailed("[DotNetRuntime] Failed to initialize CoreCLR.", result);
initialised = true;
SHLOG_INFO("[DotNetRuntime] Successfully loaded the .NET 6.0 Runtime.");
}
void SHDotNetRuntime::Exit()
{
// State checking, in case there was an unload before, we must ensure that the state is valid
if (!initialised)
throw std::runtime_error("[DotNetRuntime] Failed to deinitialise as it was not initialised before.");
// Shutdown CoreCLR
int result = shutdownCoreClr(hostHandle, domainId);
throwIfFailed("[DotNetRuntime] Failed to shut down CoreCLR.", result);
// Unset pointers
hostHandle = nullptr;
domainId = 0;
initialised = false;
SHLOG_INFO("[DotNetRuntime] Successfully shut down the .NET 6.0 Runtime.");
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
std::string SHDotNetRuntime::buildTpaList(const std::string& directory)
{
// Constants
static const std::string SEARCH_PATH = directory + "\\*.dll";
static constexpr char PATH_DELIMITER = ';';
// Create a osstream object to compile the string
std::ostringstream tpaList;
// Search the current directory for the TPAs (.DLLs)
WIN32_FIND_DATAA findData;
HANDLE fileHandle = FindFirstFileA(SEARCH_PATH.c_str(), &findData);
if (fileHandle != INVALID_HANDLE_VALUE)
{
do
{
// Append the assembly to the list
tpaList << directory << '\\' << findData.cFileName << PATH_DELIMITER;
// Note that the CLR does not guarantee which assembly will be loaded if an assembly
// is in the TPA list multiple times (perhaps from different paths or perhaps with different NI/NI.dll
// extensions. Therefore, a real host should probably add items to the list in priority order and only
// add a file if it's not already present on the list.
//
// For this simple sample, though, and because we're only loading TPA assemblies from a single path,
// and have no native images, we can ignore that complication.
}
while (FindNextFileA(fileHandle, &findData));
FindClose(fileHandle);
}
return tpaList.str();
}
void SHDotNetRuntime::throwIfFailed(const std::string& errMsg, int resultCode)
{
if (resultCode < 0)
{
std::ostringstream oss;
oss << std::hex << std::setfill('0') << std::setw(8)
<< errMsg
<< " Error 0x" << resultCode << "\n";
throw std::runtime_error(oss.str());
}
}
}

View File

@ -0,0 +1,207 @@
/*************************************************************************************//*!
\file SHDotNetRuntime.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 2, 2021
\brief Contains the interface of a wrapper class for interfacing with the
.NET 5 Runtime.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//**************************************************************************************/
#pragma once
// Standard Libraries
#include <iomanip> // std::setfill, std::setw
#include <stdexcept> // std::runtime_error
#include <string> // std::string
#include <sstream> // std::ostringstream
// External Dependencies
#include <Windows.h> // HMODULE
#include <coreclrhost.h> // coreclr_*
namespace SHADE
{
/*************************************************************************************/
/*!
class SHDotNetRuntime
\brief
Class that encapsulates the state of the .NET Core Runtime lifecycle.
*/
/*************************************************************************************/
class SHDotNetRuntime
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors/Destructor */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Default constructor that immediately initializes the CoreCLR.
\param autoInit
If true, loads the CoreCLR by calling Init().
*/
/***********************************************************************************/
SHDotNetRuntime(bool autoInit = true);
/***********************************************************************************/
/*!
\brief
Destructor that unloads the CoreCLR if it has not been unloaded yet.
*/
/***********************************************************************************/
~SHDotNetRuntime();
// Disallow copy and moving
SHDotNetRuntime(const SHDotNetRuntime&) = delete;
SHDotNetRuntime(SHDotNetRuntime&&) = delete;
/*----------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*----------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Loads the CoreCLR and grabs pointers to bootstrapping functions and kickstarts the
CoreCLR.
\throws std::runtime_error
Thrown if there is a failure in loading the CLR and related functions.
*/
/***********************************************************************************/
void Init();
/***********************************************************************************/
/*!
\brief
Unloads the CoreCLR.
\throws std::runtime_error
Thrown if there is a failure in unloading the CLR.
*/
/***********************************************************************************/
void Exit();
/*----------------------------------------------------------------------------------*/
/* Usage Functions */
/*----------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Checks if the DotNetRuntime has successfully been initialised.
\return
True if this DotNetRuntime has been initialised.
*/
/***********************************************************************************/
inline bool IsLoaded() const noexcept { return initialised; }
/***********************************************************************************/
/*!
\brief
Retrieves a function pointer from the a CLR assembly based on the specified
assembly, type and function names.
\tparam FunctionType
Type of the function pointer that the specified function name will provide.
\param assemblyName
Name of the CoreCLR assembly that contains the function.
\param typeName
Name of the CoreCLR type in the assembly that contains the function. Nested types
are separated by a period(.).
\param functionName
Name of the CoreCLR function to get a pointer to.
\return
Pointer to the function in the assembly that was specified.
*/
/***********************************************************************************/
template<typename FunctionType>
FunctionType GetFunctionPtr(const std::string_view& assemblyName,
const std::string_view& typeName,
const std::string_view& functionName) const;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
bool initialised = false;
// References to CoreCLR key components
HMODULE coreClr = nullptr;
void* hostHandle = nullptr;
unsigned int domainId = 0;
// Function Pointers to CoreCLR functions
coreclr_initialize_ptr initializeCoreClr = nullptr;
coreclr_create_delegate_ptr createManagedDelegate = nullptr;
coreclr_shutdown_ptr shutdownCoreClr = nullptr;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Retrieves a function pointer from the CoreCLR based on the specified
function name.
\tparam FunctionType
Type of the function pointer that the specified function name will provide.
\param functionName
Name of the CoreCLR function to get a pointer to.
\return
Pointer to the function in the CoreCLR that was specified.
*/
/***********************************************************************************/
template<typename FunctionType>
FunctionType getCoreClrFunctionPtr(const std::string& functionName);
/***********************************************************************************/
/*!
\brief
Compiles a semicolon separated string of trusted platform assemblies by
searching the specified directory.
\param directory
Path to the directory where the trusted platform assemblies reside.
\return
Semicolon separated string of trusted platform assemblies.
*/
/***********************************************************************************/
static std::string buildTpaList(const std::string& directory);
/***********************************************************************************/
/*!
\brief
Takes in a Win32 result code and throws an exception it if there is an error.
\param errMsg
Error message to display if the resultCode is a failure code.
\param resultCode
Result code of the function to check.
*/
/***********************************************************************************/
static void throwIfFailed(const std::string& errMsg, int resultCode);
};
}
#include "SHDotNetRuntime.hpp"

View File

@ -0,0 +1,61 @@
/*************************************************************************************//*!
\file SHDotNetRuntime.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 2, 2021
\brief Contains the implementation of the template functions of the
DotNetRuntime class.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//**************************************************************************************/
#pragma once
// Primary Include
#include "SHDotNetRuntime.h"
namespace SHADE
{
template<typename FunctionType>
FunctionType SHDotNetRuntime::GetFunctionPtr(const std::string_view & assemblyName,
const std::string_view & typeName,
const std::string_view & functionName) const
{
FunctionType managedDelegate = nullptr;
int result = createManagedDelegate
(
hostHandle,
domainId,
assemblyName.data(),
typeName.data(),
functionName.data(),
reinterpret_cast<void**>(&managedDelegate)
);
// Check if it failed
if (result < 0)
{
std::ostringstream oss;
oss << std::hex << std::setfill('0') << std::setw(8)
<< "[DotNetRuntime] Failed to get pointer to function \""
<< typeName << "." << functionName << "\" in assembly (" << assemblyName << "). "
<< "Error 0x" << result << "\n";
throw std::runtime_error(oss.str());
}
return managedDelegate;
}
template<typename FunctionType>
FunctionType SHDotNetRuntime::getCoreClrFunctionPtr(const std::string& functionName)
{
FunctionType fPtr = reinterpret_cast<FunctionType>(GetProcAddress(coreClr, functionName.c_str()));
if (!fPtr)
{
std::ostringstream oss;
oss << "[DotNetRuntime] Unable to get pointer to function: \"" << functionName << "\"";
throw std::runtime_error(oss.str());
}
return fPtr;
}
}

View File

@ -0,0 +1,506 @@
/************************************************************************************//*!
\file SHScriptEngine.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 17, 2021
\brief Contains the implementation for ScriptEngine class.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include <SHpch.h>
// Primary Header
#include "SHScriptEngine.h"
// Standard Library
#include <fstream> // std::fstream
#include <filesystem> // std::filesystem::canonical, std::filesystem::remove
// Project Headers
#include "Tools/SHLogger.h"
#include "Tools/SHStringUtils.h"
namespace SHADE
{
/*--------------------------------------------------------------------------------*/
/* Static Definitions */
/*--------------------------------------------------------------------------------*/
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
SHDotNetRuntime SHScriptEngine::dotNet { false };
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineInit = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineLoadScripts = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineUnloadScripts = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineReloadScripts = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineExit = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameSetUp = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteFixedUpdate = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteUpdate = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteLateUpdate = nullptr;
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameCleanUp = nullptr;
SHScriptEngine::CsScriptManipFuncPtr SHScriptEngine::csScriptsAdd = nullptr;
SHScriptEngine::CsScriptBasicFuncPtr SHScriptEngine::csScriptsRemoveAll = nullptr;
SHScriptEngine::CsScriptOptionalFuncPtr SHScriptEngine::csScriptsRemoveAllImmediately = nullptr;
SHScriptEngine::CsScriptSerialiseFuncPtr SHScriptEngine::csScriptsSerialise = nullptr;
SHScriptEngine::CsScriptDeserialiseFuncPtr SHScriptEngine::csScriptDeserialise = nullptr;
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptsSerialiseYaml = nullptr;
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptDeserialiseYaml = nullptr;
SHScriptEngine::CsScriptEditorFuncPtr SHScriptEngine::csEditorRenderScripts = nullptr;
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void SHScriptEngine::Init()
{
// Do not allow initialization if already initialised
if (dotNet.IsLoaded())
{
SHLOG_ERROR("[ScriptEngine] Attempted to initialise an already loaded DotNetRuntime.");
return;
}
dotNet.Init();
// Load all the helpers
loadFunctions();
// Generate script assembly if it hasn't been before
if (!fileExists(std::string(MANAGED_SCRIPT_LIB_NAME) + ".dll"))
{
BuildScriptAssembly();
}
// Initialise the CSharp Engine
csEngineInit();
// Link events
// - Entity Destruction
/*onEntityDestroy = [this](const SHEntity& e)
{
csScriptsRemoveAll(e.GetEID());
csGOLibNotifyDestroyEntity(e.GetEID());
};
ECS::OnEntityDestroy += onEntityDestroy;*/
}
void SHScriptEngine::UnloadScriptAssembly()
{
csEngineUnloadScripts();
}
void SHScriptEngine::LoadScriptAssembly()
{
csEngineLoadScripts();
}
void SHScriptEngine::ReloadScriptAssembly()
{
csEngineReloadScripts();
}
void SHScriptEngine::ExecuteFixedUpdates()
{
csScriptsExecuteFixedUpdate();
}
void SHScriptEngine::Exit()
{
// Do not allow deinitialization if not initialised
if (!dotNet.IsLoaded())
{
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
return;
}
// Unlink events
/*ECS::OnEntityCreated -= onEntityCreate;
ECS::OnEntityDestroy -= onEntityDestroy;*/
// Clean up the CSharp Engine
csEngineExit();
// Shut down the CLR
dotNet.Exit();
}
/*---------------------------------------------------------------------------------*/
/* Script Manipulation Functions */
/*---------------------------------------------------------------------------------*/
bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName)
{
return csScriptsAdd(entity.GetEID(), scriptName.data());
}
void SHScriptEngine::RemoveAllScripts(const SHEntity& entity)
{
csScriptsRemoveAll(entity.GetEID());
}
void SHScriptEngine::RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy)
{
csScriptsRemoveAllImmediately(entity.GetEID(), callOnDestroy);
}
/*---------------------------------------------------------------------------------*/
/* Script Serialisation Functions */
/*---------------------------------------------------------------------------------*/
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity)
{
// Create buffer needed to store serialised script data
constexpr int BUFFER_SIZE = 10240;
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
std::memset(buffer.get(), 0, BUFFER_SIZE);
// Attempt to serialise the script
std::string result;
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
{
result = std::string(buffer.get());
}
else
{
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
}
// Return an empty string since we failed to serialise
return result;
}
/*---------------------------------------------------------------------------------*/
/* Script Serialisation Functions */
/*---------------------------------------------------------------------------------*/
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml)
{
csScriptDeserialise(entity.GetEID(), yaml.c_str());
}
/*---------------------------------------------------------------------------------*/
/* Script Editor Functions */
/*---------------------------------------------------------------------------------*/
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity)
{
csEditorRenderScripts(entity.GetEID());
}
/*---------------------------------------------------------------------------------*/
/* Static Utility Functions */
/*---------------------------------------------------------------------------------*/
bool SHScriptEngine::BuildScriptAssembly(bool debug)
{
constexpr std::string_view BUILD_LOG_PATH = "../Build.log";
// Generate csproj file if it doesn't exist
static const std::filesystem::path CSPROJ_PATH = "../SHADE_Scripting.csproj";
if (!std::filesystem::exists(CSPROJ_PATH))
{
GenerateScriptsCsProjFile(CSPROJ_PATH);
}
// Prepare directory (delete useless files)
deleteFolder("net6.0");
deleteFolder("ref");
deleteFolder("../SHADE_Scripting");
deleteFolder("../obj");
// Attempt to build the assembly
std::ostringstream oss;
oss << "[ScriptEngine] Building " << (debug ? " debug " : "") << "Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
SHLOG_INFO(oss.str());
oss.str("");
const bool BUILD_SUCCESS = execProcess
(
L"C:\\Windows\\system32\\cmd.exe",
L"/K \"dotnet build \"../SHADE_Scripting.csproj\" -c Debug -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet & exit\""
) == 0;
if (BUILD_SUCCESS)
{
// Copy to built dll to the working directory and replace
std::filesystem::copy_file("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing);
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
SHLOG_INFO(oss.str());
}
else
{
oss << "[ScriptEngine] Failed to build Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
SHLOG_ERROR(oss.str());
}
// Clean up built files
deleteFolder("./tmp");
// Read the build log and output to the console
dumpBuildLog(BUILD_LOG_PATH);
// Delete the build log file since we no longer need it
deleteFile(BUILD_LOG_PATH);
return BUILD_SUCCESS;
}
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path)
{
// Sample
static std::string_view FILE_CONTENTS =
"<Project Sdk=\"Microsoft.NET.Sdk\">\n\
<PropertyGroup>\n\
<TargetFramework>net6.0</TargetFramework>\n\
<Platforms>x64</Platforms>\n\
<Configurations>Release;Debug</Configurations>\n\
</PropertyGroup>\n\
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n\
<OutputPath>.\\bin_Release-x64</OutputPath>\n\
<PlatformTarget>x64</PlatformTarget>\n\
</PropertyGroup>\n\
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\"> \n\
<OutputPath>.\\bin_Debug-x64</OutputPath>\n\
<PlatformTarget>x64</PlatformTarget>\n\
<DefineConstants>DEBUG;TRACE</DefineConstants>\n\
<Optimize>false</Optimize>\n\
<DebugType>full</DebugType>\n\
<DebugSymbols>true</DebugSymbols>\n\
</PropertyGroup>\n\
<ItemGroup>\n\
<Compile Remove=\"bin\\**\" />\n\
<EmbeddedResource Remove=\"Assets\\**\" />\n\
<EmbeddedResource Remove=\"bin\\**\" />\n\
<None Remove=\"bin\\**\" />\n\
</ItemGroup>\n\
<ItemGroup>\n\
<None Remove=\".gitignore\" />\n\
<None Remove=\".gitmodules\" />\n\
</ItemGroup>\n\
<ItemGroup>\n\
<Reference Include=\"SHADE_Managed\">\n\
<HintPath>.\\bin\\SHADE_Managed.dll</HintPath>\n\
</Reference>\n\
</ItemGroup>\n\
</Project>";
// Attempt to create the file
std::ofstream file(path);
if (!file.is_open())
throw std::runtime_error("Unable to create CsProj file!");
// Fill the file
file << FILE_CONTENTS;
// Close
file.close();
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
void SHScriptEngine::loadFunctions()
{
std::ostringstream oss;
oss << "[ScriptEngine] Loading \"" << DEFAULT_CSHARP_LIB_NAME << "\" CLR library.";
SHLOG_INFO(oss.str());
// Load functions
csEngineInit = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
"Init"
);
csEngineLoadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
"LoadScriptAssembly"
);
csEngineUnloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
"UnloadScriptAssembly"
);
csEngineReloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
"ReloadScriptAssembly"
);
csEngineExit = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
"Exit"
);
csScriptsFrameSetUp = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"FrameSetUp"
);
csScriptsExecuteFixedUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"ExecuteFixedUpdate"
);
csScriptsExecuteUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"ExecuteUpdate"
);
csScriptsExecuteLateUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"ExecuteLateUpdate"
);
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"FrameCleanUp"
);
csScriptsAdd = dotNet.GetFunctionPtr<CsScriptManipFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"AddScriptViaName"
);
csScriptsRemoveAll = dotNet.GetFunctionPtr<CsScriptBasicFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"RemoveAllScripts"
);
csScriptsRemoveAllImmediately = dotNet.GetFunctionPtr<CsScriptOptionalFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"RemoveAllScriptsImmediately"
);
/*csScriptsSerialise = dotNet.GetFunctionPtr<CsScriptSerialiseFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScripts"
);
csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScriptsYaml"
);
csScriptDeserialise = dotNet.GetFunctionPtr<CsScriptDeserialiseFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"DeserialiseScript"
);
csScriptDeserialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScriptsYaml"
);
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Editor",
"RenderScriptsInInspector"
);*/
}
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
{
std::ifstream buildLog(buildLogPath);
// Fail to open
if (!buildLog.is_open())
return;
// Process line by line
std::string line;
while (std::getline(buildLog, line))
{
if (line.find("error") != line.npos)
{
SHLOG_ERROR(line);
}
else
{
SHLOG_WARNING(line);
}
}
}
void SHScriptEngine::deleteFile(const std::string_view& filePath)
{
try
{
std::filesystem::remove(std::filesystem::canonical(filePath));
}
catch (...) {} // Ignore deletion failures
}
void SHScriptEngine::deleteFolder(const std::string_view& filePath)
{
try
{
std::filesystem::remove_all(std::filesystem::canonical(filePath));
}
catch (...) {} // Ignore deletion failures
}
bool SHScriptEngine::fileExists(const std::string_view& filePath)
{
std::error_code error;
if (std::filesystem::exists(filePath, error))
{
return true;
}
return false;
}
DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args)
{
STARTUPINFOW startInfo;
PROCESS_INFORMATION procInfo;
ZeroMemory(&startInfo, sizeof(startInfo));
ZeroMemory(&procInfo, sizeof(procInfo));
startInfo.cb = sizeof(startInfo);
std::wstring argsWstr = args;
// Start Process
const auto SUCCESS = CreateProcess
(
path.data(), argsWstr.data(),
nullptr, nullptr, false, NULL, nullptr, nullptr,
&startInfo, &procInfo
);
// Error Check
if (!SUCCESS)
{
auto err = GetLastError();
std::ostringstream oss;
oss << "[ScriptEngine] Failed to launch process. Error code: " << std::hex << err
<< " (" << SHStringUtils::GetWin32ErrorMessage(err) << ")";
throw std::runtime_error(oss.str());
}
// Wait for execution to end
DWORD status;
while (true)
{
const auto SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
if (!SUCCESS)
{
auto err = GetLastError();
std::ostringstream oss;
oss << "[ScriptEngine] Failed to query process. Error code: " << std::hex << err
<< " (" << SHStringUtils::GetWin32ErrorMessage(err) << ")";
throw std::runtime_error(oss.str());
}
// Break only if process ends
if (status != STILL_ACTIVE)
{
CloseHandle(procInfo.hProcess);
CloseHandle(procInfo.hThread);
return status;
}
}
}
}

View File

@ -0,0 +1,247 @@
/************************************************************************************//*!
\file ScriptEngine.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 17, 2021
\brief Contains the interface for ScriptEngine class.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <filesystem>
// Project Headers
#include "SHDotNetRuntime.h"
#include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/Entity/SHEntity.h"
#include "SH_API.h"
namespace SHADE
{
/// <summary>
/// Manages initialisation of the DotNetRuntime and interfacing with CLR code written
/// and executed on .NET.
/// </summary>
class SH_API SHScriptEngine
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor */
/*-----------------------------------------------------------------------------*/
SHScriptEngine() = delete;
/*-----------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Initialises the DotNetRuntime and retrieves function pointers to all
/// functions on the CLR used to interface with the engine.
/// </summary>
static void Init();
/// <summary>
/// Loads the managed script assembly. Ensure this is only called after
/// UnloadScriptAssembly() has been called.
/// </summary>
static void UnloadScriptAssembly();
/// <summary>
/// Unloads the managed script assembly.
/// Take note that this will clear all existing scripts, ensure that the scene
/// is saved before doing so.
/// </summary>
static void LoadScriptAssembly();
/// <summary>
/// Reloads the managed script assembly.
/// Take note that this will clear all existing scripts, ensure that the scene
/// is saved before doing so.
/// </summary>
static void ReloadScriptAssembly();
/// <summary>
/// Executes the FixedUpdate()s of the Scripts that are attached to
/// Entities.
/// </summary>
static void ExecuteFixedUpdates();
/// <summary>
/// Shuts down the DotNetRuntime.
/// </summary>
static void Exit();
/*-----------------------------------------------------------------------------*/
/* Script Manipulation Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Script to a specified Entity. Note that while you can call this
/// multiple times on a specified Entity, it will work for all intents and
/// purposes but GetScript&lt;T&gt;() (C# only) currently only
/// gives you the first Script added of the specified type.
/// </summary>
/// <param name="entity">The entity to add a script to.</param>
/// <param name="scriptName">Type name of the script to add.</param>
/// <returns>
/// True if successfully added. False otherwise with the error logged to the
/// console.
/// </returns>
static bool AddScript(const SHEntity& entity, const std::string_view& scriptName);
/// <summary>
/// Removes all Scripts attached to the specified Entity. Does not do anything
/// if the specified Entity is invalid or does not have any Scripts
/// attached.
/// </summary>
/// <param name="entity">The entity to remove the scripts from.</param>
static void RemoveAllScripts(const SHEntity& entity);
/// <summary>
/// Removes all Scripts attached to the specified Entity. Unlike
/// RemoveAllScripts(), this removes all the scripts immediately.
/// Does not do anything if the specified Entity is invalid or does not have any
/// Scripts attached.
/// </summary>
/// <param name="entity">The entity to remove the scripts from.</param>
/// <param name="callOnDestroy">
/// Whether or not to call OnDestroy on the scripts. This is ignored if not in
/// play mode.
/// </param>
static void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy);
/*-----------------------------------------------------------------------------*/
/* Script Serialisation Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Generates a JSON string that represents the set of Scripts attached to the
/// specified Entity.
/// </summary>
/// <param name="entity"> The Entity to Serialise.</param>
/// <returns>
/// String that represents the set of scripts attached to the specified Entity.
/// </returns>
static std::string SerialiseScripts(const SHEntity& entity);
/// <summary>
/// Loads the specified JSON string and creates a Script for the specified Entity
/// based on the specified JSON string.
/// </summary>
/// <param name="entity">The Entity to deserialise a Script on to.</param>
/// <param name="yaml">
/// The YAML string that represents the Script to load into the Entity.
/// </param>
static void DeserialiseScript(const SHEntity& entity, const std::string& yaml);
/*-----------------------------------------------------------------------------*/
/* Script Editor Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Renders the set of attached Scripts for the specified Entity into the
/// inspector.
/// <br/>
/// This function is meant for consumption from native code in the inspector
/// rendering code.
/// </summary>
/// <param name="entity">The Entity to render the Scripts of.</param>
static void RenderScriptsInInspector(const SHEntity& entity);
/*-----------------------------------------------------------------------------*/
/* Static Utility Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Utilises execution of a external batch file for invoking the dotnet build
/// tool to compile C# scripts in the Assets folder into the SHADE_Scripting
/// C# assembly DLL.
/// </summary>
/// <param name="debug">
/// Whether or not a debug build will be built. Only debug built C# assemblies
/// can be debugged.
/// </param>
/// <returns>Whether or not the build succeeded.</returns>
static bool BuildScriptAssembly(bool debug = false);
/// <summary>
/// Generates a .csproj file for editing and compiling the C# scripts.
/// </summary>
/// <param name="path">File path to the generated file.</param>
static void GenerateScriptsCsProjFile(const std::filesystem::path& path);
private:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using CsFuncPtr = void(*)(void);
using CsScriptManipFuncPtr = bool(*)(EntityID, const char*);
using CsScriptBasicFuncPtr = void(*)(EntityID);
using CsScriptOptionalFuncPtr = void(*)(EntityID, bool);
using CsScriptSerialiseFuncPtr = bool(*)(EntityID, char*, int);
using CsScriptDeserialiseFuncPtr = bool(*)(EntityID, const char*);
using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*);
using CsScriptEditorFuncPtr = void(*)(EntityID);
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
static constexpr std::string_view DEFAULT_CSHARP_LIB_NAME = "SHADE_Managed";
static constexpr std::string_view MANAGED_SCRIPT_LIB_NAME = "SHADE_Scripting";
static const std::string DEFAULT_CSHARP_NAMESPACE;
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
static SHDotNetRuntime dotNet;
// Function Pointers to CLR Code
// - Engine Lifecycle
static CsFuncPtr csEngineInit;
static CsFuncPtr csEngineLoadScripts;
static CsFuncPtr csEngineUnloadScripts;
static CsFuncPtr csEngineReloadScripts;
static CsFuncPtr csEngineExit;
// - Scripts Store
static CsFuncPtr csScriptsFrameSetUp;
static CsFuncPtr csScriptsExecuteFixedUpdate;
static CsFuncPtr csScriptsExecuteUpdate;
static CsFuncPtr csScriptsExecuteLateUpdate;
static CsFuncPtr csScriptsFrameCleanUp;
static CsScriptManipFuncPtr csScriptsAdd;
static CsScriptBasicFuncPtr csScriptsRemoveAll;
static CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately;
static CsScriptSerialiseFuncPtr csScriptsSerialise;
static CsScriptDeserialiseFuncPtr csScriptDeserialise;
static CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml;
static CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml;
// - Editor
static CsScriptEditorFuncPtr csEditorRenderScripts;
// Delegates
/*ECS::EntityEvent::Delegate onEntityCreate;
ECS::EntityEvent::Delegate onEntityDestroy;*/
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Loads all the function pointers to CLR code that we need to execute.
/// </summary>
static void loadFunctions();
/// <summary>
/// Reads the file via the specified path that represents a build log of error
/// and warning messages.
/// </summary>
/// <param name="buildLogPath">
/// File path to the build log of script builds done by BuildScriptAssembly() to
/// dump and process.
/// </param>
static void dumpBuildLog(const std::string_view& buildLogPath);
/// <summary>
/// Deletes the file as specified by the file path.
/// </summary>
/// <param name="filePath">File path to the file to delete.</param>
static void deleteFile(const std::string_view& filePath);
/// <summary>
/// Deletes the folder and all files in it as specified by the file path.
/// </summary>
/// <param name="filePath">File path to the file to delete.</param>
static void deleteFolder(const std::string_view& filePath);
/// <summary>
/// Checks if a specified file exists.
/// </summary>
/// <param name="filePath">File path to the file to check.</param>
/// <returns> True if the file exists </returns>
static bool fileExists(const std::string_view& filePath);
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
};
}

View File

@ -12,13 +12,15 @@
#include <exception>
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHExceptionHandler
class SH_API SHExceptionHandler
{
public:
/*---------------------------------------------------------------------------------*/

View File

@ -0,0 +1,30 @@
/************************************************************************************//*!
\file SHFileUtilities.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 15, 2022
\brief Contains the definition of functions of the SHFileUtilities static class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Header
#include "SHpch.h"
// Primary Header
#include "SHFileUtilties.h"
// Standard Libraries
#include <filesystem>
// External Dependencies
#include <shlwapi.h> // GetModuleFileName, PathRemoveFileSpec
namespace SHADE
{
void SHFileUtilities::SetWorkDirToExecDir()
{
TCHAR currentExecFilePath[MAX_PATH] = { '\0' };
GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH);
PathRemoveFileSpec(currentExecFilePath);
std::filesystem::current_path(currentExecFilePath);
}
}

View File

@ -0,0 +1,38 @@
/************************************************************************************//*!
\file SHFileUtilities.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 15, 2022
\brief Contains the SHFileUtilities static class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Project Headers
#include "SH_API.h"
namespace SHADE
{
/*!************************************************************************************
\class SHFileUtilities
\brief
Static class that contains functions for working with files and directories.
**************************************************************************************/
class SH_API SHFileUtilities
{
public:
/*!**********************************************************************************
\brief
Sets the application's current working directory to the application executable's
directory.
************************************************************************************/
static void SetWorkDirToExecDir();
};
}

View File

@ -30,8 +30,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
unsigned char SHLogger::configFlags = DEFAULT_CONFIG_FLAG;
SHLogger::DateFormat SHLogger::dateFormat = SHLogger::DateFormat::DD_MM_YY;
unsigned char SHLogger::configFlags = DEFAULT_CONFIG_FLAG;
SHLogger::DateFormat SHLogger::dateFormat = SHLogger::DateFormat::DD_MM_YY;
SHLogger::Logger SHLogger::logger = nullptr;
std::string SHLogger::trivialPattern;
std::string SHLogger::verbosePattern;
@ -142,7 +143,7 @@ namespace SHADE
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHLogger::Initialise(const Config& config)
SHLogger::Logger SHLogger::Initialise(const Config& config)
{
SetConfig(config);
@ -176,10 +177,10 @@ namespace SHADE
FILE_SINK->set_pattern(trivialPattern + "%v");
// Create and register logger with spdlog
const auto LOGGER = std::make_shared<spdlog::logger>(SHLOGGER_NAME, sinks.begin(), sinks.end());
LOGGER->set_level(spdlog::level::trace);
LOGGER->flush_on(spdlog::level::trace);
register_logger(LOGGER);
logger = std::make_shared<spdlog::logger>(SHLOGGER_NAME, sinks.begin(), sinks.end());
logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::trace);
spdlog::register_logger(logger);
// Flush every 3 seconds
spdlog::flush_every(std::chrono::seconds(config.flushTime));
@ -190,6 +191,8 @@ namespace SHADE
{
std::cout << "Log initialisation failed: " << e.what() << std::endl;
}
return logger;
}
void SHLogger::Shutdown() noexcept
@ -211,6 +214,143 @@ namespace SHADE
sinks[1]->set_pattern(verbosePattern + "%v"); // File Sink
}
void SHLogger::LogInfo(const std::string& msg) noexcept
{
SHLOG_INFO(msg)
}
void SHLogger::LogVerboseInfo(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_INFO(ss.str())
}
void SHLogger::LogWarning(const std::string& msg) noexcept
{
SHLOG_WARNING(msg)
}
void SHLogger::LogVerboseWarning(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_WARNING(ss.str())
}
void SHLogger::LogError(const std::string& msg) noexcept
{
SHLOG_ERROR(msg)
}
void SHLogger::LogVerboseError(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_ERROR(ss.str())
}
void SHLogger::LogCritical(const std::string& msg) noexcept
{
SHLOG_CRITICAL(msg)
}
void SHLogger::LogVerboseCritical(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_CRITICAL(ss.str())
}
void SHLogger::LogFloor() noexcept
{
SHLOG_FLOOR()
}
#ifdef _DEBUG
void SHLogger::LogTrace(const std::string& msg) noexcept
{
SHLOG_TRACE(msg)
}
void SHLogger::LogVerboseTrace(const std::string& msg, const std::source_location& src) noexcept
{
const bool SHOW_SRC_FILE = configFlags & (1U << 3);
const bool SHOW_SRC_LINE = configFlags & (1U << 4);
std::stringstream ss;
ss << "[";
if (SHOW_SRC_FILE)
{
ss << std::filesystem::path(src.file_name()).filename().string() << ", ";
if (SHOW_SRC_LINE)
{
ss << src.line() << ", ";
}
}
ss << src.function_name() << "] " << msg;
SHLOG_TRACE(ss.str())
}
#endif
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/

View File

@ -12,9 +12,11 @@
#include <string_view>
#include <filesystem>
#include <source_location>
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
#include <spdlog/spdlog.h>
#include "SH_API.h"
/*-------------------------------------------------------------------------------------*/
/* Macros */
@ -27,13 +29,15 @@ namespace SHADE
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHLogger
class SH_API SHLogger
{
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
using Logger = std::shared_ptr<spdlog::logger>;
enum class ClockFormat { _12HR, _24HR };
enum class DateFormat
@ -70,33 +74,33 @@ namespace SHADE
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static const std::string& GetTrivialPattern () noexcept { return trivialPattern; }
[[nodiscard]] static const std::string& GetVerbosePattern () noexcept { return verbosePattern; }
[[nodiscard]] static const std::string& GetTrivialPattern () noexcept { return trivialPattern; }
[[nodiscard]] static const std::string& GetVerbosePattern () noexcept { return verbosePattern; }
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
static void SetTrivialPattern (const std::string& pattern) noexcept { trivialPattern = pattern; }
static void SetVerbosePattern (const std::string& pattern) noexcept { verbosePattern = pattern; }
static void SetTrivialPattern (const std::string& pattern) noexcept { trivialPattern = pattern; }
static void SetVerbosePattern (const std::string& pattern) noexcept { verbosePattern = pattern; }
static void SetConfig (const Config& config) noexcept;
static void SetConfig (const Config& config) noexcept;
static void SetShowTime (bool showTime) noexcept;
static void SetShowDate (bool showDate) noexcept;
static void SetShowFunctionFileName (bool showFunctionFileName) noexcept;
static void SetShowFunctionLineNumber (bool showFunctionLineNumber) noexcept;
static void SetShowTime (bool showTime) noexcept;
static void SetShowDate (bool showDate) noexcept;
static void SetShowFunctionFileName (bool showFunctionFileName) noexcept;
static void SetShowFunctionLineNumber (bool showFunctionLineNumber) noexcept;
static void SetClockFormat (ClockFormat newClockFormat) noexcept;
static void SetDateFormat (DateFormat newDateFormat) noexcept;
static void SetClockFormat (ClockFormat newClockFormat) noexcept;
static void SetDateFormat (DateFormat newDateFormat) noexcept;
static void SetFileName (const std::string& logFileName) noexcept;
static void SetDirectoryPath (const std::filesystem::path& logDirectoryPath) noexcept;
static void SetFileName (const std::string& logFileName) noexcept;
static void SetDirectoryPath (const std::filesystem::path& logDirectoryPath) noexcept;
static void SetFlushTime (int seconds) noexcept;
static void SetFlushTime (size_t seconds) noexcept { spdlog::flush_every(std::chrono::seconds(seconds)); }
static void SetFlushTime (int seconds) noexcept;
static void SetFlushTime (size_t seconds) noexcept { spdlog::flush_every(std::chrono::seconds(seconds)); }
/*---------------------------------------------------------------------------------*/
/* Function Members */
@ -106,17 +110,34 @@ namespace SHADE
* @brief Creates a console and a file to log to.
* @param[in] config The configuration parameters for the logger.
*/
static void Initialise (const Config& config = Config{});
static Logger Initialise (const Config& config = Config{});
static void Shutdown () noexcept;
/**
* @brief The next message logged by the logger will be set to follow the trivial pattern.
*/
static void UseTrivialPattern () noexcept;
static void UseTrivialPattern () noexcept;
/**
* @brief The next message logged by the logger will be set to follow the verbose pattern.
*/
static void UseVerbosePattern () noexcept;
static void UseVerbosePattern () noexcept;
/// Logging Functions to interface with C++/CLI.
static void LogInfo (const std::string& msg) noexcept;
static void LogVerboseInfo (const std::string& msg, const std::source_location& src= std::source_location::current()) noexcept;
static void LogWarning (const std::string& msg) noexcept;
static void LogVerboseWarning (const std::string& msg, const std::source_location& src = std::source_location::current()) noexcept;
static void LogError (const std::string& msg) noexcept;
static void LogVerboseError (const std::string& msg, const std::source_location& src = std::source_location::current()) noexcept;
static void LogCritical (const std::string& msg) noexcept;
static void LogVerboseCritical (const std::string& msg, const std::source_location& src = std::source_location::current()) noexcept;
static void LogFloor () noexcept;
#ifdef _DEBUG
static void LogTrace (const std::string& msg) noexcept;
static void LogVerboseTrace (const std::string& msg, const std::source_location& src = std::source_location::current()) noexcept;
#endif
private:
/*---------------------------------------------------------------------------------*/
@ -128,6 +149,8 @@ namespace SHADE
static unsigned char configFlags; // Initialised 0 0 FuncLine# FuncFileName Date TimeFormat Time
static DateFormat dateFormat;
static Logger logger;
static std::string trivialPattern;
static std::string verbosePattern;
@ -172,3 +195,6 @@ namespace SHADE
// Misc Logging Macros
#define SHLOG_FLOOR() SHADE::SHLogger::UseTrivialPattern(); SPDLOG_LOGGER_INFO(spdlog::get(SHLOGGER_NAME), "--------------------------------");
// For use outside the library to register the logger
#define SHLOG_REGISTER(logger) spdlog::register_logger(logger); spdlog::set_level(spdlog::level::level_enum::trace);

View File

@ -0,0 +1,52 @@
/************************************************************************************//*!
\file StringUtilities.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 29, 2021
\brief Contains the definition of functions for working with strings.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Header
#include <SHpch.h>
// Primary Header
#include "SHStringUtils.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Utility Functions */
/*---------------------------------------------------------------------------------*/
std::vector<std::string> SHStringUtils::Split(const std::string& str, const char& delim)
{
return Split<char>(str, delim);
}
std::vector<std::wstring> SHStringUtils::Split(const std::wstring& str, const wchar_t& delim)
{
return Split<wchar_t>(str, delim);
}
std::string SHStringUtils::WstrToStr(const std::wstring& wstr)
{
static std::vector<char> buffer;
const int STR_SIZE = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr) + 1 /* Null Terminator */;
buffer.resize(STR_SIZE);
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), buffer.data(), MAX_PATH, nullptr, nullptr);
return std::string(buffer.data());
}
std::wstring SHStringUtils::StrToWstr(const std::string& str)
{
static std::vector<wchar_t> buffer;
const int WSTR_SIZE = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), nullptr, 0) + 1 /* Null Terminator */;
buffer.resize(WSTR_SIZE);
MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), buffer.data(), WSTR_SIZE);
return std::wstring(buffer.data());
}
std::string SHStringUtils::GetWin32ErrorMessage(unsigned long errorCode)
{
return std::system_category().message(errorCode);
}
}

View File

@ -0,0 +1,81 @@
/************************************************************************************//*!
\file StringUtilities.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 29, 2021
\brief Contains the declaration of functions for working with files and folders.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Standard Libraries
#include <string> // std::basic_string
#include <vector> // std::vector
namespace SHADE
{
/// <summary>
/// Contains useful functions for operating on strings.
/// </summary>
class SHStringUtils
{
public:
/*-----------------------------------------------------------------------------*/
/* Utility Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Splits a string separated by a specified delimiter into a vector of strings.
/// </summary>
/// <typeparam name="T">Internal type of each element in the string.</typeparam>
/// <param name="str">Read only reference to the string to split.</param>
/// <param name="delim">Read only reference to the delimiter.</param>
/// <returns>Vector of strings that have been split.</returns>
template<typename T>
static std::vector<std::basic_string<T>> Split(const std::basic_string<T>& str, const T& delim);
/// <summary>
/// Splits a string separated by a specified delimiter into a vector of strings.
/// Overload of Split<T>() to allow for string literals to be accepted.
/// </summary>
/// <param name="str">Read only reference to the string to split.</param>
/// <param name="delim">Read only reference to the delimiter.</param>
/// <returns>Vector of strings that have been split.</returns>
static std::vector<std::string> Split(const std::string& str, const char& delim);
/// <summary>
/// Splits a string separated by a specified delimiter into a vector of strings.
/// Overload of Split<T>() to allow for wide string literals to be accepted.
/// </summary>
/// <param name="str">Read only reference to the string to split.</param>
/// <param name="delim">Read only reference to the delimiter.</param>
/// <returns>Vector of strings that have been split.</returns>
static std::vector<std::wstring> Split(const std::wstring& str, const wchar_t& delim);
/// <summary>
/// Converts a wstring to a string.
/// </summary>
/// <param name="wstr">wstring to convert.</param>
/// <returns>The converted wstring in string form.</returns>
static std::string WstrToStr(const std::wstring& wstr);
/// <summary>
/// Converts a string to a wstring.
/// </summary>
/// <param name="str">string to convert.</param>
/// <returns>The converted string in wstring form.</returns>
static std::wstring StrToWstr(const std::string& str);
/// <summary>
/// Retrieves the error message associated with a Win32 error code.
/// </summary>
/// <param name="errorCode">Win32 error code to decode.</param>
/// <returns>String that represents the Win32 error.</returns>
static std::string GetWin32ErrorMessage(unsigned long errorCode);
private:
/*-------------------------------------------------------------------------------*/
/* Constructors/Destructors */
/*-------------------------------------------------------------------------------*/
SHStringUtils() = delete;
};
}
#include "SHStringUtils.hpp"

View File

@ -0,0 +1,46 @@
/************************************************************************************//*!
\file StringUtilities.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 29, 2021
\brief Contains the implementation of template functions for working with files
and folders.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Primary Header
#include "SHStringUtils.h"
namespace SHADE
{
/*-------------------------------------------------------------------------------*/
/* Template Function Definitions */
/*-------------------------------------------------------------------------------*/
template<typename T>
inline std::vector<std::basic_string<T>> SHStringUtils::Split(const std::basic_string<T>& str, const T& delim)
{
std::vector<std::basic_string<T>> results;
std::basic_string<T> remaining = str;
// Go through looking for delimiters
while (true)
{
const size_t DELIM_POS = remaining.find_first_of(delim);
results.emplace_back(remaining.substr(0, DELIM_POS));
// Check if we hit the end of the string
if (DELIM_POS == remaining.npos)
{
break;
}
// Otherwise, cut the remainder
remaining = remaining.substr(DELIM_POS + 1);
}
return results;
}
}

View File

@ -0,0 +1,50 @@
/****************************************************************************************
* \file SHutilities.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for various utility functions.
*
* \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 "Math/SHMathHelpers.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Concepts */
/*-----------------------------------------------------------------------------------*/
template <typename EnumType>
concept IsEnum = std::is_enum_v<EnumType>;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHUtilities
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
/**
* @brief Converts an enum class member from it's type to any other type.
* @tparam InputType Restricted to an enum class
* @tparam OutputType The type to convert the enum class member to. Defaults to int.
* @param[in] enumClassMember A member of the specified enum class.
* @returns The value of the enum class member in the output type.
*/
template <IsEnum InputType, IsIntegral OutputType = int>
static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept;
};
} // namespace SHADE
#include "SHUtilities.hpp"

View File

@ -0,0 +1,28 @@
/****************************************************************************************
* \file SHutilities.hpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for various templated utility functions.
*
* \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
// Primary Header
#include "SHUtilities.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Function Members Definitions */
/*-----------------------------------------------------------------------------------*/
template <IsEnum InputType, IsIntegral OutputType>
constexpr OutputType SHUtilities::ConvertEnum (InputType enumClassMember) noexcept
{
return static_cast<OutputType>(enumClassMember);
}
} // namespace SHADE

View File

@ -0,0 +1,74 @@
project "SHADE_Managed"
kind "SharedLib"
language "C++"
clr "NetCore"
dotnetframework "net6.0"
cppdialect "C++17"
targetdir (outputdir)
objdir (interdir)
systemversion "latest"
pchheader "SHpch.h"
pchsource "%{prj.location}/src/SHpch.cpp"
staticruntime "off"
files
{
"%{prj.location}/src/**.hxx",
"%{prj.location}/src/**.h++",
"%{prj.location}/src/**.cxx",
"%{prj.location}/src/**.h",
"%{prj.location}/src/**.hpp",
"%{prj.location}/src/**.c",
"%{prj.location}/src/**.cpp",
}
includedirs
{
"%{prj.location}/src",
"%{IncludeDir.spdlog}/include",
"%{IncludeDir.imgui}",
"%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}",
"%{IncludeDir.yamlcpp}",
"%{IncludeDir.RTTR}/include",
"%{wks.location}/SHADE_Engine/src"
}
links
{
"yaml-cpp",
"imgui",
"SHADE_Engine"
}
disablewarnings
{
"4251"
}
defines
{
"NOMINMAX"
}
flags
{
"MultiProcessorCompile"
}
dependson
{
"yaml-cpp",
"imgui",
"SHADE_Engine"
}
warnings 'Extra'
filter "configurations:Debug"
symbols "On"
defines {"_DEBUG"}
filter "configurations:Release"
optimize "On"
defines{"_RELEASE"}

View File

@ -0,0 +1,39 @@
/************************************************************************************//*!
\file AssemblyInfo.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 24, 2021
\brief Defines the properties of this managed .NET Assembly.
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.
*//*************************************************************************************/
#include "SHpch.h"
/*-------------------------------------------------------------------------------------*/
/* Using Declarations */
/*-------------------------------------------------------------------------------------*/
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
/*-------------------------------------------------------------------------------------*/
/* Assembly Properties */
/*-------------------------------------------------------------------------------------*/
[assembly:AssemblyTitleAttribute(L"SHADE_Managed")];
[assembly:AssemblyDescriptionAttribute(L"")];
[assembly:AssemblyConfigurationAttribute(L"")];
[assembly:AssemblyCompanyAttribute(L"")];
[assembly:AssemblyProductAttribute(L"SHADE_Managed")];
[assembly:AssemblyCopyrightAttribute(L"Copyright (C) 2022 DigiPen Institute of Technology")];
[assembly:AssemblyTrademarkAttribute(L"")];
[assembly:AssemblyCultureAttribute(L"")];
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];

View File

@ -0,0 +1,107 @@
/************************************************************************************//*!
\file Component.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 27, 2021
\brief Contains the definition of the functions for the Component class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Components/Component.hxx"
// External Dependencies
#include "Engine/ECS.hxx"
// Project Headers
#include "Scripts/ScriptStore.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Component Access Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T BaseComponent::AddComponent()
{
return ECS::AddComponent<T>(owner.GetEntity());
}
generic <typename T>
T BaseComponent::GetComponent()
{
return ECS::GetComponent<T>(owner.GetEntity());
}
generic <typename T>
void BaseComponent::RemoveComponent()
{
ECS::RemoveComponent<T>(owner.GetEntity());
}
/*---------------------------------------------------------------------------------*/
/* Script Access Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T BaseComponent::AddScript()
{
return ScriptStore::AddScript<T>(owner.GetEntity());
}
generic <typename T>
T BaseComponent::GetScript()
{
return ScriptStore::GetScript<T>(owner.GetEntity());
}
generic <typename T>
System::Collections::Generic::IEnumerable<T>^ BaseComponent::GetScripts()
{
return ScriptStore::GetScripts<T>(owner.GetEntity());
}
generic <typename T>
void BaseComponent::RemoveScript()
{
ScriptStore::RemoveScript<T>(owner.GetEntity());
}
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
BaseComponent::BaseComponent(Entity entity)
: owner { entity }
{}
/*---------------------------------------------------------------------------------*/
/* IEquatable */
/*---------------------------------------------------------------------------------*/
bool BaseComponent::Equals(BaseComponent^ other)
{
if (other == nullptr)
return false;
return owner == other->owner;
}
/*---------------------------------------------------------------------------------*/
/* Object */
/*---------------------------------------------------------------------------------*/
bool BaseComponent::Equals(Object^ o)
{
try
{
BaseComponent^ cmp = safe_cast<BaseComponent^>(o);
return Equals(cmp);
}
catch (System::InvalidCastException^)
{
return false;
}
}
int BaseComponent::GetHashCode()
{
return owner.GetHashCode();
}
}

View File

@ -0,0 +1,41 @@
/************************************************************************************//*!
\file Component.h++
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 27, 2021
\brief Contains the definition of templated functions for the managed Component
classes.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Primary Include
#include "Component.hxx"
// Project includes
#include "Utility/Convert.hxx"
#include "Engine/ECS.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
template <typename NativeType>
Component<NativeType>::Component(Entity entity)
: BaseComponent { entity }
{}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
template <typename NativeType>
typename Component<NativeType>::NativeComponent* Component<NativeType>::GetNativeComponent()
{
return ECS::GetNativeComponent<NativeType>(owner.GetEntity());
}
}

View File

@ -0,0 +1,200 @@
/************************************************************************************//*!
\file Component.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 27, 2021
\brief Contains the definition of the managed Component classes with the
declaration of functions for working with it.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include "ECS_Base/Components/SHComponent.h"
// Project Includes
#include "Engine/Entity.hxx"
#include "Scripts/Script.hxx"
namespace SHADE
{
/// <summary>
/// Class that serves as the base for a wrapper class to Components in native code.
/// </summary>
public ref class BaseComponent : public System::IEquatable<BaseComponent^>
{
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the GameObject that this Component belongs to.
/// </summary>
property GameObject Owner
{
GameObject get() { return owner; }
}
/*-----------------------------------------------------------------------------*/
/* Component Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Component to this GameObject.
/// </summary>
/// <typeparam name="T">Type of the Component to add. </typeparam>
/// <returns>Reference to the Component that was added.</returns>
generic<typename T> where T : BaseComponent
T AddComponent();
/// <summary>
/// Gets a Component from this GameObject.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
/// <returns>
/// Reference to the Component or null if this GameObject does not have the
/// specified Component.
/// </returns>
generic<typename T> where T : BaseComponent
T GetComponent();
/// <summary>
/// Removes a Component from this GameObject. If no Component exists to begin
/// with, nothing happens.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
generic<typename T> where T : BaseComponent
void RemoveComponent();
/*-----------------------------------------------------------------------------*/
/* Script Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Script of the specified type to this GameObject.
/// </summary>
/// <typeparam name="T">Type of Script to add.</typeparam>
/// <returns>Reference to the created Script.</returns>
generic<typename T> where T : ref class, Script
T AddScript();
/// <summary>
/// Retrieves a Script of the specified type from this GameObject.
/// If multiple Scripts of the same specified type are added on the same
/// GameObject, this will retrieve the first one added.
/// </summary>
/// <typeparam name="T">Type of Script to add.</typeparam>
/// <returns>Reference to the Script to retrieve.</returns>
generic<typename T> where T : ref class, Script
T GetScript();
/// <summary>
/// Retrieves a immutable list of Scripts of the specified type from this
/// GameObject.
/// </summary>
/// <typeparam name="T">Type of Scripts to Get.</typeparam>
/// <returns>Immutable list of Scripts of the specified type.</returns>
generic<typename T> where T : ref class, Script
System::Collections::Generic::IEnumerable<T>^ GetScripts();
/// <summary>
/// Removes all Scripts of the specified type from this GameObject.
/// </summary>
/// <typeparam name="T">Type of PLushieScripts to remove.</typeparam>
generic<typename T> where T : ref class, Script
void RemoveScript();
protected:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for BaseComponent to tie it to a specific Entity.
/// Constructors of derived Components should call this Constructor.
/// </summary>
/// <param name="entity">Entity that this Component will be tied to.</param>
BaseComponent(Entity entity);
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Entity that this Component belongs to.
/// </summary>
GameObject owner;
public:
/*-----------------------------------------------------------------------------*/
/* IEquatable */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with an object of the same type.
/// </summary>
/// <param name="other">The object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
virtual bool Equals(BaseComponent^ other);
/*-----------------------------------------------------------------------------*/
/* Object */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with another unboxed object.
/// </summary>
/// <param name="o">The unboxed object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
bool Equals(Object^ o) override;
/// <summary>
/// Gets a unique hash for this object.
/// </summary>
/// <returns>Unique hash for this object.</returns>
int GetHashCode() override;
};
/// <summary>
/// C++ template for the BaseComponent class used to generate common template-able
/// functions and types.
/// </summary>
/// <typeparam name="NativeType">
/// Type of the native component that this Component wraps.
/// </typeparam>
template<typename NativeType>
public ref class Component : public BaseComponent
{
internal:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Type of the native component that this Component wraps.
/// </summary>
using NativeComponent = NativeType;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves a pointer to the native unmanaged component that is tied to the
/// Entity described by the owner value.
/// </summary>
/// <returns>
/// Pointer to the native component. Will be nullptr if it does not exist.
/// </returns>
/// <exception cref="System.InvalidOperationException">
/// Thrown if the internal ID stored by this native component is invalid.
/// </exception>
/// <exception cref="System.NullReferenceException">
/// Thrown if an attempt to retrieve the native component fails.
/// </exception>
NativeComponent* GetNativeComponent();
protected:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for Component to tie it to a specific Entity.
/// Constructors of derived Components should call this Constructor.
/// </summary>
/// <param name="entity">Entity that this Component will be tied to.</param>
Component(Entity entity);
};
}
#include "Component.h++"

View File

@ -0,0 +1,255 @@
/************************************************************************************//*!
\file ECS.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definition of the functions for the ECS managed static
class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "ECS.hxx"
// Standard Library
#include <sstream>
#include <msclr\marshal_cppstd.h>
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
// Project Headers
#include "Utility/Convert.hxx"
#include "Utility/Debug.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Component Manipulation Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T ECS::AddComponent(EntityID entity)
{
System::Type^ componentType = T::typeid;
// Check if entity is correct
if (!SHEntityManager::IsValidEID(entity))
{
std::ostringstream oss;
oss << "[ECS] Attempted to add Component \""
<< msclr::interop::marshal_as<std::string>(componentType->Name)
<< "\" to invalid Entity.";
Debug::LogError(oss.str());
return T();
}
// Add based on the correct component
for each(ComponentSet^ type in componentMap)
{
if (componentType == type->Type)
{
// Attempt to add
type->AddFunction(entity);
// Return the managed component
return createManagedComponent<T>(entity);
}
}
std::ostringstream oss;
oss << "[ECS] Failed to add unsupported Component \""
<< Convert::ToNative(componentType->Name)
<< "\" to Entity #"
<< entity;
Debug::LogError(oss.str());
return T();
}
generic <typename T>
T ECS::GetComponent(EntityID entity)
{
System::Type^ componentType = T::typeid;
// Check if entity is correct
if (!SHEntityManager::IsValidEID(entity))
{
std::ostringstream oss;
oss << "[ECS] Attempted to retrieve Component \""
<< Convert::ToNative(componentType->Name)
<< "\" from invalid Entity.";
Debug::LogError(oss.str());
return T();
}
// Get based on the correct component
for each(ComponentSet^ type in componentMap)
{
if (componentType == type->Type)
{
if (type->HasFunction(entity))
{
return createManagedComponent<T>(entity);
}
else
{
return T();
}
}
}
std::ostringstream oss;
oss << "[ECS] Failed to retrieve unsupported Component \""
<< Convert::ToNative(componentType->Name)
<< "\" to Entity #"
<< entity;
Debug::LogError(oss.str());
return T();
}
generic <typename T>
T ECS::GetComponentInChildren(EntityID entity)
{
System::Type^ componentType = T::typeid;
// Check if entity is correct
if (!SHEntityManager::IsValidEID(entity))
{
std::ostringstream oss;
oss << "[ECS] Attempted to retrieve Component \""
<< Convert::ToNative(componentType->Name)
<< "\" from invalid Entity.";
Debug::LogError(oss.str());
return T();
}
// Get Transform component and get the children list
throw gcnew System::NotImplementedException;
//Pls::Transform* tf = Pls::ECS::GetComponent<Pls::Transform>(entity);
//if (tf == nullptr)
// return T();
//// Search direct children first
//for (const auto& child : tf->GetChildren())
//{
// T component = GetComponent<T>(child);
// if (component != nullptr)
// return component;
//}
//// Search their children
//for (const auto& child : tf->GetChildren())
//{
// T script = GetComponentInChildren<T>(child);
// if (script != nullptr)
// return script;
//}
// None here
return T();
}
generic <typename T>
T ECS::EnsureComponent(EntityID entity)
{
if (HasComponent<T>(entity))
{
AddComponent<T>(entity);
}
return GetComponent<T>(entity);
}
generic <typename T>
bool ECS::HasComponent(EntityID entity)
{
System::Type^ componentType = T::typeid;
// Check if entity is correct
if (!SHEntityManager::IsValidEID(entity))
{
std::ostringstream oss;
oss << "[ECS] Attempted to check existence of Component \""
<< Convert::ToNative(componentType->Name)
<< "\" from invalid Entity.";
Debug::LogError(oss.str());
return false;
}
// Add based on the correct component
for each(ComponentSet^ type in componentMap)
{
if (componentType == type->Type)
{
return type->HasFunction(entity);
}
}
std::ostringstream oss;
oss << "[ECS] Attempted to check existence of unsupported Component \""
<< msclr::interop::marshal_as<std::string>(componentType->Name)
<< "\" from Entity #"
<< entity;
Debug::LogError(oss.str());
return false;
}
generic <typename T>
void ECS::RemoveComponent(EntityID entity)
{
System::Type^ componentType = T::typeid;
// Check if entity is correct
if (!SHEntityManager::IsValidEID(entity))
{
std::ostringstream oss;
oss << "[ECS] Attempted to remove Component \""
<< Convert::ToNative(componentType->Name)
<< "\" from invalid Entity.";
Debug::LogError(oss.str());
}
// Add based on the correct component
for each(ComponentSet^ type in componentMap)
{
if (componentType == type->Type)
{
type->RemoveFunction(entity);
return;
}
}
std::ostringstream oss;
oss << "[ECS] Attempted to remove unsupported Component \""
<< msclr::interop::marshal_as<std::string>(componentType->Name)
<< "\" from Entity #"
<< entity;
Debug::LogError(oss.str());
}
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
static ECS::ECS()
{
// TODO
// componentMap.Add(createComponentSet<Transform, Transform>());
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T ECS::createManagedComponent(EntityID entity)
{
using namespace System::Reflection;
array<System::Object^>^ params = gcnew array<System::Object^>{ static_cast<Entity>(entity) };
return safe_cast<T>(System::Activator::CreateInstance
(
T::typeid,
BindingFlags::Instance | BindingFlags::NonPublic | BindingFlags::CreateInstance,
nullptr, params, nullptr)
);
}
}

View File

@ -0,0 +1,60 @@
/************************************************************************************//*!
\file ECS.h++
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 27, 2021
\brief Contains the definition of templated functions for the managed Component
classes.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Primary Include
#include "ECS.hxx"
// External Dependencies
#include "ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/System/SHEntityManager.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Static Functions */
/*---------------------------------------------------------------------------------*/
template <typename NativeComponent>
NativeComponent* ECS::GetNativeComponent(Entity entity)
{
// Get native Entity
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
// Entity Validity Check
if (nativeEntity == nullptr)
throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity.");
// Null Check
NativeComponent* component = SHComponentManager::GetComponent_s<NativeComponent>(nativeEntity);
if (component == nullptr)
throw gcnew System::NullReferenceException("Attempted to get a native Component that does not exist.");
return component;
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
template<typename NativeType, typename ManagedType>
ECS::ComponentSet ECS::createComponentSet()
{
return ComponentSet
{
ManagedType::typeid,
SHComponentManager::AddComponent<NativeType>,
SHComponentManager::EnsureComponent<NativeType>,
SHComponentManager::HasComponent<NativeType>,
SHComponentManager::RemoveComponent<NativeType>
};
}
}

View File

@ -0,0 +1,174 @@
/************************************************************************************//*!
\file ECS.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definitions of the GameObject managed class which define an
abstraction for working with Entities in managed code.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include "ECS_Base/System/SHComponentManager.h"
// Project Includes
#include "Components/Component.hxx"
namespace SHADE
{
/// <summary>
/// Static class which contains functions that map Pls::ECS's Component manipulation
/// functions to managed generic functions.
/// </summary>
private ref class ECS abstract sealed
{
public:
/*-----------------------------------------------------------------------------*/
/* Component Manipulation Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Component to the specified Entity.
/// </summary>
/// <typeparam name="T">Type of the Component to add.</typeparam>
/// <param name="entity">
/// Entity object that should have the specified Component added to.
/// </param>
/// <returns>Reference to the Component that was added.</returns>
generic<typename T> where T : BaseComponent
static T AddComponent(EntityID entity);
/// <summary>
/// Gets a Component from the specified Entity.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
/// <param name="entity"> Entity object to get the Component from. </param>
/// <returns>
/// Reference to the Component or null if the Entity does not have the
/// specified Component.
/// </returns>
generic<typename T> where T : BaseComponent
static T GetComponent(EntityID entity);
/// <summary>
/// Retrieves the first Component from the specified GameObjectt's children that
/// matches the specified type.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
/// <param name="entity"> Entity object to get the Component from. </param>
/// <returns>
/// Reference to the Component or null if the Entity does not have the
/// specified Component.
/// </returns>
generic<typename T> where T : BaseComponent
static T GetComponentInChildren(EntityID entity);
/// <summary>
/// Ensures a Component on the specified Entity.
/// </summary>
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
/// <param name="entity"> Entity object to ensure the Component on. </param>
/// <returns>Reference to the Component.</returns>
generic<typename T> where T : BaseComponent
static T EnsureComponent(EntityID entity);
/// <summary>
/// Checks if the specified Entity has the specified Component.
/// </summary>
/// <typeparam name="T">Type of the Component to check for.</typeparam>
/// <param name="entity">Entity object to check for the Component.</param>
/// <returns>
/// True if the specified Entity has the specified Component. False otherwise.
/// </returns>
generic<typename T> where T : BaseComponent
static bool HasComponent(EntityID entity);
/// <summary>
/// Removes a Component from the specified Entity.
/// </summary>
/// <typeparam name="T">Type of the Component to remove.</typeparam>
/// <param name="entity">
/// Entity object that should have the specified Component removed from/
/// </param>
generic<typename T> where T : BaseComponent
static void RemoveComponent(EntityID entity);
internal:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Pointer to a function for Component manipulation operations.
/// </summary>
using ComponentFunc = void(*)(const EntityID&);
using ComponentHasFunc = bool(*)(const EntityID&);
/// <summary>
/// Contains a set of Component related data used for resolving operations for
/// each Component.
/// </summary>
value struct ComponentSet
{
public:
System::Type^ Type;
ComponentFunc AddFunction;
ComponentHasFunc HasFunction;
ComponentFunc RemoveFunction;
};
/*-----------------------------------------------------------------------------*/
/* Static Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves a pointer to the native unmanaged component of the specified
/// Entity.
/// </summary>
/// <returns>
/// Pointer to the native component. Will be nullptr if it does not exist.
/// </returns>
/// <exception cref="System.InvalidOperationException">
/// Thrown if the Entity specified is invalid.
/// </exception>
/// <exception cref="System.NullReferenceException">
/// Thrown if an attempt to retrieve the native component fails.
/// </exception>
template<typename NativeComponent>
static NativeComponent* GetNativeComponent(Entity entity);
private:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Static constructor to initialize static data
/// </summary>
static ECS();
/*-----------------------------------------------------------------------------*/
/* Static Data Members */
/*-----------------------------------------------------------------------------*/
static System::Collections::Generic::List<ComponentSet> componentMap;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Creates a ComponentSet for a pair of Native and Managed Components.
/// </summary>
/// <typeparam name="NativeType">Type of the Native Component.</typeparam>
/// <typeparam name="ManagedType">Type of the Managed Component.</typeparam>
/// <returns>ComponentSet for the parameters specified.</returns>
template<typename NativeType, typename ManagedType>
static ComponentSet createComponentSet();
/// <summary>
/// Creates an instance of the Managed representation of a Component with a
/// native Entity.
/// </summary>
/// <typeparam name="T">Type of Component to create.</typeparam>
/// <param name="entity">Native Entity that this Component is tied to.</param>
/// <returns>The created Managed representation of the Component.</returns>
generic<typename T> where T : BaseComponent
static T createManagedComponent(EntityID entity);
};
}
#include "ECS.h++"

View File

@ -0,0 +1,138 @@
/************************************************************************************//*!
\file EngineInterface.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the implementation of the managed EngineInterface static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "EngineInterface.hxx"
// Standard Libraries
#include <sstream>
// Project Headers
#include "Utility/Convert.hxx"
#include "Utility/Debug.hxx"
#include "Scripts/ScriptStore.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Interop Static Functions */
/*---------------------------------------------------------------------------------*/
void EngineInterface::Init()
{
SAFE_NATIVE_CALL_BEGIN
// Set up exception handler
System::AppDomain::CurrentDomain->UnhandledException += exceptionHandler;
LoadScriptAssembly();
Debug::Log("[EngineInterface] Successfully initialized managed runtime.");
SAFE_NATIVE_CALL_END_N("SHADE_Managed.EngineInterface")
}
void EngineInterface::UnloadScriptAssembly()
{
SAFE_NATIVE_CALL_BEGIN
std::ostringstream oss;
oss << "[EngineInterface] Unloading " << Convert::ToNative(ManagedLibraryName) << ".dll";
ScriptStore::Exit();
// Unload the script
scriptContext->Unload();
scriptContext = nullptr;
System::GC::Collect();
System::GC::WaitForPendingFinalizers();
// Unload the assembly File
if (managedLibFile != nullptr)
{
managedLibFile->Close();
managedLibFile = nullptr;
}
oss.str("");
oss << "[EngineInterface] Successfully unloaded " << Convert::ToNative(ManagedLibraryName) << ".dll";
Debug::Log(oss.str());
SAFE_NATIVE_CALL_END_N("SHADE_Managed.EngineInterface")
}
void EngineInterface::LoadScriptAssembly()
{
SAFE_NATIVE_CALL_BEGIN
scriptContext = gcnew DisposableAssemblyLoadContext();
loadManagedLibrary();
ScriptStore::Init();
SAFE_NATIVE_CALL_END_N("SHADE_Managed.EngineInterface")
}
void EngineInterface::ReloadScriptAssembly()
{
SAFE_NATIVE_CALL_BEGIN
// Stop scripts
UnloadScriptAssembly();
// Reload assembly and restart scripts runtime
LoadScriptAssembly();
SAFE_NATIVE_CALL_END_N("SHADE_Managed.EngineInterface")
}
void EngineInterface::Exit()
{
SAFE_NATIVE_CALL_BEGIN
// Clean up ScriptStore
ScriptStore::Exit();
scriptContext->Unload();
// Release exception handler
System::AppDomain::CurrentDomain->UnhandledException -= exceptionHandler;
SAFE_NATIVE_CALL_END_N("SHADE_Managed.EngineInterface")
}
/*---------------------------------------------------------------------------------*/
/* Constructor */
/*---------------------------------------------------------------------------------*/
static EngineInterface::EngineInterface()
{
exceptionHandler = gcnew System::UnhandledExceptionEventHandler(unhandledExceptionHandler);
managedLibPath = System::Reflection::Assembly::GetExecutingAssembly()->Location->Replace("SHADE_Managed.dll", ManagedLibraryName + ".dll");
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
void EngineInterface::loadManagedLibrary()
{
using namespace System::IO;
std::ostringstream oss;
try
{
oss << "[EngineInterface] Loading " << Convert::ToNative(ManagedLibraryName) << ".dll";
managedLibFile = File::Open(managedLibPath, FileMode::Open, FileAccess::Read);
scriptContext->LoadFromStream(managedLibFile);
oss.str("");
oss << "[EngineInterface] Successfully loaded " << Convert::ToNative(ManagedLibraryName) << ".dll";
Debug::Log(oss.str());
}
catch (System::Exception^ e)
{
oss << "[EngineInterface] Unable to load " << Convert::ToNative(ManagedLibraryName) << ".dll!"
<< "(" << Convert::ToNative(e->ToString()) << ")";
Debug::LogError(oss.str());
}
}
/*---------------------------------------------------------------------------------*/
/* Exception Handler Functions */
/*---------------------------------------------------------------------------------*/
void EngineInterface::unhandledExceptionHandler(System::Object^, System::UnhandledExceptionEventArgs^ e)
{
std::ostringstream oss;
oss << "[EngineInterface] Unhandled managed exception: "
<< Convert::ToNative(e->ExceptionObject->GetType()->ToString()) << ": "
<< Convert::ToNative(e->ExceptionObject->ToString());
Debug::LogError(oss.str());
}
}

View File

@ -0,0 +1,90 @@
/************************************************************************************//*!
\file EngineInterface.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definitions of the managed EngineInterface static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Project Includes
#include "Utility/DisposableAssemblyLoadContext.hxx"
namespace SHADE
{
/// <summary>
/// Static class that contains the functions for interfacing with the core
/// PlushieEngine written in C++ for managing the lifecycle of managed code.
/// </summary>
private ref class EngineInterface abstract sealed
{
public:
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Name of the Managed Library that contains the C# scripts written externally.
/// </summary>
literal System::String^ ManagedLibraryName = "SHADE_Scripting";
/*-----------------------------------------------------------------------------*/
/* Interop Static Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Initialises all required components for managed code.
/// </summary>
static void Init();
/// <summary>
/// Unloads the managed script assembly.
/// Take note that this will clear all existing scripts, ensure that the scene
/// is saved before doing so.
/// </summary>
static void UnloadScriptAssembly();
/// <summary>
/// Loads the managed script assembly. Ensure this is only called after
/// UnloadScriptAssembly() has been called.
/// </summary>
static void LoadScriptAssembly();
/// <summary>
/// Reloads the managed script assembly.
/// Take note that this will clear all existing scripts, ensure that the scene
/// is saved before doing so.
/// Equivalent to calling UnloadScriptAssembly() and then LoadScriptAssembly().
/// </summary>
static void ReloadScriptAssembly();
/// <summary>
/// Cleans up all required components for managed code.
/// </summary>
static void Exit();
private:
/*-----------------------------------------------------------------------------*/
/* Constructor */
/*-----------------------------------------------------------------------------*/
static EngineInterface();
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
static DisposableAssemblyLoadContext^ scriptContext;
static System::UnhandledExceptionEventHandler^ exceptionHandler;
static System::String^ managedLibPath;
static System::IO::FileStream^ managedLibFile;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
static void loadManagedLibrary();
/*-----------------------------------------------------------------------------*/
/* Exception Handler Functions */
/*-----------------------------------------------------------------------------*/
static void unhandledExceptionHandler(System::Object^ sender, System::UnhandledExceptionEventArgs^ e);
};
}

View File

@ -0,0 +1,28 @@
/************************************************************************************//*!
\file Entity.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definition of the functions for the EntityUtils managed
static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Entity.hxx"
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
namespace SHADE
{
bool EntityUtils::IsValid(Entity^ entity)
{
return SHEntityManager::IsValidEID(static_cast<EntityID>(entity));
}
}

View File

@ -0,0 +1,41 @@
/************************************************************************************//*!
\file Entity.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definitions of a managed Entity identifier and declarations
of useful utility functions for working with Entity identifiers.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include "ECS_Base/Entity/SHEntity.h"
namespace SHADE
{
/// <summary>
/// Managed representation of a native ECS Entity.
/// </summary>
using Entity = System::UInt32;
/// <summary>
/// Static class that contains useful utility functions for working with Entity.
/// </summary>
private ref class EntityUtils abstract sealed
{
public:
/// <summary>
/// Checks if the specified entity is valid. This is done by checking if it
/// matches Pls::Entity::INVALID.
/// </summary>
/// <param name="entity">The Entity to check.</param>
/// <returns>True if the specified Entity is valid.</returns>
static bool IsValid(Entity^ entity);
};
}

View File

@ -0,0 +1,201 @@
/************************************************************************************//*!
\file GameObject.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definition of the functions for the GameObject managed class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "GameObject.hxx"
// External Dependencies
#include "ECS_Base/System/SHEntityManager.h"
// Project Headers
#include "ECS.hxx"
#include "Scripts/ScriptStore.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Static Functions */
/*---------------------------------------------------------------------------------*/
GameObject GameObject::Create()
{
return GameObject(SHEntityManager::CreateEntity());
}
void GameObject::Destroy(GameObject obj)
{
SHEntityManager::DestroyEntity(static_cast<EntityID>(obj.GetEntity()));
}
System::Nullable<GameObject> GameObject::Find(System::String ^ name)
{
// Search the GameObjectLibrary for an Entity with the specified name
throw gcnew System::NotImplementedException();
}
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
System::String^ GameObject::Name::get()
{
return Convert::ToCLI(GetNativeEntity().name);
}
bool GameObject::IsActiveSelf::get()
{
return GetNativeEntity().isActive;
}
bool GameObject::IsActiveInHierarchy::get()
{
throw gcnew System::NotImplementedException();
}
/*---------------------------------------------------------------------------------*/
/* GameObject Property Functions */
/*---------------------------------------------------------------------------------*/
void GameObject::SetName(System::String^ name)
{
GetNativeEntity().name = Convert::ToNative(name);
}
void GameObject::SetActive(bool active)
{
GetNativeEntity().isActive = active;
}
/*---------------------------------------------------------------------------------*/
/* Component Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T GameObject::AddComponent()
{
return ECS::AddComponent<T>(entity);
}
generic <typename T>
T GameObject::GetComponent()
{
return ECS::GetComponent<T>(entity);
}
generic <typename T>
T GameObject::GetComponentInChildren()
{
return ECS::GetComponentInChildren<T>(entity);
}
generic <typename T>
T GameObject::EnsureComponent()
{
return ECS::EnsureComponent<T>(entity);
}
generic <typename T>
void GameObject::RemoveComponent()
{
ECS::RemoveComponent<T>(entity);
}
/*---------------------------------------------------------------------------------*/
/* Script Access Functions */
/*---------------------------------------------------------------------------------*/
generic <typename T>
T GameObject::AddScript()
{
return ScriptStore::AddScript<T>(entity);
}
generic <typename T>
T GameObject::GetScript()
{
return ScriptStore::GetScript<T>(entity);
}
generic <typename T>
T GameObject::GetScriptInChildren()
{
return ScriptStore::GetScriptInChildren<T>(entity);
}
generic <typename T>
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
{
return ScriptStore::GetScripts<T>(entity);
}
generic <typename T>
void GameObject::RemoveScript()
{
ScriptStore::RemoveScript<T>(entity);
}
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
GameObject::GameObject(const SHEntity& entity)
: entity { entity.GetEID() }
{}
GameObject::GameObject(Entity entity)
: entity { entity }
{}
/*---------------------------------------------------------------------------------*/
/* Getters */
/*---------------------------------------------------------------------------------*/
SHEntity& GameObject::GetNativeEntity()
{
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
if (nativeEntity == nullptr)
throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject.");
return *nativeEntity;
}
/*---------------------------------------------------------------------------------*/
/* IEquatable */
/*---------------------------------------------------------------------------------*/
bool GameObject::Equals(GameObject other)
{
return entity == other.entity;
}
/*---------------------------------------------------------------------------------*/
/* Object */
/*---------------------------------------------------------------------------------*/
bool GameObject::Equals(Object^ o)
{
try
{
GameObject^ cmp = safe_cast<GameObject^>(o);
return Equals(cmp);
}
catch (System::InvalidCastException^)
{
return false;
}
}
int GameObject::GetHashCode()
{
return entity.GetHashCode();
}
bool GameObject::operator==(GameObject lhs, GameObject rhs)
{
return lhs.Equals(rhs);
}
bool GameObject::operator!=(GameObject lhs, GameObject rhs)
{
return !(lhs == rhs);
}
}

View File

@ -0,0 +1,282 @@
/************************************************************************************//*!
\file GameObject.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 28, 2021
\brief Contains the definitions of the GameObject managed class which define an
abstraction for working with Entities in managed code.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Project Includes
#include "Entity.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
ref class Script;
ref class BaseComponent;
/*---------------------------------------------------------------------------------*/
/* Class Definitions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Lightweight object for an PlushieEngine Entity that allows for easy access
/// to Component and Script operations.
/// </summary>
public value class GameObject : public System::IEquatable<GameObject>
{
public:
/*-----------------------------------------------------------------------------*/
/* Static Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Creates a new GameObject in the current Scene. If multiple Scenes are loaded,
/// and you would like to create an object in a specific Scene, call the Scene's
/// CreateGameObject().
/// </summary>
/// <returns>GameObject that represents the newly created GameObject.</returns>
static GameObject Create();
/// <summary>
/// Destroys the specified GameObject. Note that the specified GameObject will no
/// longer be a valid GameObject after this function is called.
/// </summary>
/// <param name="obj">The GameObject to be destroyed.</param>
static void Destroy(GameObject obj);
/// <summary>
/// Retrieves a GameObject with the specified name. If there are multiple
/// GameObjects with the same name, the first found GameObject will be retrieved.
/// There is no guaranteed order of which GameObject is considered "first".
/// </summary>
/// <param name="name">Name of the GameObject to find.</param>
/// <returns>GameObject that has the specified name. Null if not found.</returns>
static System::Nullable<GameObject> Find(System::String^ name);
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Name of the object that this Entity represents.
/// </summary>
property System::String^ Name
{
System::String^ get();
}
/// <summary>
/// Whether or not this Entity alone, is active. This does not mean that this
/// object is active in the scene. For example, if this Entity's parent is not
/// active, then this Entity would also be not active.
/// </summary>
property bool IsActiveSelf
{
bool get();
}
/// <summary>
/// Whether or not this Entity is active in the Scene hierarchy.
/// </summary>
property bool IsActiveInHierarchy
{
bool get();
}
/*-----------------------------------------------------------------------------*/
/* GameObject Property Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Sets the name of this GameObject.
/// </summary>
/// <param name="name">The name to set.</param>
void SetName(System::String^ name);
/// <summary>
/// Sets the active state of this GameObject.
/// <br/>
/// The actual "activeness" of this GameObject is still dependent on the parents'
/// active states.
/// </summary>
/// <param name="active">
/// Whether to activate or deactivate this GameObject.
/// </param>
void SetActive(bool active);
/*-----------------------------------------------------------------------------*/
/* Component Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Component to this GameObject.
/// </summary>
/// <typeparam name="T">Type of the Component to add. </typeparam>
/// <returns>Reference to the Component that was added.</returns>
generic<typename T> where T : BaseComponent
T AddComponent();
/// <summary>
/// Gets a Component from this GameObject.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
/// <returns>
/// Reference to the Component or null if this GameObject does not have the
/// specified Component.
/// </returns>
generic<typename T> where T : BaseComponent
T GetComponent();
/// <summary>
/// Retrieves the first Component from this GameObject's children that matches
/// the specified type.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
/// <returns>
/// Reference to the Component or null if neither of this GameObject's children
/// does not have the specified Component.
/// </returns>
generic<typename T> where T : BaseComponent
T GetComponentInChildren();
/// <summary>
/// Ensures a Component on this GameObject.
/// </summary>
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
/// <returns>
/// Reference to the Component.
/// </returns>
generic<typename T> where T : BaseComponent
T EnsureComponent();
/// <summary>
/// Removes a Component from this GameObject. If no Component exists to begin
/// with, nothing happens.
/// </summary>
/// <typeparam name="T">Type of the Component to get.</typeparam>
generic<typename T> where T : BaseComponent
void RemoveComponent();
/*-----------------------------------------------------------------------------*/
/* Script Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds a Script of the specified type to this GameObject.
/// </summary>
/// <typeparam name="T">Type of Script to add.</typeparam>
/// <returns>Reference to the created Script.</returns>
generic<typename T> where T : ref class, Script
T AddScript();
/// <summary>
/// Retrieves a Script of the specified type from this GameObject.
/// If multiple Scripts of the same specified type are added on the same
/// GameObject, this will retrieve the first one added.
/// </summary>
/// <typeparam name="T">Type of Script to retrieve.</typeparam>
/// <returns>Reference to the Script to retrieve.</returns>
generic<typename T> where T : ref class, Script
T GetScript();
/// <summary>
/// Retrieves a Script of the specified type from child GameObjects.
/// If multiple Scripts of the same specified type are added on the same
/// child GameObject, this will retrieve the first one added.
/// </summary>
/// <typeparam name="T">Type of Script to retrieve.</typeparam>
/// <returns>Reference to the Script to retrieve.</returns>
generic<typename T> where T : ref class, Script
T GetScriptInChildren();
/// <summary>
/// Retrieves a immutable list of Scripts of the specified type from this
/// GameObject.
/// </summary>
/// <typeparam name="T">Type of Scripts to retrieve.</typeparam>
/// <returns>Immutable list of Scripts of the specified type.</returns>
generic<typename T> where T : ref class, Script
System::Collections::Generic::IEnumerable<T>^ GetScripts();
/// <summary>
/// Removes all Scripts of the specified type from this GameObject.
/// </summary>
/// <typeparam name="T">Type of PLushieScripts to remove.</typeparam>
generic<typename T> where T : ref class, Script
void RemoveScript();
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for the GameObject.
/// </summary>
/// <param name="entity">
/// The ECS Entity that this GameObject should represent.
/// </param>
GameObject(const SHEntity& entity);
/// <summary>
/// Constructor for the GameObject.
/// </summary>
/// <param name="entity">
/// Managed numerical representation of the ECS Entity that this GameObject
/// should represent.
/// </param>
GameObject(Entity entity);
/*-----------------------------------------------------------------------------*/
/* Getters */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the CLR Entity object that this GameObject represents.
/// </summary>
/// <returns>Entity object that this GameObject represents.</returns>
inline Entity GetEntity() { return entity; }
/// <summary>
/// Retrieves the native Entity object that this GameObject represents.
/// </summary>
/// <returns>Native Entity object that this GameObject represents.</returns>
SHEntity& GetNativeEntity();
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Entity entity;
public:
/*-----------------------------------------------------------------------------*/
/* IEquatable */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with an object of the same type.
/// </summary>
/// <param name="other">The object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
virtual bool Equals(GameObject other);
/*-----------------------------------------------------------------------------*/
/* Object */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with another unboxed object.
/// </summary>
/// <param name="o">The unboxed object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
bool Equals(Object^ o) override;
/// <summary>
/// Gets a unique hash for this object.
/// </summary>
/// <returns>Unique hash for this object.</returns>
int GetHashCode() override;
/// <summary>
/// Checks if two GameObject references are the same.
/// </summary>
/// <param name="lhs">GameObject to check.</param>
/// <param name="rhs">Another GameObject to check with.</param>
/// <returns>True if both Components are the same.</returns>
static bool operator==(GameObject lhs, GameObject rhs);
/// <summary>
/// Checks if two GameObject references are different.
/// </summary>
/// <param name="lhs">GameObject to check.</param>
/// <param name="rhs">Another GameObject to check with.</param>
/// <returns>True if both Components are different.</returns>
static bool operator!=(GameObject lhs, GameObject rhs);
};
}

View File

@ -0,0 +1,57 @@
/************************************************************************************//*!
\file Math.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 11, 2021
\brief Contains the implementation of the functions of the managed Math struct.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Math/Math.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Utility Functions */
/*---------------------------------------------------------------------------------*/
double Math::Wrap(double value, double min, double max)
{
while (value < min)
{
value = max - (min - value);
}
while (value > max)
{
value = min + (value - max);
}
return value;
}
double Math::DegreesToRadians(double degrees)
{
return degrees * Deg2Rad;
}
double Math::RadiansToDegrees(double radians)
{
return radians * Rad2Deg;
}
double Math::Lerp(double a, double b, double t)
{
return LerpUnclamped(a, b, System::Math::Clamp(t, 0.0, 1.0));
}
double Math::LerpUnclamped(double a, double b, double t)
{
return a + t * (b - a);
}
double Math::InverseLerp(double a, double b, double value)
{
return (value - a) / (b - a);
}
}

View File

@ -0,0 +1,92 @@
/************************************************************************************//*!
\file Math.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 11, 2021
\brief Contains the definition of the managed Math static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
namespace SHADE
{
/// <summary>
/// Contains utility Math functions.
/// </summary>
public ref class Math abstract sealed
{
public:
/*-----------------------------------------------------------------------------*/
/* Static Constants */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Degrees-to-radians conversion constant
/// </summary>
static constexpr double Deg2Rad = System::Math::PI / 180.0;
/// <summary>
/// Radians-to-degrees conversion constant
/// </summary>
static constexpr double Rad2Deg = 180.0 / System::Math::PI;
/// <summary>
/// Small value used for single precision floating point comparisons.
/// </summary>
static constexpr float Epsilon = 0.001f;
/*-----------------------------------------------------------------------------*/
/* Utility Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Wraps a value if they get to low or too high.
/// </summary>
/// <param name="value">Value to wrap.</param>
/// <param name="min">Minimum value to wrap at.</param>
/// <param name="max">Maximum value to wrap at.</param>
/// <returns>Wrapped value.</returns>
static double Wrap(double value, double min, double max);
/// <summary>
/// Converts an angle from degree representation to radian representation.
/// </summary>
/// <param name="degrees">Degree-based angle to convert.</param>
/// <returns>The specified angle in radians.</returns>
static double DegreesToRadians(double degrees);
/// <summary>
/// Converts an angle from radian representation to degree representation.
/// </summary>
/// <param name="radians">Radian-based angle to convert.</param>
/// <returns>The specified angle in degrees.</returns>
static double RadiansToDegrees(double radians);
/// <summary>
/// Linearly interpolates between a and b by t.
/// The parameter t is clamped to the range [0, 1].
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation value between the two double.</param>
/// <returns>The interpolated double result between the two double values.</returns>
static double Lerp(double a, double b, double t);
/// <summary>
/// Linearly interpolates between a and b by t.
/// The parameter t is not clamped and a value based on a and b is supported.
/// If t is less than zero, or greater than one, then LerpUnclamped will result
/// in a return value outside the range a to b.
/// </summary>
/// <param name="a">The start value.</param>
/// <param name="b">The end value.</param>
/// <param name="t">The interpolation value between the two double.</param>
/// <returns>The interpolated double result between the two double values.</returns>
static double LerpUnclamped(double a, double b, double t);
/// <summary>
/// Calculates the linear parameter t that produces the interpolant value within the range [a, b].
/// </summary>
/// <param name="a">Start value.</param>
/// <param name="b">End value.</param>
/// <param name="value">Value between start and end.</param>
/// <returns>Percentage of value between start and end.</returns>
static double InverseLerp(double a, double b, double value);
};
}

View File

@ -0,0 +1,263 @@
/************************************************************************************//*!
\file Vector2.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 2, 2021
\brief Contains the definitions of functions of the Vector2 struct.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Math/Vector2.hxx"
// Standard Libraries
#include <cmath>
#include <algorithm>
// Project Headers
#include "Math.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
Vector2::Vector2(double _x)
: Vector2 { _x, 0.0 }
{}
Vector2::Vector2(double _x, double _y)
: x { _x }
, y { _y }
{}
/*---------------------------------------------------------------------------------*/
/* Usage Functions */
/*---------------------------------------------------------------------------------*/
void Vector2::Normalise()
{
*this = GetNormalised();
}
Vector2 Vector2::GetNormalised()
{
return *this / GetMagnitude();
}
double Vector2::GetMagnitude()
{
return sqrt(x * x + y * y);
}
double Vector2::GetSqrMagnitude()
{
return x * x + y * y;
}
double Vector2::AngleFromRightRadians()
{
return atan2(y, x);
}
double Vector2::AngleFromRightDegrees()
{
return Math::RadiansToDegrees(AngleFromRightRadians());
}
bool Vector2::IsNearPoint(Vector2 point)
{
return IsNearPoint(point, Math::Epsilon);
}
bool Vector2::IsNearPoint(Vector2 point, double tolerance)
{
return (*this - point).GetSqrMagnitude() < (tolerance * tolerance);
}
/*---------------------------------------------------------------------------------*/
/* IEquatable */
/*---------------------------------------------------------------------------------*/
bool Vector2::Equals(Object^ o)
{
try
{
Vector2 vec = safe_cast<Vector2>(o);
return Equals(vec);
}
catch (System::InvalidCastException^)
{
return false;
}
}
/*---------------------------------------------------------------------------------*/
/* Object Overrides */
/*---------------------------------------------------------------------------------*/
bool Vector2::Equals(Vector2 other)
{
return IsNear(*this, other);
}
int Vector2::GetHashCode()
{
const int HASH = 19;
return x.GetHashCode() * HASH + y.GetHashCode();
}
/*---------------------------------------------------------------------------------*/
/* Static Functions */
/*---------------------------------------------------------------------------------*/
bool Vector2::IsNear(Vector2 lhs, Vector2 rhs)
{
return IsNear(lhs, rhs, Math::Epsilon);
}
bool Vector2::IsNear(Vector2 lhs, Vector2 rhs, double tolerance)
{
return (std::abs(lhs.x) - std::abs(rhs.x)) < tolerance
&&
(std::abs(lhs.y) - std::abs(rhs.y)) < tolerance;
}
double Vector2::Dot(Vector2 lhs, Vector2 rhs)
{
return lhs.x * rhs.x + lhs.y * rhs.y;
}
Vector2 Vector2::Perpendicular(Vector2 lhs)
{
return Perpendicular(lhs, true);
}
Vector2 Vector2::Perpendicular(Vector2 lhs, bool inward)
{
if (inward)
{
return Vector2
(
-lhs.y, lhs.x
);
}
else
{
return Vector2
(
lhs.y, -lhs.x
);
}
}
Vector2 Vector2::Project(Vector2 vec, Vector2 direction)
{
return direction.GetNormalised() * vec.GetMagnitude();
}
Vector2 Vector2::Reflect(Vector2 vec, Vector2 normal)
{
return vec - (Project(vec, normal.GetNormalised()) * 2.0);
}
Vector2 Vector2::RotateRadians(Vector2 vec, double radians)
{
const double SINE = sin(radians);
const double COSINE = cos(radians);
return Vector2
(
vec.x * COSINE - vec.y * SINE,
vec.x * SINE + vec.y * COSINE
);
}
Vector2 Vector2::RotateDegrees(Vector2 vec, double degrees)
{
return RotateRadians(vec, Math::DegreesToRadians(degrees));
}
Vector2 Vector2::Min(Vector2 lhs, Vector2 rhs)
{
double lx = lhs.x, rx = rhs.x;
double ly = lhs.y, ry = rhs.y;
return Vector2(std::min(lx, rx),
std::min(ly, ry));
}
Vector2 Vector2::Max(Vector2 lhs, Vector2 rhs)
{
double lx = lhs.x, rx = rhs.x;
double ly = lhs.y, ry = rhs.y;
return Vector2(std::max(lx, rx),
std::max(ly, ry));
}
Vector2 Vector2::Lerp(Vector2 a, Vector2 b, double t)
{
return LerpUnclamped(a, b, std::clamp(t, 0.0, 1.0));
}
Vector2 Vector2::LerpUnclamped(Vector2 a, Vector2 b, double t)
{
return a + ((b - a) * t);
}
Vector2 Vector2::MoveTowards(Vector2 current, Vector2 target, double maxDistanceDelta)
{
// Ignore if it is exactly on the same point
if (current == target)
return target;
// Calculate new position
Vector2 DELTA = (target - current).GetNormalised() * maxDistanceDelta;
Vector2 newPos = current + DELTA;
// Check if check if is behind or ahead of target
Vector2 DIFF = target - newPos;
if (Dot(DELTA, DIFF) < 0.0)
{
newPos = target;
}
return newPos;
}
Vector2 Vector2::operator+(Vector2 lhs, Vector2 rhs)
{
return Vector2
(
lhs.x + rhs.x,
lhs.y + rhs.y
);
}
Vector2 Vector2::operator-(Vector2 lhs, Vector2 rhs)
{
return Vector2
(
lhs.x - rhs.x,
lhs.y - rhs.y
);
}
Vector2 Vector2::operator*(Vector2 lhs, Vector2 rhs)
{
return Vector2
(
lhs.x * rhs.x,
lhs.y * rhs.y
);
}
Vector2 Vector2::operator*(Vector2 lhs, double rhs)
{
return Vector2
(
lhs.x * rhs,
lhs.y * rhs
);
}
Vector2 Vector2::operator/(Vector2 lhs, double rhs)
{
return Vector2
(
lhs.x / rhs,
lhs.y / rhs
);
}
bool Vector2::operator==(Vector2 lhs, Vector2 rhs)
{
return lhs.Equals(rhs);
}
bool Vector2::operator!=(Vector2 lhs, Vector2 rhs)
{
return !(lhs == rhs);
}
} // namespace PlushieAPI::Mathematics

View File

@ -0,0 +1,396 @@
/************************************************************************************//*!
\file Vector2.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 2, 2021
\brief Contains the definitions of Vector2 struct.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Standard Libraries
#include <limits>
namespace SHADE
{
///<summary>
/// CLR version of the the PlushieEngine's Vector2 class that represents a
/// 2-Dimensional Vector. Designed to closely match Unity's Vector2 struct.
/// </summary>
[System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)]
public value struct Vector2 : public System::IEquatable<Vector2>
{
public:
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
#pragma region Constants
///<summary>
/// Shorthand for writing Vector2(0, -1).
///</summary>
static initonly Vector2 Down = Vector2(0.0, -1.0);
///<summary>
/// Shorthand for writing Vector2(-1, 0).
///</summary>
static initonly Vector2 Left = Vector2(-1.0, 0.0);
///<summary>
/// Shorthand for writing Vector2(double.NegativeInfinity,
/// double.NegativeInfinity).
///</summary>
static initonly Vector2 NegativeInfinity = Vector2(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
///<summary>
/// Shorthand for writing Vector2(1, 1).
///</summary>
static initonly Vector2 One = Vector2(1.0, 1.0);
///<summary>
/// Shorthand for writing Vector2(double.PositiveInfinity,
/// double.PositiveInfinity).
///</summary>
static initonly Vector2 PositiveInfinity = Vector2(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
///<summary>
/// Shorthand for writing Vector2(1, 0).
///</summary>
static initonly Vector2 Right = Vector2(1.0, 0.0);
///<summary>
/// Shorthand for writing Vector2(0, 1).
///</summary>
static initonly Vector2 Up = Vector2(0.0, 1.0);
///<summary>
/// Shorthand for writing Vector2(0, 0).
///</summary>
static initonly Vector2 Zero = Vector2(0.0, 0.0);
#pragma endregion
/*-----------------------------------------------------------------------------*/
/* Public Members */
/*-----------------------------------------------------------------------------*/
///<summary>
/// X-component of the Vector2.
///</summary>
double x;
///<summary>
/// Y-component of the Vector2.
///</summary>
double y;
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor to construct a Vector2 with the specified components with the
/// Y-component set to 0.0.
/// </summary>
/// <param name="_x">X-coordinate to set.</param>
Vector2(double _x);
/// <summary>
/// Constructor to construct a Vector2 with the specified components..
/// </summary>
/// <param name="_x">X-coordinate to set.</param>
/// <param name="_y">Y-coordinate to set.</param>
Vector2(double _x, double _y);
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Normalises this current Vector2. This changes the data of this Vector2.
/// If you would like to get a copy, use GetNormalised() instead.
/// This function does nothing to a zero vector.
/// </summary>
void Normalise();
/// <summary>
/// Creates a copy of this Vector2 and returns a normalized version.
/// </summary>
/// <returns>
/// Returns a normalised copy of this Vector2.
/// If this Vector2 is a zero vector, a zero vector will be returned.
/// </returns>
Vector2 GetNormalised();
/// <summary>
/// Calculates and returns the magnitude of this Vector2. Note that this function
/// incurs a performance cost from the square root calculation. If you do not
/// need the precise magnitude, consider using GetSqrMagnitude() instead.
/// </summary>
/// <returns>Returns the length of this Vector2.</returns>
double GetMagnitude();
/// <summary>
/// Calculates and returns the squared magnitude of this Vector2.
/// </summary>
/// <returns>Returns the squared length of this Vector2.</returns>
double GetSqrMagnitude();
/// <summary>
/// Calculates and returns the angle of this vector from the right vector. This
/// function returns values between -Math.PI and Math.PI.
/// </summary>
/// <returns>Returns the angle of this vector from the right vector in radians.</returns>
double AngleFromRightRadians();
/// <summary>
/// Calculates and returns the angle of this vector from the right vector. This
/// function returns values between -180.0 and 180.0.
/// </summary>
/// <returns>Returns the angle of this vector from the right vector in degrees.</returns>
double AngleFromRightDegrees();
/// <summary>
/// Checks if a specified point is near this Vector2 that represents a point with
/// a tolerance value of PLS_EPSILON.
/// </summary>
/// <param name="point">The other point to check if we are near.</param>
/// <returns>
/// True if this Vector2 representing a point and the specified point are within
/// the range of the specified tolerance. False otherwise.
/// </returns>
bool IsNearPoint(Vector2 point);
/// <summary>
/// Checks if a specified point is near this Vector2 that represents a point.
/// </summary>
/// <param name="point">The other point to check if we are near.</param>
/// <param name="tolerance">
/// The amount of tolerance before we consider these points as "near".
/// </param>
/// <returns>
/// True if this Vector2 representing a point and the specified point are within
/// the range of the specified tolerance. False otherwise.
/// </returns>
bool IsNearPoint(Vector2 point, double tolerance);
/*-----------------------------------------------------------------------------*/
/* IEquatable */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with an object of the same type.
/// </summary>
/// <param name="other">The object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
virtual bool Equals(Vector2 other);
/*-----------------------------------------------------------------------------*/
/* Object */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Compares equality with another unboxed object.
/// </summary>
/// <param name="o">The unboxed object to compare with.</param>
/// <returns>True if both objects are the same.</returns>
bool Equals(Object^ o) override;
/// <summary>
/// Gets a unique hash for this object.
/// </summary>
/// <returns>Unique hash for this object.</returns>
int GetHashCode() override;
/*-----------------------------------------------------------------------------*/
/* Static Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Checks if two specified Vector2s are near in value.
/// </summary>
/// <param name="lhs">Vector2 to check if is near in value.</param>
/// <param name="rhs">Another Vector2 to check if is near in value.</param>
/// <returns>
/// True if the two Vector2s are within the tolerance value specified
/// </returns>
static bool IsNear(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Checks if two specified Vector2s are near in value.
/// </summary>
/// <param name="lhs">Vector2 to check if is near in value.</param>
/// <param name="rhs">Another Vector2 to check if is near in value.</param>
/// <param name="tolerance">
/// Amount of tolerance to do the comparison with.
/// </param>
/// <returns>
/// True if the two Vector2s are within the tolerance value specified
/// </returns>
static bool IsNear(Vector2 lhs, Vector2 rhs, double tolerance);
/// <summary>
/// Computes and returns the dot product of 2 specified Vector2s.
/// </summary>
/// <param name="lhs">Vector2 to calculate dot product with.</param>
/// <param name="rhs">Another Vector2 to calculate dot product with.</param>
/// <returns>
/// Scalar value representing the dot product of the two Vector2s.
/// </returns>
static double Dot(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Computes the inward perpendicular Vector2 to the specified Vector2.
/// Equivalent to calling Perpendicular(lhs, true). This means, the
/// resultant Vector2 is rotated 90-degrees in a counter-clockwise.
/// </summary>
/// <param name="lhs">Vector2 to find a perpendicular of.</param>
/// <returns>
/// The perpendicular Vector2 relative to the specified Vector2.
/// </returns>
static Vector2 Perpendicular(Vector2 lhs);
/// <summary>
/// Computes a perpendicular Vector2 to the specified Vector2.
/// </summary>
/// <param name="lhs">Vector2 to find a perpendicular of.</param>
/// <param name="inward">
/// Whether the inward perpendicular Vector is retrieved. If true, the
/// resultant vector is rotated 90-degrees in a counter-clockwise.
/// </param>
/// <returns>The perpendicular Vector2 relative to the specified Vector2.
/// </returns>
static Vector2 Perpendicular(Vector2 lhs, bool inward);
/// <summary>
/// Computes and returns a Vector2 projection.
/// </summary>
/// <param name="vec">Vector2 to project.</param>
/// <param name="direction">Vector2 to project onto.</param>
/// <returns>The Vector2 that represents the projected vec onto direction.</returns>
static Vector2 Project(Vector2 vec, Vector2 direction);
/// <summary>
/// Reflects a Vector2 across another Vector2.
/// </summary>
/// <param name="vec">A Vector2 to reflect.</param>
/// <param name="normal">A normal to reflect the Vector2 across.</param>
/// <returns>The Vector2 that represents vec reflected across normal.</returns>
static Vector2 Reflect(Vector2 vec, Vector2 normal);
/// <summary>
/// Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise
/// direction.
/// </summary>
/// <param name="vec">A Vector2 to rotate.</param>
/// <param name="radians">
/// Angle to rotate the vector by in an anti-clockwise direction in radians.
/// </param>
/// <returns>The Vector2 that represents the rotated vector.</returns>
static Vector2 RotateRadians(Vector2 vec, double radians);
/// <summary>
/// Rotates a Vector2 on the Z-axis by a specified angle in an anti-clockwise
/// direction.
/// </summary>
/// <param name="vec">A Vector2 to rotate.</param>
/// <param name="degrees">
/// Angle to rotate the vector by in an anti-clockwise direction in degrees.
/// </param>
/// <returns>The Vector2 that represents the rotated vector.</returns>
static Vector2 RotateDegrees(Vector2 vec, double degrees);
/// <summary>
/// Computes and returns a Vector2 that is made from the smallest components of
/// the two specified Vector2s.
/// </summary>
/// <param name="lhs">Vector2 to calculate minimum Vector2 with.</param>
/// <param name="rhs">Another Vector2 to calculate minimum Vector2 with.</param>
/// <returns>
/// The Vector2 that contains the smallest components of the two specified
/// Vector2s.
/// </returns>
static Vector2 Min(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Computes and returns a Vector2 that is made from the largest components of
/// the two specified Vector2s.
/// </summary>
/// <param name="lhs">Vector2 to calculate maximum Vector2 with.</param>
/// <param name="rhs">Another Vector2 to calculate maximum Vector2 with.</param>
/// <returns>
/// The Vector2 that contains the largest components of the two specified
/// Vector2s.
/// </returns>
static Vector2 Max(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Linearly interpolates between two specified points.
/// This is most commonly used to find a point some fraction of the way along a
/// line between two endpoints.
/// </summary>
/// <param name="a">The start Vector2, returned when t = 0.0.</param>
/// <param name="b">The end Vector2, returned when t = 1.0.</param>
/// <param name="t">
/// Value used to interpolate between a and b which is clamped to
/// the range[0, 1].
/// </param>
/// <returns>The interpolated Vector2.</returns>
static Vector2 Lerp(Vector2 a, Vector2 b, double t);
/// <summary>
/// Linearly interpolates between two specified points.
/// This is most commonly used to find a point some fraction of the way along a
/// line between two endpoints.
/// Unlike Lerp(), t is not clamped to a range at all.
/// </summary>
/// <param name="a">The start Vector2, returned when t = 0.0.</param>
/// <param name="b">The end Vector2, returned when t = 1.0.</param>
/// <param name="t">Value used to interpolate between a and b.</param>
/// <returns>The interpolated Vector2.</returns>
static Vector2 LerpUnclamped(Vector2 a, Vector2 b, double t);
/// <summary>
/// Moves a point current towards target.
/// Similar to Lerp(), however, the function will ensure that the distance never
/// exceeds maxDistanceDelta. Negative values of maxDistanceDelta pushes the
/// vector away from target
/// </summary>
/// <param name="current">The current position of the point.</param>
/// <param name="target">The target position to move to.</param>
/// <param name="maxDistanceDelta">Maximum distance moved per call.</param>
/// <returns>Vector representing the moved point.</returns>
static Vector2 MoveTowards(Vector2 current, Vector2 target, double maxDistanceDelta);
/*-----------------------------------------------------------------------------*/
/* Overloaded Operators */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Adds two Vector2s together and returns the result.
/// </summary>
/// <param name="lhs">Vector2 to add.</param>
/// <param name="rhs">Another Vector2 to add.</param>
/// <returns>The result of lhs added to rhs</returns>
static Vector2 operator+(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Subtracts a Vector2 from another Vector2 and returns the result.
/// </summary>
/// <param name="lhs">Vector2 to subtract from.</param>
/// <param name="rhs">Another Vector2 to subtract.</param>
/// <returns>The result of rhs subtracted from lhs.</returns>
static Vector2 operator-(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Calculates the component-wise multiplication of two Vector2s and returns the
/// result.
/// </summary>
/// <param name="lhs">Vector2 to multiply with.</param>
/// <param name="rhs">Another Vector2 to multiply with.</param>
/// <returns>The result of rhs subtracted from lhs.</returns>
static Vector2 operator*(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Calculates the multiplication of a Vector2 with a scalar value and returns
/// the result.
/// </summary>
/// <param name="lhs">Vector2 to multiply with.</param>
/// <param name="rhs">Scalar to multiply with.</param>
/// <returns>The result of the scalar multiplication.</returns>
static Vector2 operator*(Vector2 lhs, double rhs);
/// <summary>
/// Calculates the division of a Vector2 with a scalar value and returns
/// the result.
/// </summary>
/// <param name="lhs">Scalar to divide with.</param>
/// <param name="rhs">Vector2 to divide with.</param>
/// <returns>The result of the scalar division.</returns>
static Vector2 operator/(Vector2 lhs, double rhs);
/// <summary>
/// Checks if two Vector2s are approximately equal. This is equivalent to
/// calling Vector2.IsNear() with default tolerance values.
/// </summary>
/// <param name="lhs">Vector2 to compare.</param>
/// <param name="rhs">Another Vector2 to compare.</param>
/// <returns>
/// True if all components are approximately equal within the default
/// tolerance value.
/// </returns>
static bool operator==(Vector2 lhs, Vector2 rhs);
/// <summary>
/// Checks if two Vector2s are not approximately equal. This is equivalent to
/// calling !Vector2.IsNear() with default tolerance values.
/// </summary>
/// <param name="lhs">Vector2 to compare.</param>
/// <param name="rhs">Another Vector2 to compare.</param>
/// <returns>
/// True if all components are not approximately equal within the default
/// tolerance value.
/// </returns>
static bool operator!=(Vector2 lhs, Vector2 rhs);
};
}

View File

@ -0,0 +1,278 @@
/************************************************************************************//*!
\file Vector3.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 24, 2021
\brief Contains the definitions of functions of the Vector3 struct.
Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "Vector3.hxx"
// Standard Libraries
#include <cmath>
#include <algorithm>
// Project Headers
#include "Math.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
Vector3::Vector3(double _x)
: Vector3 {_x, 0.0, 0.0}
{}
Vector3::Vector3(double _x, double _y)
: Vector3 {_x, _y, 0.0}
{}
Vector3::Vector3(double _x, double _y, double _z)
: x { _x }
, y { _y }
, z { _z }
{}
Vector3::Vector3(Vector2 vec)
: Vector3(vec.x, vec.y)
{}
/*---------------------------------------------------------------------------------*/
/* Usage Functions */
/*---------------------------------------------------------------------------------*/
void Vector3::Normalise()
{
*this = GetNormalised();
}
Vector3 Vector3::GetNormalised()
{
return *this / GetSqrMagnitude();
}
double Vector3::GetMagnitude()
{
return sqrt(x * x + y * y + z * z);
}
double Vector3::GetSqrMagnitude()
{
return x * x + y * y + z * z;
}
double Vector3::Angle2DFromRightRadians()
{
return atan2(y, x);
}
double Vector3::Angle2DFromRightDegrees()
{
return Math::RadiansToDegrees(Angle2DFromRightRadians());
}
bool Vector3::IsNearPoint(Vector3 point)
{
return IsNearPoint(point, Math::Epsilon);
}
bool Vector3::IsNearPoint(Vector3 point, double tolerance)
{
return (*this - point).GetSqrMagnitude() < (tolerance * tolerance);
}
/*---------------------------------------------------------------------------------*/
/* IEquatable */
/*---------------------------------------------------------------------------------*/
bool Vector3::Equals(Object^ o)
{
try
{
Vector3 vec = safe_cast<Vector3>(o);
return Equals(vec);
}
catch (System::InvalidCastException^)
{
return false;
}
}
/*---------------------------------------------------------------------------------*/
/* Object Overrides */
/*---------------------------------------------------------------------------------*/
bool Vector3::Equals(Vector3 other)
{
return IsNear(*this, other);
}
int Vector3::GetHashCode()
{
const int HASH = 19;
const int HASH2 = 23;
return x.GetHashCode() * HASH + y.GetHashCode() * HASH2 + z.GetHashCode();
}
/*---------------------------------------------------------------------------------*/
/* Static Functions */
/*---------------------------------------------------------------------------------*/
bool Vector3::IsNear(Vector3 lhs, Vector3 rhs)
{
return IsNear(lhs, rhs, Math::Epsilon);
}
bool Vector3::IsNear(Vector3 lhs, Vector3 rhs, double tolerance)
{
return (std::abs(lhs.x) - std::abs(rhs.x)) < tolerance
&&
(std::abs(lhs.y) - std::abs(rhs.y)) < tolerance
&&
(std::abs(lhs.z) - std::abs(rhs.z)) < tolerance;
}
double Vector3::Dot(Vector3 lhs, Vector3 rhs)
{
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
}
Vector3 Vector3::Cross(Vector3 lhs, Vector3 rhs)
{
return Vector3(lhs.y * rhs.z - lhs.z * rhs.y,
lhs.z * rhs.x - lhs.x * rhs.z,
lhs.x * rhs.y - lhs.y * rhs.x);
}
Vector3 Vector3::Project(Vector3 vec, Vector3 direction)
{
return direction.GetNormalised() * vec.GetMagnitude();
}
Vector3 Vector3::Reflect(Vector3 vec, Vector3 normal)
{
return vec - (Project(vec, normal.GetNormalised()) * 2.0);
}
Vector3 Vector3::RotateRadians(Vector3 vec, double radians)
{
const double SINE = sin(radians);
const double COSINE = cos(radians);
return Vector3
(
vec.x * COSINE - vec.y * SINE,
vec.x * SINE + vec.y * COSINE,
vec.z
);
}
Vector3 Vector3::RotateDegrees(Vector3 vec, double degrees)
{
return RotateRadians(vec, Math::DegreesToRadians(degrees));
}
Vector3 Vector3::Min(Vector3 lhs, Vector3 rhs)
{
double lx = lhs.x, rx = rhs.x;
double ly = lhs.y, ry = rhs.y;
double lz = lhs.z, rz = rhs.z;
return Vector3(std::min(lx, rx),
std::min(ly, ry),
std::min(lz, rz));
}
Vector3 Vector3::Max(Vector3 lhs, Vector3 rhs)
{
double lx = lhs.x, rx = rhs.x;
double ly = lhs.y, ry = rhs.y;
double lz = lhs.z, rz = rhs.z;
return Vector3(std::max(lx, rx),
std::max(ly, ry),
std::max(lz, rz));
}
Vector3 Vector3::Lerp(Vector3 a, Vector3 b, double t)
{
return LerpUnclamped(a, b, std::clamp(t, 0.0, 1.0));
}
Vector3 Vector3::LerpUnclamped(Vector3 a, Vector3 b, double t)
{
return a + ((b - a) * t);
}
Vector3 Vector3::MoveTowards(Vector3 current, Vector3 target, double maxDistanceDelta)
{
// Ignore if it is exactly on the same point
if (current == target)
return target;
// Calculate new position
Vector3 DELTA = (target - current).GetNormalised() * maxDistanceDelta;
Vector3 newPos = current + DELTA;
// Check if check if is behind or ahead of target
Vector3 DIFF = target - newPos;
if (Dot(DELTA, DIFF) < 0.0)
{
newPos = target;
}
return newPos;
}
Vector3 Vector3::operator+(Vector3 lhs, Vector3 rhs)
{
return Vector3
(
lhs.x + rhs.x,
lhs.y + rhs.y,
lhs.z + rhs.z
);
}
Vector3 Vector3::operator-(Vector3 lhs, Vector3 rhs)
{
return Vector3
(
lhs.x - rhs.x,
lhs.y - rhs.y,
lhs.z - rhs.z
);
}
Vector3 Vector3::operator*(Vector3 lhs, Vector3 rhs)
{
return Vector3
(
lhs.x * rhs.x,
lhs.y * rhs.y,
lhs.z * rhs.z
);
}
Vector3 Vector3::operator*(Vector3 lhs, double rhs)
{
return Vector3
(
lhs.x * rhs,
lhs.y * rhs,
lhs.z * rhs
);
}
Vector3 Vector3::operator/(Vector3 lhs, double rhs)
{
return Vector3
(
lhs.x / rhs,
lhs.y / rhs,
lhs.z / rhs
);
}
bool Vector3::operator==(Vector3 lhs, Vector3 rhs)
{
return lhs.Equals(rhs);
}
bool Vector3::operator!=(Vector3 lhs, Vector3 rhs)
{
return !(lhs == rhs);
}
/*---------------------------------------------------------------------------------*/
/* Conversion Operators */
/*---------------------------------------------------------------------------------*/
Vector3::operator Vector2(Vector3 vec)
{
return Vector2(vec.x, vec.y);
}
Vector3::operator Vector3(Vector2 vec)
{
return Vector3(vec);
}
} // namespace PlushieAPI::Mathematics

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