From 7e2c4c05615d9300f26a1182e50f444ece003892 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 13 Nov 2014 10:57:32 -0800 Subject: [PATCH] SImplified the Transform usage in the gpu::api, no more pointers, just values. Improved the Transform by compressing the memory footprint --- interface/src/Application.cpp | 10 ++--- interface/src/Application.h | 6 +-- interface/src/gpu/Batch.cpp | 6 +-- interface/src/gpu/Batch.h | 40 ++++++++---------- interface/src/gpu/GLBackend.cpp | 36 ++++++---------- interface/src/gpu/GLBackend.h | 12 +++--- interface/src/renderer/Model.cpp | 17 ++++---- interface/src/renderer/Model.h | 2 +- libraries/shared/src/Transform.h | 70 ++++++++++++++++++++------------ 9 files changed, 101 insertions(+), 98 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c3ab4fe115..f11ac14d40 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -160,7 +160,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), - _viewTransform(new gpu::Transform()), + _viewTransform(), _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), @@ -2911,13 +2911,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation // the viewTransofmr object is updatded with the correct values and saved, // this is what is used for rendering the Entities and avatars - gpu::Transform viewTransform; + Transform viewTransform; viewTransform.setTranslation(whichCamera.getPosition()); viewTransform.setRotation(rotation); viewTransform.postTranslate(eyeOffsetPos); viewTransform.postRotate(eyeOffsetOrient); if (whichCamera.getMode() == CAMERA_MODE_MIRROR) { - viewTransform.setScale(gpu::Transform::Vec3(-1.0f, 1.0f, 1.0f)); + viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f)); } setViewTransform(viewTransform); @@ -3117,8 +3117,8 @@ void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTransl _viewMatrixTranslation = viewMatrixTranslation; } -void Application::setViewTransform(const gpu::Transform& view) { - (*_viewTransform) = view; +void Application::setViewTransform(const Transform& view) { + _viewTransform = view; } void Application::loadTranslatedViewMatrix(const glm::vec3& translation) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 9ce857ee8a..cba39317a5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -232,8 +232,8 @@ public: const glm::vec3& getViewMatrixTranslation() const { return _viewMatrixTranslation; } void setViewMatrixTranslation(const glm::vec3& translation) { _viewMatrixTranslation = translation; } - const gpu::TransformPointer& getViewTransform() const { return _viewTransform; } - void setViewTransform(const gpu::Transform& view); + const Transform& getViewTransform() const { return _viewTransform; } + void setViewTransform(const Transform& view); /// if you need to access the application settings, use lockSettings()/unlockSettings() QSettings* lockSettings() { _settingsMutex.lock(); return _settings; } @@ -526,7 +526,7 @@ private: QRect _mirrorViewRect; RearMirrorTools* _rearMirrorTools; - gpu::TransformPointer _viewTransform; + Transform _viewTransform; glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; glm::mat4 _projectionMatrix; diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index 2bf92f43cf..30e591cc60 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -135,19 +135,19 @@ void Batch::setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset _params.push_back(type); } -void Batch::setModelTransform(const TransformPointer& model) { +void Batch::setModelTransform(const Transform& model) { ADD_COMMAND(setModelTransform); _params.push_back(_transforms.cache(model)); } -void Batch::setViewTransform(const TransformPointer& view) { +void Batch::setViewTransform(const Transform& view) { ADD_COMMAND(setViewTransform); _params.push_back(_transforms.cache(view)); } -void Batch::setProjectionTransform(const TransformPointer& proj) { +void Batch::setProjectionTransform(const Transform& proj) { ADD_COMMAND(setProjectionTransform); _params.push_back(_transforms.cache(proj)); diff --git a/interface/src/gpu/Batch.h b/interface/src/gpu/Batch.h index 3c15fef63b..d006473b50 100644 --- a/interface/src/gpu/Batch.h +++ b/interface/src/gpu/Batch.h @@ -50,10 +50,6 @@ enum Primitive { NUM_PRIMITIVES, }; -typedef ::Transform Transform; -typedef QSharedPointer< ::gpu::Transform > TransformPointer; -typedef std::vector< TransformPointer > Transforms; - class Batch { public: typedef Stream::Slot Slot; @@ -87,9 +83,9 @@ public: // finaly projected into the clip space by the projection transform // WARNING: ViewTransform transform from eye space to world space, its inverse is composed // with the ModelTransformu to create the equivalent of the glModelViewMatrix - void setModelTransform(const TransformPointer& model); - void setViewTransform(const TransformPointer& view); - void setProjectionTransform(const TransformPointer& proj); + void setModelTransform(const Transform& model); + void setViewTransform(const Transform& view); + void setProjectionTransform(const Transform& proj); // TODO: As long as we have gl calls explicitely issued from interface @@ -258,35 +254,35 @@ public: template class Cache { public: - typedef QSharedPointer Pointer; - Pointer _pointer; - Cache(const Pointer& pointer) : _pointer(pointer) {} + typedef T Data; + Data _data; + Cache(const Data& data) : _data(data) {} class Vector { public: - std::vector< Cache > _pointers; + std::vector< Cache > _items; - uint32 cache(const Pointer& pointer) { - uint32 offset = _pointers.size(); - _pointers.push_back(Cache(pointer)); + uint32 cache(const Data& data) { + uint32 offset = _items.size(); + _items.push_back(Cache(data)); return offset; } - Pointer get(uint32 offset) { - if (offset >= _pointers.size()) { - return Pointer(); + Data get(uint32 offset) { + if (offset >= _items.size()) { + return Data(); } - return (_pointers.data() + offset)->_pointer; + return (_items.data() + offset)->_data; } void clear() { - _pointers.clear(); + _items.clear(); } }; }; - - typedef Cache::Vector BufferCaches; - typedef Cache::Vector StreamFormatCaches; + + typedef Cache::Vector BufferCaches; + typedef Cache::Vector StreamFormatCaches; typedef Cache::Vector TransformCaches; typedef unsigned char Byte; diff --git a/interface/src/gpu/GLBackend.cpp b/interface/src/gpu/GLBackend.cpp index 8921dc6d1c..539ac69b8d 100644 --- a/interface/src/gpu/GLBackend.cpp +++ b/interface/src/gpu/GLBackend.cpp @@ -430,30 +430,18 @@ void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) { // Transform Stage void GLBackend::do_setModelTransform(Batch& batch, uint32 paramOffset) { - TransformPointer modelTransform = batch._transforms.get(batch._params[paramOffset]._uint); - - if (_transform._model.isNull() || (modelTransform != _transform._model)) { - _transform._model = modelTransform; - _transform._invalidModel = true; - } + _transform._model = batch._transforms.get(batch._params[paramOffset]._uint); + _transform._invalidModel = true; } void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) { - TransformPointer viewTransform = batch._transforms.get(batch._params[paramOffset]._uint); - - if (_transform._view.isNull() || (viewTransform != _transform._view)) { - _transform._view = viewTransform; - _transform._invalidView = true; - } + _transform._view = batch._transforms.get(batch._params[paramOffset]._uint); + _transform._invalidView = true; } void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) { - TransformPointer projectionTransform = batch._transforms.get(batch._params[paramOffset]._uint); - - if (_transform._projection.isNull() || (projectionTransform != _transform._projection)) { - _transform._projection = projectionTransform; - _transform._invalidProj = true; - } + _transform._projection = batch._transforms.get(batch._params[paramOffset]._uint); + _transform._invalidProj = true; } void GLBackend::updateTransform() { @@ -468,28 +456,28 @@ void GLBackend::updateTransform() { } if (_transform._invalidModel || _transform._invalidView) { - if (!_transform._model.isNull()) { + if (!_transform._model.isIdentity()) { if (_transform._lastMode != GL_MODELVIEW) { glMatrixMode(GL_MODELVIEW); _transform._lastMode = GL_MODELVIEW; } Transform::Mat4 modelView; - if (!_transform._view.isNull()) { + if (!_transform._view.isIdentity()) { Transform mvx; - Transform::inverseMult(mvx, (*_transform._view), (*_transform._model)); + Transform::inverseMult(mvx, _transform._view, _transform._model); mvx.getMatrix(modelView); } else { - _transform._model->getMatrix(modelView); + _transform._model.getMatrix(modelView); } glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView)); } else { - if (!_transform._view.isNull()) { + if (!_transform._view.isIdentity()) { if (_transform._lastMode != GL_MODELVIEW) { glMatrixMode(GL_MODELVIEW); _transform._lastMode = GL_MODELVIEW; } Transform::Mat4 modelView; - _transform._view->getInverseMatrix(modelView); + _transform._view.getInverseMatrix(modelView); glLoadMatrixf(reinterpret_cast< const GLfloat* >(&modelView)); } else { // TODO: eventually do something about the matrix when neither view nor model is specified? diff --git a/interface/src/gpu/GLBackend.h b/interface/src/gpu/GLBackend.h index 0f58ec192d..8524722e75 100644 --- a/interface/src/gpu/GLBackend.h +++ b/interface/src/gpu/GLBackend.h @@ -86,9 +86,9 @@ protected: void updateTransform(); struct TransformStageState { - TransformPointer _model; - TransformPointer _view; - TransformPointer _projection; + Transform _model; + Transform _view; + Transform _projection; bool _invalidModel; bool _invalidView; bool _invalidProj; @@ -96,9 +96,9 @@ protected: GLenum _lastMode; TransformStageState() : - _model(0), - _view(0), - _projection(0), + _model(), + _view(), + _projection(), _invalidModel(true), _invalidView(true), _invalidProj(true), diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8b3c656ae7..8cbcbaa959 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -567,11 +567,11 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { // Capture the view matrix once for the rendering of this model if (_transforms.empty()) { - _transforms.push_back(gpu::TransformPointer(new gpu::Transform())); + _transforms.push_back(Transform()); } - (*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform())); + _transforms[0] = Application::getInstance()->getViewTransform(); // apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space) - _transforms[0]->preTranslate(-_translation); + _transforms[0].preTranslate(-_translation); batch.setViewTransform(_transforms[0]); @@ -1493,10 +1493,10 @@ void Model::setupBatchTransform(gpu::Batch& batch) { // Capture the view matrix once for the rendering of this model if (_transforms.empty()) { - _transforms.push_back(gpu::TransformPointer(new gpu::Transform())); + _transforms.push_back(Transform()); } - (*_transforms[0]) = gpu::Transform((*Application::getInstance()->getViewTransform())); - _transforms[0]->preTranslate(-_translation); + _transforms[0] = Application::getInstance()->getViewTransform(); + _transforms[0].preTranslate(-_translation); batch.setViewTransform(_transforms[0]); } @@ -2149,10 +2149,9 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl if (state.clusterMatrices.size() > 1) { GLBATCH(glUniformMatrix4fv)(skinLocations->clusterMatrices, state.clusterMatrices.size(), false, (const float*)state.clusterMatrices.constData()); - batch.setModelTransform(gpu::TransformPointer()); + batch.setModelTransform(Transform()); } else { - gpu::TransformPointer modelTransform(new gpu::Transform(state.clusterMatrices[0])); - batch.setModelTransform(modelTransform); + batch.setModelTransform(Transform(state.clusterMatrices[0])); } if (mesh.blendshapes.isEmpty()) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 8c74b1a222..e6454a964a 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -283,7 +283,7 @@ private: QUrl _url; gpu::Buffers _blendedVertexBuffers; - gpu::Transforms _transforms; + std::vector _transforms; gpu::Batch _renderBatch; QVector > > _dilatedTextures; diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index 6ad106063f..3c668adcd6 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -20,6 +20,8 @@ #include +#include + class Transform { public: typedef glm::mat4 Mat4; @@ -30,16 +32,16 @@ public: typedef glm::quat Quat; Transform() : - _translation(0), _rotation(1.0f, 0, 0, 0), _scale(1.0f), + _translation(0), _flags(FLAG_CACHE_INVALID_BITSET) // invalid cache { } Transform(const Transform& transform) : - _translation(transform._translation), _rotation(transform._rotation), _scale(transform._scale), + _translation(transform._translation), _flags(transform._flags) { invalidCache(); @@ -49,6 +51,15 @@ public: } ~Transform() {} + Transform& operator=(const Transform& transform) { + _rotation = transform._rotation; + _scale = transform._scale; + _translation = transform._translation; + _flags = transform._flags; + invalidCache(); + return (*this); + } + void setIdentity(); const Vec3& getTranslation() const; @@ -89,7 +100,6 @@ public: // Left will be inversed before the multiplication static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right); - protected: enum Flag { @@ -111,14 +121,15 @@ protected: // TRS - Vec3 _translation; Quat _rotation; Vec3 _scale; + Vec3 _translation; mutable Flags _flags; // Cached transform - mutable Mat4 _matrix; + // TODO: replace this auto ptr by a "unique ptr" as soon as we are compiling in C++11 + mutable std::auto_ptr _matrix; bool isCacheInvalid() const { return _flags[FLAG_CACHE_INVALID]; } void validCache() const { _flags.set(FLAG_CACHE_INVALID, false); } @@ -135,6 +146,7 @@ protected: void flagNonUniform() { _flags.set(FLAG_NON_UNIFORM, true); } void updateCache() const; + Mat4& getCachedMatrix(Mat4& result) const; }; inline void Transform::setIdentity() { @@ -271,8 +283,25 @@ inline void Transform::postScale(const Vec3& scale) { } inline Transform::Mat4& Transform::getMatrix(Transform::Mat4& result) const { - updateCache(); - result = _matrix; + if (isRotating()) { + Mat3 rot = glm::mat3_cast(_rotation); + + if (isScaling()) { + rot[0] *= _scale.x; + rot[1] *= _scale.y; + rot[2] *= _scale.z; + } + + result[0] = Vec4(rot[0], 0.f); + result[1] = Vec4(rot[1], 0.f); + result[2] = Vec4(rot[2], 0.f); + } else { + result[0] = Vec4(_scale.x, 0.f, 0.f, 0.f); + result[1] = Vec4(0.f, _scale.y, 0.f, 0.f); + result[2] = Vec4(0.f, 0.f, _scale.z, 0.f); + } + + result[3] = Vec4(_translation, 1.0f); return result; } @@ -369,27 +398,18 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le return result; } +inline Transform::Mat4& Transform::getCachedMatrix(Transform::Mat4& result) const { + updateCache(); + result = (*_matrix); + return result; +} + inline void Transform::updateCache() const { if (isCacheInvalid()) { - if (isRotating()) { - Mat3 rot = glm::mat3_cast(_rotation); - - if (isScaling()) { - rot[0] *= _scale.x; - rot[1] *= _scale.y; - rot[2] *= _scale.z; - } - - _matrix[0] = Vec4(rot[0], 0.f); - _matrix[1] = Vec4(rot[1], 0.f); - _matrix[2] = Vec4(rot[2], 0.f); - } else { - _matrix[0] = Vec4(_scale.x, 0.f, 0.f, 0.f); - _matrix[1] = Vec4(0.f, _scale.y, 0.f, 0.f); - _matrix[2] = Vec4(0.f, 0.f, _scale.z, 0.f); + if (!_matrix.get()) { + _matrix.reset(new Mat4()); } - - _matrix[3] = Vec4(_translation, 1.0f); + getMatrix((*_matrix)); validCache(); } }