mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 18:23:22 +02:00
Merge branch 'team-teaching' of https://github.com/highfidelity/hifi into punk
This commit is contained in:
commit
a28c99bb40
14 changed files with 145 additions and 119 deletions
|
@ -392,7 +392,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
// emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background
|
||||
// downloads.
|
||||
QSharedPointer<GeometryCache> geometryCacheP = DependencyManager::get<GeometryCache>();
|
||||
ResourceCache *geometryCache = geometryCacheP.data();
|
||||
ResourceCache* geometryCache = geometryCacheP.data();
|
||||
connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets);
|
||||
|
||||
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
|
||||
|
@ -3292,7 +3292,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
gpu::Batch batch;
|
||||
model::Skybox::render(batch, _viewFrustum, *skybox);
|
||||
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
gpu::GLBackend::renderBatch(batch, true);
|
||||
glUseProgram(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,8 +126,7 @@ void Cube3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
} else {
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
// FIXME Remove non Batch version of renderWireCube once we use the render pipeline
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f, cubeColor);
|
||||
DependencyManager::get<GeometryCache>()->renderWireCube(1.0f, cubeColor);
|
||||
}
|
||||
}
|
||||
glPopMatrix();
|
||||
|
|
|
@ -510,7 +510,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
_tree->unlock();
|
||||
|
||||
glPushMatrix();
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
gpu::GLBackend::renderBatch(batch, true);
|
||||
glPopMatrix();
|
||||
|
||||
// stats...
|
||||
|
|
|
@ -51,9 +51,9 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
|
|||
|
||||
// TODO: Determine if we want these entities to have the deferred lighting effect? I think we do, so that the color
|
||||
// used for a sphere, or box have the same look as those used on a text entity.
|
||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram();
|
||||
//DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram();
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, glm::vec4(toGlm(getBackgroundColorX()), alpha));
|
||||
DependencyManager::get<DeferredLightingEffect>()->releaseSimpleProgram();
|
||||
//DependencyManager::get<DeferredLightingEffect>()->releaseSimpleProgram();
|
||||
|
||||
glTranslatef(-(halfDimensions.x - leftMargin), halfDimensions.y - topMargin, 0.0f);
|
||||
glm::vec4 textColor(toGlm(getTextColorX()), alpha);
|
||||
|
|
|
@ -76,12 +76,10 @@ GLBackend::GLBackend() :
|
|||
_output()
|
||||
{
|
||||
initTransform();
|
||||
initInput();
|
||||
}
|
||||
|
||||
GLBackend::~GLBackend() {
|
||||
killTransform();
|
||||
killInput();
|
||||
}
|
||||
|
||||
void GLBackend::render(Batch& batch) {
|
||||
|
@ -98,8 +96,11 @@ void GLBackend::render(Batch& batch) {
|
|||
}
|
||||
}
|
||||
|
||||
void GLBackend::renderBatch(Batch& batch) {
|
||||
void GLBackend::renderBatch(Batch& batch, bool syncCache) {
|
||||
GLBackend backend;
|
||||
if (syncCache) {
|
||||
backend.syncCache();
|
||||
}
|
||||
backend.render(batch);
|
||||
}
|
||||
|
||||
|
@ -136,6 +137,13 @@ bool GLBackend::checkGLError(const char* name) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::syncCache() {
|
||||
syncTransformStateCache();
|
||||
syncPipelineStateCache();
|
||||
syncInputStateCache();
|
||||
}
|
||||
|
||||
void GLBackend::do_draw(Batch& batch, uint32 paramOffset) {
|
||||
updateInput();
|
||||
updateTransform();
|
||||
|
@ -549,4 +557,3 @@ void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,12 +24,20 @@ namespace gpu {
|
|||
class GLBackend : public Backend {
|
||||
public:
|
||||
|
||||
explicit GLBackend(bool syncCache);
|
||||
GLBackend();
|
||||
~GLBackend();
|
||||
|
||||
void render(Batch& batch);
|
||||
|
||||
static void renderBatch(Batch& batch);
|
||||
// Render Batch create a local Context and execute the batch with it
|
||||
// WARNING:
|
||||
// if syncCache is true, then the gpu::GLBackend will synchornize
|
||||
// its cache with the current gl state and it's BAD
|
||||
// If you know you don't rely on any state changed by naked gl calls then
|
||||
// leave to false where it belongs
|
||||
// if true, the needed resync IS EXPENSIVE
|
||||
static void renderBatch(Batch& batch, bool syncCache = false);
|
||||
|
||||
static bool checkGLError(const char* name = nullptr);
|
||||
|
||||
|
@ -79,6 +87,7 @@ public:
|
|||
static GLShader* syncGPUObject(const Shader& shader);
|
||||
static GLuint getShaderID(const ShaderPointer& shader);
|
||||
|
||||
// FIXME: Please remove these 2 calls once the text renderer doesn't use naked gl calls anymore
|
||||
static void loadMatrix(GLenum target, const glm::mat4 & m);
|
||||
static void fetchMatrix(GLenum target, glm::mat4 & m);
|
||||
|
||||
|
@ -186,6 +195,12 @@ public:
|
|||
|
||||
void do_setStateColorWriteMask(uint32 mask);
|
||||
|
||||
// This call synchronize the Full Backend cache with the current GLState
|
||||
// THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync
|
||||
// the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls
|
||||
// Let's try to avoid to do that as much as possible!
|
||||
void syncCache();
|
||||
|
||||
protected:
|
||||
|
||||
// Draw Stage
|
||||
|
@ -201,8 +216,8 @@ protected:
|
|||
void do_setInputBuffer(Batch& batch, uint32 paramOffset);
|
||||
void do_setIndexBuffer(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void initInput();
|
||||
void killInput();
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void syncInputStateCache();
|
||||
void updateInput();
|
||||
struct InputStageState {
|
||||
bool _invalidFormat;
|
||||
|
@ -243,6 +258,8 @@ protected:
|
|||
|
||||
void initTransform();
|
||||
void killTransform();
|
||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||
void syncTransformStateCache();
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
|
@ -299,7 +316,6 @@ protected:
|
|||
|
||||
GLState* _state;
|
||||
bool _invalidState = false;
|
||||
bool _needStateSync = true;
|
||||
|
||||
PipelineStageState() :
|
||||
_pipeline(),
|
||||
|
@ -308,8 +324,7 @@ protected:
|
|||
_stateCache(State::DEFAULT),
|
||||
_stateSignatureCache(0),
|
||||
_state(nullptr),
|
||||
_invalidState(false),
|
||||
_needStateSync(true)
|
||||
_invalidState(false)
|
||||
{}
|
||||
} _pipeline;
|
||||
|
||||
|
|
|
@ -46,24 +46,12 @@ static const GLenum attributeSlotToClassicAttribName[NUM_CLASSIC_ATTRIBS] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
void GLBackend::initInput() {
|
||||
glPushClientAttrib(GL_VERTEX_ARRAY);
|
||||
glPushClientAttrib(GL_NORMAL_ARRAY);
|
||||
glPushClientAttrib(GL_COLOR_ARRAY);
|
||||
glPushClientAttrib(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
void GLBackend::syncInputStateCache() {
|
||||
for (int i = 0; i < NUM_CLASSIC_ATTRIBS; i++) {
|
||||
_input._attributeActivation[i] = glIsEnabled(attributeSlotToClassicAttribName[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::killInput() {
|
||||
glPopClientAttrib(); // GL_VERTEX_ARRAY
|
||||
glPopClientAttrib(); // GL_NORMAL_ARRAY
|
||||
glPopClientAttrib(); // GL_COLOR_ARRAY
|
||||
glPopClientAttrib(); // GL_TEXTURE_COORD_ARRAY
|
||||
}
|
||||
|
||||
void GLBackend::updateInput() {
|
||||
if (_input._invalidFormat || _input._buffersState.any()) {
|
||||
|
||||
|
@ -164,9 +152,6 @@ void GLBackend::updateInput() {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
// everything format related should be in sync now
|
||||
_input._invalidFormat = false;
|
||||
|
|
|
@ -63,11 +63,6 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
|||
if (_pipeline._pipeline == pipeline) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pipeline._needStateSync) {
|
||||
syncPipelineStateCache();
|
||||
_pipeline._needStateSync = false;
|
||||
}
|
||||
|
||||
// null pipeline == reset
|
||||
if (!pipeline) {
|
||||
|
@ -108,17 +103,7 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) {
|
|||
}
|
||||
}
|
||||
|
||||
#define DEBUG_GLSTATE
|
||||
void GLBackend::updatePipeline() {
|
||||
#ifdef DEBUG_GLSTATE
|
||||
if (_pipeline._needStateSync) {
|
||||
State::Data state;
|
||||
getCurrentGLState(state);
|
||||
State::Signature signature = State::evalSignature(state);
|
||||
(void) signature; // quiet compiler
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_pipeline._invalidProgram) {
|
||||
// doing it here is aproblem for calls to glUniform.... so will do it on assing...
|
||||
glUseProgram(_pipeline._program);
|
||||
|
|
|
@ -55,6 +55,25 @@ void GLBackend::killTransform() {
|
|||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::syncTransformStateCache() {
|
||||
_transform._invalidProj = true;
|
||||
_transform._invalidView = true;
|
||||
_transform._invalidModel = true;
|
||||
|
||||
GLint currentMode;
|
||||
glGetIntegerv(GL_MATRIX_MODE, ¤tMode);
|
||||
_transform._lastMode = currentMode;
|
||||
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, (float*) &_transform._projection);
|
||||
|
||||
Mat4 modelView;
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, (float*) &modelView);
|
||||
auto modelViewInv = glm::inverse(modelView);
|
||||
_transform._view.evalFromRawMatrix(modelViewInv);
|
||||
_transform._model.setIdentity();
|
||||
}
|
||||
|
||||
void GLBackend::updateTransform() {
|
||||
// Check all the dirty flags and update the state accordingly
|
||||
if (_transform._invalidProj) {
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
@ -48,16 +47,26 @@
|
|||
#include "point_light_frag.h"
|
||||
#include "spot_light_frag.h"
|
||||
|
||||
static const std::string glowIntensityShaderHandle = "glowIntensity";
|
||||
|
||||
void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
||||
auto vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert)));
|
||||
auto pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_frag)));
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(glowIntensityShaderHandle, 0));
|
||||
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setCullMode(gpu::State::CULL_BACK);
|
||||
state->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(false,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_simpleProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
|
||||
_viewState = viewState;
|
||||
_simpleProgram.addShaderFromSourceCode(QGLShader::Vertex, simple_vert);
|
||||
_simpleProgram.addShaderFromSourceCode(QGLShader::Fragment, simple_frag);
|
||||
_simpleProgram.link();
|
||||
|
||||
_simpleProgram.bind();
|
||||
_glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity");
|
||||
_simpleProgram.release();
|
||||
|
||||
loadLightProgram(directional_light_frag, false, _directionalLight, _directionalLightLocations);
|
||||
loadLightProgram(directional_light_shadow_map_frag, false, _directionalLightShadowMap,
|
||||
_directionalLightShadowMapLocations);
|
||||
|
@ -92,29 +101,12 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
|
|||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram() {
|
||||
DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(true, true, true);
|
||||
_simpleProgram.bind();
|
||||
_simpleProgram.setUniformValue(_glowIntensityLocation, DependencyManager::get<GlowEffect>()->getIntensity());
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch) {
|
||||
DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(batch, true, true, true);
|
||||
batch._glUseProgram(_simpleProgram.programId());
|
||||
batch._glUniform1f(_glowIntensityLocation, DependencyManager::get<GlowEffect>()->getIntensity());
|
||||
batch._glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::releaseSimpleProgram() {
|
||||
glEnable(GL_BLEND);
|
||||
_simpleProgram.release();
|
||||
DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(true, false, false);
|
||||
batch.setPipeline(_simpleProgram);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::releaseSimpleProgram(gpu::Batch& batch) {
|
||||
batch._glEnable(GL_BLEND);
|
||||
batch._glUseProgram(0);
|
||||
DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(batch, true, false, false);
|
||||
}
|
||||
|
||||
|
@ -136,12 +128,6 @@ void DeferredLightingEffect::renderSolidCube(gpu::Batch& batch, float size, cons
|
|||
releaseSimpleProgram(batch);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderWireCube(float size, const glm::vec4& color) {
|
||||
gpu::Batch batch;
|
||||
renderWireCube(batch, size, color);
|
||||
gpu::GLBackend::renderBatch(batch);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) {
|
||||
bindSimpleProgram(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderWireCube(batch, size, color);
|
||||
|
|
|
@ -33,15 +33,10 @@ public:
|
|||
|
||||
void init(AbstractViewStateInterface* viewState);
|
||||
|
||||
/// Returns a reference to a simple program suitable for rendering static untextured geometry
|
||||
ProgramObject& getSimpleProgram() { return _simpleProgram; }
|
||||
|
||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||
void bindSimpleProgram();
|
||||
void bindSimpleProgram(gpu::Batch& batch);
|
||||
|
||||
/// Tears down the state necessary to render static untextured geometry with the simple program.
|
||||
void releaseSimpleProgram();
|
||||
void releaseSimpleProgram(gpu::Batch& batch);
|
||||
|
||||
//// Renders a solid sphere with the simple program.
|
||||
|
@ -54,8 +49,6 @@ public:
|
|||
void renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color);
|
||||
|
||||
//// Renders a wireframe cube with the simple program.
|
||||
// FIXME Remove non Batch version once Cube3DOverlay uses the render pipeline
|
||||
void renderWireCube(float size, const glm::vec4& color);
|
||||
void renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color);
|
||||
|
||||
//// Renders a quad with the simple program.
|
||||
|
@ -105,10 +98,9 @@ private:
|
|||
};
|
||||
|
||||
static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations);
|
||||
|
||||
ProgramObject _simpleProgram;
|
||||
int _glowIntensityLocation;
|
||||
|
||||
gpu::PipelinePointer _simpleProgram;
|
||||
|
||||
ProgramObject _directionalSkyboxLight;
|
||||
LightLocations _directionalSkyboxLightLocations;
|
||||
ProgramObject _directionalSkyboxLightShadowMap;
|
||||
|
|
|
@ -946,8 +946,8 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
glPushMatrix();
|
||||
#endif
|
||||
|
||||
::gpu::GLBackend::renderBatch(batch);
|
||||
|
||||
::gpu::GLBackend::renderBatch(batch, true); // force sync with gl state here
|
||||
|
||||
#if defined(ANDROID)
|
||||
#else
|
||||
glPopMatrix();
|
||||
|
@ -1859,6 +1859,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
}
|
||||
|
||||
gpu::GLBackend backend;
|
||||
backend.syncCache(); // force sync with gl state here
|
||||
|
||||
if (args) {
|
||||
glm::mat4 proj;
|
||||
|
|
|
@ -12,16 +12,22 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal for interpolation
|
||||
interpolatedNormal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
||||
|
||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||
}
|
|
@ -22,6 +22,18 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
inline bool isValidScale(glm::vec3 scale) {
|
||||
bool result = scale.x != 0.0f && scale.y != 0.0f && scale.z != 0.0f;
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool isValidScale(float scale) {
|
||||
bool result = scale != 0.0f;
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
class Transform {
|
||||
public:
|
||||
typedef glm::mat4 Mat4;
|
||||
|
@ -32,7 +44,7 @@ public:
|
|||
typedef glm::quat Quat;
|
||||
|
||||
Transform() :
|
||||
_rotation(1.0f, 0, 0, 0),
|
||||
_rotation(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
_scale(1.0f),
|
||||
_translation(0.0f),
|
||||
_flags(FLAG_CACHE_INVALID_BITSET) // invalid cache
|
||||
|
@ -44,6 +56,9 @@ public:
|
|||
_translation(translation),
|
||||
_flags(FLAG_CACHE_INVALID_BITSET) // invalid cache
|
||||
{
|
||||
if (!isValidScale(_scale)) {
|
||||
_scale = Vec3(1.0f);
|
||||
}
|
||||
}
|
||||
Transform(const Transform& transform) :
|
||||
_rotation(transform._rotation),
|
||||
|
@ -166,8 +181,8 @@ protected:
|
|||
};
|
||||
|
||||
inline void Transform::setIdentity() {
|
||||
_translation = Vec3(0);
|
||||
_rotation = Quat(1.0f, 0, 0, 0);
|
||||
_translation = Vec3(0.0f);
|
||||
_rotation = Quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
_scale = Vec3(1.0f);
|
||||
_flags = Flags(FLAG_CACHE_INVALID_BITSET);
|
||||
}
|
||||
|
@ -187,19 +202,25 @@ inline void Transform::setTranslation(const Vec3& translation) {
|
|||
}
|
||||
|
||||
inline void Transform::preTranslate(const Vec3& translation) {
|
||||
if (translation == Vec3() ) return;
|
||||
if (translation == Vec3()) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
flagTranslation();
|
||||
_translation += translation;
|
||||
}
|
||||
|
||||
inline void Transform::postTranslate(const Vec3& translation) {
|
||||
if (translation == Vec3() ) return;
|
||||
if (translation == Vec3()) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
flagTranslation();
|
||||
|
||||
Vec3 scaledT = translation;
|
||||
if (isScaling()) scaledT *= _scale;
|
||||
if (isScaling()) {
|
||||
scaledT *= _scale;
|
||||
}
|
||||
|
||||
if (isRotating()) {
|
||||
_translation += glm::rotate(_rotation, scaledT);
|
||||
|
@ -223,7 +244,9 @@ inline void Transform::setRotation(const Quat& rotation) {
|
|||
}
|
||||
|
||||
inline void Transform::preRotate(const Quat& rotation) {
|
||||
if (rotation == Quat()) return;
|
||||
if (rotation == Quat()) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
if (isRotating()) {
|
||||
_rotation = rotation * _rotation;
|
||||
|
@ -236,7 +259,9 @@ inline void Transform::preRotate(const Quat& rotation) {
|
|||
}
|
||||
|
||||
inline void Transform::postRotate(const Quat& rotation) {
|
||||
if (rotation == Quat()) return;
|
||||
if (rotation == Quat()) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
|
||||
if (isNonUniform()) {
|
||||
|
@ -269,8 +294,12 @@ inline const Transform::Vec3& Transform::getScale() const {
|
|||
}
|
||||
|
||||
inline void Transform::setScale(float scale) {
|
||||
if (!isValidScale(scale)) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
flagUniform();
|
||||
|
||||
if (scale == 1.0f) {
|
||||
unflagScaling();
|
||||
} else {
|
||||
|
@ -280,6 +309,9 @@ inline void Transform::setScale(float scale) {
|
|||
}
|
||||
|
||||
inline void Transform::setScale(const Vec3& scale) {
|
||||
if (!isValidScale(scale)) {
|
||||
return;
|
||||
}
|
||||
if ((scale.x == scale.y) && (scale.x == scale.z)) {
|
||||
setScale(scale.x);
|
||||
} else {
|
||||
|
@ -291,9 +323,11 @@ inline void Transform::setScale(const Vec3& scale) {
|
|||
}
|
||||
|
||||
inline void Transform::postScale(float scale) {
|
||||
if (scale == 1.0f) return;
|
||||
if (isValidScale(scale) || scale == 1.0f) {
|
||||
return;
|
||||
}
|
||||
if (isScaling()) {
|
||||
// if already scaling, just invalid cache and aply uniform scale
|
||||
// if already scaling, just invalid cache and apply uniform scale
|
||||
invalidCache();
|
||||
_scale *= scale;
|
||||
} else {
|
||||
|
@ -302,6 +336,9 @@ inline void Transform::postScale(float scale) {
|
|||
}
|
||||
|
||||
inline void Transform::postScale(const Vec3& scale) {
|
||||
if (!isValidScale(scale)) {
|
||||
return;
|
||||
}
|
||||
invalidCache();
|
||||
if (isScaling()) {
|
||||
_scale *= scale;
|
||||
|
@ -360,7 +397,7 @@ inline Transform::Mat4& Transform::getRotationScaleMatrixInverse(Mat4& result) c
|
|||
|
||||
inline 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.0f)) {
|
||||
if ((matrix[0][3] == 0.0f) && (matrix[1][3] == 0.0f) && (matrix[2][3] == 0.0f) && (matrix[3][3] == 1.0f)) {
|
||||
setTranslation(Vec3(matrix[3]));
|
||||
evalFromRawMatrix(Mat3(matrix));
|
||||
}
|
||||
|
@ -377,15 +414,10 @@ inline void Transform::evalFromRawMatrix(const Mat3& rotationScaleMatrix) {
|
|||
inline Transform& Transform::evalInverse(Transform& inverse) const {
|
||||
inverse.setIdentity();
|
||||
if (isScaling()) {
|
||||
// TODO: At some point we will face the case when scale is 0 and so 1/0 will blow up...
|
||||
// WHat should we do for this one?
|
||||
assert(_scale.x != 0);
|
||||
assert(_scale.y != 0);
|
||||
assert(_scale.z != 0);
|
||||
if (isNonUniform()) {
|
||||
inverse.setScale(Vec3(1.0f/_scale.x, 1.0f/_scale.y, 1.0f/_scale.z));
|
||||
inverse.setScale(Vec3(1.0f) / _scale);
|
||||
} else {
|
||||
inverse.setScale(1.0f/_scale.x);
|
||||
inverse.setScale(1.0f / _scale.x);
|
||||
}
|
||||
}
|
||||
if (isRotating()) {
|
||||
|
@ -421,8 +453,7 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le
|
|||
result.setIdentity();
|
||||
|
||||
if (left.isScaling()) {
|
||||
const Vec3& s = left.getScale();
|
||||
result.setScale(Vec3(1.0f / s.x, 1.0f / s.y, 1.0f / s.z));
|
||||
result.setScale(Vec3(1.0f) / left.getScale());
|
||||
}
|
||||
if (left.isRotating()) {
|
||||
result.postRotate(glm::conjugate(left.getRotation()));
|
||||
|
|
Loading…
Reference in a new issue