mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 23:32:48 +02:00
alternate approach to mirror projection wip
This commit is contained in:
parent
ea38b32dea
commit
6466a05740
2 changed files with 84 additions and 7 deletions
|
@ -14,6 +14,9 @@
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
#include <EntityScriptingInterface.h>
|
#include <EntityScriptingInterface.h>
|
||||||
|
#include <EntityTree.h>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
#include <DebugDraw.h>
|
||||||
|
|
||||||
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
|
using RenderArgsPointer = std::shared_ptr<RenderArgs>;
|
||||||
|
|
||||||
|
@ -48,6 +51,63 @@ public:
|
||||||
_farClipPlaneDistance = config.farClipPlaneDistance;
|
_farClipPlaneDistance = config.farClipPlaneDistance;
|
||||||
_textureWidth = config.textureWidth;
|
_textureWidth = config.textureWidth;
|
||||||
_textureHeight = config.textureHeight;
|
_textureHeight = config.textureHeight;
|
||||||
|
_mirrorProjection = config.mirrorProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMirrorProjection(ViewFrustum& srcViewFrustum) {
|
||||||
|
if (_attachedEntityId.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 mainCamPos = qApp->getCamera().getPosition();
|
||||||
|
|
||||||
|
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_attachedEntityId, _attachedEntityPropertyFlags);
|
||||||
|
glm::vec3 mirrorPropsPos = entityProperties.getPosition();
|
||||||
|
glm::quat mirrorPropsRot = entityProperties.getRotation();
|
||||||
|
glm::vec3 mirrorPropsDim = entityProperties.getDimensions();
|
||||||
|
|
||||||
|
// get mirrored camera's position and rotation reflected about the mirror plane
|
||||||
|
glm::vec3 mirrorLocalPos = mirrorPropsRot * glm::vec3(0.f, 0.f, 0.f);
|
||||||
|
glm::vec3 mirrorWorldPos = mirrorPropsPos + mirrorLocalPos;
|
||||||
|
glm::vec3 mirrorToHeadVec = mainCamPos - mirrorWorldPos;
|
||||||
|
glm::vec3 zLocalVecNormalized = mirrorPropsRot * Vectors::UNIT_Z;
|
||||||
|
float distanceFromMirror = glm::dot(zLocalVecNormalized, mirrorToHeadVec);
|
||||||
|
glm::vec3 eyePos = mainCamPos - (2.f * distanceFromMirror * zLocalVecNormalized);
|
||||||
|
glm::quat eyeOrientation = glm::inverse(glm::lookAt(eyePos, mirrorWorldPos, mirrorPropsRot * Vectors::UP));
|
||||||
|
srcViewFrustum.setPosition(eyePos);
|
||||||
|
srcViewFrustum.setOrientation(eyeOrientation);
|
||||||
|
|
||||||
|
// setup world from mirrored camera transformation matrix
|
||||||
|
glm::mat4 worldFromEyeRot = glm::mat4_cast(eyeOrientation);
|
||||||
|
glm::mat4 worldFromEyeTrans = glm::translate(eyePos);
|
||||||
|
glm::mat4 worldFromEye = worldFromEyeTrans * worldFromEyeRot;
|
||||||
|
|
||||||
|
// setup mirror from world inverse of world from mirror transformation matrices
|
||||||
|
glm::mat4 worldFromMirrorRot = glm::mat4_cast(mirrorPropsRot) * glm::scale(vec3(-1.f, 1.f, -1.f));
|
||||||
|
glm::mat4 worldFromMirrorTrans = glm::translate(mirrorWorldPos);
|
||||||
|
glm::mat4 worldFromMirror = worldFromMirrorTrans * worldFromMirrorRot;
|
||||||
|
glm::mat4 mirrorFromWorld = glm::inverse(worldFromMirror);
|
||||||
|
|
||||||
|
glm::mat4 mirrorFromEye = mirrorFromWorld * worldFromEye;
|
||||||
|
glm::vec4 mirrorCenterPos = vec4(mirrorFromEye[3]);
|
||||||
|
mirrorFromEye[3] = vec4(0.f, 0.f, 0.f, 1.f);
|
||||||
|
|
||||||
|
float n = mirrorCenterPos.z + mirrorPropsDim.z * 2.f;
|
||||||
|
float f = _farClipPlaneDistance;
|
||||||
|
float r = -mirrorCenterPos.x + mirrorPropsDim.x / 2.f;
|
||||||
|
float l = -mirrorCenterPos.x - mirrorPropsDim.x / 2.f;
|
||||||
|
float t = mirrorCenterPos.y + mirrorPropsDim.y / 2.f;
|
||||||
|
float b = mirrorCenterPos.y - mirrorPropsDim.y / 2.f;
|
||||||
|
|
||||||
|
glm::mat4 frustum = glm::frustum(l, r, b, t, n, f);
|
||||||
|
glm::mat4 projection = frustum * mirrorFromEye;
|
||||||
|
srcViewFrustum.setProjection(projection);
|
||||||
|
|
||||||
|
glm::vec3 mirrorCenterPos3World = transformPoint(worldFromMirror, glm::vec3(mirrorCenterPos));
|
||||||
|
qDebug() << "mirrorCenterPos3World " << mirrorCenterPos3World.x << " , " << mirrorCenterPos3World.y << " , " << mirrorCenterPos3World.z;
|
||||||
|
qDebug() << "mirrorWorldPos " << mirrorWorldPos.x << " , " << mirrorWorldPos.y << " , " << mirrorWorldPos.z;
|
||||||
|
DebugDraw::getInstance().drawRay(mirrorCenterPos3World, mirrorCenterPos3World + glm::vec3(0.f, 5.f, 0.f), glm::vec4(0.f, 1.f, 0.f, 1.f)); // green
|
||||||
|
DebugDraw::getInstance().drawRay(mirrorWorldPos, mirrorWorldPos + glm::vec3(0.f, 5.f, 0.f), glm::vec4(1.f, 0.5f, 0.f, 1.f)); // orange
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(const render::RenderContextPointer& renderContext, RenderArgsPointer& cachedArgs) {
|
void run(const render::RenderContextPointer& renderContext, RenderArgsPointer& cachedArgs) {
|
||||||
|
@ -71,20 +131,34 @@ public:
|
||||||
});
|
});
|
||||||
|
|
||||||
auto srcViewFrustum = args->getViewFrustum();
|
auto srcViewFrustum = args->getViewFrustum();
|
||||||
if (!_attachedEntityId.isNull()) {
|
if (_mirrorProjection && !_attachedEntityId.isNull()) {
|
||||||
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_attachedEntityId, _attachedEntityPropertyFlags);
|
setMirrorProjection(srcViewFrustum);
|
||||||
srcViewFrustum.setPosition(entityProperties.getPosition());
|
|
||||||
srcViewFrustum.setOrientation(entityProperties.getRotation());
|
|
||||||
} else {
|
} else {
|
||||||
srcViewFrustum.setPosition(_position);
|
if (!_attachedEntityId.isNull()) {
|
||||||
srcViewFrustum.setOrientation(_orientation);
|
EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_attachedEntityId, _attachedEntityPropertyFlags);
|
||||||
|
srcViewFrustum.setPosition(entityProperties.getPosition());
|
||||||
|
srcViewFrustum.setOrientation(entityProperties.getRotation());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
srcViewFrustum.setPosition(_position);
|
||||||
|
srcViewFrustum.setOrientation(_orientation);
|
||||||
|
}
|
||||||
|
srcViewFrustum.setProjection(glm::perspective(glm::radians(_vFoV), ((float)args->_viewport.z / (float)args->_viewport.w), _nearClipPlaneDistance, _farClipPlaneDistance));
|
||||||
}
|
}
|
||||||
srcViewFrustum.setProjection(glm::perspective(glm::radians(_vFoV), ((float)args->_viewport.z / (float)args->_viewport.w), _nearClipPlaneDistance, _farClipPlaneDistance));
|
|
||||||
// Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera,
|
// Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera,
|
||||||
// which is not what we want here.
|
// which is not what we want here.
|
||||||
srcViewFrustum.calculate();
|
srcViewFrustum.calculate();
|
||||||
args->pushViewFrustum(srcViewFrustum);
|
args->pushViewFrustum(srcViewFrustum);
|
||||||
cachedArgs = _cachedArgsPointer;
|
cachedArgs = _cachedArgsPointer;
|
||||||
|
|
||||||
|
glm::vec3 dirNorm = glm::normalize(srcViewFrustum.getDirection());
|
||||||
|
glm::vec3 nearPos = srcViewFrustum.getPosition() + dirNorm * srcViewFrustum.getNearClip();
|
||||||
|
|
||||||
|
DebugDraw::getInstance().drawRay(srcViewFrustum.getPosition(), srcViewFrustum.getPosition() + dirNorm * srcViewFrustum.getNearClip(), glm::vec4(1.f, 0.f, 0.f, 1.f)); // red
|
||||||
|
DebugDraw::getInstance().drawRay(nearPos, nearPos + srcViewFrustum.getRight(), glm::vec4(0.f, 0.f, 1.f, 1.f)); // blue
|
||||||
|
DebugDraw::getInstance().drawRay(nearPos, nearPos + srcViewFrustum.getUp(), glm::vec4(0.5f, 0.f, 1.f, 1.f)); // purple
|
||||||
|
|
||||||
|
srcViewFrustum.printDebugDetails();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +175,7 @@ private:
|
||||||
float _farClipPlaneDistance;
|
float _farClipPlaneDistance;
|
||||||
int _textureWidth;
|
int _textureWidth;
|
||||||
int _textureHeight;
|
int _textureHeight;
|
||||||
|
bool _mirrorProjection;
|
||||||
EntityPropertyFlags _attachedEntityPropertyFlags;
|
EntityPropertyFlags _attachedEntityPropertyFlags;
|
||||||
QSharedPointer<EntityScriptingInterface> _entityScriptingInterface;
|
QSharedPointer<EntityScriptingInterface> _entityScriptingInterface;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,7 @@ class SecondaryCameraJobConfig : public render::Task::Config { // Exposes second
|
||||||
Q_PROPERTY(float vFoV MEMBER vFoV NOTIFY dirty) // Secondary camera's vertical field of view. In degrees.
|
Q_PROPERTY(float vFoV MEMBER vFoV NOTIFY dirty) // Secondary camera's vertical field of view. In degrees.
|
||||||
Q_PROPERTY(float nearClipPlaneDistance MEMBER nearClipPlaneDistance NOTIFY dirty) // Secondary camera's near clip plane distance. In meters.
|
Q_PROPERTY(float nearClipPlaneDistance MEMBER nearClipPlaneDistance NOTIFY dirty) // Secondary camera's near clip plane distance. In meters.
|
||||||
Q_PROPERTY(float farClipPlaneDistance MEMBER farClipPlaneDistance NOTIFY dirty) // Secondary camera's far clip plane distance. In meters.
|
Q_PROPERTY(float farClipPlaneDistance MEMBER farClipPlaneDistance NOTIFY dirty) // Secondary camera's far clip plane distance. In meters.
|
||||||
|
Q_PROPERTY(bool mirrorProjection MEMBER mirrorProjection NOTIFY dirty) // Flag to apply oblique near-plane clipping using perspective projection from attached mirror entity
|
||||||
public:
|
public:
|
||||||
QUuid attachedEntityId;
|
QUuid attachedEntityId;
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
@ -44,6 +45,7 @@ public:
|
||||||
float farClipPlaneDistance { DEFAULT_FAR_CLIP };
|
float farClipPlaneDistance { DEFAULT_FAR_CLIP };
|
||||||
int textureWidth { TextureCache::DEFAULT_SPECTATOR_CAM_WIDTH };
|
int textureWidth { TextureCache::DEFAULT_SPECTATOR_CAM_WIDTH };
|
||||||
int textureHeight { TextureCache::DEFAULT_SPECTATOR_CAM_HEIGHT };
|
int textureHeight { TextureCache::DEFAULT_SPECTATOR_CAM_HEIGHT };
|
||||||
|
bool mirrorProjection { false };
|
||||||
|
|
||||||
SecondaryCameraJobConfig() : render::Task::Config(false) {}
|
SecondaryCameraJobConfig() : render::Task::Config(false) {}
|
||||||
signals:
|
signals:
|
||||||
|
|
Loading…
Reference in a new issue