Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions 3DRadSpace/3DRadSpace_Editor_WindowsDX11/Editor/EditorGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ void EditorGame::_picking()
static_cast<int>(mousePos.Y * scaleY)
);

auto ray = GetMouseRay(scaledMousePos, View, Projection);
auto activeCamera = Cameras->GetActiveCamera();

auto ray = GetMouseRay(scaledMousePos, activeCamera->GetViewMatrix(), activeCamera->GetProjectionMatrix());

float closestDistance = std::numeric_limits<float>::infinity();
Vector3 closestIntersection = cursor3D;
Expand Down Expand Up @@ -390,27 +392,31 @@ void EditorGame::Update()

Camera.Rotation = Quaternion::FromYawPitchRoll(cameraPos.X, cameraPos.Y, 0);
Camera.Position = cursor3D + Vector3::UnitZ().Transform(Camera.Rotation) * (zoom + 5);

Cameras->SetActiveCamera(&Camera);
}

void EditorGame::Draw3D()
{
Camera.Draw3D();

axis->Transform = Matrix4x4::CreateTranslation(cursor3D);
axis->View = View;
axis->Projection = Projection;
auto activeCamera = Cameras->GetActiveCamera();

axis->View = activeCamera->GetViewMatrix();
axis->Projection = activeCamera->GetProjectionMatrix();
axis->Draw3D();

if (Settings::ShowGrid.Value)
{
grid->View = View;
grid->Projection = Projection;
grid->View = activeCamera->GetViewMatrix();
grid->Projection = activeCamera->GetProjectionMatrix();
grid->Draw3D();

if (!Math::WithinEpsilon(cursor3D.X, 0) || !Math::WithinEpsilon(cursor3D.Y, 0) || !Math::WithinEpsilon(cursor3D.Z, 0))
{
grid_center->View = View;
grid_center->Projection = Projection;
grid_center->View = activeCamera->GetViewMatrix();
grid_center->Projection = activeCamera->GetProjectionMatrix();
grid_center->Draw3D();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void* EditObject(HWND hwnd, HINSTANCE hInstance, void* pRefl, void* pContent, vo

if (useDefaultWindow)
{
EditObjectDialog dialog(hwnd, hInstance, refl, content);
EditObjectDialog dialog(hwnd, hInstance, refl, content, obj);
return dialog.ShowDialog();
}
else
Expand Down
4 changes: 3 additions & 1 deletion 3DRadSpace/Data/Shaders/ExponentialFogSS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
Texture2D Main : register(t0);
Texture2D Depth : register(t1);
SamplerState TextureSampler : register(s0);
SamplerState DepthSampler : register(s1);


cbuffer FogInfo : register(b0)
{
Expand All @@ -17,5 +19,5 @@ cbuffer FogInfo : register(b0)
float4 PS_Main(VertexOut v) : SV_TARGET
{
return Main.Sample(TextureSampler, v.UV) + //color component
FogColor * (1 / exp(Density * Depth.Sample(TextureSampler, v.UV))); //linear fog component
FogColor * (1 / exp(Density * Depth.Sample(DepthSampler, v.UV))); //linear fog component
}
6 changes: 3 additions & 3 deletions 3DRadSpace/Data/Shaders/PositionColor_Pick.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ VertexOut VS_Main(VertexIn v)

struct PSOutput
{
float4 Color : SV_Target0;
uint ID : SV_Target1;
}
float4 Color : SV_Target0;
uint ID : SV_Target1;
};

PSOutput PS_Main(VertexOut v)
{
Expand Down
82 changes: 82 additions & 0 deletions 3DRadSpace/Data/Shaders/PositionNormalTangentUV_Shadow.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
cbuffer Data : register(b0)
{
row_major matrix matWorldViewProj; // MVP transformation
row_major matrix matWorld; // World transformation
}

cbuffer ShadowData : register(b1)
{
row_major matrix matWorldViewProjLight; // MVP transformation for light
row_major matrix matInvViewProj; //Camera Inv(VP)
float3 LightDirection;
float ShadowBias;
float ShadowIntensity;
float2 padding;
}

Texture2D TextureModel : register(t0);
SamplerState TextureSampler : register(s0);

Texture2D ShadowMap : register(t1);
SamplerState ShadowSampler : register(s1);

struct VertexIn
{
float3 Position : POSITION;
float3 Normal : NORMAL;
float3 Tangent : TANGENT;
float3 Bitangent: BITANGENT;
float2 UV : TEXCOORD;
};

struct VertexOut
{
float4 Position : SV_POSITION;
float3 WorldPos : POSITION;
float2 UV: TEXCOORD;
};

VertexOut VS_Main(VertexIn v)
{
VertexOut r;
r.Position = mul(float4(v.Position.xyz,1), matWorldViewProj);
r.WorldPos = mul(float4(v.Position.xyz,1), matWorld).xyz;
r.UV = v.UV;
return r;
}

float CalculateShadow(float3 worldPos)
{
// Transform world position to light space
float4 lightSpacePos = mul(float4(worldPos, 1.0), matWorldViewProjLight);

// Perform perspective divide
float3 projCoords = lightSpacePos.xyz / lightSpacePos.w;

// Transform to [0,1] range for texture sampling
projCoords.x = projCoords.x * 0.5 + 0.5;
projCoords.y = projCoords.y * -0.5 + 0.5; // Flip Y for D3D

// Outside shadow map bounds = not in shadow
if (projCoords.x < 0.0 || projCoords.x > 1.0 ||
projCoords.y < 0.0 || projCoords.y > 1.0 ||
projCoords.z > 1.0)
return 1.0;

// Get closest depth from shadow map
float closestDepth = ShadowMap.Sample(ShadowSampler, projCoords.xy).r;

// Get current fragment depth
float currentDepth = projCoords.z;

// Compare depths with bias
float shadow = (currentDepth - ShadowBias) > closestDepth ? ShadowIntensity : 1.0;

return shadow;
}

float4 PS_Main(VertexOut v) : SV_TARGET
{
float shadowFactor = CalculateShadow(v.WorldPos);
return TextureModel.Sample(TextureSampler, v.UV) * shadowFactor;
}
8 changes: 8 additions & 0 deletions 3DRadSpace/Engine3DRadSpace/Games/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void Game::_initialize()
RequireService(typeid(Rendering::RenderingManager));
RequireService(typeid(ObjectList));
RequireService(typeid(Content::ContentManager));
RequireService(typeid(Objects::CameraProvider));

Internal::RegisterDefaultTypes(Content.get());

Expand Down Expand Up @@ -102,6 +103,13 @@ IService* Game::RequireService(const std::type_index& type)
AddService(Content.get());
return Content.get();
}
if (typeid(CameraProvider) == type)
{
if (Cameras) return Cameras.get();
Cameras = std::make_unique<CameraProvider>(this);
AddService(Cameras.get());
return Cameras.get();
}

return nullptr;
}
Expand Down
9 changes: 4 additions & 5 deletions 3DRadSpace/Engine3DRadSpace/Games/Game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "../Audio/IAudioEngine.hpp"
#include "../Graphics/Rendering/PostProcessCollection.hpp"
#include "../Graphics/Rendering/RenderingManager.hpp"
#include "../Objects/CameraProvider.hpp"
#include "../Core/IGame.hpp"

namespace Engine3DRadSpace
Expand All @@ -38,15 +39,12 @@ namespace Engine3DRadSpace

Game(Game&) = delete;
Game(Game&&) = delete;
Game& operator=(const Game&) = default;
Game& operator=(Game&&) = default;
Game& operator=(const Game&) = delete;
Game& operator=(Game&&) = delete;

std::unique_ptr<Native::Window> Window;
std::unique_ptr<Graphics::IGraphicsDevice> Device;

Math::Matrix4x4 View;
Math::Matrix4x4 Projection;

std::unique_ptr<Content::ContentManager> Content;

std::unique_ptr<Graphics::SpriteBatch> SpriteBatch;
Expand All @@ -62,6 +60,7 @@ namespace Engine3DRadSpace
std::unique_ptr<Graphics::Rendering::PostProcessCollection> PostProcesses;

std::unique_ptr<Objects::ObjectList> Objects;
std::unique_ptr<Objects::CameraProvider> Cameras;

IService* RequireService(const std::type_index& type);

Expand Down
3 changes: 3 additions & 0 deletions 3DRadSpace/Engine3DRadSpace/Objects/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.21)
project("Engine3DRadSpace.Objects")

add_library(3DRadSpace.Objects SHARED
"CameraProvider.hpp"
"CameraProvider.cpp"
"ChildObjectCollection.hpp"
"ChildObjectCollection.cpp"
"Gizmos.hpp"
Expand Down Expand Up @@ -49,5 +51,6 @@ target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Math)
target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Audio)
target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Graphics)
target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Content)
target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Logging)
target_link_libraries(3DRadSpace.Objects PRIVATE 3DRadSpace.Reflection)
target_include_directories(3DRadSpace.Objects PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../)
65 changes: 65 additions & 0 deletions 3DRadSpace/Engine3DRadSpace/Objects/CameraProvider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "CameraProvider.hpp"
#include "ObjectList.hpp"
#include "../Logging/Exception.hpp"

