SP3-2 Integrated Physics with a test scene #78

Merged
direnbharwani merged 16 commits from SP3-2-Physics into main 2022-10-01 22:17:23 +08:00
33 changed files with 904 additions and 226 deletions
Showing only changes of commit e4a6877ed3 - Show all commits

BIN
Assets/Cube.003.shmesh Normal file

Binary file not shown.

BIN
Assets/Cube.012.shmesh Normal file

Binary file not shown.

Binary file not shown.

View File

@ -31,7 +31,7 @@
#include "Math/Transform/SHTransformSystem.h" #include "Math/Transform/SHTransformSystem.h"
#include "Input/SHInputManagerSystem.h" #include "Input/SHInputManagerSystem.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
//#include "AudioSystem/SHAudioSystem.h" #include "AudioSystem/SHAudioSystem.h"
// Components // Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -69,7 +69,7 @@ namespace Sandbox
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>(); SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>()); SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>(); SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
//SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>(); SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>();
// Create Routines // Create Routines
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
@ -91,22 +91,24 @@ namespace Sandbox
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>(); SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHColliderComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>(); SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>(); SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); //SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); SHADE::SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); //SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds"); //SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
//TODO: REMOVE AFTER PRESENTATION
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
//TODO: REMOVE AFTER PRESENTATION
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
// Set up graphics system and windows // Set up graphics system and windows
graphicsSystem->SetWindow(&window); graphicsSystem->SetWindow(&window);

View File

@ -11,6 +11,7 @@
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Components/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
@ -43,7 +44,7 @@ namespace Sandbox
std::vector<Handle<SHMesh>> handles; std::vector<Handle<SHMesh>> handles;
for (auto const& mesh : meshes) for (auto const& mesh : meshes)
{ {
if (mesh.meshName == "Cube.012") if (mesh.header.meshName == "Cube.012")
{ {
handles.push_back(graphicsSystem->AddMesh( handles.push_back(graphicsSystem->AddMesh(
mesh.header.vertexCount, mesh.header.vertexCount,
@ -72,66 +73,73 @@ namespace Sandbox
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance(); auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst); auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f)); customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
customMat->SetProperty("data.textureIndex", 1); customMat->SetProperty("data.textureIndex", 0);
customMat->SetProperty("data.alpha", 0.1f); customMat->SetProperty("data.alpha", 0.1f);
// Create Stress Test Objects // Create Stress Test Objects
//static const SHVec3 TEST_OBJ_SCALE = { 0.05f, 0.05f, 0.05f }; static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f;
//constexpr int NUM_ROWS = 100; constexpr int NUM_ROWS = 10;
//constexpr int NUM_COLS = 100; constexpr int NUM_COLS = 10;
//static const SHVec3 TEST_OBJ_SPACING = { 0.05f, 0.05f, 0.05f }; static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
//static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
//for (int y = 0; y < NUM_ROWS; ++y) for (int y = 0; y < NUM_ROWS; ++y)
// for (int x = 0; x < NUM_COLS; ++x) for (int x = 0; x < NUM_COLS; ++x)
// { {
// auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
// auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
// auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
// //renderable.Mesh = handles.front();
// renderable.Mesh = CUBE_MESH;
// renderable.SetMaterial(customMat);
// if (y == 50)
// renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
// //Set initial positions
// transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{
// x * TEST_OBJ_SPACING.x,
// y * TEST_OBJ_SPACING.y,
// 0.0f
// });
// //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
// //transform.SetWorldRotation(3.14159265f * 1.5f, -3.14159265f / 2.0f, 0.0f);
// transform.SetLocalScale(TEST_OBJ_SCALE);
// stressTestObjects.emplace_back(entity);
// }
//auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
//auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
//auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
//renderable.Mesh = handles.front();
//renderable.SetMaterial(customMat);
//renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
//renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
//renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
//transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
//transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity); auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity); auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
auto& rb = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entity); auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
//renderable.Mesh = handles.front();
renderable.Mesh = CUBE_MESH; renderable.Mesh = CUBE_MESH;
renderable.SetMaterial(customMat); renderable.SetMaterial(customMat);
transform.SetLocalScale(SHVec3::One * 0.25f); if (y == 50)
transform.SetWorldPosition({0.0f, 2.0f, -1.0f}); renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
//Set initial positions
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f)});
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber());
transform.SetWorldScale(TEST_OBJ_SCALE);
auto* box = collider.AddBoundingBox();
box->SetHalfExtents(transform.GetWorldScale() * 0.5f);
stressTestObjects.emplace_back(entity);
}
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
renderable.Mesh = handles.front();
renderable.SetMaterial(customMat);
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor);
floorRenderable.Mesh = CUBE_MESH;
floorRenderable.SetMaterial(customMat);
floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
floorTransform.SetWorldScale({7.5f, 0.5f, 7.5});
floorTransform.SetWorldPosition({0.0f, -3.0f, -5.0f});
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox();
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
// Create blank entity with a script // Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); //testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
@ -140,22 +148,22 @@ namespace Sandbox
//testObjRenderable.SetMaterial(matInst); //testObjRenderable.SetMaterial(matInst);
//SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>()); SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
//scriptEngine->AddScript(raccoonSpin, "RaccoonSpin"); scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
//auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
//auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase); auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
//auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase); auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
//renderableShowcase.Mesh = handles.front(); renderableShowcase.Mesh = handles.front();
//renderableShowcase.SetMaterial(customMat); renderableShowcase.SetMaterial(customMat);
//renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f)); renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
//renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f); renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
//renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1); renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
//transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
//transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
//scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
} }
void SBTestScene::Update(float dt) void SBTestScene::Update(float dt)

