mirror of
https://github.com/lubosz/overte.git
synced 2025-04-16 06:16:18 +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()");
|
||||
// transform by eye offset
|
||||
|
||||
gpu::Transform viewTransform;
|
||||
|
||||
// load the view frustum
|
||||
loadViewFrustum(whichCamera, _displayViewFrustum);
|
||||
|
||||
// flip x if in mirror mode (also requires reversing winding order for backface culling)
|
||||
if (whichCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
glScalef(-1.0f, 1.0f, 1.0f);
|
||||
viewTransform.setScale(gpu::Transform::Vec3(-1.0f, 1.0f, 1.0f));
|
||||
glFrontFace(GL_CW);
|
||||
|
||||
} else {
|
||||
|
@ -2906,7 +2909,9 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
glm::quat eyeOffsetOrient = whichCamera.getEyeOffsetOrientation();
|
||||
glm::vec3 eyeOffsetAxis = glm::axis(eyeOffsetOrient);
|
||||
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
|
||||
// could be myCamera (if in normal mode)
|
||||
|
@ -2915,9 +2920,11 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
glm::quat rotation = whichCamera.getRotation();
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
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
|
||||
updateUntranslatedViewMatrix(-whichCamera.getPosition());
|
||||
viewTransform.preTranslate(-whichCamera.getPosition());
|
||||
|
||||
glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
#include <assert.h>
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include "Transform.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gpu/Stream.h"
|
||||
#include "gpu/Transform.h"
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
@ -49,6 +50,10 @@ enum Primitive {
|
|||
NUM_PRIMITIVES,
|
||||
};
|
||||
|
||||
typedef ::Transform Transform;
|
||||
typedef QSharedPointer<::gpu::Transform> TransformPointer;
|
||||
typedef std::vector< TransformPointer > Transforms;
|
||||
|
||||
class Batch {
|
||||
public:
|
||||
typedef Stream::Slot Slot;
|
||||
|
|
|
@ -476,7 +476,9 @@ void GLBackend::updateTransform() {
|
|||
_transform._lastMode = GL_MODELVIEW;
|
||||
}
|
||||
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]);
|
||||
} else {
|
||||
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());
|
||||
|
||||
gpu::TransformPointer currentView(Application::getInstance()->getViewTransform());
|
||||
currentView->getMatrix();
|
||||
|
||||
gpu::Transform::Mat4 glview = Application::getInstance()->getUntranslatedViewMatrix();
|
||||
|
||||
_transforms[0]->setTranslation(currentView->getTranslation());
|
||||
_transforms[0]->setRotation(currentView->getRotation());
|
||||
_transforms[0]->setScale(currentView->getScale());
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
#include "Transform.h"
|
||||
#include <AABox.h>
|
||||
#include <AnimationCache.h>
|
||||
#include <PhysicsEntity.h>
|
||||
|
@ -38,7 +39,6 @@ typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
|||
|
||||
|
||||
#include "gpu/Stream.h"
|
||||
#include "gpu/Transform.h"
|
||||
#include "gpu/Batch.h"
|
||||
|
||||
/// 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
|
||||
// interface/src/gpu
|
||||
// shared/src/gpu
|
||||
//
|
||||
// Created by Sam Gateau on 11/4/2014.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -12,12 +12,6 @@
|
|||
#define hifi_gpu_Transform_h
|
||||
|
||||
#include <assert.h>
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include "gpu/Format.h"
|
||||
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
@ -26,8 +20,6 @@
|
|||
|
||||
#include <bitset>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class Transform {
|
||||
public:
|
||||
typedef glm::mat4 Mat4;
|
||||
|
@ -113,6 +105,13 @@ public:
|
|||
if ( right.isTranslating()) result.postTranslate(right.getTranslation());
|
||||
if ( right.isRotating()) result.postRotate(right.getRotation());
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -181,10 +180,5 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
typedef QSharedPointer< Transform > TransformPointer;
|
||||
typedef std::vector< TransformPointer > Transforms;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue