From c2113ea96b2cd969a6dde2c63eb7e0cceb545f13 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 23 Jul 2015 07:42:58 -0700 Subject: [PATCH 01/10] remove non-batch versions of GeometryCache renderXYZ() methods --- interface/src/Util.cpp | 7 -- interface/src/Util.h | 2 - interface/src/avatar/SkeletonModel.cpp | 12 ++- interface/src/avatar/SkeletonModel.h | 3 +- interface/src/ui/ApplicationCompositor.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 1 - libraries/render-utils/src/GeometryCache.cpp | 98 ------------------- libraries/render-utils/src/GeometryCache.h | 42 -------- libraries/render-utils/src/Model.cpp | 4 +- libraries/render-utils/src/Model.h | 2 +- libraries/render-utils/src/RenderUtil.cpp | 25 ----- libraries/render-utils/src/RenderUtil.h | 18 ---- 12 files changed, 13 insertions(+), 203 deletions(-) delete mode 100644 libraries/render-utils/src/RenderUtil.cpp delete mode 100644 libraries/render-utils/src/RenderUtil.h diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index cb3865d336..3a01367fc7 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -77,13 +77,6 @@ const glm::vec3 randVector() { return glm::vec3(randFloat() - 0.5f, randFloat() - 0.5f, randFloat() - 0.5f) * 2.0f; } -void renderCollisionOverlay(int width, int height, float magnitude, float red, float blue, float green) { - const float MIN_VISIBLE_COLLISION = 0.01f; - if (magnitude > MIN_VISIBLE_COLLISION) { - DependencyManager::get()->renderQuad(0, 0, width, height, glm::vec4(red, blue, green, magnitude)); - } -} - // Do some basic timing tests and report the results void runTimingTests() { // How long does it take to make a call to get the time? diff --git a/interface/src/Util.h b/interface/src/Util.h index 2599847f7e..e3938502d2 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -23,8 +23,6 @@ const glm::vec3 randVector(); void renderWorldBox(gpu::Batch& batch); -void renderCollisionOverlay(int width, int height, float magnitude, float red = 0, float blue = 0, float green = 0); - void runTimingTests(); void runUnitTests(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index d92481494a..20ea9477dc 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -375,13 +375,15 @@ void SkeletonModel::renderJointConstraints(gpu::Batch& batch, int jointIndex) { } - renderOrientationDirections(jointIndex, position, _rotation * jointState.getRotation(), directionSize); + renderOrientationDirections(batch, jointIndex, position, _rotation * jointState.getRotation(), directionSize); jointIndex = joint.parentIndex; } while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree); } -void SkeletonModel::renderOrientationDirections(int jointIndex, glm::vec3 position, const glm::quat& orientation, float size) { +void SkeletonModel::renderOrientationDirections(gpu::Batch& batch, int jointIndex, + glm::vec3 position, const glm::quat& orientation, float size) { + auto geometryCache = DependencyManager::get(); if (!_jointOrientationLines.contains(jointIndex)) { @@ -398,13 +400,13 @@ void SkeletonModel::renderOrientationDirections(int jointIndex, glm::vec3 positi glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size; glm::vec3 red(1.0f, 0.0f, 0.0f); - geometryCache->renderLine(position, pRight, red, jointLineIDs._right); + geometryCache->renderLine(batch, position, pRight, red, jointLineIDs._right); glm::vec3 green(0.0f, 1.0f, 0.0f); - geometryCache->renderLine(position, pUp, green, jointLineIDs._up); + geometryCache->renderLine(batch, position, pUp, green, jointLineIDs._up); glm::vec3 blue(0.0f, 0.0f, 1.0f); - geometryCache->renderLine(position, pFront, blue, jointLineIDs._front); + geometryCache->renderLine(batch, position, pFront, blue, jointLineIDs._front); } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 3d63238cf2..1044a16696 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -145,7 +145,8 @@ protected: private: void renderJointConstraints(gpu::Batch& batch, int jointIndex); - void renderOrientationDirections(int jointIndex, glm::vec3 position, const glm::quat& orientation, float size); + void renderOrientationDirections(gpu::Batch& batch, int jointIndex, + glm::vec3 position, const glm::quat& orientation, float size); struct OrientationLineIDs { int _up; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index afdeb7b94e..2cae51de3e 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -529,7 +529,7 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) { glm::vec2 texCoordTopLeft(0.0f, 0.0f); glm::vec2 texCoordBottomRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f)); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e6f2b520c7..b135bb8bb7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -21,7 +21,6 @@ #include "AbstractViewStateInterface.h" #include "GeometryCache.h" -#include "RenderUtil.h" #include "TextureCache.h" #include "FramebufferCache.h" diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 6c03d57de3..c43cddff6e 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -54,12 +54,6 @@ const int NUM_TRIANGLES_PER_QUAD = 2; const int NUM_VERTICES_PER_TRIANGULATED_QUAD = NUM_VERTICES_PER_TRIANGLE * NUM_TRIANGLES_PER_QUAD; const int NUM_COORDS_PER_VERTEX = 3; -void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid, int id) { - gpu::Batch batch; - renderSphere(batch, radius, slices, stacks, color, solid, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color, bool solid, int id) { bool registered = (id != UNKNOWN_ID); @@ -304,12 +298,6 @@ void GeometryCache::renderSphere(gpu::Batch& batch, float radius, int slices, in } } -void GeometryCache::renderGrid(int xDivisions, int yDivisions, const glm::vec4& color) { - gpu::Batch batch; - renderGrid(batch, xDivisions, yDivisions, color); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color) { IntPair key(xDivisions, yDivisions); Vec3Pair colorKey(glm::vec3(color.x, color.y, yDivisions), glm::vec3(color.z, color.y, xDivisions)); @@ -384,12 +372,6 @@ void GeometryCache::renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions batch.draw(gpu::LINES, vertices, 0); } -void GeometryCache::renderGrid(int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id) { - gpu::Batch batch; - renderGrid(batch, x, y, width, height, rows, cols, color, id); - gpu::GLBackend::renderBatch(batch); -} - // TODO: why do we seem to create extra BatchItemDetails when we resize the window?? what's that?? void GeometryCache::renderGrid(gpu::Batch& batch, int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id) { #ifdef WANT_DEBUG @@ -691,12 +673,6 @@ void GeometryCache::updateVertices(int id, const QVector& points, con #endif } -void GeometryCache::renderVertices(gpu::Primitive primitiveType, int id) { - gpu::Batch batch; - renderVertices(batch, primitiveType, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id) { BatchItemDetails& details = _registeredVertices[id]; if (details.isCreated) { @@ -706,12 +682,6 @@ void GeometryCache::renderVertices(gpu::Batch& batch, gpu::Primitive primitiveTy } } -void GeometryCache::renderSolidCube(float size, const glm::vec4& color) { - gpu::Batch batch; - renderSolidCube(batch, size, color); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color) { Vec2Pair colorKey(glm::vec2(color.x, color.y), glm::vec2(color.z, color.y)); const int FLOATS_PER_VERTEX = 3; @@ -833,12 +803,6 @@ void GeometryCache::renderSolidCube(gpu::Batch& batch, float size, const glm::ve batch.drawIndexed(gpu::TRIANGLES, indices); } -void GeometryCache::renderWireCube(float size, const glm::vec4& color) { - gpu::Batch batch; - renderWireCube(batch, size, color); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) { Vec2Pair colorKey(glm::vec2(color.x, color.y),glm::vec2(color.z, color.y)); const int FLOATS_PER_VERTEX = 3; @@ -922,12 +886,6 @@ void GeometryCache::renderWireCube(gpu::Batch& batch, float size, const glm::vec batch.drawIndexed(gpu::LINES, indices); } -void GeometryCache::renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) { - gpu::Batch batch; - renderBevelCornersRect(batch, x, y, width, height, bevelDistance, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id) { bool registered = (id != UNKNOWN_ID); Vec3Pair key(glm::vec3(x, y, 0.0f), glm::vec3(width, height, bevelDistance)); @@ -1029,12 +987,6 @@ void GeometryCache::renderBevelCornersRect(gpu::Batch& batch, int x, int y, int batch.draw(gpu::TRIANGLE_STRIP, details.vertices, 0); } -void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id) { - gpu::Batch batch; - renderQuad(batch, minCorner, maxCorner, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id) { bool registered = (id != UNKNOWN_ID); Vec4Pair key(glm::vec4(minCorner.x, minCorner.y, maxCorner.x, maxCorner.y), color); @@ -1111,12 +1063,6 @@ void GeometryCache::renderUnitCube(gpu::Batch& batch) { renderSolidCube(batch, 1, color); } -void GeometryCache::renderUnitQuad(const glm::vec4& color, int id) { - gpu::Batch batch; - renderUnitQuad(batch, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, int id) { static const glm::vec2 topLeft(-1, 1); static const glm::vec2 bottomRight(1, -1); @@ -1126,14 +1072,6 @@ void GeometryCache::renderUnitQuad(gpu::Batch& batch, const glm::vec4& color, in } -void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, - const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, - const glm::vec4& color, int id) { - gpu::Batch batch; - renderQuad(batch, minCorner, maxCorner, texCoordMinCorner, texCoordMaxCorner, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, const glm::vec4& color, int id) { @@ -1214,12 +1152,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, co batch.draw(gpu::QUADS, 4, 0); } -void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { - gpu::Batch batch; - renderQuad(batch, minCorner, maxCorner, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { bool registered = (id != UNKNOWN_ID); Vec3PairVec4 key(Vec3Pair(minCorner, maxCorner), color); @@ -1291,17 +1223,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, co batch.draw(gpu::QUADS, 4, 0); } -void GeometryCache::renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft, - const glm::vec3& bottomRight, const glm::vec3& topRight, - const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft, - const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, - const glm::vec4& color, int id) { - gpu::Batch batch; - renderQuad(batch, topLeft, bottomLeft, bottomRight, topRight, texCoordTopLeft, texCoordBottomLeft, - texCoordBottomRight, texCoordTopRight, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft, const glm::vec3& bottomRight, const glm::vec3& topRight, const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft, @@ -1395,12 +1316,6 @@ void GeometryCache::renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, cons batch.draw(gpu::QUADS, 4, 0); } -void GeometryCache::renderDashedLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id) { - gpu::Batch batch; - renderDashedLine(batch, start, end, color, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id) { bool registered = (id != UNKNOWN_ID); Vec3PairVec2Pair key(Vec3Pair(start, end), Vec2Pair(glm::vec2(color.x, color.y), glm::vec2(color.z, color.w))); @@ -1555,13 +1470,6 @@ void GeometryCache::BatchItemDetails::clear() { stream.reset(); } -void GeometryCache::renderLine(const glm::vec3& p1, const glm::vec3& p2, - const glm::vec4& color1, const glm::vec4& color2, int id) { - gpu::Batch batch; - renderLine(batch, p1, p2, color1, color2, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color1, const glm::vec4& color2, int id) { @@ -1646,12 +1554,6 @@ void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm batch.draw(gpu::LINES, 2, 0); } -void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color1, const glm::vec4& color2, int id) { - gpu::Batch batch; - renderLine(batch, p1, p2, color1, color2, id); - gpu::GLBackend::renderBatch(batch); -} - void GeometryCache::renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color1, const glm::vec4& color2, int id) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 147b4f8093..2f90c33adf 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -129,56 +129,35 @@ public: int allocateID() { return _nextID++; } static const int UNKNOWN_ID; - void renderSphere(float radius, int slices, int stacks, const glm::vec3& color, bool solid = true, int id = UNKNOWN_ID) - { renderSphere(radius, slices, stacks, glm::vec4(color, 1.0f), solid, id); } void renderSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec3& color, bool solid = true, int id = UNKNOWN_ID) { renderSphere(batch, radius, slices, stacks, glm::vec4(color, 1.0f), solid, id); } - void renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid = true, int id = UNKNOWN_ID); void renderSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color, bool solid = true, int id = UNKNOWN_ID); - void renderGrid(int xDivisions, int yDivisions, const glm::vec4& color); void renderGrid(gpu::Batch& batch, int xDivisions, int yDivisions, const glm::vec4& color); - void renderGrid(int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID); void renderGrid(gpu::Batch& batch, int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID); - void renderSolidCube(float size, const glm::vec4& color); void renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color); - void renderWireCube(float size, const glm::vec4& color); void renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color); - void renderBevelCornersRect(int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id = UNKNOWN_ID); void renderBevelCornersRect(gpu::Batch& batch, int x, int y, int width, int height, int bevelDistance, const glm::vec4& color, int id = UNKNOWN_ID); void renderUnitCube(gpu::Batch& batch); - void renderUnitQuad(const glm::vec4& color = glm::vec4(1), int id = UNKNOWN_ID); void renderUnitQuad(gpu::Batch& batch, const glm::vec4& color = glm::vec4(1), int id = UNKNOWN_ID); - void renderQuad(int x, int y, int width, int height, const glm::vec4& color, int id = UNKNOWN_ID) - { renderQuad(glm::vec2(x,y), glm::vec2(x + width, y + height), color, id); } void renderQuad(gpu::Batch& batch, int x, int y, int width, int height, const glm::vec4& color, int id = UNKNOWN_ID) { renderQuad(batch, glm::vec2(x,y), glm::vec2(x + width, y + height), color, id); } // TODO: I think there's a bug in this version of the renderQuad() that's not correctly rebuilding the vbos // if the color changes by the corners are the same, as evidenced by the audio meter which should turn white // when it's clipping - void renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID); void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID); - void renderQuad(const glm::vec2& minCorner, const glm::vec2& maxCorner, - const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, - const glm::vec4& color, int id = UNKNOWN_ID); void renderQuad(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner, const glm::vec2& texCoordMinCorner, const glm::vec2& texCoordMaxCorner, const glm::vec4& color, int id = UNKNOWN_ID); - void renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID); void renderQuad(gpu::Batch& batch, const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id = UNKNOWN_ID); - void renderQuad(const glm::vec3& topLeft, const glm::vec3& bottomLeft, - const glm::vec3& bottomRight, const glm::vec3& topRight, - const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft, - const glm::vec2& texCoordBottomRight, const glm::vec2& texCoordTopRight, - const glm::vec4& color, int id = UNKNOWN_ID); void renderQuad(gpu::Batch& batch, const glm::vec3& topLeft, const glm::vec3& bottomLeft, const glm::vec3& bottomRight, const glm::vec3& topRight, const glm::vec2& texCoordTopLeft, const glm::vec2& texCoordBottomLeft, @@ -186,53 +165,33 @@ public: const glm::vec4& color, int id = UNKNOWN_ID); - void renderLine(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id = UNKNOWN_ID) - { renderLine(p1, p2, color, color, id); } void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, color, color, id); } - void renderLine(const glm::vec3& p1, const glm::vec3& p2, - const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID) - { renderLine(p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); } void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); } - void renderLine(const glm::vec3& p1, const glm::vec3& p2, - const glm::vec4& color, int id = UNKNOWN_ID) - { renderLine(p1, p2, color, color, id); } void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, color, color, id); } - void renderLine(const glm::vec3& p1, const glm::vec3& p2, - const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); void renderLine(gpu::Batch& batch, const glm::vec3& p1, const glm::vec3& p2, const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); - void renderDashedLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id = UNKNOWN_ID); void renderDashedLine(gpu::Batch& batch, const glm::vec3& start, const glm::vec3& end, const glm::vec4& color, int id = UNKNOWN_ID); - void renderLine(const glm::vec2& p1, const glm::vec2& p2, const glm::vec3& color, int id = UNKNOWN_ID) - { renderLine(p1, p2, glm::vec4(color, 1.0f), id); } void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec3& color, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, glm::vec4(color, 1.0f), id); } - void renderLine(const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color, int id = UNKNOWN_ID) - { renderLine(p1, p2, color, color, id); } void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, color, color, id); } - void renderLine(const glm::vec2& p1, const glm::vec2& p2, - const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID) - { renderLine(p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); } void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec3& color1, const glm::vec3& color2, int id = UNKNOWN_ID) { renderLine(batch, p1, p2, glm::vec4(color1, 1.0f), glm::vec4(color2, 1.0f), id); } - void renderLine(const glm::vec2& p1, const glm::vec2& p2, - const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); void renderLine(gpu::Batch& batch, const glm::vec2& p1, const glm::vec2& p2, const glm::vec4& color1, const glm::vec4& color2, int id = UNKNOWN_ID); @@ -240,7 +199,6 @@ public: void updateVertices(int id, const QVector& points, const glm::vec4& color); void updateVertices(int id, const QVector& points, const QVector& texCoords, const glm::vec4& color); void renderVertices(gpu::Batch& batch, gpu::Primitive primitiveType, int id); - void renderVertices(gpu::Primitive primitiveType, int id); /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9ef835a054..67eb85edfc 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -946,7 +946,7 @@ void Model::removeFromScene(std::shared_ptr scene, render::Pendin _readyWhenAdded = false; } -void Model::renderDebugMeshBoxes() { +void Model::renderDebugMeshBoxes(gpu::Batch& batch) { int colorNdx = 0; _mutex.lock(); foreach(AABox box, _calculatedMeshBoxes) { @@ -995,7 +995,7 @@ void Model::renderDebugMeshBoxes() { { 0.0f, 0.5f, 0.5f, 1.0f } }; DependencyManager::get()->updateVertices(_debugMeshBoxesID, points, color[colorNdx]); - DependencyManager::get()->renderVertices(gpu::LINES, _debugMeshBoxesID); + DependencyManager::get()->renderVertices(batch, gpu::LINES, _debugMeshBoxesID); colorNdx++; } _mutex.unlock(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 8c792c8a3b..ec0e80fad6 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -399,7 +399,7 @@ private: // debug rendering support - void renderDebugMeshBoxes(); + void renderDebugMeshBoxes(gpu::Batch& batch); int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID; // helper functions used by render() or renderInScene() diff --git a/libraries/render-utils/src/RenderUtil.cpp b/libraries/render-utils/src/RenderUtil.cpp deleted file mode 100644 index 44733418ff..0000000000 --- a/libraries/render-utils/src/RenderUtil.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// RenderUtil.cpp -// interface/src/renderer -// -// Created by Andrzej Kapolka on 8/15/13. -// Copyright 2013 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 -#include "GeometryCache.h" - -#include "RenderUtil.h" - -void renderFullscreenQuad(float sMin, float sMax, float tMin, float tMax) { - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); - glm::vec2 texCoordBottomRight(sMax, tMax); - - DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); -} diff --git a/libraries/render-utils/src/RenderUtil.h b/libraries/render-utils/src/RenderUtil.h deleted file mode 100644 index b2f244733a..0000000000 --- a/libraries/render-utils/src/RenderUtil.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// RenderUtil.h -// interface/src/renderer -// -// Created by Andrzej Kapolka on 8/15/13. -// Copyright 2013 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 -// - -#ifndef hifi_RenderUtil_h -#define hifi_RenderUtil_h - -/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax). -void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f); - -#endif // hifi_RenderUtil_h From bd6534a991fee0361c753a8d30bd496138957e5b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 23 Jul 2015 08:35:03 -0700 Subject: [PATCH 02/10] remove deprecated renderBatch() --- libraries/gpu/src/gpu/GLBackend.cpp | 18 ++++++------------ libraries/gpu/src/gpu/GLBackend.h | 9 --------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 721be0f402..7fd0f9be76 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -92,9 +92,12 @@ GLBackend::GLBackend() : { static std::once_flag once; std::call_once(once, [] { - qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); - qCDebug(gpulogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); - qCDebug(gpulogging) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); + qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); + + qCDebug(gpulogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); + + qCDebug(gpulogging) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); + qCDebug(gpulogging) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); #ifdef WIN32 @@ -143,15 +146,6 @@ void GLBackend::render(Batch& batch) { } } -void GLBackend::renderBatch(Batch& batch, bool syncCache) { - qCDebug(gpulogging) << "GLBackend::renderBatch : Deprecated call, don;t do it!!!"; - GLBackend backend; - if (syncCache) { - backend.syncCache(); - } - backend.render(batch); -} - bool GLBackend::checkGLError(const char* name) { GLenum error = glGetError(); if (!error) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index b3e905bf21..0e6f181028 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -38,15 +38,6 @@ public: // Let's try to avoid to do that as much as possible! virtual void syncCache(); - // 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); // Only checks in debug builds From 06b6c49b9a1827b3af6cd09b3548512cab678b22 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 23 Jul 2015 08:56:59 -0700 Subject: [PATCH 03/10] remove rescaling of textures --- libraries/render-utils/src/TextureCache.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index f86d15079d..1a6ea97b64 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -325,19 +325,6 @@ void ImageReader::run() { auto ntex = dynamic_cast(&*texture); if (ntex && (ntex->getType() == CUBE_TEXTURE)) { qCDebug(renderutils) << "Cube map size:" << _url << image.width() << image.height(); - } else { - - // enforce a fixed maximum area (1024 * 2048) - const int MAXIMUM_AREA_SIZE = 2097152; - if (imageArea > MAXIMUM_AREA_SIZE) { - float scaleRatio = sqrtf((float)MAXIMUM_AREA_SIZE) / sqrtf((float)imageArea); - int resizeWidth = static_cast(std::floor(scaleRatio * static_cast(image.width()))); - int resizeHeight = static_cast(std::floor(scaleRatio * static_cast(image.height()))); - qCDebug(renderutils) << "Image greater than maximum size:" << _url << image.width() << image.height() << - " scaled to:" << resizeWidth << resizeHeight; - image = image.scaled(resizeWidth, resizeHeight, Qt::IgnoreAspectRatio); - imageArea = image.width() * image.height(); - } } int opaquePixels = 0; From f19800f0de0f19f92647cd2c343d432bbc8987a9 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Thu, 23 Jul 2015 12:37:58 -0400 Subject: [PATCH 04/10] Don't overwrite the normals buffer when copying the resolved lighting back to the primary FBO --- .../src/DeferredLightingEffect.cpp | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e6f2b520c7..eccae42c90 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -542,30 +542,34 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) { auto framebufferCache = DependencyManager::get(); QSize framebufferSize = framebufferCache->getFrameBufferSize(); - batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); - batch.setPipeline(_blitLightBuffer); - - batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0)); - + // TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror. + auto destFbo = framebufferCache->getPrimaryFramebuffer(); +// gpu::Vec4i vp = args->_viewport; +// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp); + batch.setFramebuffer(destFbo); + batch.setViewportTransform(args->_viewport); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); - - float sMin = args->_viewport.x / (float)framebufferSize.width(); - float sWidth = args->_viewport.z / (float)framebufferSize.width(); - float tMin = args->_viewport.y / (float)framebufferSize.height(); - float tHeight = args->_viewport.w / (float)framebufferSize.height(); + { + float sMin = args->_viewport.x / (float)framebufferSize.width(); + float sWidth = args->_viewport.z / (float)framebufferSize.width(); + float tMin = args->_viewport.y / (float)framebufferSize.height(); + float tHeight = args->_viewport.w / (float)framebufferSize.height(); + Transform model; + batch.setPipeline(_blitLightBuffer); + model.setTranslation(glm::vec3(sMin, tMin, 0.0)); + model.setScale(glm::vec3(sWidth, tHeight, 1.0)); + batch.setModelTransform(model); + } - batch.setViewportTransform(args->_viewport); - - Transform model; - model.setTranslation(glm::vec3(sMin, tMin, 0.0)); - model.setScale(glm::vec3(sWidth, tHeight, 1.0)); - batch.setModelTransform(model); + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + batch._glDrawBuffers(bufferCount, buffers); + batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); - - args->_context->syncCache(); args->_context->render(batch); framebufferCache->releaseFramebuffer(_copyFBO); } From b26f4b0c8d034f298bc317db6fbb157cc66992d1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 23 Jul 2015 14:49:15 -0700 Subject: [PATCH 05/10] fix for underdamped avatar rotation momentum --- interface/src/avatar/MyAvatar.cpp | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ac0cb3feda..980a4d3e14 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -54,7 +54,7 @@ using namespace std; const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f); -const float YAW_SPEED = 500.0f; // degrees/sec +const float YAW_SPEED = 150.0f; // degrees/sec const float PITCH_SPEED = 100.0f; // degrees/sec const float DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES = 30.0f; @@ -1290,22 +1290,34 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { void MyAvatar::updateOrientation(float deltaTime) { // Smoothly rotate body with arrow keys - _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; - _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; - getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); + float driveLeft = _driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]; + float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED; + if (targetSpeed != 0.0f) { + const float ROTATION_RAMP_TIMESCALE = 0.1f; + float blend = deltaTime / ROTATION_RAMP_TIMESCALE; + if (blend > 1.0f) { + blend = 1.0f; + } + _bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed; + } else if (_bodyYawDelta != 0.0f) { + // attenuate body rotation speed + const float ROTATION_DECAY_TIMESCALE = 0.05f; + float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE; + if (attenuation < 0.0f) { + attenuation = 0.0f; + } + _bodyYawDelta *= attenuation; + float MINIMUM_ROTATION_RATE = 2.0f; + if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { + _bodyYawDelta = 0.0f; + } + } + + getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); // update body orientation by movement inputs setOrientation(getOrientation() * - glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta, 0.0f) * deltaTime))); - - // decay body rotation momentum - const float BODY_SPIN_FRICTION = 7.5f; - float bodySpinMomentum = 1.0f - BODY_SPIN_FRICTION * deltaTime; - if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } - _bodyYawDelta *= bodySpinMomentum; - - float MINIMUM_ROTATION_RATE = 2.0f; - if (fabs(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { _bodyYawDelta = 0.0f; } + glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f)))); if (qApp->isHMDMode()) { // these angles will be in radians From 9593668110ee4971971ee006b0df244619e1b60c Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 23 Jul 2015 15:08:22 -0700 Subject: [PATCH 06/10] Bring animation file headers up to date. --- libraries/animation/src/AnimationCache.cpp | 2 +- libraries/animation/src/AnimationCache.h | 2 +- libraries/animation/src/AnimationHandle.cpp | 2 +- libraries/animation/src/AnimationHandle.h | 2 +- libraries/animation/src/AnimationLoop.cpp | 2 +- libraries/animation/src/AnimationLoop.h | 2 +- libraries/animation/src/AnimationObject.cpp | 2 +- libraries/animation/src/AnimationObject.h | 2 +- libraries/animation/src/JointState.cpp | 2 +- libraries/animation/src/JointState.h | 2 +- libraries/animation/src/Rig.cpp | 2 +- libraries/animation/src/Rig.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index 99224f7dce..fef20b3cdb 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -1,6 +1,6 @@ // // AnimationCache.cpp -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Andrzej Kapolka on 4/14/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index c90c4c9225..840d7a0355 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -1,6 +1,6 @@ // // AnimationCache.h -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Andrzej Kapolka on 4/14/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index d11dcacfc6..996b8cb1fb 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -1,6 +1,6 @@ // // AnimationHandle.cpp -// interface/src/renderer +// libraries/animation/src/ // // Created by Andrzej Kapolka on 10/18/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/animation/src/AnimationHandle.h b/libraries/animation/src/AnimationHandle.h index a8c9d800a4..9075118f43 100644 --- a/libraries/animation/src/AnimationHandle.h +++ b/libraries/animation/src/AnimationHandle.h @@ -1,6 +1,6 @@ // // AnimationHandle.h -// interface/src/renderer +// libraries/animation/src/ // // Created by Andrzej Kapolka on 10/18/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 43e049f851..a2a27170c2 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -1,6 +1,6 @@ // // AnimationLoop.cpp -// libraries/animation +// libraries/animation/src/ // // Created by Brad Hefta-Gaub on 11/12/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index d4537c4656..02161544ba 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -1,6 +1,6 @@ // // AnimationLoop.h -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Brad Hefta-Gaub on 11/12/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/AnimationObject.cpp b/libraries/animation/src/AnimationObject.cpp index ede1e82623..25a5743121 100644 --- a/libraries/animation/src/AnimationObject.cpp +++ b/libraries/animation/src/AnimationObject.cpp @@ -1,6 +1,6 @@ // // AnimationObject.cpp -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Andrzej Kapolka on 4/17/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/AnimationObject.h b/libraries/animation/src/AnimationObject.h index 078fc31fb3..aa69e78ceb 100644 --- a/libraries/animation/src/AnimationObject.h +++ b/libraries/animation/src/AnimationObject.h @@ -1,6 +1,6 @@ // // AnimationObject.h -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Andrzej Kapolka on 4/17/14. // Copyright (c) 2014 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/JointState.cpp b/libraries/animation/src/JointState.cpp index a82a57f0ed..8f14342e80 100644 --- a/libraries/animation/src/JointState.cpp +++ b/libraries/animation/src/JointState.cpp @@ -1,6 +1,6 @@ // // JointState.cpp -// interface/src/renderer +// libraries/animation/src/ // // Created by Andrzej Kapolka on 10/18/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/animation/src/JointState.h b/libraries/animation/src/JointState.h index 0ef84e50c4..f15590e5f2 100644 --- a/libraries/animation/src/JointState.h +++ b/libraries/animation/src/JointState.h @@ -1,6 +1,6 @@ // // JointState.h -// interface/src/renderer +// libraries/animation/src/ // // Created by Andrzej Kapolka on 10/18/13. // Copyright 2013 High Fidelity, Inc. diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0a889fce88..4466bdbe26 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1,6 +1,6 @@ // // Rig.cpp -// libraries/script-engine/src/ +// libraries/animation/src/ // // Created by Howard Stearns, Seth Alves, Anthony Thibault, Andrew Meadows on 7/15/15. // Copyright (c) 2015 High Fidelity, Inc. All rights reserved. diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e60116a35e..7e209841a1 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -1,6 +1,6 @@ // // Rig.h -// libraries/script-engine/src/ +// libraries/animation/src/ // // Produces animation data and hip placement for the current timestamp. // From 81e0a1e629be09cdd811225e40a6399bf32b7d40 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 23 Jul 2015 15:09:06 -0700 Subject: [PATCH 07/10] Better name for signal. --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 942dbeeaf7..aab760810f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1087,7 +1087,7 @@ void AvatarData::setJointMappingsFromNetworkReply() { } networkReply->deleteLater(); - emit jointsLoaded(); + emit jointMappingLoaded(); } void AvatarData::sendAvatarDataPacket() { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 285460651a..60c643eff9 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -313,7 +313,7 @@ public: bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; } signals: - void jointsLoaded(); // So that test cases or anyone waiting on asynchronous loading can be informed. + void jointMappingLoaded(); // So that test cases or anyone waiting on asynchronous loading can be informed. public slots: void sendAvatarDataPacket(); From eea3ce4369237b32be6d61993057c9e5588709d6 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 23 Jul 2015 15:11:21 -0700 Subject: [PATCH 08/10] Make an actual rig in the test case. --- tests/rig/src/RigTests.cpp | 61 +++++++++++++++++++++++++++----------- tests/rig/src/RigTests.h | 6 ++-- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/tests/rig/src/RigTests.cpp b/tests/rig/src/RigTests.cpp index 37f7a2bbab..100d70ed25 100644 --- a/tests/rig/src/RigTests.cpp +++ b/tests/rig/src/RigTests.cpp @@ -40,30 +40,55 @@ */ #include -//#include "FSTReader.h" -// There are two good ways we could organize this: -// 1. Create a MyAvatar the same way that Interface does, and poke at it. -// We can't do that because MyAvatar (and even Avatar) are in interface, not a library, and our build system won't allow that dependency. -// 2. Create just the minimum skeleton in the most direct way possible, using only very basic library APIs (such as fbx). -// I don't think we can do that because not everything we need is exposed directly from, e.g., the fst and fbx readers. -// So here we do neither. Using as much as we can from AvatarData (which is in the avatar and further requires network and audio), and -// duplicating whatever other code we need from (My)Avatar. Ugh. We may refactor that later, but right now, cleaning this up is not on our critical path. +#include + #include "AvatarData.h" +#include "OBJReader.h" +#include "FBXReader.h" + +#include "AvatarRig.h" // We might later test Rig vs AvatarRig separately, but for now, we're concentrating on the main use case. #include "RigTests.h" QTEST_MAIN(RigTests) void RigTests::initTestCase() { - AvatarData avatar; - QEventLoop loop; // Create an event loop that will quit when we get the finished signal - QObject::connect(&avatar, &AvatarData::jointsLoaded, &loop, &QEventLoop::quit); - avatar.setSkeletonModelURL(QUrl("https://hifi-public.s3.amazonaws.com/marketplace/contents/4a690585-3fa3-499e-9f8b-fd1226e561b1/e47e6898027aa40f1beb6adecc6a7db5.fst")); // Zach - //std::cout << "sleep start" << std::endl; - loop.exec(); // Nothing is going to happen on this whole run thread until we get this - _rig = new Rig(); -} -void RigTests::dummyPassTest() { + // There are two good ways we could organize this: + // 1. Create a MyAvatar the same way that Interface does, and poke at it. + // We can't do that because MyAvatar (and even Avatar) are in interface, not a library, and our build system won't allow that dependency. + // 2. Create just the minimum skeleton in the most direct way possible, using only very basic library APIs (such as fbx). + // I don't think we can do that because not everything we need is exposed directly from, e.g., the fst and fbx readers. + // So here we do neither. Using as much as we can from AvatarData (which is in the avatar and further requires network and audio), and + // duplicating whatever other code we need from (My)Avatar. Ugh. We may refactor that later, but right now, cleaning this up is not on our critical path. + + // Joint mapping from fst + auto avatar = std::make_shared(); + QEventLoop loop; // Create an event loop that will quit when we get the finished signal + QObject::connect(avatar.get(), &AvatarData::jointMappingLoaded, &loop, &QEventLoop::quit); + avatar->setSkeletonModelURL(QUrl("https://hifi-public.s3.amazonaws.com/marketplace/contents/4a690585-3fa3-499e-9f8b-fd1226e561b1/e47e6898027aa40f1beb6adecc6a7db5.fst")); // Zach fst + loop.exec(); // Blocking all further tests until signalled. + + // Joint geometry from fbx. + QUrl fbxUrl("https://s3.amazonaws.com/hifi-public/models/skeletons/Zack/Zack.fbx"); + QNetworkReply* netReply = OBJReader().request(fbxUrl, false); // Just a convenience hack for synchronoud http request + QCOMPARE(netReply->isFinished() && (netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200), true); + FBXGeometry geometry = readFBX(netReply->readAll(), QVariantHash()); + QCOMPARE(geometry.joints.count(), avatar->getJointNames().count()); + + QVector jointStates; + for (int i = 0; i < geometry.joints.size(); ++i) { + const FBXJoint& joint = geometry.joints[i]; + JointState state; + state.setFBXJoint(&joint); + jointStates.append(state); + } + + _rig = std::make_shared(); + _rig->initJointStates(jointStates, glm::mat4()); + std::cout << "Rig is ready " << geometry.joints.count() << " joints " << std::endl; + } + +/*void RigTests::dummyPassTest() { bool x = true; std::cout << "dummyPassTest x=" << x << std::endl; QCOMPARE(x, true); @@ -73,4 +98,4 @@ void RigTests::dummyFailTest() { bool x = false; std::cout << "dummyFailTest x=" << x << std::endl; QCOMPARE(x, true); -} +}*/ diff --git a/tests/rig/src/RigTests.h b/tests/rig/src/RigTests.h index 9f8ba22eb8..1ce692b858 100644 --- a/tests/rig/src/RigTests.h +++ b/tests/rig/src/RigTests.h @@ -46,11 +46,11 @@ class RigTests : public QObject { private slots: void initTestCase(); - void dummyPassTest(); - void dummyFailTest(); + /*void dummyPassTest(); + void dummyFailTest();*/ private: - Rig* _rig; + RigPointer _rig; }; #endif // hifi_RigTests_h From 33c97a18337fdbf46a5713aad8a03bf7ca882c93 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 23 Jul 2015 15:14:10 -0700 Subject: [PATCH 09/10] get rid of _firstPersonSkeletonModel in MyAvatar. add flag in Rig for joints being dirty so Model knows when to recompute meshes --- interface/src/avatar/MyAvatar.cpp | 25 +----- interface/src/avatar/MyAvatar.h | 2 - interface/src/avatar/SkeletonModel.cpp | 90 ++++++++------------- interface/src/avatar/SkeletonModel.h | 7 +- libraries/animation/src/AnimationHandle.cpp | 6 +- libraries/animation/src/Rig.cpp | 89 ++++++++++++++++---- libraries/animation/src/Rig.h | 31 +++++-- libraries/render-utils/src/Model.cpp | 24 +----- libraries/render-utils/src/Model.h | 3 - 9 files changed, 137 insertions(+), 140 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 178ebc0487..d46870b479 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -103,11 +103,8 @@ MyAvatar::MyAvatar(RigPointer rig) : _realWorldFieldOfView("realWorldFieldOfView", DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES), _rig(rig), - _firstPersonSkeletonModel(this, nullptr, rig), _prevShouldDrawHead(true) { - _firstPersonSkeletonModel.setIsFirstPerson(true); - ShapeCollider::initDispatchTable(); for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -141,7 +138,6 @@ QByteArray MyAvatar::toByteArray() { void MyAvatar::reset() { _skeletonModel.reset(); - _firstPersonSkeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -200,7 +196,6 @@ void MyAvatar::simulate(float deltaTime) { { PerformanceTimer perfTimer("skeleton"); _skeletonModel.simulate(deltaTime); - _firstPersonSkeletonModel.simulate(deltaTime); } if (!_skeletonModel.hasSkeleton()) { @@ -1028,15 +1023,8 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { if (_useFullAvatar) { _skeletonModel.setVisibleInScene(_prevShouldDrawHead, scene); - - const QUrl DEFAULT_SKELETON_MODEL_URL = QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_body.fst"); - _firstPersonSkeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar()); - _firstPersonSkeletonModel.setVisibleInScene(!_prevShouldDrawHead, scene); } else { _skeletonModel.setVisibleInScene(true, scene); - - _firstPersonSkeletonModel.setVisibleInScene(false, scene); - _firstPersonSkeletonModel.reset(); } } @@ -1254,23 +1242,14 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { const bool shouldDrawHead = shouldRenderHead(renderArgs); _skeletonModel.initWhenReady(scene); - if (_useFullAvatar) { - _firstPersonSkeletonModel.initWhenReady(scene); - } if (shouldDrawHead != _prevShouldDrawHead) { if (_useFullAvatar) { - if (shouldDrawHead) { - _skeletonModel.setVisibleInScene(true, scene); - _firstPersonSkeletonModel.setVisibleInScene(false, scene); - } else { - _skeletonModel.setVisibleInScene(false, scene); - _firstPersonSkeletonModel.setVisibleInScene(true, scene); - } + _skeletonModel.setVisibleInScene(true, scene); + _rig->setFirstPerson(!shouldDrawHead); } else { getHead()->getFaceModel().setVisibleInScene(shouldDrawHead, scene); } - } _prevShouldDrawHead = shouldDrawHead; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0c598c21be..c6cb48878f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -287,8 +287,6 @@ private: QString _fullAvatarModelName; RigPointer _rig; - // used for rendering when in first person view or when in an HMD. - SkeletonModel _firstPersonSkeletonModel; bool _prevShouldDrawHead; }; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2d9db1abb7..0ee3898a20 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -40,8 +40,7 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent, RigPointer r _standingFoot(NO_FOOT), _standingOffset(0.0f), _clampedFootPosition(0.0f), - _headClipDistance(DEFAULT_NEAR_CLIP), - _isFirstPerson(false) + _headClipDistance(DEFAULT_NEAR_CLIP) { assert(_rig); assert(_owningAvatar); @@ -54,7 +53,7 @@ SkeletonModel::~SkeletonModel() { void SkeletonModel::initJointStates(QVector states) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset; - _boundingRadius = _rig->initJointStates(states, parentTransform); + _boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; @@ -98,6 +97,29 @@ void SkeletonModel::initJointStates(QVector states) { const float PALM_PRIORITY = DEFAULT_PRIORITY; const float LEAN_PRIORITY = DEFAULT_PRIORITY; + +void SkeletonModel::updateClusterMatrices() { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + glm::mat4 modelToWorld = glm::mat4_cast(_rotation); + for (int i = 0; i < _meshStates.size(); i++) { + MeshState& state = _meshStates[i]; + const FBXMesh& mesh = geometry.meshes.at(i); + if (_showTrueJointTransforms) { + for (int j = 0; j < mesh.clusters.size(); j++) { + const FBXCluster& cluster = mesh.clusters.at(j); + state.clusterMatrices[j] = + modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix; + } + } else { + for (int j = 0; j < mesh.clusters.size(); j++) { + const FBXCluster& cluster = mesh.clusters.at(j); + state.clusterMatrices[j] = + modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix; + } + } + } +} + void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getSkeletonPosition()); static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); @@ -154,8 +176,11 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { } } - if (_isFirstPerson) { - cauterizeHead(); + // if (_isFirstPerson) { + // cauterizeHead(); + // updateClusterMatrices(); + // } + if (_rig->getJointsAreDirty()) { updateClusterMatrices(); } @@ -764,7 +789,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() { // geometry or joints have not yet been created return; } - + const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (geometry.joints.isEmpty()) { return; @@ -820,7 +845,7 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha // draw a green cylinder between the two points glm::vec3 origin(0.0f); - Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), + Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); } @@ -828,56 +853,5 @@ bool SkeletonModel::hasSkeleton() { return isActive() ? _geometry->getFBXGeometry().rootJointIndex != -1 : false; } -void SkeletonModel::initHeadBones() { - _headBones.clear(); - const FBXGeometry& fbxGeometry = _geometry->getFBXGeometry(); - const int neckJointIndex = fbxGeometry.neckJointIndex; - std::queue q; - q.push(neckJointIndex); - _headBones.push_back(neckJointIndex); - - // fbxJoints only hold links to parents not children, so we have to do a bit of extra work here. - while (q.size() > 0) { - int jointIndex = q.front(); - for (int i = 0; i < fbxGeometry.joints.size(); i++) { - const FBXJoint& fbxJoint = fbxGeometry.joints[i]; - if (jointIndex == fbxJoint.parentIndex) { - _headBones.push_back(i); - q.push(i); - } - } - q.pop(); - } -} - -void SkeletonModel::invalidateHeadBones() { - _headBones.clear(); -} - -void SkeletonModel::cauterizeHead() { - if (isActive()) { - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const int neckJointIndex = geometry.neckJointIndex; - if (neckJointIndex > 0 && neckJointIndex < _rig->getJointStateCount()) { - - // lazy init of headBones - if (_headBones.size() == 0) { - initHeadBones(); - } - - // preserve the translation for the neck - // glm::vec4 trans = _jointStates[neckJointIndex].getTransform()[3]; - glm::vec4 trans = _rig->getJointTransform(neckJointIndex)[3]; - glm::vec4 zero(0, 0, 0, 0); - for (const int &i : _headBones) { - glm::mat4 newXform(zero, zero, zero, trans); - _rig->setJointTransform(i, newXform); - _rig->setJointVisibleTransform(i, newXform); - } - } - } -} - void SkeletonModel::onInvalidate() { - invalidateHeadBones(); } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index c4cd43b4df..0678ae48d4 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -112,9 +112,6 @@ public: float getHeadClipDistance() const { return _headClipDistance; } - void setIsFirstPerson(bool value) { _isFirstPerson = value; } - bool getIsFirstPerson() const { return _isFirstPerson; } - virtual void onInvalidate() override; signals: @@ -138,6 +135,7 @@ protected: void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, int index); void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, int index); + void updateClusterMatrices(); void cauterizeHead(); void initHeadBones(); void invalidateHeadBones(); @@ -173,9 +171,6 @@ private: glm::vec3 _clampedFootPosition; float _headClipDistance; // Near clip distance to use if no separate head model - - bool _isFirstPerson; - std::vector _headBones; }; #endif // hifi_SkeletonModel_h diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index d11dcacfc6..8978abd93c 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -176,8 +176,7 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - JointState state = _rig->getJointState(mapping); - if (_priority == state._animationPriority) { + if (_priority == _rig->getJointAnimatinoPriority(mapping)) { _rig->setJointAnimatinoPriority(mapping, newPriority); } } @@ -188,8 +187,7 @@ void AnimationHandle::restoreJoints() { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - JointState state = _rig->getJointState(mapping); - _rig->restoreJointRotation(mapping, 1.0f, state._animationPriority); + _rig->restoreJointRotation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); } } } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0a889fce88..d42f65df32 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "AnimationHandle.h" #include "Rig.h" @@ -48,9 +50,9 @@ void Rig::deleteAnimations() { } } - -float Rig::initJointStates(QVector states, glm::mat4 parentTransform) { +float Rig::initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex) { _jointStates = states; + _neckJointIndex = neckJointIndex; initJointTransforms(parentTransform); int numStates = _jointStates.size(); @@ -66,6 +68,8 @@ float Rig::initJointStates(QVector states, glm::mat4 parentTransform _jointStates[i].slaveVisibleTransform(); } + initHeadBones(); + return radius; } @@ -106,7 +110,8 @@ JointState Rig::getJointState(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return JointState(); } - return _jointStates[jointIndex]; + // return _jointStates[jointIndex]; + return maybeCauterizeHead(jointIndex); } bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { @@ -144,6 +149,13 @@ void Rig::clearJointAnimationPriority(int index) { } } +float Rig::getJointAnimatinoPriority(int index) { + if (index != -1 && index < _jointStates.size()) { + return _jointStates[index]._animationPriority; + } + return 0.0f; +} + void Rig::setJointAnimatinoPriority(int index, float newPriority) { if (index != -1 && index < _jointStates.size()) { _jointStates[index]._animationPriority = newPriority; @@ -173,7 +185,8 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, return false; } // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getPosition(); + // position = translation + rotation * _jointStates[jointIndex].getPosition(); + position = translation + rotation * maybeCauterizeHead(jointIndex).getPosition(); return true; } @@ -182,7 +195,7 @@ bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const { return false; } // position is in model-frame - position = extractTranslation(_jointStates[jointIndex].getTransform()); + position = extractTranslation(maybeCauterizeHead(jointIndex).getTransform()); return true; } @@ -190,7 +203,7 @@ bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -198,7 +211,7 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - rotation = _jointStates[jointIndex].getRotation(); + rotation = maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -206,7 +219,7 @@ bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm: if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -217,7 +230,7 @@ bool Rig::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& positio return false; } // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getVisiblePosition(); + position = translation + rotation * maybeCauterizeHead(jointIndex).getVisiblePosition(); return true; } @@ -225,7 +238,7 @@ bool Rig::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result, if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getVisibleRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getVisibleRotation(); return true; } @@ -233,14 +246,14 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return glm::mat4(); } - return _jointStates[jointIndex].getTransform(); + return maybeCauterizeHead(jointIndex).getTransform(); } glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return glm::mat4(); } - return _jointStates[jointIndex].getVisibleTransform(); + return maybeCauterizeHead(jointIndex).getVisibleTransform(); } void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform) { @@ -492,7 +505,7 @@ glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) { if (jointIndex == -1 || _jointStates.isEmpty()) { return glm::vec3(); } - return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame(); + return maybeCauterizeHead(jointIndex).getDefaultTranslationInConstrainedFrame(); } glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain) { @@ -537,5 +550,53 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { if (jointIndex == -1 || _jointStates.isEmpty()) { return glm::quat(); } - return _jointStates[jointIndex].getDefaultRotationInParentFrame(); + return maybeCauterizeHead(jointIndex).getDefaultRotationInParentFrame(); +} + +void Rig::initHeadBones() { + if (_neckJointIndex == -1) { + return; + } + _headBones.clear(); + std::queue q; + q.push(_neckJointIndex); + _headBones.push_back(_neckJointIndex); + + // fbxJoints only hold links to parents not children, so we have to do a bit of extra work here. + while (q.size() > 0) { + int jointIndex = q.front(); + for (int i = 0; i < _jointStates.size(); i++) { + const FBXJoint& fbxJoint = _jointStates[i].getFBXJoint(); + if (jointIndex == fbxJoint.parentIndex) { + _headBones.push_back(i); + q.push(i); + } + } + q.pop(); + } +} + +JointState Rig::maybeCauterizeHead(int jointIndex) const { + // if (_headBones.contains(jointIndex)) { + // XXX fix this... make _headBones a hash? add a flag to JointState? + if (_neckJointIndex != -1 && + _isFirstPerson && + std::find(_headBones.begin(), _headBones.end(), jointIndex) != _headBones.end()) { + glm::vec4 trans = _jointStates[jointIndex].getTransform()[3]; + glm::vec4 zero(0, 0, 0, 0); + glm::mat4 newXform(zero, zero, zero, trans); + JointState jointStateCopy = _jointStates[jointIndex]; + jointStateCopy.setTransform(newXform); + jointStateCopy.setVisibleTransform(newXform); + return jointStateCopy; + } else { + return _jointStates[jointIndex]; + } +} + +void Rig::setFirstPerson(bool isFirstPerson) { + if (_isFirstPerson != isFirstPerson) { + _isFirstPerson = isFirstPerson; + _jointsAreDirty = true; + } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e60116a35e..1073bd6dab 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -11,14 +11,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /* TBD: - - What iare responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop? + - What are responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop? Is there common/copied code (e.g., ScriptableAvatar::update)? - - How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object physics? - - Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the system choosing randomly? + - How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object + physics? + - Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the + system choosing randomly? - Distribute some doc from here to the right files if it turns out to be correct: - - AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything equivalent to editEntity. - But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject is to AnimationPointer? + - AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything + equivalent to editEntity. + But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject + is to AnimationPointer? */ #ifndef __hifi__Rig__ @@ -51,7 +55,7 @@ public: const QList& getRunningAnimations() const { return _runningAnimations; } void deleteAnimations(); - float initJointStates(QVector states, glm::mat4 parentTransform); + float initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; int getJointStateCount() const { return _jointStates.size(); } @@ -60,11 +64,12 @@ public: void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority); - JointState getJointState(int jointIndex) const; + JointState getJointState(int jointIndex) const; // XXX bool getVisibleJointState(int index, glm::quat& rotation) const; void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); + float getJointAnimatinoPriority(int index); void setJointAnimatinoPriority(int index, float newPriority); void setJointState(int index, bool valid, const glm::quat& rotation, float priority); void restoreJointRotation(int index, float fraction, float priority); @@ -102,11 +107,23 @@ public: virtual void updateJointState(int index, glm::mat4 parentTransform) = 0; virtual void updateFaceJointState(int index, glm::mat4 parentTransform) = 0; + virtual void setFirstPerson(bool isFirstPerson); + virtual bool getIsFirstPerson() const { return _isFirstPerson; } + + bool getJointsAreDirty() { return _jointsAreDirty; } + protected: QVector _jointStates; QSet _animationHandles; QList _runningAnimations; + + JointState maybeCauterizeHead(int jointIndex) const; + void initHeadBones(); + bool _isFirstPerson = false; + std::vector _headBones; + bool _jointsAreDirty = false; + int _neckJointIndex = -1; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index bd33e75207..c769f6bbe5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -478,7 +478,7 @@ bool Model::updateGeometry() { void Model::initJointStates(QVector states) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset; - _boundingRadius = _rig->initJointStates(states, parentTransform); + _boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex); } bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, @@ -1341,28 +1341,6 @@ void Model::simulate(float deltaTime, bool fullUpdate) { } } -void Model::updateClusterMatrices() { - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - glm::mat4 modelToWorld = glm::mat4_cast(_rotation); - for (int i = 0; i < _meshStates.size(); i++) { - MeshState& state = _meshStates[i]; - const FBXMesh& mesh = geometry.meshes.at(i); - if (_showTrueJointTransforms) { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - state.clusterMatrices[j] = - modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix; - } - } else { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - state.clusterMatrices[j] = - modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix; - } - } - } -} - void Model::simulateInternal(float deltaTime) { // update the world space transforms for all joints diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 30c5211990..d7178a389a 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -308,9 +308,6 @@ protected: _calculatedMeshTrianglesValid = false; } - // rebuild the clusterMatrices from the current jointStates - void updateClusterMatrices(); - // hook for derived classes to be notified when setUrl invalidates the current model. virtual void onInvalidate() {}; From cc26f5165bba9714d12edfc9e1eeedf2b0a30fa8 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 23 Jul 2015 15:40:33 -0700 Subject: [PATCH 10/10] Supply neck index per new protocol. --- tests/rig/src/RigTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rig/src/RigTests.cpp b/tests/rig/src/RigTests.cpp index 100d70ed25..95ddc86b3f 100644 --- a/tests/rig/src/RigTests.cpp +++ b/tests/rig/src/RigTests.cpp @@ -84,7 +84,7 @@ void RigTests::initTestCase() { } _rig = std::make_shared(); - _rig->initJointStates(jointStates, glm::mat4()); + _rig->initJointStates(jointStates, glm::mat4(), geometry.neckJointIndex); std::cout << "Rig is ready " << geometry.joints.count() << " joints " << std::endl; }