View File

@ -1,3 +1,15 @@
/*************************************************************************//**
* \file SHMeshAsset.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Struct to contain ready data for loading into GPU. Also used for
* compilation into binary files
*
*
* 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 #pragma once
#include <vector> #include <vector>
@ -10,6 +22,7 @@ namespace SHADE
{ {
uint32_t vertexCount; uint32_t vertexCount;
uint32_t indexCount; uint32_t indexCount;
std::string meshName;
}; };
struct SH_API SHMeshAsset struct SH_API SHMeshAsset
@ -19,8 +32,6 @@ namespace SHADE
SHMeshAssetHeader header; SHMeshAssetHeader header;
std::string meshName;
std::vector<SHVec3> vertexPosition; std::vector<SHVec3> vertexPosition;
std::vector<SHVec3> vertexTangent; std::vector<SHVec3> vertexTangent;
std::vector<SHVec3> vertexNormal; std::vector<SHVec3> vertexNormal;

View File

@ -1,15 +1,14 @@
#pragma once #pragma once
#include "tinyddsloader.h" #include "tinyddsloader.h"
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
#include <memory>
namespace SHADE namespace SHADE
{ {
struct SHTextureAsset struct SHTextureAsset
{ {
bool compiled;
uint32_t numBytes; uint32_t numBytes;
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;

View File

@ -0,0 +1,70 @@
/*************************************************************************//**
* \file SHMeshCompiler.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHMeshAsset into binary file for faster
* loading in the future
*
*
* 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 "SHMeshCompiler.h"
#include "Graphics/MiddleEnd/Meshes/SHMeshData.h"
#include <fstream>
void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
{
std::string newPath{ path.string() };
newPath = newPath.substr(0, newPath.find_last_of('/') + 1);
newPath += asset.header.meshName + MESH_EXTENSION;
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.write(
reinterpret_cast<char const*>(asset.indices.data()),
sizeof(uint32_t) * asset.header.indexCount
);
file.close();
}

View File

@ -0,0 +1,26 @@
/*************************************************************************//**
* \file SHMeshCompiler.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHMeshAsset into binary file for faster
* loading in the future
*
*
* 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 "../Asset Types/SHMeshAsset.h"
#include "../SHAssetMacros.h"
namespace SHADE
{
class SHMeshCompiler
{
private:
public:
static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
};
}

View File

@ -1,12 +1,25 @@
/*************************************************************************//**
* \file SHMeshLoader.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Implementation for Mesh loader. Accounts for custom binary format
* as well as GLTF file format.
*
*
* 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 "SHpch.h"
#include "SHMeshLoader.h" #include "SHMeshLoader.h"
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <fstream>
namespace SHADE namespace SHADE
{ {
Assimp::Importer SHMeshLoader::aiImporter; Assimp::Importer SHMeshLoader::aiImporter;
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) noexcept
{ {
for (size_t i {0}; i < node.mNumMeshes; ++i) for (size_t i {0}; i < node.mNumMeshes; ++i)
{ {
@ -20,15 +33,14 @@ namespace SHADE
} }
} }
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept
{ {
(void)scene; (void)scene;
SHMeshAsset result SHMeshAsset result
{ {
.compiled { false}, .compiled { false},
.changed { false }, .changed { false }
.meshName { mesh.mName.C_Str() }
}; };
for (size_t i{0}; i < mesh.mNumVertices; ++i) for (size_t i{0}; i < mesh.mNumVertices; ++i)
@ -81,34 +93,31 @@ namespace SHADE
result.header.vertexCount = result.vertexPosition.size(); result.header.vertexCount = result.vertexPosition.size();
result.header.indexCount = result.indices.size(); result.header.indexCount = result.indices.size();
result.header.meshName = mesh.mName.C_Str();
return result; return result;
} }
bool SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) void SHMeshLoader::LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept
{ {
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(), const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
aiProcess_Triangulate aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
// Make sure we get triangles rather than nvert polygons
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping | aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
| aiProcess_TransformUVCoords | aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
// preprocess UV transformations (scaling, translation ...) | aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
| aiProcess_FindInstances | aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
// search for instanced meshes and remove them by references to one master | aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
| aiProcess_CalcTangentSpace
// calculate tangents and bitangents if possible
| aiProcess_JoinIdenticalVertices
// join identical vertices/ optimize indexing
| aiProcess_RemoveRedundantMaterials // remove redundant materials | aiProcess_RemoveRedundantMaterials // remove redundant materials
| aiProcess_FindInvalidData// detect invalid model data, such as invalid normal vectors | aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs | aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
); );
if (!scene || !scene->HasMeshes()) if (!scene || !scene->HasMeshes())
{ {
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string()); SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
return false; return;
} }
//TODO MATERIALS FROM MESHES //TODO MATERIALS FROM MESHES
//if (scene->HasMaterials()) //if (scene->HasMaterials())
//{ //{
@ -123,7 +132,101 @@ namespace SHADE
//} //}
ProcessNode(*scene->mRootNode, *scene, meshes); ProcessNode(*scene->mRootNode, *scene, meshes);
}
return true; void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept
{
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
}
std::string name{ path.filename().string() };
name = name.substr(0, name.find_last_of('.'));
file.seekg(0);
uint32_t vertCount, indexCount;
std::vector<SHVec3> vertPos, vertTan, vertNorm;
std::vector<SHVec2> texCoord;
std::vector<uint32_t> indices;
file.read(reinterpret_cast<char*>(&vertCount), sizeof(uint32_t));
file.read(reinterpret_cast<char*>(&indexCount), sizeof(uint32_t));
auto const vertexVec3Byte{ sizeof(SHVec3) * vertCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * vertCount };
vertPos.resize(vertCount);
vertTan.resize(vertCount);
vertNorm.resize(vertCount);
texCoord.resize(vertCount);
indices.resize(indexCount);
file.read(reinterpret_cast<char *>(vertPos.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(vertTan.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte);
file.read(reinterpret_cast<char *>(indices.data()), sizeof(uint32_t) * indexCount);
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertPos[i].x;
// file >> vertPos[i].y;
// file >> vertPos[i].z;
//}
//
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertTan[i].x;
// file >> vertTan[i].y;
// file >> vertTan[i].z;
//}
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertNorm[i].x;
// file >> vertNorm[i].y;
// file >> vertNorm[i].z;
//}
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> texCoord[i].x;
// file >> texCoord[i].y;
//}
//for (auto i{ 0 }; i < indexCount; ++i)
//{
// file >> indices[i];
//}
mesh.compiled = true;
mesh.changed = false;
mesh.header.indexCount = indexCount;
mesh.header.vertexCount = vertCount;
mesh.header.meshName = name;
mesh.vertexPosition = std::move(vertPos);
mesh.vertexTangent = std::move(vertTan);
mesh.vertexNormal = std::move(vertNorm);
mesh.texCoords = std::move(texCoord);
mesh.indices = std::move(indices);
file.close();
}
void SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept
{
if (path.extension().string() == GLTF_EXTENSION)
{
LoadExternal(meshes, path);
return;
}
meshes.emplace_back();
LoadSHMesh(meshes.back(), path);
} }
} }

View File

@ -1,3 +1,14 @@
/*************************************************************************//**
* \file SHMeshLoader.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to load gltf mesh files and custom binary format
*
*
* 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 #pragma once
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
@ -12,10 +23,14 @@ namespace SHADE
private: private:
static Assimp::Importer aiImporter; static Assimp::Importer aiImporter;
static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes); static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) noexcept;
static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene); static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept;
static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
public: public:
static bool LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path); static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
}; };
} }

View File

@ -1,48 +0,0 @@
#include "SHpch.h"
#include "SHMeshWriter.h"
#include <fstream>
void SHADE::SHMeshWriter::WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
{
std::ofstream file{path, std::ios::out | std::ios::binary};
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.close();
}

View File

@ -1,14 +0,0 @@
#pragma once
#include "../Asset Types/SHMeshAsset.h"
#include "../SHAssetMacros.h"
namespace SHADE
{
class SHMeshWriter
{
private:
public:
static void WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
};
}

View File

@ -0,0 +1,73 @@
/*************************************************************************//**
* \file SHTextureCompiler.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHTextureAsset into binary file for
* faster loading in the future
*
*
* 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 "SHTextureCompiler.h"
#include <fstream>
namespace SHADE
{
void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
{
std::string newPath{ path.string() };
newPath = newPath.substr(0, newPath.find_last_of('.'));
newPath += TEXTURE_EXTENSION;
std::ofstream file{ newPath, std::ios::out | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing texture file: {}", path.string());
}
auto const intBytes{sizeof(uint32_t)};
uint32_t mipOffsetCount{ static_cast<uint32_t>(asset.mipOffsets.size()) };
file.write(
reinterpret_cast<char const*>(&asset.numBytes),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.width),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.height),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.format),
sizeof(SHTexture::TextureFormat)
);
file.write(
reinterpret_cast<char const*>(&mipOffsetCount),
intBytes
);
file.write(
reinterpret_cast<char const*>(asset.mipOffsets.data()),
intBytes * asset.mipOffsets.size()
);
file.write(
reinterpret_cast<char const*>(asset.pixelData),
asset.numBytes
);
file.close();
}
}

View File

@ -0,0 +1,24 @@
/*************************************************************************//**
* \file SHTextureCompiler.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to write data in SHTextureAsset into binary file for
* faster loading in the future
*
*
* 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 "Assets/Asset Types/SHTextureAsset.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
struct SHTextureCompiler
{
static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
};
}

View File

@ -1,3 +1,14 @@
/*************************************************************************//**
* \file SHTextureLoader.cpp
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to load dds textures and custom binary format
*
*
* 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 "SHpch.h"
#include "SHTextureLoader.h" #include "SHTextureLoader.h"
@ -58,7 +69,7 @@ namespace SHADE
} }
} }
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset) void SHTextureLoader::LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept
{ {
tinyddsloader::Result loadResult = tinyddsloader::Result::Success; tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
tinyddsloader::DDSFile file; tinyddsloader::DDSFile file;
@ -82,6 +93,7 @@ namespace SHADE
std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes); std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes);
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData())); //pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
asset.compiled = false;
asset.numBytes = totalBytes; asset.numBytes = totalBytes;
asset.width = file.GetWidth(); asset.width = file.GetWidth();
asset.height = file.GetHeight(); asset.height = file.GetHeight();
@ -89,4 +101,46 @@ namespace SHADE
asset.mipOffsets = std::move(mipOff); asset.mipOffsets = std::move(mipOff);
asset.pixelData = std::move(pixel); asset.pixelData = std::move(pixel);
} }
void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept
{
std::ifstream file{path.string(), std::ios::in | std::ios::binary};
if (!file.is_open())
{
SHLOG_ERROR("Error opening SHTexture file: {}", path.string());
}
auto const intBytes{ sizeof(uint32_t) };
uint32_t mipCount;
file.read(reinterpret_cast<char*>(&asset.numBytes), intBytes);
file.read(reinterpret_cast<char*>(&asset.width), intBytes);
file.read(reinterpret_cast<char*>(&asset.height), intBytes);
file.read(reinterpret_cast<char*>(&asset.format), sizeof(SHTexture::TextureFormat));
file.read(reinterpret_cast<char*>(&mipCount), intBytes);
std::vector<uint32_t> mips(mipCount);
file.read(reinterpret_cast<char*>(mips.data()), intBytes * mipCount);
auto pixel = new SHTexture::PixelChannel[asset.numBytes];
file.read(reinterpret_cast<char*>(pixel), asset.numBytes);
asset.mipOffsets = std::move(mips);
asset.pixelData = std::move( pixel );
asset.compiled = true;
file.close();
}
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
{
if (path.extension().string() == DDS_EXTENSION)
{
LoadTinyDDS(path, asset);
}
else if (path.extension().string() == TEXTURE_EXTENSION)
{
LoadSHTexture(path, asset);
}
}
} }

View File

@ -1,3 +1,14 @@
/*************************************************************************//**
* \file SHTextureLoader.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Library to load dds textures and custom binary format
*
*
* 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 #pragma once
#define TINYDDSLOADER_IMPLEMENTATION #define TINYDDSLOADER_IMPLEMENTATION
@ -13,6 +24,9 @@ namespace SHADE
static std::string TinyDDSResultToString(tinyddsloader::Result value); static std::string TinyDDSResultToString(tinyddsloader::Result value);
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept;
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
public: public:
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
}; };

View File

@ -1,3 +1,14 @@
/*************************************************************************//**
* \file SHAsset.h
* \author Loh Xiao Qi
* \date 30 September 2022
* \brief Struct for asset identification and meta file writing
*
*
* 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 #pragma once
#include "Filesystem/SHFileSystem.h" #include "Filesystem/SHFileSystem.h"

View File

@ -17,6 +17,9 @@
#include "Libraries/SHMeshLoader.h" #include "Libraries/SHMeshLoader.h"
#include "Libraries/SHTextureLoader.h" #include "Libraries/SHTextureLoader.h"
#include "Libraries/SHMeshCompiler.h"
#include "Libraries/SHTextureCompiler.h"
namespace SHADE namespace SHADE
{ {
FMOD::System* SHAssetManager::audioSystem; FMOD::System* SHAssetManager::audioSystem;
@ -199,7 +202,9 @@ namespace SHADE
{ {
AssetPath path{ p }; AssetPath path{ p };
if (path.extension().string() == GLTF_EXTENSION) if (path.extension().string() == FBX_EXTENSION
|| path.extension().string() == GLTF_EXTENSION
|| path.extension().string() == MESH_EXTENSION)
{ {
LoadGLTF( LoadGLTF(
{ {
@ -211,7 +216,8 @@ namespace SHADE
} }
); );
} }
else if (path.extension().string() == DDS_EXTENSION) else if (path.extension().string() == DDS_EXTENSION
|| path.extension().string() == TEXTURE_EXTENSION)
{ {
LoadDDS( LoadDDS(
{ {
@ -300,6 +306,11 @@ namespace SHADE
for (auto const& mesh : meshes) for (auto const& mesh : meshes)
{ {
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh); meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
if (!mesh.compiled)
{
SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
}
} }
} }
@ -310,6 +321,11 @@ namespace SHADE
SHTextureLoader::LoadImageAsset(asset.path, image); SHTextureLoader::LoadImageAsset(asset.path, image);
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image); textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
if (!image.compiled)
{
SHTextureCompiler::CompileTextureBinary(image, asset.path);
}
} }
/**************************************************************************** /****************************************************************************

View File

@ -99,6 +99,7 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
{ {
//TODO: Write into binary eventually
std::string path{ meta.path.string() }; std::string path{ meta.path.string() };
path.append(META_EXTENSION); path.append(META_EXTENSION);
@ -110,8 +111,20 @@ namespace SHADE
return; return;
} }
metaFile << "Name: " << meta.name << "\n";
metaFile << "ID: " << meta.id << "\n"; metaFile << "ID: " << meta.id << "\n";
metaFile << "Type: " << static_cast<int>(meta.type) << std::endl; metaFile << "Type: " << static_cast<int>(meta.type) << std::endl;
//TODO Add in information that is specific to types like mesh
switch(meta.type)
{
case AssetType::MESH:
break;
default:
void;
}
metaFile.close(); metaFile.close();
} }

View File

@ -93,8 +93,8 @@ namespace SHADE
void SHADE::SHAudioSystem::Run(float dt) void SHADE::SHAudioSystem::Run(float dt)
{ {
static_cast<void>(dt); static_cast<void>(dt);
if (GetKeyState(VK_SPACE) & 0x8000) //if (GetKeyState(VK_SPACE) & 0x8000)
PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); // PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
fmodStudioSystem->update(); fmodStudioSystem->update();
if (!denseListener->empty()) if (!denseListener->empty())

View File

@ -45,6 +45,12 @@ namespace SHADE
SHEditorWindow::Update(); SHEditorWindow::Update();
if (Begin()) if (Begin())
{ {
if (ImGui::Button("AUDIO"))
{
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
audioSystem->PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
}
if (!SHEditor::selectedEntities.empty()) if (!SHEditor::selectedEntities.empty())
{ {
EntityID const& eid = SHEditor::selectedEntities[0]; EntityID const& eid = SHEditor::selectedEntities[0];

View File

@ -10,6 +10,8 @@
#pragma once #pragma once
#include <DirectXCollision.h>
// Project Headers // Project Headers
#include "SHShape.h" #include "SHShape.h"
#include "SH_API.h" #include "SH_API.h"
@ -20,6 +22,7 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
// TODO(Diren): Use DirectX BoundingBox instead of custom
class SH_API SHBoundingBox : public SHShape class SH_API SHBoundingBox : public SHShape
{ {
public: public:

View File

@ -23,4 +23,14 @@ namespace SHADE
: type { Type::NONE } : type { Type::NONE }
{} {}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
SHShape::Type SHShape::GetType() const
{
return type;
}
} // namespace SHADE } // namespace SHADE

View File

@ -103,6 +103,9 @@ namespace SHADE
template <IsArithmetic T> template <IsArithmetic T>
T SHMath::GenerateRandomNumber(T lowerBound, T upperBound) T SHMath::GenerateRandomNumber(T lowerBound, T upperBound)
{ {
if (lowerBound > upperBound)
std::swap(lowerBound, upperBound);
if constexpr (IsIntegral<T>) if constexpr (IsIntegral<T>)
{ {
std::uniform_int_distribution<T> distribution(lowerBound, upperBound); std::uniform_int_distribution<T> distribution(lowerBound, upperBound);

View File

@ -15,6 +15,7 @@
// Project Headers // Project Headers
#include "Vector/SHVec3.h" #include "Vector/SHVec3.h"
#include "SHMatrix.h" #include "SHMatrix.h"
#include "SHMathHelpers.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
using namespace DirectX; using namespace DirectX;
@ -249,9 +250,30 @@ namespace SHADE
SHVec3 SHQuaternion::ToEuler() const noexcept SHVec3 SHQuaternion::ToEuler() const noexcept
{ {
// TODO (Diren) const float xx = x * x;
const float yy = y * y;
const float zz = z * z;
return SHVec3::Zero; const float m31 = 2.f * x * z + 2.f * y * w;
const float m32 = 2.f * y * z - 2.f * x * w;
const float m33 = 1.f - 2.f * xx - 2.f * yy;
const float cy = sqrtf(m33 * m33 + m31 * m31);
const float cx = atan2f(-m32, cy);
if (cy > 16.0f * SHMath::EPSILON)
{
const float m12 = 2.f * x * y + 2.f * z * w;
const float m22 = 1.f - 2.f * xx - 2.f * zz;
return SHVec3(cx, atan2f(m31, m33), atan2f(m12, m22));
}
else
{
const float m11 = 1.f - 2.f * yy - 2.f * zz;
const float m21 = 2.f * x * y - 2.f * z * w;
return SHVec3(cx, 0.f, atan2f(-m21, m11));
}
} }
std::string SHQuaternion::ToString() const noexcept std::string SHQuaternion::ToString() const noexcept

View File

@ -13,16 +13,24 @@
// Primary Header // Primary Header
#include "SHColliderComponent.h" #include "SHColliderComponent.h"
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Physics/SHPhysicsSystem.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHColliderComponent::SHColliderComponent() noexcept
: system { nullptr }
{}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
bool SHColliderComponent::HasChanged() const noexcept
{
return dirty;
}
const SHVec3& SHColliderComponent::GetPosition() const noexcept const SHVec3& SHColliderComponent::GetPosition() const noexcept
{ {
@ -44,7 +52,7 @@ namespace SHADE
return colliders; return colliders;
} }
SHCollider& SHColliderComponent::GetCollider(int index) noexcept SHCollider& SHColliderComponent::GetCollider(int index)
{ {
if (index < 0 || static_cast<size_t>(index) >= colliders.size()) if (index < 0 || static_cast<size_t>(index) >= colliders.size())
throw std::invalid_argument("Out-of-range access!"); throw std::invalid_argument("Out-of-range access!");
@ -58,26 +66,60 @@ namespace SHADE
void SHColliderComponent::OnCreate() void SHColliderComponent::OnCreate()
{ {
system = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (!system)
{
SHLOG_ERROR("Physics system does not exist, Collider Component not added!")
return;
}
system->AddCollider(GetEID());
} }
void SHColliderComponent::OnDestroy() void SHColliderComponent::OnDestroy()
{ {
if (!system)
}
void SHColliderComponent::AddBoundingBox() noexcept
{ {
const auto BOX_PAIR = std::make_pair(SHCollider{SHCollider::Type::BOX}, true); SHLOG_ERROR("Physics system does not exist, unable to remove Collider component!")
colliders.emplace_back(BOX_PAIR); return;
} }
void SHColliderComponent::AddSphere() noexcept system->RemoveCollider(GetEID());
}
SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept
{ {
const auto TYPE = SHCollider::Type::BOX;
const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true);
auto& collider = colliders.emplace_back(BOX_PAIR).first;
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
return nullptr;
} }
void SHColliderComponent::RemoveCollider(int index) noexcept // Notify Physics System
system->AddCollisionShape(GetEID(), collider.GetShape());
return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
}
//void SHColliderComponent::AddSphere() noexcept
//{
// const auto TYPE = SHCollider::Type::SPHERE;
// if (!system)
// {
// SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
// return;
// }
// // Notify Physics System
//}
void SHColliderComponent::RemoveCollider(int index)
{ {
if (index < 0 || static_cast<size_t>(index) >= colliders.size()) if (index < 0 || static_cast<size_t>(index) >= colliders.size())
throw std::invalid_argument("Out-of-range access!"); throw std::invalid_argument("Out-of-range access!");
@ -93,6 +135,15 @@ namespace SHADE
} }
it = colliders.erase(it); it = colliders.erase(it);
// Notify Physics System
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to remove Collider!")
return;
}
system->RemoveCollisionShape(GetEID(), index);
} }
} // namespace SHADE } // namespace SHADE

View File

@ -10,6 +10,8 @@
#pragma once #pragma once
#include <rttr/registration>
// Project Headers // Project Headers
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHCollider.h" #include "Physics/SHCollider.h"
@ -42,7 +44,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHColliderComponent () noexcept = default; SHColliderComponent () noexcept;
SHColliderComponent (const SHColliderComponent& rhs) noexcept = default; SHColliderComponent (const SHColliderComponent& rhs) noexcept = default;
SHColliderComponent (SHColliderComponent&& rhs) noexcept = default; SHColliderComponent (SHColliderComponent&& rhs) noexcept = default;
~SHColliderComponent () override = default; ~SHColliderComponent () override = default;
@ -65,7 +67,7 @@ namespace SHADE
[[nodiscard]] SHVec3 GetRotation () const noexcept; [[nodiscard]] SHVec3 GetRotation () const noexcept;
[[nodiscard]] const Colliders& GetColliders () const noexcept; [[nodiscard]] const Colliders& GetColliders () const noexcept;
[[nodiscard]] SHCollider& GetCollider (int index) noexcept; [[nodiscard]] SHCollider& GetCollider (int index);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -74,10 +76,9 @@ namespace SHADE
void OnCreate () override; void OnCreate () override;
void OnDestroy () override; void OnDestroy () override;
void AddBoundingBox () noexcept; SHBoundingBox* AddBoundingBox () noexcept;
void AddSphere () noexcept;
void RemoveCollider (int index) noexcept; void RemoveCollider (int index);
private: private:
@ -85,7 +86,8 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool dirty; SHPhysicsSystem* system;
SHVec3 position; SHVec3 position;
SHQuaternion orientation; SHQuaternion orientation;
Colliders colliders; Colliders colliders;

View File

@ -82,7 +82,7 @@ namespace SHADE
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::SetPosition(const SHVec3& position) const noexcept void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept
{ {
const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z }; const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z };
@ -91,9 +91,10 @@ namespace SHADE
rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation()); rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation());
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
} }
void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) const noexcept void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept
{ {
const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w }; const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w };
@ -102,9 +103,10 @@ namespace SHADE
rp3dTF.setOrientation(RP3D_ORIENTATION); rp3dTF.setOrientation(RP3D_ORIENTATION);
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
} }
void SHPhysicsObject::SetRotation(const SHVec3& rotation) const noexcept void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept
{ {
const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z ); const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z );
@ -113,6 +115,7 @@ namespace SHADE
rp3dTF.setOrientation(RP3D_ORIENTATION); rp3dTF.setOrientation(RP3D_ORIENTATION);
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -63,9 +63,9 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetPosition (const SHVec3& position) const noexcept; void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) const noexcept; void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) const noexcept; void SetRotation (const SHVec3& rotation) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -26,7 +26,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHPhysicsSystem::SHPhysicsSystem() SHPhysicsSystem::SHPhysicsSystem()
: interpolationFactor { 0.0 } : worldUpdated { false }
, interpolationFactor { 0.0 }
, fixedDT { 60.0 } , fixedDT { 60.0 }
, world { nullptr } , world { nullptr }
{} {}
@ -186,8 +187,13 @@ namespace SHADE
settings.isSleepingEnabled = true; settings.isSleepingEnabled = true;
settings.defaultVelocitySolverNbIterations = 8; settings.defaultVelocitySolverNbIterations = 8;
settings.defaultPositionSolverNbIterations = 3; settings.defaultPositionSolverNbIterations = 3;
settings.defaultFrictionCoefficient = 0.4f;
settings.defaultBounciness = 0.0f;
world = factory.createPhysicsWorld(settings); world = factory.createPhysicsWorld(settings);
// Set up solvers
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
} }
void SHPhysicsSystem::Exit() void SHPhysicsSystem::Exit()
@ -209,6 +215,76 @@ namespace SHADE
physicsObject->entityID = entityID; physicsObject->entityID = entityID;
} }
// Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
// Possibly redundant
if (!SHADE_TF)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
// If collider already exists
if (physicsObject->hasColliders)
world->destroyCollisionBody(physicsObject->rp3dBody);
physicsObject->rp3dBody = world->createRigidBody(RP3D_TF);
physicsObject->isRigidBody = true;
// Recreate colliders
if (physicsObject->hasColliders)
{
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
}
}
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept
{
#ifdef _DEBUG
SHLOG_INFO("Adding a Collider to the Physics World.")
#endif
// Check if entity is already a physics object
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
// Get entity transform // Get entity transform
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
@ -226,15 +302,39 @@ namespace SHADE
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z }; const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z ); const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
physicsObject->rp3dBody = world->createRigidBody(rp3d::Transform{ RP3D_POS, RP3D_ROT }); const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
physicsObject->isRigidBody = true;
// No rb
if (!physicsObject->isRigidBody)
physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF);
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
} }
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept physicsObject->hasColliders = true;
{
#ifdef _DEBUG
SHLOG_INFO("Adding a Collider to the Physics World.")
#endif
} }
void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept
@ -292,16 +392,47 @@ namespace SHADE
} }
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape)
{
auto* physicsObject = GetPhysicsObject(entityID);
switch (shape->GetType())
{
case SHShape::Type::BOUNDING_BOX:
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
rp3d::Transform tf = rp3d::Transform::identity();
physicsObject->rp3dBody->addCollider(newBox, tf);
break;
}
case SHShape::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index)
{
}
void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept
{ {
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem()); auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
// Get dense arrays
auto& rbDense = SHComponentManager::GetDense<SHRigidBodyComponent>();
auto& cDense = SHComponentManager::GetDense<SHColliderComponent>();
// Update bodies and colliders if component is dirty // Update bodies and colliders if component is dirty
system->SyncRigidBodyComponents(rbDense); system->SyncRigidBodyComponents(SHComponentManager::GetDense<SHRigidBodyComponent>());
system->SyncColliderComponents(SHComponentManager::GetDense<SHColliderComponent>());
// Sync transforms // Sync transforms
for (auto& physicsObject : system->map | std::views::values) for (auto& physicsObject : system->map | std::views::values)
@ -331,6 +462,7 @@ namespace SHADE
} }
stats.numSteps = count; stats.numSteps = count;
system->worldUpdated = count > 0;
system->interpolationFactor = accumulatedTime / fixedTimeStep; system->interpolationFactor = accumulatedTime / fixedTimeStep;
} }
@ -340,10 +472,12 @@ namespace SHADE
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem()); auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
// Interpolate transforms for rendering // Interpolate transforms for rendering
if (system->worldUpdated)
{
system->SyncTransforms(); system->SyncTransforms();
// TODO(Diren): Handle trigger messages for scripting // TODO(Diren): Handle trigger messages for scripting
} }
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */ /* Private Function Member Definitions */
@ -385,12 +519,38 @@ namespace SHADE
if (comp.dirtyFlags > 0) if (comp.dirtyFlags > 0)
{ {
SyncRB(physicsObject, &comp); SyncRigidBody(physicsObject, &comp);
comp.dirtyFlags = 0; comp.dirtyFlags = 0;
} }
} }
} }
void SHPhysicsSystem::SyncColliderComponents(std::vector<SHColliderComponent>& denseArray) noexcept
{
if (denseArray.empty())
return;
for (auto& comp : denseArray)
{
const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive;
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE)
continue;
SyncCollider(physicsObject, &comp);
}
}
void SHPhysicsSystem::SyncTransforms() noexcept void SHPhysicsSystem::SyncTransforms() noexcept
{ {
for (auto& pair : map) for (auto& pair : map)
@ -408,6 +568,9 @@ namespace SHADE
if (physicsObject.isRigidBody) if (physicsObject.isRigidBody)
{ {
auto const* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(ENTITY_ID); auto const* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(ENTITY_ID);
if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
continue;
if (rbComponent->IsInterpolating()) if (rbComponent->IsInterpolating())
{ {
const rp3d::Transform PREV_TF = physicsObject.prevTransform; const rp3d::Transform PREV_TF = physicsObject.prevTransform;
@ -442,7 +605,7 @@ namespace SHADE
} }
} }
void SHPhysicsSystem::SyncRB(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept
{ {
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody); auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody);
@ -542,9 +705,43 @@ namespace SHADE
rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS); rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS);
} }
void SHPhysicsSystem::SyncColliders(SHPhysicsObject const* physicsObject, const SHColliderComponent* comp) noexcept void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept
{ {
int index = 0;
for (auto& [collider, dirty] : comp->colliders)
{
if (!dirty)
continue;
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(physicsObject->rp3dBody->getCollider(index)->getCollisionShape());
rp3dBoxShape->setHalfExtents(RP3D_EXTENTS);
if (rp3dBoxShape)
{
SHLOG_INFO("Updating box things")
}
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
default: break;
}
dirty = false;
++index;
}
} }
} // namespace SHADE } // namespace SHADE

