added core changes to dicon viewer branch

This commit is contained in:
2026-03-26 18:51:29 +01:00
parent f50b68c9ba
commit 51a6ea1328
2 changed files with 404 additions and 382 deletions

View File

@@ -1,217 +1,239 @@
#include "Camera.hpp"
#include "elements/Transformable.hpp"
#include "interfaces/IRenderer.hpp"
#include "uuid.h"
TSE::Camera* TSE::Camera::mainCamera = nullptr;
TSE::ICameraHelper* TSE::Camera::helper = nullptr;
float TSE::Camera::GetRenderScale() const
{
return RenderScale;
}
TSE::ProjectionType TSE::Camera::GetProjection() const
{
return projection;
}
float TSE::Camera::GetNearClippingPlane() const
{
return nearClippingPlane;
}
float TSE::Camera::GetFarClippingPlane() const
{
return farClippingPlane;
}
float TSE::Camera::GetFov() const
{
return fov;
}
const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const
{
return lastRtSize;
}
TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos)
{
float x = 2.0f * screenPos.x / lastRtSize.x -1.0f;
float y = 1.0f - 2.0f * screenPos.y / lastRtSize.y;
float z = -1.0f;
Vector4 ndc(x,y,x,1);
Matrix4x4 InversProj = Matrix4x4(*projectionMatrix);
InversProj.Invert();
Vector4 camSpace = InversProj * ndc;
camSpace = camSpace / camSpace.w;
Vector3 relativPos(camSpace);
relativPos.z = 0;
return baseObject->LocalToGlobalPosition(relativPos);
}
void TSE::Camera::SetRenderScale(float v)
{
RenderScale = v; RecalculateProjMatrix();
}
void TSE::Camera::SetProjection(ProjectionType v)
{
projection = v; RecalculateProjMatrix();
}
void TSE::Camera::SetNearClippingPlane(float v)
{
nearClippingPlane = v; RecalculateProjMatrix();
}
void TSE::Camera::SetFarClippingPlane(float v)
{
farClippingPlane = v; RecalculateProjMatrix();
}
void TSE::Camera::SetFov(float v)
{
fov = v; RecalculateProjMatrix();
}
TSE::Camera::Camera()
{
}
TSE::Camera::~Camera()
{
delete(projectionMatrix);
if(mainCamera == this)
mainCamera = nullptr;
}
void TSE::Camera::OnResize(float width, float height, IResizable *wnd)
{
lastRtSize = {width, height};
RecalculateProjMatrix();
}
void TSE::Camera::SetRenderTarget(IRenderTarget *target)
{
if(rt != nullptr)
rt->RemoveResizeNotifiable(this);
if(target != nullptr)
target->AddResizeNotifiable(this);
rt = target;
if(lastRtSize != rt->GetRawIResizableSize())
{
lastRtSize = rt->GetRawIResizableSize();
RecalculateProjMatrix();
}
}
TSE::IRenderTarget *TSE::Camera::GetRenderTarget()
{
return rt;
}
void TSE::Camera::RecalculateProjMatrix()
{
if(projectionMatrix)
delete(projectionMatrix);
if(projection == ProjectionType::Orthographic)
{
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float mx = -x;
float my = -y;
projectionMatrix = new Matrix4x4(Matrix4x4::Orthographic(mx, x, my, y, nearClippingPlane, farClippingPlane));
}
else if(projection == ProjectionType::Perspective)
{
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float aspectRatio = x / y;
projectionMatrix = new Matrix4x4(Matrix4x4::Perspective(fov, aspectRatio, nearClippingPlane, farClippingPlane));
}
}
void TSE::Camera::OnUpdate()
{
if(mainCamera == nullptr && baseObject->name != ".EditorCamera")
{
mainCamera = this;
}
if(rt != nullptr)
IRenderer::camerasToRenderWith.push_back(this);
}
void TSE::Camera::Start()
{
if(mainCamera == nullptr && baseObject->name != ".EditorCamera")
{
mainCamera = this;
}
}
TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world)
{
using namespace TSE;
// Welt-Position (w=1)
Vector3 pos = Vector3(world * Vector4(0,0,0,1));
// Richtungsachsen in Welt (w=0, KEINE Translation!)
Vector3 fwdWS = Vector3(world * Vector4(0,0,1,0)); // +Z vorwärts in Welt
Vector3 upWS = Vector3(world * Vector4(0,1,0,0)); // +Y oben in Welt
// Orthonormale Basis aufbauen (X+ soll "right" sein)
Vector3 f = Vector3::Normalize(fwdWS);
Vector3 r = Vector3::Normalize(Vector3::Cross(upWS, f)); // right = up × forward => (+1,0,0) im Identity-Fall
Vector3 u = Vector3::Cross(f, r); // re-orthonormalisiertes up
Matrix4x4 view(1.0f); // Identität als Basis
// Row-major befüllen (Zeilen = r,u,-f), letzte Spalte = -dot(row, pos) bzw. +dot(f,pos)
view.m[0][0] = r.x; view.m[0][1] = r.y; view.m[0][2] = r.z; view.m[0][3] = -Vector3::Dot(r, pos);
view.m[1][0] = u.x; view.m[1][1] = u.y; view.m[1][2] = u.z; view.m[1][3] = -Vector3::Dot(u, pos);
view.m[2][0] = -f.x; view.m[2][1] = -f.y; view.m[2][2] = -f.z; view.m[2][3] = Vector3::Dot(f, pos);
view.m[3][0] = 0.0f; view.m[3][1] = 0.0f; view.m[3][2] = 0.0f; view.m[3][3] = 1.0f;
return view;
}
void TSE::Camera::PreDraw(IShader *shader)
{
rt->Bind();
shader->SetUniform("prMatrix", projectionMatrix);
auto worlmatrix = baseObject->GetGlobalMatrix();
viewMatrix = BuildView_Zplus_RH(worlmatrix);
shader->SetUniform("camMatrix", &viewMatrix);
helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y);
}
void TSE::Camera::PostDraw()
{
rt->Unbind();
}
void TSE::Camera::Bind()
{
rt->Bind();
}
void TSE::Camera::Unbind()
{
rt->Unbind();
}
void TSE::Camera::UpdateRenderTarget()
{
rt->Update();
}
#include "Camera.hpp"
#include "elements/Transformable.hpp"
#include "interfaces/IRenderer.hpp"
#include "uuid.h"
TSE::Camera* TSE::Camera::mainCamera = nullptr;
TSE::ICameraHelper* TSE::Camera::helper = nullptr;
float TSE::Camera::GetRenderScale() const
{
return RenderScale;
}
TSE::ProjectionType TSE::Camera::GetProjection() const
{
return projection;
}
float TSE::Camera::GetNearClippingPlane() const
{
return nearClippingPlane;
}
float TSE::Camera::GetFarClippingPlane() const
{
return farClippingPlane;
}
float TSE::Camera::GetFov() const
{
return fov;
}
const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const
{
return lastRtSize;
}
TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos)
{
float x = 2.0f * screenPos.x / lastRtSize.x -1.0f;
float y = 1.0f - 2.0f * screenPos.y / lastRtSize.y;
float z = -1.0f;
Vector4 ndc(x,y,x,1);
Matrix4x4 InversProj = Matrix4x4(*projectionMatrix);
InversProj.Invert();
Vector4 camSpace = InversProj * ndc;
camSpace = camSpace / camSpace.w;
Vector3 relativPos(camSpace);
relativPos.z = 0;
return baseObject->LocalToGlobalPosition(relativPos);
}
void TSE::Camera::SetRenderScale(float v)
{
RenderScale = v; RecalculateProjMatrix();
}
void TSE::Camera::SetProjection(ProjectionType v)
{
projection = v; RecalculateProjMatrix();
}
void TSE::Camera::SetNearClippingPlane(float v)
{
nearClippingPlane = v; RecalculateProjMatrix();
}
void TSE::Camera::SetFarClippingPlane(float v)
{
farClippingPlane = v; RecalculateProjMatrix();
}
void TSE::Camera::SetFov(float v)
{
fov = v; RecalculateProjMatrix();
}
TSE::Camera::Camera()
{
}
TSE::Camera::~Camera()
{
delete(projectionMatrix);
if(mainCamera == this)
mainCamera = nullptr;
}
void TSE::Camera::OnResize(float width, float height, IResizable *wnd)
{
lastRtSize = {width, height};
RecalculateProjMatrix();
}
void TSE::Camera::SetRenderTarget(IRenderTarget *target)
{
if(rt != nullptr)
rt->RemoveResizeNotifiable(this);
if(target != nullptr)
target->AddResizeNotifiable(this);
rt = target;
if(lastRtSize != rt->GetRawIResizableSize())
{
lastRtSize = rt->GetRawIResizableSize();
RecalculateProjMatrix();
}
}
TSE::IRenderTarget *TSE::Camera::GetRenderTarget()
{
return rt;
}
void TSE::Camera::RecalculateProjMatrix()
{
if(projectionMatrix)
delete(projectionMatrix);
if(projection == ProjectionType::Orthographic)
{
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float mx = -x;
float my = -y;
projectionMatrix = new Matrix4x4(Matrix4x4::Orthographic(mx, x, my, y, nearClippingPlane, farClippingPlane));
}
else if(projection == ProjectionType::Perspective)
{
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float aspectRatio = x / y;
projectionMatrix = new Matrix4x4(Matrix4x4::Perspective(fov, aspectRatio, nearClippingPlane, farClippingPlane));
}
}
void TSE::Camera::OnUpdate()
{
if(mainCamera == nullptr && baseObject->name != ".EditorCamera")
{
mainCamera = this;
}
if(rt != nullptr)
IRenderer::camerasToRenderWith.push_back(this);
}
void TSE::Camera::Start()
{
if(mainCamera == nullptr && baseObject->name != ".EditorCamera")
{
mainCamera = this;
}
}
TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world)
{
using namespace TSE;
// Welt-Position (w=1)
Vector3 pos = Vector3(world * Vector4(0,0,0,1));
// Richtungsachsen in Welt (w=0, KEINE Translation!)
Vector3 fwdWS = Vector3(world * Vector4(0,0,1,0)); // +Z vorwärts in Welt
Vector3 upWS = Vector3(world * Vector4(0,1,0,0)); // +Y oben in Welt
// Orthonormale Basis aufbauen (X+ soll "right" sein)
Vector3 f = Vector3::Normalize(fwdWS);
Vector3 r = Vector3::Normalize(Vector3::Cross(upWS, f)); // right = up × forward => (+1,0,0) im Identity-Fall
Vector3 u = Vector3::Cross(f, r); // re-orthonormalisiertes up
Matrix4x4 view(1.0f); // Identität als Basis
// Row-major befüllen (Zeilen = r,u,-f), letzte Spalte = -dot(row, pos) bzw. +dot(f,pos)
view.m[0][0] = r.x; view.m[0][1] = r.y; view.m[0][2] = r.z; view.m[0][3] = -Vector3::Dot(r, pos);
view.m[1][0] = u.x; view.m[1][1] = u.y; view.m[1][2] = u.z; view.m[1][3] = -Vector3::Dot(u, pos);
view.m[2][0] = -f.x; view.m[2][1] = -f.y; view.m[2][2] = -f.z; view.m[2][3] = Vector3::Dot(f, pos);
view.m[3][0] = 0.0f; view.m[3][1] = 0.0f; view.m[3][2] = 0.0f; view.m[3][3] = 1.0f;
return view;
}
void TSE::Camera::PreDraw(IShader *shader)
{
rt->Bind();
// shader->SetUniform("prMatrix", projectionMatrix);
// auto worlmatrix = baseObject->GetGlobalMatrix();
// viewMatrix = BuildView_Zplus_RH(worlmatrix);
// shader->SetUniform("camMatrix", &viewMatrix);
// helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y);
Vector3 pos = baseObject->GetGlobalPosition();
Vector3 right = baseObject->LocalToGlobalPosition(Vector3::right) - pos;
Vector3 up = baseObject->LocalToGlobalPosition(Vector3::up) - pos;
Vector3 forward = baseObject->LocalToGlobalPosition(Vector3::forward) - pos;
forward.Normalize();
shader->SetUniform("CamPos", &pos);
shader->SetUniform("CamRight", &right);
shader->SetUniform("CamUp", &up);
shader->SetUniform("CamForward", &forward);
float x = lastRtSize.x / RenderScale;
float y = lastRtSize.y / RenderScale;
float mx = -x;
float my = -y;
shader->SetUniform("OrthoLeft", mx);
shader->SetUniform("OrthoRight", x);
shader->SetUniform("OrthoBottom", my);
shader->SetUniform("OrthoTop", y);
shader->SetUniform("NearPlane", nearClippingPlane);
shader->SetUniform("FarPlane", farClippingPlane);
}
void TSE::Camera::PostDraw()
{
rt->Unbind();
}
void TSE::Camera::Bind()
{
rt->Bind();
}
void TSE::Camera::Unbind()
{
rt->Unbind();
}
void TSE::Camera::UpdateRenderTarget()
{
rt->Update();
}