using namespace Engine3DRadSpace;
using namespace Engine3DRadSpace::Objects;

CameraProvider::CameraProvider(IGame* owner) : IService(owner)
{
Refresh();
}

void CameraProvider::Refresh()
{
_cameras.clear();

auto objList = _owner->RequireService<ObjectList>({});
if (objList == nullptr) throw Logging::Exception("CameraProvider requires ObjectList service to be available.");

size_t numCameras = 0;
for (auto& obj : *objList)
{
if (ICamera* cam = dynamic_cast<ICamera*>(obj.Object.get()))
{
_cameras.push_back(cam);

if (numCameras == 0)
{
_mainRTCamera = cam;
}

++numCameras;
}
}
}

void CameraProvider::SetActiveCamera(size_t idx)
{
if (idx >= _cameras.size())
throw Logging::Exception("CameraProvider: Index out of range.");
_mainRTCamera = _cameras[idx];
}

void CameraProvider::SetActiveCamera(ICamera* camera)
{
_mainRTCamera = camera;
}

ICamera* CameraProvider::GetActiveCamera() const noexcept
{
return _mainRTCamera;
}

ICamera* CameraProvider::operator[](size_t idx) const
{
if (idx >= _cameras.size())
throw Logging::Exception("CameraProvider: Index out of range.");
return _cameras[idx];
}

