diff --git a/engine/includes/pipelinetasks/shadowmap.h b/engine/includes/pipelinetasks/shadowmap.h index 67a1237ea..91007fd9f 100644 --- a/engine/includes/pipelinetasks/shadowmap.h +++ b/engine/includes/pipelinetasks/shadowmap.h @@ -26,7 +26,7 @@ class ShadowMap : public PipelineTask { void exec(PipelineContext *context) override; void areaLightUpdate(PipelineContext *context, AreaLight *light, list &components); - void directLightUpdate(PipelineContext *context, DirectLight *light, list &components, Camera &camera); + void directLightUpdate(PipelineContext *context, DirectLight *light, list &components, const Camera &camera); void pointLightUpdate(PipelineContext *context, PointLight *light, list &components); void spotLightUpdate(PipelineContext *context, SpotLight *light, list &components); diff --git a/engine/src/pipelinetasks/shadowmap.cpp b/engine/src/pipelinetasks/shadowmap.cpp index 063944509..fcd143427 100644 --- a/engine/src/pipelinetasks/shadowmap.cpp +++ b/engine/src/pipelinetasks/shadowmap.cpp @@ -104,7 +104,7 @@ void ShadowMap::areaLightUpdate(PipelineContext *context, AreaLight *light, list buffer->setRenderTarget(shadowTarget); for(int32_t i = 0; i < m_directions.size(); i++) { - Matrix4 mat = (wp * Matrix4(m_directions[i].toMatrix())).inverse(); + Matrix4 mat((wp * Matrix4(m_directions[i].toMatrix())).inverse()); matrix[i] = m_scale * crop * mat; tiles[i] = Vector4(static_cast(x[i]) / pageSize, @@ -142,7 +142,7 @@ void ShadowMap::areaLightUpdate(PipelineContext *context, AreaLight *light, list } } -void ShadowMap::directLightUpdate(PipelineContext *context, DirectLight *light, list &components, Camera &camera) { +void ShadowMap::directLightUpdate(PipelineContext *context, DirectLight *light, list &components, const Camera &camera) { CommandBuffer *buffer = context->buffer(); Vector4 distance; @@ -166,12 +166,12 @@ void ShadowMap::directLightUpdate(PipelineContext *context, DirectLight *light, } Transform *lightTransform = light->transform(); - Quaternion q = lightTransform->worldQuaternion(); - Matrix4 rot = Matrix4(q.toMatrix()).inverse(); + Quaternion lightRot = lightTransform->worldQuaternion(); + Matrix4 rot = Matrix4(lightRot.toMatrix()).inverse(); Transform *cameraTransform = camera.transform(); - Vector3 wPosition = cameraTransform->worldPosition(); - Quaternion wRotation = cameraTransform->worldQuaternion(); + Vector3 cameraPos = cameraTransform->worldPosition(); + Quaternion cameraRot = cameraTransform->worldQuaternion(); bool orthographic = camera.orthographic(); float sigma = (camera.orthographic()) ? camera.orthoSize() : camera.fov(); @@ -188,26 +188,26 @@ void ShadowMap::directLightUpdate(PipelineContext *context, DirectLight *light, buffer->setRenderTarget(shadowTarget); for(int32_t lod = 0; lod < MAX_LODS; lod++) { float dist = distance[lod]; - auto points = Camera::frustumCorners(orthographic, sigma, ratio, wPosition, wRotation, nearPlane, dist); + auto points = Camera::frustumCorners(orthographic, sigma, ratio, cameraPos, cameraRot, nearPlane, dist); nearPlane = dist; AABBox box; box.setBox(points.data(), 8); - box *= rot; + box *= rot.rotation(); AABBox bb; - auto corners = Camera::frustumCorners(true, box.extent.y * 2.0f, 1.0f, box.center, q, -FLT_MAX, FLT_MAX); - RenderList filter = context->frustumCulling(corners, components, bb); + auto corners = Camera::frustumCorners(true, box.extent.y * 2.0f, 1.0f, box.center, lightRot, -FLT_MAX, FLT_MAX); + RenderList filter(context->frustumCulling(corners, components, bb)); float radius = MAX(box.radius, bb.radius); Matrix4 m; - m.translate(-box.center - q * Vector3(0.0f, 0.0f, radius)); - Matrix4 view = rot * m; - Matrix4 crop = Matrix4::ortho(-box.extent.x, box.extent.x, - -box.extent.y, box.extent.y, - 0.0f, radius * 2.0f); + m.translate(-box.center - lightRot * Vector3(0.0f, 0.0f, radius)); + Matrix4 view(rot * m); + Matrix4 crop(Matrix4::ortho(-box.extent.x, box.extent.x, + -box.extent.y, box.extent.y, + 0.0f, radius * 2.0f)); uint32_t pageSize = Texture::maxTextureSize(); @@ -233,7 +233,7 @@ void ShadowMap::directLightUpdate(PipelineContext *context, DirectLight *light, auto instance = light->material(); if(instance) { - Vector3 direction(q * Vector3(0.0f, 0.0f, 1.0f)); + Vector3 direction(lightRot * Vector3(0.0f, 0.0f, 1.0f)); Vector4 bias(m_bias); float shadows = light->castShadows() ? 1.0f : 0.0; @@ -275,7 +275,7 @@ void ShadowMap::pointLightUpdate(PipelineContext *context, PointLight *light, li buffer->setRenderTarget(shadowTarget); for(int32_t i = 0; i < m_directions.size(); i++) { - Matrix4 mat = (wp * Matrix4(m_directions[i].toMatrix())).inverse(); + Matrix4 mat((wp * Matrix4(m_directions[i].toMatrix())).inverse()); matrix[i] = m_scale * crop * mat; tiles[i] = Vector4(static_cast(x[i]) / pageSize, @@ -329,15 +329,18 @@ void ShadowMap::spotLightUpdate(PipelineContext *context, SpotLight *light, list float zFar = light->attenuationDistance(); Matrix4 crop = Matrix4::perspective(light->outerAngle() * 2.0f, 1.0f, zNear, zFar); - int32_t x, y, w, h; + int32_t x = 0; + int32_t y = 0; + int32_t w = 0; + int32_t h = 0; RenderTarget *shadowTarget = requestShadowTiles(light->uuid(), 1, &x, &y, &w, &h, 1); uint32_t pageSize = Texture::maxTextureSize(); - Matrix4 matrix = m_scale * crop * rot; - Vector4 tiles = Vector4(static_cast(x) / pageSize, - static_cast(y) / pageSize, - static_cast(w) / pageSize, - static_cast(h) / pageSize); + Matrix4 matrix(m_scale * crop * rot); + Vector4 tiles(static_cast(x) / pageSize, + static_cast(y) / pageSize, + static_cast(w) / pageSize, + static_cast(h) / pageSize); buffer->setRenderTarget(shadowTarget); buffer->enableScissor(x, y, w, h); diff --git a/thirdparty/next/inc/math/aabb.h b/thirdparty/next/inc/math/aabb.h index de6f2bb44..561341ca4 100644 --- a/thirdparty/next/inc/math/aabb.h +++ b/thirdparty/next/inc/math/aabb.h @@ -25,6 +25,7 @@ #include "vector3.h" #include "plane.h" +class Matrix3; class Matrix4; class NEXT_LIBRARY_EXPORT AABBox { @@ -39,8 +40,10 @@ class NEXT_LIBRARY_EXPORT AABBox { const AABBox operator*(areal factor) const; const AABBox operator*(const Vector3 &vector) const; + const AABBox operator*(const Matrix3 &matrix) const; const AABBox operator*(const Matrix4 &matrix) const; + AABBox &operator*=(const Matrix3 &matrix); AABBox &operator*=(const Matrix4 &matrix); void encapsulate(const Vector3 &position, areal radius = 0.0f); diff --git a/thirdparty/next/src/math/aabb.cpp b/thirdparty/next/src/math/aabb.cpp index bd5a3f5b2..de140dbb1 100644 --- a/thirdparty/next/src/math/aabb.cpp +++ b/thirdparty/next/src/math/aabb.cpp @@ -152,32 +152,45 @@ const AABBox AABBox::operator*(const Vector3 &vector) const { return AABBox(center * vector, extent * vector); } /*! - Returns a copy of this box, multiplied by the given \a matrix. + Returns a copy of this box, multiplied by the given rotation \a matrix. */ -const AABBox AABBox::operator*(const Matrix4 &matrix) const { +const AABBox AABBox::operator*(const Matrix3 &matrix) const { AABBox result; - Vector3 min = -extent; - Vector3 max = extent; - - Matrix3 rot = matrix.rotation(); Vector3 rotPoints[4] = { - (rot * Vector3(min.x, max.y, min.z)).abs(), - (rot * Vector3(min.x, max.y, max.z)).abs(), - (rot * Vector3(max.x, max.y, max.z)).abs(), - (rot * Vector3(max.x, max.y, min.z)).abs() + (matrix * Vector3(-extent.x, extent.y, -extent.z)).abs(), + (matrix * Vector3(-extent.x, extent.y, extent.z)).abs(), + (matrix * Vector3( extent.x, extent.y, extent.z)).abs(), + (matrix * Vector3( extent.x, extent.y, -extent.z)).abs() }; - result.center = matrix * center; + result.center = center; result.extent = Vector3(MAX(rotPoints[0].x, MAX(rotPoints[1].x, MAX(rotPoints[2].x, rotPoints[3].x))), MAX(rotPoints[0].y, MAX(rotPoints[1].y, MAX(rotPoints[2].y, rotPoints[3].y))), MAX(rotPoints[0].z, MAX(rotPoints[1].z, MAX(rotPoints[2].z, rotPoints[3].z)))); + result.radius = result.extent.length(); return result; } /*! - Multiplies this box by the given \a matrix, and returns a reference to this vector. + Returns a copy of this box, multiplied by the given transform \a matrix. +*/ +const AABBox AABBox::operator*(const Matrix4 &matrix) const { + AABBox result = *this * matrix.rotation(); + + result.center = matrix * center; + + return result; +} +/*! + Multiplies this box by the given rotation \a matrix, and returns a reference to this vector. +*/ +AABBox &AABBox::operator*=(const Matrix3 &matrix) { + return *this = *this * matrix; +} +/*! + Multiplies this box by the given transform \a matrix, and returns a reference to this vector. */ AABBox &AABBox::operator*=(const Matrix4 &matrix) { return *this = *this * matrix;