View File

@ -100,6 +100,9 @@ namespace SHADE
void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept;
void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept;
void AddCollisionShape (EntityID entityID, SHShape* shape);
void RemoveCollisionShape (EntityID entityID, int index);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* System Routines */ /* System Routines */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -168,12 +171,13 @@ namespace SHADE
// TODO(Diren): Store interpFactor // TODO(Diren): Store interpFactor
bool worldUpdated;
double interpolationFactor; double interpolationFactor;
double fixedDT; double fixedDT;
rp3d::PhysicsCommon factory;
rp3d::PhysicsWorld* world; rp3d::PhysicsWorld* world;
rp3d::PhysicsCommon factory;
EntityObjectMap map; EntityObjectMap map;
@ -188,11 +192,11 @@ namespace SHADE
void SyncTransforms () noexcept; void SyncTransforms () noexcept;
// TODO(Diren): Trigger handling // TODO(Diren): Trigger handling
static void SyncRB (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept;
static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SyncColliders (SHPhysicsObject const* physicsObject, const SHColliderComponent* comp) noexcept; static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept;
}; };

View File

@ -254,8 +254,8 @@ namespace SHADE
</ItemGroup>\n\ </ItemGroup>\n\
<ItemGroup>\n\ <ItemGroup>\n\
<Reference Include=\"SHADE_Managed\">\n\ <Reference Include=\"SHADE_Managed\">\n\
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\ <HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\ <HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
</Reference>\n\ </Reference>\n\
</ItemGroup>\n\ </ItemGroup>\n\
</Project>"; </Project>";
@ -520,7 +520,7 @@ namespace SHADE
std::wostringstream oss; std::wostringstream oss;
oss << "dotnet build \"" << SHStringUtils::StrToWstr(CSPROJ_PATH) << "\" -c "; oss << "dotnet build \"" << SHStringUtils::StrToWstr(CSPROJ_PATH) << "\" -c ";
oss << debug ? "Debug" : "Release"; oss << debug ? "Debug" : "Release";
oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet"; oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet -r \"win-x64\"";
return oss.str(); return oss.str();
} }
} }