From 60874e6041bd584962bf4e1b85022274061ca694 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 20 Mar 2017 16:31:38 -0700 Subject: [PATCH 1/8] remove unused cruft --- libraries/fbx/src/FBXReader.cpp | 20 +------------------- libraries/fbx/src/FBXReader.h | 2 -- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 718793fefa..f4af39fdf4 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1631,13 +1631,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS // whether we're skinned depends on how many clusters are attached const FBXCluster& firstFBXCluster = extracted.mesh.clusters.at(0); - int maxJointIndex = firstFBXCluster.jointIndex; glm::mat4 inverseModelTransform = glm::inverse(modelTransform); if (clusterIDs.size() > 1) { // this is a multi-mesh joint extracted.mesh.clusterIndices.resize(extracted.mesh.vertices.size()); extracted.mesh.clusterWeights.resize(extracted.mesh.vertices.size()); - float maxWeight = 0.0f; for (int i = 0; i < clusterIDs.size(); i++) { QString clusterID = clusterIDs.at(i); const Cluster& cluster = clusters[clusterID]; @@ -1662,11 +1660,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform; ShapeVertices& points = shapeVertices.at(jointIndex); - float totalWeight = 0.0f; for (int j = 0; j < cluster.indices.size(); j++) { int oldIndex = cluster.indices.at(j); float weight = cluster.weights.at(j); - totalWeight += weight; for (QMultiHash::const_iterator it = extracted.newIndices.constFind(oldIndex); it != extracted.newIndices.end() && it.key() == oldIndex; it++) { @@ -1701,10 +1697,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } } - if (totalWeight > maxWeight) { - maxWeight = totalWeight; - maxJointIndex = jointIndex; - } } // normalize the weights if they don't add up to one for (int i = 0; i < extracted.mesh.clusterWeights.size(); i++) { @@ -1716,7 +1708,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } else { // this is a single-mesh joint - int jointIndex = maxJointIndex; + int jointIndex = firstFBXCluster.jointIndex; FBXJoint& joint = geometry.joints[jointIndex]; // transform cluster vertices to joint-frame and save for later @@ -1736,18 +1728,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } } - extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex); - buildModelMesh(extracted.mesh, url); - if (extracted.mesh.isEye) { - if (maxJointIndex == geometry.leftEyeJointIndex) { - geometry.leftEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale; - } else { - geometry.rightEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale; - } - } - geometry.meshes.append(extracted.mesh); int meshIndex = geometry.meshes.size() - 1; meshIDsToMeshIndices.insert(it.key(), meshIndex); diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index fa047e512f..3e38de74d6 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -219,8 +219,6 @@ public: Extents meshExtents; glm::mat4 modelTransform; - bool isEye; - QVector blendshapes; unsigned int meshIndex; // the order the meshes appeared in the object file From 18544581e6402393383e43282b14f67a60fe0cce Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 21 Mar 2017 15:15:02 -0700 Subject: [PATCH 2/8] remove warnings about implicit float cast --- interface/src/ui/AvatarInputs.cpp | 4 ++-- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index 944be4bf9e..63e7dcdad9 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -46,7 +46,7 @@ AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) { #define AI_UPDATE_FLOAT(name, src, epsilon) \ { \ float val = src; \ - if (fabs(_##name - val) >= epsilon) { \ + if (fabsf(_##name - val) >= epsilon) { \ _##name = val; \ emit name##Changed(); \ } \ @@ -82,7 +82,7 @@ void AvatarInputs::update() { if (audioLevel > 1.0f) { audioLevel = 1.0; } - AI_UPDATE_FLOAT(audioLevel, audioLevel, 0.01); + AI_UPDATE_FLOAT(audioLevel, audioLevel, 0.01f); AI_UPDATE(audioClipping, ((audioIO->getTimeSinceLastClip() > 0.0f) && (audioIO->getTimeSinceLastClip() < 1.0f))); AI_UPDATE(audioMuted, audioIO->isMuted()); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 31284b2f69..050635a063 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1038,7 +1038,7 @@ void EntityTreeRenderer::playEntityCollisionSound(EntityItemPointer entity, cons // Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2) const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f; - const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); + const float stretchFactor = logf(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / logf(2.0f); AudioInjector::playSound(collisionSound, volume, stretchFactor, collision.contactPoint); } From f6d6c62fab7766595ecdf2e0381015f6e1c712b1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 21 Mar 2017 15:15:15 -0700 Subject: [PATCH 3/8] move variable closer to context where it is used --- libraries/ui/src/ui/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ui/src/ui/Menu.cpp b/libraries/ui/src/ui/Menu.cpp index a793942056..50833e90fc 100644 --- a/libraries/ui/src/ui/Menu.cpp +++ b/libraries/ui/src/ui/Menu.cpp @@ -471,10 +471,10 @@ void Menu::removeSeparator(const QString& menuName, const QString& separatorName int textAt = findPositionOfMenuItem(menu, separatorName); QList menuActions = menu->actions(); if (textAt > 0 && textAt < menuActions.size()) { - QAction* separatorText = menuActions[textAt]; QAction* separatorLine = menuActions[textAt - 1]; if (separatorLine) { if (separatorLine->isSeparator()) { + QAction* separatorText = menuActions[textAt]; menu->removeAction(separatorText); menu->removeAction(separatorLine); separatorRemoved = true; From 60bc76e1c4cf4bbee488e94180bc8f86bc481533 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 Mar 2017 10:35:10 -0700 Subject: [PATCH 4/8] store cluster indices and weights in uint16_t --- libraries/fbx/src/FBXReader.cpp | 56 +++++++++++++++++---------- libraries/fbx/src/FBXReader.h | 8 ++-- libraries/fbx/src/FBXReader_Mesh.cpp | 57 ++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 27 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index f4af39fdf4..64ee0bc869 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1634,8 +1634,12 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS glm::mat4 inverseModelTransform = glm::inverse(modelTransform); if (clusterIDs.size() > 1) { // this is a multi-mesh joint - extracted.mesh.clusterIndices.resize(extracted.mesh.vertices.size()); - extracted.mesh.clusterWeights.resize(extracted.mesh.vertices.size()); + const int WEIGHTS_PER_VERTEX = 4; + int numClusterIndices = extracted.mesh.vertices.size() * WEIGHTS_PER_VERTEX; + extracted.mesh.clusterIndices.fill(0, numClusterIndices); + QVector weightAccumulators; + weightAccumulators.fill(0.0f, numClusterIndices); + for (int i = 0; i < clusterIDs.size(); i++) { QString clusterID = clusterIDs.at(i); const Cluster& cluster = clusters[clusterID]; @@ -1665,45 +1669,59 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS float weight = cluster.weights.at(j); for (QMultiHash::const_iterator it = extracted.newIndices.constFind(oldIndex); it != extracted.newIndices.end() && it.key() == oldIndex; it++) { + int newIndex = it.value(); // remember vertices with at least 1/4 weight const float EXPANSION_WEIGHT_THRESHOLD = 0.99f; if (weight > EXPANSION_WEIGHT_THRESHOLD) { // transform to joint-frame and save for later - const glm::mat4 vertexTransform = meshToJoint * glm::translate(extracted.mesh.vertices.at(it.value())); + const glm::mat4 vertexTransform = meshToJoint * glm::translate(extracted.mesh.vertices.at(newIndex)); points.push_back(extractTranslation(vertexTransform) * clusterScale); } // look for an unused slot in the weights vector - glm::vec4& weights = extracted.mesh.clusterWeights[it.value()]; + int weightIndex = newIndex * WEIGHTS_PER_VERTEX; int lowestIndex = -1; float lowestWeight = FLT_MAX; int k = 0; - for (; k < 4; k++) { - if (weights[k] == 0.0f) { - extracted.mesh.clusterIndices[it.value()][k] = i; - weights[k] = weight; + for (; k < WEIGHTS_PER_VERTEX; k++) { + if (weightAccumulators[weightIndex + k] == 0.0f) { + extracted.mesh.clusterIndices[weightIndex + k] = i; + weightAccumulators[weightIndex + k] = weight; break; } - if (weights[k] < lowestWeight) { + if (weightAccumulators[weightIndex + k] < lowestWeight) { lowestIndex = k; - lowestWeight = weights[k]; + lowestWeight = weightAccumulators[weightIndex + k]; } } - if (k == 4 && weight > lowestWeight) { + if (k == WEIGHTS_PER_VERTEX && weight > lowestWeight) { // no space for an additional weight; we must replace the lowest - weights[lowestIndex] = weight; - extracted.mesh.clusterIndices[it.value()][lowestIndex] = i; + weightAccumulators[weightIndex + lowestIndex] = weight; + extracted.mesh.clusterIndices[weightIndex + lowestIndex] = i; } } } } - // normalize the weights if they don't add up to one - for (int i = 0; i < extracted.mesh.clusterWeights.size(); i++) { - glm::vec4& weights = extracted.mesh.clusterWeights[i]; - float total = weights.x + weights.y + weights.z + weights.w; - if (total != 1.0f && total != 0.0f) { - weights /= total; + + // now that we've accumulated the most relevant weights for each vertex + // normalize and compress to 8-bits + extracted.mesh.clusterWeights.fill(0, numClusterIndices); + int numVertices = extracted.mesh.vertices.size(); + for (int i = 0; i < numVertices; ++i) { + int j = i * WEIGHTS_PER_VERTEX; + + // normalize weights into uint8_t + float totalWeight = weightAccumulators[j]; + for (int k = j + 1; k < j + WEIGHTS_PER_VERTEX; ++k) { + totalWeight += weightAccumulators[k]; + } + if (totalWeight > 0.0f) { + const float ALMOST_HALF = 0.499f; + float weightScalingFactor = (float)(UINT8_MAX) / totalWeight; + for (int k = j; k < j + WEIGHTS_PER_VERTEX; ++k) { + extracted.mesh.clusterWeights[k] = (uint8_t)(weightScalingFactor * weightAccumulators[k] + ALMOST_HALF); + } } } } else { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3e38de74d6..f73088e7a1 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -202,7 +202,7 @@ public: /// A single mesh (with optional blendshapes) extracted from an FBX document. class FBXMesh { public: - + QVector parts; QVector vertices; @@ -211,9 +211,9 @@ public: QVector colors; QVector texCoords; QVector texCoords1; - QVector clusterIndices; - QVector clusterWeights; - + QVector clusterIndices; + QVector clusterWeights; + QVector clusters; Extents meshExtents; diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 8eb31b0731..9f1ccbbe47 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -422,8 +422,18 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { int colorsSize = fbxMesh.colors.size() * sizeof(glm::vec3); int texCoordsSize = fbxMesh.texCoords.size() * sizeof(glm::vec2); int texCoords1Size = fbxMesh.texCoords1.size() * sizeof(glm::vec2); - int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(glm::vec4); - int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(glm::vec4); +#define UNFORTUNATE_HACK +#ifdef UNFORTUNATE_HACK + // HACK: store clusterIndices in floats rather than short integers + int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(float); +#else // UNFORTUNATE_HACK + int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(uint8_t); + if (fbxMesh.clusters.size() > UINT8_MAX) { + // we need 16 bits instead of just 8 for clusterIndices + clusterIndicesSize *= 2; + } +#endif // UNFORTUNATE_HACK + int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(uint8_t); int normalsOffset = 0; int tangentsOffset = normalsOffset + normalsSize; @@ -442,7 +452,31 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribBuffer->setSubData(colorsOffset, colorsSize, (gpu::Byte*) fbxMesh.colors.constData()); attribBuffer->setSubData(texCoordsOffset, texCoordsSize, (gpu::Byte*) fbxMesh.texCoords.constData()); attribBuffer->setSubData(texCoords1Offset, texCoords1Size, (gpu::Byte*) fbxMesh.texCoords1.constData()); - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) fbxMesh.clusterIndices.constData()); +#ifdef UNFORTUNATE_HACK + // HACK: copy clusterIndices back into floats to appease render pipeline + QVector clusterIndices; + int32_t numIndices = fbxMesh.clusterIndices.size(); + clusterIndices.resize(numIndices); + for (int32_t i = 0; i < numIndices; ++i) { + assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); + clusterIndices[i] = (float)(fbxMesh.clusterIndices[i]); + } + attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) clusterIndices.constData()); +#else // UNFORTUNATE_HACK + if (fbxMesh.clusters.size() < UINT8_MAX) { + // yay! we can fit the clusterIndices within 8-bits + int32_t numIndices = fbxMesh.clusterIndices.size(); + QVector clusterIndices; + clusterIndices.resize(numIndices); + for (int32_t i = 0; i < numIndices; ++i) { + assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); + clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); + } + attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) clusterIndices.constData()); + } else { + attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) fbxMesh.clusterIndices.constData()); + } +#endif // UNFORTUNATE_HACK attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (gpu::Byte*) fbxMesh.clusterWeights.constData()); if (normalsSize) { @@ -475,15 +509,30 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } +#ifdef UNFORTUNATE_HACK + // HACK: cluster indices are submitted to render pipeline in FLOAT format if (clusterIndicesSize) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); } +#else // UNFORTUNATE_HACK + if (clusterIndicesSize) { + if (fbxMesh.clusters.size() < UINT8_MAX) { + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, + gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); + } else { + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, + gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); + } + } +#endif // UNFORTUNATE_HACK if (clusterWeightsSize) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, - gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::XYZW))); } From fcf18cba91e924b23a4d5cf5227d3e141b5b95de Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 Mar 2017 10:35:58 -0700 Subject: [PATCH 5/8] render pipeline support for normalized intergers --- libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 9 +++++++-- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 7 +++++-- libraries/gpu/src/gpu/Format.h | 12 ++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 638841b170..51a24563f3 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -99,8 +99,13 @@ void GL41Backend::updateInput() { GLboolean isNormalized = attrib._element.isNormalized(); for (size_t locNum = 0; locNum < locationCount; ++locNum) { - glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, - reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); + if (attrib._element.isInteger()) { + glVertexAttribIPointer(slot + (GLuint)locNum, count, type, stride, + reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); + } else { + glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, + reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); + } #ifdef GPU_STEREO_DRAWCALL_INSTANCED glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency * (isStereo() ? 2 : 1)); #else diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 01bd2d7bce..ece62e15f1 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -61,8 +61,11 @@ void GL45Backend::updateInput() { _input._attributeActivation.set(attriNum); glEnableVertexAttribArray(attriNum); } - glVertexAttribFormat(attriNum, count, type, isNormalized, offset + locNum * perLocationSize); - // TODO: Support properly the IAttrib version + if (attrib._element.isInteger()) { + glVertexAttribIFormat(attriNum, count, type, offset + locNum * perLocationSize); + } else { + glVertexAttribFormat(attriNum, count, type, isNormalized, offset + locNum * perLocationSize); + } glVertexAttribBinding(attriNum, attrib._channel); } diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 493a2de3c2..4114ccb15c 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -75,12 +75,12 @@ static const bool TYPE_IS_INTEGER[NUM_TYPES] = { true, // Normalized values - true, - true, - true, - true, - true, - true + false, + false, + false, + false, + false, + false }; // Dimension of an Element From ff2f4da4b25eec2e7a6e30eb25d6557da9b48555 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 27 Mar 2017 15:19:28 -0700 Subject: [PATCH 6/8] final changes as per samcake --- libraries/fbx/src/FBXReader_Mesh.cpp | 29 ++----------------------- libraries/gpu/src/gpu/Inputs.slh | 2 +- libraries/render-utils/src/Skinning.slh | 12 +++++----- 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 9f1ccbbe47..4e153dfe3a 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -422,17 +422,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { int colorsSize = fbxMesh.colors.size() * sizeof(glm::vec3); int texCoordsSize = fbxMesh.texCoords.size() * sizeof(glm::vec2); int texCoords1Size = fbxMesh.texCoords1.size() * sizeof(glm::vec2); -#define UNFORTUNATE_HACK -#ifdef UNFORTUNATE_HACK - // HACK: store clusterIndices in floats rather than short integers - int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(float); -#else // UNFORTUNATE_HACK + int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(uint8_t); if (fbxMesh.clusters.size() > UINT8_MAX) { // we need 16 bits instead of just 8 for clusterIndices clusterIndicesSize *= 2; } -#endif // UNFORTUNATE_HACK int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(uint8_t); int normalsOffset = 0; @@ -452,17 +447,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribBuffer->setSubData(colorsOffset, colorsSize, (gpu::Byte*) fbxMesh.colors.constData()); attribBuffer->setSubData(texCoordsOffset, texCoordsSize, (gpu::Byte*) fbxMesh.texCoords.constData()); attribBuffer->setSubData(texCoords1Offset, texCoords1Size, (gpu::Byte*) fbxMesh.texCoords1.constData()); -#ifdef UNFORTUNATE_HACK - // HACK: copy clusterIndices back into floats to appease render pipeline - QVector clusterIndices; - int32_t numIndices = fbxMesh.clusterIndices.size(); - clusterIndices.resize(numIndices); - for (int32_t i = 0; i < numIndices; ++i) { - assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); - clusterIndices[i] = (float)(fbxMesh.clusterIndices[i]); - } - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) clusterIndices.constData()); -#else // UNFORTUNATE_HACK + if (fbxMesh.clusters.size() < UINT8_MAX) { // yay! we can fit the clusterIndices within 8-bits int32_t numIndices = fbxMesh.clusterIndices.size(); @@ -476,7 +461,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } else { attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (gpu::Byte*) fbxMesh.clusterIndices.constData()); } -#endif // UNFORTUNATE_HACK attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (gpu::Byte*) fbxMesh.clusterWeights.constData()); if (normalsSize) { @@ -509,14 +493,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } -#ifdef UNFORTUNATE_HACK - // HACK: cluster indices are submitted to render pipeline in FLOAT format - if (clusterIndicesSize) { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, - gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); - } -#else // UNFORTUNATE_HACK if (clusterIndicesSize) { if (fbxMesh.clusters.size() < UINT8_MAX) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, @@ -528,7 +504,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); } } -#endif // UNFORTUNATE_HACK if (clusterWeightsSize) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, diff --git a/libraries/gpu/src/gpu/Inputs.slh b/libraries/gpu/src/gpu/Inputs.slh index ce5e4227eb..843d1059f2 100644 --- a/libraries/gpu/src/gpu/Inputs.slh +++ b/libraries/gpu/src/gpu/Inputs.slh @@ -15,7 +15,7 @@ layout(location = 1) in vec4 inNormal; layout(location = 2) in vec4 inColor; layout(location = 3) in vec4 inTexCoord0; layout(location = 4) in vec4 inTangent; -layout(location = 5) in vec4 inSkinClusterIndex; +layout(location = 5) in ivec4 inSkinClusterIndex; layout(location = 6) in vec4 inSkinClusterWeight; layout(location = 7) in vec4 inTexCoord1; <@endif@> diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 687dab536b..2d1f010029 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -18,11 +18,11 @@ layout(std140) uniform skinClusterBuffer { mat4 clusterMatrices[MAX_CLUSTERS]; }; -void skinPosition(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) { +void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) { vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; newPosition += clusterMatrix * inPosition * clusterWeight; } @@ -30,13 +30,13 @@ void skinPosition(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition skinnedPosition = newPosition; } -void skinPositionNormal(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, +void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, out vec4 skinnedPosition, out vec3 skinnedNormal) { vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; newPosition += clusterMatrix * inPosition * clusterWeight; newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; @@ -46,14 +46,14 @@ void skinPositionNormal(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPo skinnedNormal = newNormal.xyz; } -void skinPositionNormalTangent(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent, +void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent, out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) { vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0); vec4 newTangent = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])]; float clusterWeight = skinClusterWeight[i]; newPosition += clusterMatrix * inPosition * clusterWeight; newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; From 92b41d7a3848b01c4b87a0e4b3c3a3a2db935622 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 27 Mar 2017 15:50:40 -0700 Subject: [PATCH 7/8] fix link error for linux build --- libraries/gpu-gl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/gpu-gl/CMakeLists.txt b/libraries/gpu-gl/CMakeLists.txt index 65df5ed9dc..e665b7a28e 100644 --- a/libraries/gpu-gl/CMakeLists.txt +++ b/libraries/gpu-gl/CMakeLists.txt @@ -1,6 +1,7 @@ set(TARGET_NAME gpu-gl) setup_hifi_library() link_hifi_libraries(shared gl gpu) +target_link_libraries(${TARGET_NAME} pthread) GroupSources("src") target_opengl() From 5fc1e9716605871eb74b5fe8e1d4e860600c44d4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 27 Mar 2017 16:49:43 -0700 Subject: [PATCH 8/8] fix windows build of render-utils-test --- libraries/gpu-gl/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/gpu-gl/CMakeLists.txt b/libraries/gpu-gl/CMakeLists.txt index e665b7a28e..3e3853532a 100644 --- a/libraries/gpu-gl/CMakeLists.txt +++ b/libraries/gpu-gl/CMakeLists.txt @@ -1,7 +1,9 @@ set(TARGET_NAME gpu-gl) setup_hifi_library() link_hifi_libraries(shared gl gpu) -target_link_libraries(${TARGET_NAME} pthread) +if (UNIX) + target_link_libraries(${TARGET_NAME} pthread) +endif(UNIX) GroupSources("src") target_opengl()