size_t CameraProvider::Count() const noexcept
{
return _cameras.size();
}

53 changes: 53 additions & 0 deletions 3DRadSpace/Engine3DRadSpace/Objects/CameraProvider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once
#include "../Core/IService.hpp"
#include "ICamera.hpp"

namespace Engine3DRadSpace::Objects
{
/// <summary>
/// Stores references to all ICamera instances in the scene.
/// </summary>
class E3DRSP_OBJECTS_EXPORT CameraProvider : public IService
{
std::vector<ICamera*> _cameras;
ICamera* _mainRTCamera = nullptr;
public:
/// <summary>
/// Constructs a new instance.
/// </summary>
/// <param name="owner">Owner</param>
CameraProvider(IGame* owner);

Check warning on line 19 in 3DRadSpace/Engine3DRadSpace/Objects/CameraProvider.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

3DRadSpace/Engine3DRadSpace/Objects/CameraProvider.hpp#L19

Class 'CameraProvider' has a constructor with 1 argument that is not explicit.

/// <summary>
/// Returns the idx-th ICamera instance in the scene.
/// </summary>
/// <param name="idx">index</param>
/// <returns>ICamera pointer.</returns>
ICamera* operator[](size_t idx) const;

/// <summary>
/// Gets an reference to the active camera object.
/// </summary>
/// <returns>Active camera pointer.</returns>
ICamera* GetActiveCamera() const noexcept;
/// <summary>
/// Same as SetActiveCamera(this->operator[](idx)), but with bounds checking.
/// </summary>
/// <param name="idx">index</param>
void SetActiveCamera(size_t idx);
/// <summary>
/// Sets an alternate camera to be used for rendering.
/// </summary>
/// <param name="camera">Must be valid during draw calls</param>
void SetActiveCamera(ICamera* camera);
/// <summary>
/// Should be called when adding/removing cameras into the scene.
/// </summary>
void Refresh();
/// <summary>
/// Returns the number of ICamera instances in the scene.
/// </summary>
/// <returns>Number of ICamera instances.</returns>
size_t Count() const noexcept;
};
}
Loading
Loading