mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-08 16:48:55 +02:00
move the transform class files to the Shared library, still problem with negative scale composition
This commit is contained in:
parent
7ccb7495c7
commit
ad51416c28
8 changed files with 147 additions and 92 deletions
|
@ -2890,12 +2890,15 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||||
// transform by eye offset
|
// transform by eye offset
|
||||||
|
|
||||||
|
gpu::Transform viewTransform;
|
||||||
|
|
||||||
// load the view frustum
|
// load the view frustum
|
||||||
loadViewFrustum(whichCamera, _displayViewFrustum);
|
loadViewFrustum(whichCamera, _displayViewFrustum);
|
||||||
|
|
||||||
// flip x if in mirror mode (also requires reversing winding order for backface culling)
|
// flip x if in mirror mode (also requires reversing winding order for backface culling)
|
||||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
glScalef(-1.0f, 1.0f, 1.0f);
|
glScalef(-1.0f, 1.0f, 1.0f);
|
||||||
|
viewTransform.setScale(gpu::Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||||
glFrontFace(GL_CW);
|
glFrontFace(GL_CW);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -2906,7 +2909,9 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation();
|
glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation();
|
||||||
glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient);
|
glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient);
|
||||||
glRotatef(-glm::degrees(glm::angle(eyeOffsetOrient)), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z);
|
glRotatef(-glm::degrees(glm::angle(eyeOffsetOrient)), eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z);
|
||||||
glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z);
|
viewTransform.preRotate(glm::quat(-glm::angle(eyeOffsetOrient), glm::vec3(eyeOffsetAxis.x, eyeOffsetAxis.y, eyeOffsetAxis.z)));
|
||||||
|
glTranslatef(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z);
|
||||||
|
viewTransform.preTranslate(glm::vec3(-eyeOffsetPos.x, -eyeOffsetPos.y, -eyeOffsetPos.z));
|
||||||
|
|
||||||
// transform view according to whichCamera
|
// transform view according to whichCamera
|
||||||
// could be myCamera (if in normal mode)
|
// could be myCamera (if in normal mode)
|
||||||
|
@ -2915,9 +2920,11 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
||||||
glm::quat rotation = whichCamera.getRotation();
|
glm::quat rotation = whichCamera.getRotation();
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
viewTransform.preRotate(glm::quat(-glm::angle(rotation), axis));
|
||||||
|
|
||||||
// store view matrix without translation, which we'll use for precision-sensitive objects
|
// store view matrix without translation, which we'll use for precision-sensitive objects
|
||||||
updateUntranslatedViewMatrix(-whichCamera.getPosition());
|
updateUntranslatedViewMatrix(-whichCamera.getPosition());
|
||||||
|
viewTransform.preTranslate(-whichCamera.getPosition());
|
||||||
|
|
||||||
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
#include "Transform.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gpu/Stream.h"
|
#include "gpu/Stream.h"
|
||||||
#include "gpu/Transform.h"
|
|
||||||
|
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
#include "nvToolsExt.h"
|
#include "nvToolsExt.h"
|
||||||
|
@ -49,6 +50,10 @@ enum Primitive {
|
||||||
NUM_PRIMITIVES,
|
NUM_PRIMITIVES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef ::Transform Transform;
|
||||||
|
typedef QSharedPointer<::gpu::Transform> TransformPointer;
|
||||||
|
typedef std::vector< TransformPointer > Transforms;
|
||||||
|
|
||||||
class Batch {
|
class Batch {
|
||||||
public:
|
public:
|
||||||
typedef Stream::Slot Slot;
|
typedef Stream::Slot Slot;
|
||||||
|
|
|
@ -476,7 +476,9 @@ void GLBackend::updateTransform() {
|
||||||
_transform._lastMode = GL_MODELVIEW;
|
_transform._lastMode = GL_MODELVIEW;
|
||||||
}
|
}
|
||||||
if (!_transform._view.isNull()) {
|
if (!_transform._view.isNull()) {
|
||||||
Transform::Mat4 mv = _transform._view->getMatrix() * _transform._model->getMatrix();
|
Transform mvx;
|
||||||
|
Transform::mult(mvx, (*_transform._view), (*_transform._model));
|
||||||
|
Transform::Mat4 mv = mvx.getMatrix();
|
||||||
glLoadMatrixf((const GLfloat*) &mv[0]);
|
glLoadMatrixf((const GLfloat*) &mv[0]);
|
||||||
} else {
|
} else {
|
||||||
glLoadMatrixf((const GLfloat*) &_transform._model->getMatrix());
|
glLoadMatrixf((const GLfloat*) &_transform._model->getMatrix());
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
//
|
|
||||||
// Transform.cpp
|
|
||||||
// interface/src/gpu
|
|
||||||
//
|
|
||||||
// Created by Sam Gateau on 11/4/2014.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "Transform.h"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace gpu;
|
|
||||||
|
|
||||||
Transform::Transform() :
|
|
||||||
_translation(0),
|
|
||||||
_rotation(1.f, 0, 0, 0),
|
|
||||||
_scale(1.f),
|
|
||||||
_flags(1) // invalid cache
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Transform::Transform(const Mat4& raw) {
|
|
||||||
evalFromRawMatrix(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform::Mat4& Transform::evalRelativeTransform( Mat4& result, const Vec3& origin) {
|
|
||||||
updateCache();
|
|
||||||
result = _matrix;
|
|
||||||
result[3] = Vec4(_translation - origin, 1.f);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transform::evalRotationScale(const Mat3& rotationScaleMatrix) {
|
|
||||||
Vec3 scale(glm::length(rotationScaleMatrix[0]), glm::length(rotationScaleMatrix[1]), glm::length(rotationScaleMatrix[2]));
|
|
||||||
if (scale.x < 0.00001f) scale.x = 0.00001f;
|
|
||||||
if (scale.y < 0.00001f) scale.y = 0.00001f;
|
|
||||||
if (scale.z < 0.00001f) scale.z = 0.00001f;
|
|
||||||
|
|
||||||
Mat3 matRotScale(
|
|
||||||
rotationScaleMatrix[0] / scale.x,
|
|
||||||
rotationScaleMatrix[1] / scale.y,
|
|
||||||
rotationScaleMatrix[2] / scale.z);
|
|
||||||
setRotation(glm::quat_cast(matRotScale));
|
|
||||||
|
|
||||||
float determinant = glm::determinant(matRotScale);
|
|
||||||
if (determinant < 0.f) {
|
|
||||||
scale.x = -scale.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
setScale(scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transform::evalFromRawMatrix(const Mat4& matrix) {
|
|
||||||
if ((matrix[0][3] == 0) && (matrix[1][3] == 0) && (matrix[2][3] == 0) && (matrix[3][3] == 1.f)) {
|
|
||||||
setTranslation(Vec3(matrix[3]));
|
|
||||||
|
|
||||||
evalRotationScale(Mat3(matrix));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform& Transform::evalInverseTranspose(Transform& result) {
|
|
||||||
result.setTranslation(-_translation);
|
|
||||||
result.setRotation(-_rotation);
|
|
||||||
|
|
||||||
if (isScaling()) {
|
|
||||||
result.setScale(Vec3(1.f/_scale.x, 1.f/_scale.y, 1.f/_scale.z));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -565,7 +565,10 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
_transforms[0]->evalFromRawMatrix(Application::getInstance()->getUntranslatedViewMatrix());
|
_transforms[0]->evalFromRawMatrix(Application::getInstance()->getUntranslatedViewMatrix());
|
||||||
|
|
||||||
gpu::TransformPointer currentView(Application::getInstance()->getViewTransform());
|
gpu::TransformPointer currentView(Application::getInstance()->getViewTransform());
|
||||||
|
currentView->getMatrix();
|
||||||
|
|
||||||
|
gpu::Transform::Mat4 glview = Application::getInstance()->getUntranslatedViewMatrix();
|
||||||
|
|
||||||
_transforms[0]->setTranslation(currentView->getTranslation());
|
_transforms[0]->setTranslation(currentView->getTranslation());
|
||||||
_transforms[0]->setRotation(currentView->getRotation());
|
_transforms[0]->setRotation(currentView->getRotation());
|
||||||
_transforms[0]->setScale(currentView->getScale());
|
_transforms[0]->setScale(currentView->getScale());
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include "Transform.h"
|
||||||
#include <AABox.h>
|
#include <AABox.h>
|
||||||
#include <AnimationCache.h>
|
#include <AnimationCache.h>
|
||||||
#include <PhysicsEntity.h>
|
#include <PhysicsEntity.h>
|
||||||
|
@ -38,7 +39,6 @@ typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
||||||
|
|
||||||
|
|
||||||
#include "gpu/Stream.h"
|
#include "gpu/Stream.h"
|
||||||
#include "gpu/Transform.h"
|
|
||||||
#include "gpu/Batch.h"
|
#include "gpu/Batch.h"
|
||||||
|
|
||||||
/// A generic 3D model displaying geometry loaded from a URL.
|
/// A generic 3D model displaying geometry loaded from a URL.
|
||||||
|
|
118
libraries/shared/src/Transform.cpp
Normal file
118
libraries/shared/src/Transform.cpp
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
//
|
||||||
|
// Transform.cpp
|
||||||
|
// shared/src/gpu
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 11/4/2014.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Transform.h"
|
||||||
|
|
||||||
|
|
||||||
|
Transform::Transform() :
|
||||||
|
_translation(0),
|
||||||
|
_rotation(1.f, 0, 0, 0),
|
||||||
|
_scale(1.f),
|
||||||
|
_flags(1) // invalid cache
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Transform::Transform(const Mat4& raw) {
|
||||||
|
evalFromRawMatrix(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform::Mat4& Transform::evalRelativeTransform( Mat4& result, const Vec3& origin) {
|
||||||
|
updateCache();
|
||||||
|
result = _matrix;
|
||||||
|
result[3] = Vec4(_translation - origin, 1.f);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transform::evalRotationScale(const Mat3& rotationScaleMatrix) {
|
||||||
|
const float ACCURACY_THREASHOLD = 0.00001f;
|
||||||
|
|
||||||
|
// Extract the rotation component - this is done using polar decompostion, where
|
||||||
|
// we successively average the matrix with its inverse transpose until there is
|
||||||
|
// no/a very small difference between successive averages
|
||||||
|
float norm;
|
||||||
|
int count = 0;
|
||||||
|
Mat3 rotationMat = rotationScaleMatrix;
|
||||||
|
do {
|
||||||
|
Mat3 nextRotation;
|
||||||
|
Mat3 currInvTranspose =
|
||||||
|
glm::inverse(glm::transpose(rotationMat));
|
||||||
|
|
||||||
|
// Go through every component in the matrices and find the next matrix
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j <3; j++) {
|
||||||
|
nextRotation[j][i] = 0.5f *
|
||||||
|
(rotationMat[j][i] + currInvTranspose[j][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
norm = 0.0;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
float n = static_cast<float>(
|
||||||
|
fabs(rotationMat[0][i] - nextRotation[0][i]) +
|
||||||
|
fabs(rotationMat[1][i] - nextRotation[1][i]) +
|
||||||
|
fabs(rotationMat[2][i] - nextRotation[2][i]));
|
||||||
|
norm = (norm > n ? norm : n);
|
||||||
|
}
|
||||||
|
rotationMat = nextRotation;
|
||||||
|
} while (count < 100 && norm > ACCURACY_THREASHOLD);
|
||||||
|
|
||||||
|
|
||||||
|
// extract scale of the matrix as the length of each axis
|
||||||
|
Mat3 scaleMat = glm::inverse(rotationMat) * rotationScaleMatrix;
|
||||||
|
|
||||||
|
Vec3 scale2(glm::length(rotationScaleMatrix[0]), glm::length(rotationScaleMatrix[1]), glm::length(rotationScaleMatrix[2]));
|
||||||
|
Vec3 scale(scaleMat[0][0], scaleMat[1][1], scaleMat[2][2]);
|
||||||
|
if (scale.x < ACCURACY_THREASHOLD) scale.x = ACCURACY_THREASHOLD;
|
||||||
|
if (scale.y < ACCURACY_THREASHOLD) scale.y = ACCURACY_THREASHOLD;
|
||||||
|
if (scale.z < ACCURACY_THREASHOLD) scale.z = ACCURACY_THREASHOLD;
|
||||||
|
|
||||||
|
|
||||||
|
// Let's work on a local matrix containing rotation only
|
||||||
|
Mat3 matRot(
|
||||||
|
rotationScaleMatrix[0] / scale.x,
|
||||||
|
rotationScaleMatrix[1] / scale.y,
|
||||||
|
rotationScaleMatrix[2] / scale.z);
|
||||||
|
|
||||||
|
// Beware!!! needs to detect for the case there is a negative scale
|
||||||
|
// Based on the determinant sign we just can flip the scale sign of one component: we choose X axis
|
||||||
|
float determinant = glm::determinant(matRot);
|
||||||
|
if (determinant < 0.f) {
|
||||||
|
scale.x = -scale.x;
|
||||||
|
// matRot[0] *= -1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beware: even though the matRot is supposed to be normalized at that point,
|
||||||
|
// glm::quat_cast doesn't always return a normalized quaternion...
|
||||||
|
setRotation(glm::normalize(glm::quat_cast(matRot)));
|
||||||
|
|
||||||
|
// and assign the scale
|
||||||
|
setScale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transform::evalFromRawMatrix(const Mat4& matrix) {
|
||||||
|
// for now works only in the case of TRS transformation
|
||||||
|
if ((matrix[0][3] == 0) && (matrix[1][3] == 0) && (matrix[2][3] == 0) && (matrix[3][3] == 1.f)) {
|
||||||
|
setTranslation(Vec3(matrix[3]));
|
||||||
|
evalRotationScale(Mat3(matrix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform& Transform::evalInverseTranspose(Transform& result) {
|
||||||
|
result.setTranslation(-_translation);
|
||||||
|
result.setRotation(-_rotation);
|
||||||
|
|
||||||
|
if (isScaling()) {
|
||||||
|
result.setScale(Vec3(1.f/_scale.x, 1.f/_scale.y, 1.f/_scale.z));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// Transform.h
|
// Transform.h
|
||||||
// interface/src/gpu
|
// shared/src/gpu
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 11/4/2014.
|
// Created by Sam Gateau on 11/4/2014.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
@ -12,12 +12,6 @@
|
||||||
#define hifi_gpu_Transform_h
|
#define hifi_gpu_Transform_h
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "InterfaceConfig.h"
|
|
||||||
|
|
||||||
#include "gpu/Format.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <QSharedPointer>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
@ -26,8 +20,6 @@
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
namespace gpu {
|
|
||||||
|
|
||||||
class Transform {
|
class Transform {
|
||||||
public:
|
public:
|
||||||
typedef glm::mat4 Mat4;
|
typedef glm::mat4 Mat4;
|
||||||
|
@ -113,6 +105,13 @@ public:
|
||||||
if ( right.isTranslating()) result.postTranslate(right.getTranslation());
|
if ( right.isTranslating()) result.postTranslate(right.getTranslation());
|
||||||
if ( right.isRotating()) result.postRotate(right.getRotation());
|
if ( right.isRotating()) result.postRotate(right.getRotation());
|
||||||
if (right.isScaling()) result.postScale(right.getScale());
|
if (right.isScaling()) result.postScale(right.getScale());
|
||||||
|
|
||||||
|
Transform::Mat4 mv = left.getMatrix() * right.getMatrix();
|
||||||
|
Transform::Mat4 mv2 = result.getMatrix();
|
||||||
|
|
||||||
|
result.evalFromRawMatrix(mv);
|
||||||
|
Transform::Mat4 mv3 = result.getMatrix();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,10 +180,5 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QSharedPointer< Transform > TransformPointer;
|
|
||||||
typedef std::vector< TransformPointer > Transforms;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue