mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-23 19:09:18 +02:00
Removed "springiness" bits.
This commit is contained in:
parent
8413a3cacd
commit
299dbb93ea
5 changed files with 58 additions and 211 deletions
|
@ -1331,14 +1331,11 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
geometry.staticExtents.reset();
|
geometry.staticExtents.reset();
|
||||||
geometry.meshExtents.reset();
|
geometry.meshExtents.reset();
|
||||||
|
|
||||||
QVariantHash springs = mapping.value("spring").toHash();
|
|
||||||
QVariant defaultSpring = springs.value("default");
|
|
||||||
for (QHash<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
for (QHash<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
|
||||||
ExtractedMesh& extracted = it.value();
|
ExtractedMesh& extracted = it.value();
|
||||||
|
|
||||||
// accumulate local transforms
|
// accumulate local transforms
|
||||||
QString modelID = models.contains(it.key()) ? it.key() : parentMap.value(it.key());
|
QString modelID = models.contains(it.key()) ? it.key() : parentMap.value(it.key());
|
||||||
extracted.mesh.springiness = springs.value(models.value(modelID).name, defaultSpring).toFloat();
|
|
||||||
glm::mat4 modelTransform = getGlobalTransform(parentMap, models, modelID);
|
glm::mat4 modelTransform = getGlobalTransform(parentMap, models, modelID);
|
||||||
|
|
||||||
// compute the mesh extents from the transformed vertices
|
// compute the mesh extents from the transformed vertices
|
||||||
|
@ -1591,49 +1588,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex);
|
||||||
|
|
||||||
// extract spring edges, connections if springy
|
|
||||||
if (extracted.mesh.springiness > 0.0f) {
|
|
||||||
QSet<QPair<int, int> > edges;
|
|
||||||
|
|
||||||
extracted.mesh.vertexConnections.resize(extracted.mesh.vertices.size());
|
|
||||||
foreach (const FBXMeshPart& part, extracted.mesh.parts) {
|
|
||||||
for (int i = 0; i < part.quadIndices.size(); i += 4) {
|
|
||||||
int index0 = part.quadIndices.at(i);
|
|
||||||
int index1 = part.quadIndices.at(i + 1);
|
|
||||||
int index2 = part.quadIndices.at(i + 2);
|
|
||||||
int index3 = part.quadIndices.at(i + 3);
|
|
||||||
|
|
||||||
edges.insert(QPair<int, int>(qMin(index0, index1), qMax(index0, index1)));
|
|
||||||
edges.insert(QPair<int, int>(qMin(index1, index2), qMax(index1, index2)));
|
|
||||||
edges.insert(QPair<int, int>(qMin(index2, index3), qMax(index2, index3)));
|
|
||||||
edges.insert(QPair<int, int>(qMin(index3, index0), qMax(index3, index0)));
|
|
||||||
|
|
||||||
extracted.mesh.vertexConnections[index0].append(QPair<int, int>(index3, index1));
|
|
||||||
extracted.mesh.vertexConnections[index1].append(QPair<int, int>(index0, index2));
|
|
||||||
extracted.mesh.vertexConnections[index2].append(QPair<int, int>(index1, index3));
|
|
||||||
extracted.mesh.vertexConnections[index3].append(QPair<int, int>(index2, index0));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < part.triangleIndices.size(); i += 3) {
|
|
||||||
int index0 = part.triangleIndices.at(i);
|
|
||||||
int index1 = part.triangleIndices.at(i + 1);
|
|
||||||
int index2 = part.triangleIndices.at(i + 2);
|
|
||||||
|
|
||||||
edges.insert(QPair<int, int>(qMin(index0, index1), qMax(index0, index1)));
|
|
||||||
edges.insert(QPair<int, int>(qMin(index1, index2), qMax(index1, index2)));
|
|
||||||
edges.insert(QPair<int, int>(qMin(index2, index0), qMax(index2, index0)));
|
|
||||||
|
|
||||||
extracted.mesh.vertexConnections[index0].append(QPair<int, int>(index2, index1));
|
|
||||||
extracted.mesh.vertexConnections[index1].append(QPair<int, int>(index0, index2));
|
|
||||||
extracted.mesh.vertexConnections[index2].append(QPair<int, int>(index1, index0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (QSet<QPair<int, int> >::const_iterator edge = edges.constBegin(); edge != edges.constEnd(); edge++) {
|
|
||||||
extracted.mesh.springEdges.append(*edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
geometry.meshes.append(extracted.mesh);
|
geometry.meshes.append(extracted.mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1797,7 +1752,6 @@ FBXGeometry readSVO(const QByteArray& model) {
|
||||||
// and one mesh with one cluster and one part
|
// and one mesh with one cluster and one part
|
||||||
FBXMesh mesh;
|
FBXMesh mesh;
|
||||||
mesh.isEye = false;
|
mesh.isEye = false;
|
||||||
mesh.springiness = 0.0f;
|
|
||||||
|
|
||||||
FBXCluster cluster = { 0 };
|
FBXCluster cluster = { 0 };
|
||||||
mesh.clusters.append(cluster);
|
mesh.clusters.append(cluster);
|
||||||
|
|
|
@ -130,10 +130,6 @@ public:
|
||||||
bool isEye;
|
bool isEye;
|
||||||
|
|
||||||
QVector<FBXBlendshape> blendshapes;
|
QVector<FBXBlendshape> blendshapes;
|
||||||
|
|
||||||
float springiness;
|
|
||||||
QVector<QPair<int, int> > springEdges;
|
|
||||||
QVector<QVarLengthArray<QPair<int, int>, 4> > vertexConnections;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An attachment to an FBX document.
|
/// An attachment to an FBX document.
|
||||||
|
|
|
@ -565,8 +565,8 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
||||||
networkMesh.vertexBuffer.bind();
|
networkMesh.vertexBuffer.bind();
|
||||||
networkMesh.vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
networkMesh.vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
|
||||||
|
|
||||||
// if we don't need to do any blending or springing, then the positions/normals can be static
|
// if we don't need to do any blending, the positions/normals can be static
|
||||||
if (mesh.blendshapes.isEmpty() && mesh.springiness == 0.0f) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
int normalsOffset = mesh.vertices.size() * sizeof(glm::vec3);
|
int normalsOffset = mesh.vertices.size() * sizeof(glm::vec3);
|
||||||
int tangentsOffset = normalsOffset + mesh.normals.size() * sizeof(glm::vec3);
|
int tangentsOffset = normalsOffset + mesh.normals.size() * sizeof(glm::vec3);
|
||||||
int colorsOffset = tangentsOffset + mesh.tangents.size() * sizeof(glm::vec3);
|
int colorsOffset = tangentsOffset + mesh.tangents.size() * sizeof(glm::vec3);
|
||||||
|
@ -587,8 +587,8 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
||||||
networkMesh.vertexBuffer.write(clusterWeightsOffset, mesh.clusterWeights.constData(),
|
networkMesh.vertexBuffer.write(clusterWeightsOffset, mesh.clusterWeights.constData(),
|
||||||
mesh.clusterWeights.size() * sizeof(glm::vec4));
|
mesh.clusterWeights.size() * sizeof(glm::vec4));
|
||||||
|
|
||||||
// if there's no springiness, then the cluster indices/weights can be static
|
// otherwise, at least the cluster indices/weights can be static
|
||||||
} else if (mesh.springiness == 0.0f) {
|
} else {
|
||||||
int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
|
int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
|
||||||
int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3);
|
int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3);
|
||||||
int clusterIndicesOffset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2);
|
int clusterIndicesOffset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2);
|
||||||
|
@ -601,16 +601,7 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {
|
||||||
networkMesh.vertexBuffer.write(clusterIndicesOffset, mesh.clusterIndices.constData(),
|
networkMesh.vertexBuffer.write(clusterIndicesOffset, mesh.clusterIndices.constData(),
|
||||||
mesh.clusterIndices.size() * sizeof(glm::vec4));
|
mesh.clusterIndices.size() * sizeof(glm::vec4));
|
||||||
networkMesh.vertexBuffer.write(clusterWeightsOffset, mesh.clusterWeights.constData(),
|
networkMesh.vertexBuffer.write(clusterWeightsOffset, mesh.clusterWeights.constData(),
|
||||||
mesh.clusterWeights.size() * sizeof(glm::vec4));
|
mesh.clusterWeights.size() * sizeof(glm::vec4));
|
||||||
|
|
||||||
} else {
|
|
||||||
int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3);
|
|
||||||
int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3);
|
|
||||||
networkMesh.vertexBuffer.allocate(texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2));
|
|
||||||
networkMesh.vertexBuffer.write(0, mesh.tangents.constData(), mesh.tangents.size() * sizeof(glm::vec3));
|
|
||||||
networkMesh.vertexBuffer.write(colorsOffset, mesh.colors.constData(), mesh.colors.size() * sizeof(glm::vec3));
|
|
||||||
networkMesh.vertexBuffer.write(texCoordsOffset, mesh.texCoords.constData(),
|
|
||||||
mesh.texCoords.size() * sizeof(glm::vec2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
networkMesh.vertexBuffer.release();
|
networkMesh.vertexBuffer.release();
|
||||||
|
|
|
@ -175,7 +175,7 @@ bool Model::render(float alpha) {
|
||||||
if (_blendedVertexBufferIDs.isEmpty()) {
|
if (_blendedVertexBufferIDs.isEmpty()) {
|
||||||
foreach (const FBXMesh& mesh, geometry.meshes) {
|
foreach (const FBXMesh& mesh, geometry.meshes) {
|
||||||
GLuint id = 0;
|
GLuint id = 0;
|
||||||
if (!mesh.blendshapes.isEmpty() || mesh.springiness > 0.0f) {
|
if (!mesh.blendshapes.isEmpty()) {
|
||||||
glGenBuffers(1, &id);
|
glGenBuffers(1, &id);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, id);
|
glBindBuffer(GL_ARRAY_BUFFER, id);
|
||||||
glBufferData(GL_ARRAY_BUFFER, (mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3),
|
glBufferData(GL_ARRAY_BUFFER, (mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3),
|
||||||
|
@ -490,11 +490,6 @@ void Model::simulate(float deltaTime, bool fullUpdate, const QVector<JointState>
|
||||||
foreach (const FBXMesh& mesh, geometry.meshes) {
|
foreach (const FBXMesh& mesh, geometry.meshes) {
|
||||||
MeshState state;
|
MeshState state;
|
||||||
state.clusterMatrices.resize(mesh.clusters.size());
|
state.clusterMatrices.resize(mesh.clusters.size());
|
||||||
if (mesh.springiness > 0.0f) {
|
|
||||||
state.worldSpaceVertices.resize(mesh.vertices.size());
|
|
||||||
state.vertexVelocities.resize(mesh.vertices.size());
|
|
||||||
state.worldSpaceNormals.resize(mesh.vertices.size());
|
|
||||||
}
|
|
||||||
_meshStates.append(state);
|
_meshStates.append(state);
|
||||||
}
|
}
|
||||||
foreach (const FBXAttachment& attachment, geometry.attachments) {
|
foreach (const FBXAttachment& attachment, geometry.attachments) {
|
||||||
|
@ -541,80 +536,6 @@ void Model::simulate(float deltaTime, bool fullUpdate, const QVector<JointState>
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
state.clusterMatrices[j] = _jointStates[cluster.jointIndex].transform * cluster.inverseBindMatrix;
|
state.clusterMatrices[j] = _jointStates[cluster.jointIndex].transform * cluster.inverseBindMatrix;
|
||||||
}
|
}
|
||||||
int vertexCount = state.worldSpaceVertices.size();
|
|
||||||
if (vertexCount == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
glm::vec3* destVertices = state.worldSpaceVertices.data();
|
|
||||||
glm::vec3* destVelocities = state.vertexVelocities.data();
|
|
||||||
glm::vec3* destNormals = state.worldSpaceNormals.data();
|
|
||||||
|
|
||||||
const glm::vec3* sourceVertices = mesh.vertices.constData();
|
|
||||||
if (!mesh.blendshapes.isEmpty()) {
|
|
||||||
_blendedVertices.resize(max(_blendedVertices.size(), vertexCount));
|
|
||||||
memcpy(_blendedVertices.data(), mesh.vertices.constData(), vertexCount * sizeof(glm::vec3));
|
|
||||||
|
|
||||||
// blend in each coefficient
|
|
||||||
for (unsigned int j = 0; j < _blendshapeCoefficients.size(); j++) {
|
|
||||||
float coefficient = _blendshapeCoefficients[j];
|
|
||||||
if (coefficient == 0.0f || j >= (unsigned int)mesh.blendshapes.size() || mesh.blendshapes[j].vertices.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const glm::vec3* vertex = mesh.blendshapes[j].vertices.constData();
|
|
||||||
for (const int* index = mesh.blendshapes[j].indices.constData(),
|
|
||||||
*end = index + mesh.blendshapes[j].indices.size(); index != end; index++, vertex++) {
|
|
||||||
_blendedVertices[*index] += *vertex * coefficient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sourceVertices = _blendedVertices.constData();
|
|
||||||
}
|
|
||||||
glm::mat4 transform = glm::translate(_translation);
|
|
||||||
if (mesh.clusters.size() > 1) {
|
|
||||||
_blendedVertices.resize(max(_blendedVertices.size(), vertexCount));
|
|
||||||
|
|
||||||
// skin each vertex
|
|
||||||
const glm::vec4* clusterIndices = mesh.clusterIndices.constData();
|
|
||||||
const glm::vec4* clusterWeights = mesh.clusterWeights.constData();
|
|
||||||
for (int j = 0; j < vertexCount; j++) {
|
|
||||||
_blendedVertices[j] =
|
|
||||||
glm::vec3(state.clusterMatrices[clusterIndices[j][0]] *
|
|
||||||
glm::vec4(sourceVertices[j], 1.0f)) * clusterWeights[j][0] +
|
|
||||||
glm::vec3(state.clusterMatrices[clusterIndices[j][1]] *
|
|
||||||
glm::vec4(sourceVertices[j], 1.0f)) * clusterWeights[j][1] +
|
|
||||||
glm::vec3(state.clusterMatrices[clusterIndices[j][2]] *
|
|
||||||
glm::vec4(sourceVertices[j], 1.0f)) * clusterWeights[j][2] +
|
|
||||||
glm::vec3(state.clusterMatrices[clusterIndices[j][3]] *
|
|
||||||
glm::vec4(sourceVertices[j], 1.0f)) * clusterWeights[j][3];
|
|
||||||
}
|
|
||||||
sourceVertices = _blendedVertices.constData();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
transform = state.clusterMatrices[0];
|
|
||||||
}
|
|
||||||
if (_resetStates) {
|
|
||||||
for (int j = 0; j < vertexCount; j++) {
|
|
||||||
destVertices[j] = glm::vec3(transform * glm::vec4(sourceVertices[j], 1.0f));
|
|
||||||
destVelocities[j] = glm::vec3();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const float SPRINGINESS_MULTIPLIER = 200.0f;
|
|
||||||
const float DAMPING = 5.0f;
|
|
||||||
for (int j = 0; j < vertexCount; j++) {
|
|
||||||
destVelocities[j] += ((glm::vec3(transform * glm::vec4(sourceVertices[j], 1.0f)) - destVertices[j]) *
|
|
||||||
mesh.springiness * SPRINGINESS_MULTIPLIER - destVelocities[j] * DAMPING) * deltaTime;
|
|
||||||
destVertices[j] += destVelocities[j] * deltaTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j = 0; j < vertexCount; j++) {
|
|
||||||
destNormals[j] = glm::vec3();
|
|
||||||
|
|
||||||
const glm::vec3& middle = destVertices[j];
|
|
||||||
for (QVarLengthArray<QPair<int, int>, 4>::const_iterator connection = mesh.vertexConnections.at(j).constBegin();
|
|
||||||
connection != mesh.vertexConnections.at(j).constEnd(); connection++) {
|
|
||||||
destNormals[j] += glm::normalize(glm::cross(destVertices[connection->second] - middle,
|
|
||||||
destVertices[connection->first] - middle));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_resetStates = false;
|
_resetStates = false;
|
||||||
}
|
}
|
||||||
|
@ -980,34 +901,30 @@ void Model::renderMeshes(float alpha, bool translucent) {
|
||||||
const MeshState& state = _meshStates.at(i);
|
const MeshState& state = _meshStates.at(i);
|
||||||
ProgramObject* activeProgram = program;
|
ProgramObject* activeProgram = program;
|
||||||
int tangentLocation = _normalMapTangentLocation;
|
int tangentLocation = _normalMapTangentLocation;
|
||||||
if (state.worldSpaceVertices.isEmpty()) {
|
glPushMatrix();
|
||||||
glPushMatrix();
|
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
||||||
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
|
||||||
|
if (state.clusterMatrices.size() > 1) {
|
||||||
if (state.clusterMatrices.size() > 1) {
|
skinProgram->bind();
|
||||||
skinProgram->bind();
|
glUniformMatrix4fvARB(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
|
||||||
glUniformMatrix4fvARB(skinLocations->clusterMatrices, state.clusterMatrices.size(), false,
|
(const float*)state.clusterMatrices.constData());
|
||||||
(const float*)state.clusterMatrices.constData());
|
int offset = (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3) +
|
||||||
int offset = (mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3) +
|
mesh.texCoords.size() * sizeof(glm::vec2) +
|
||||||
mesh.texCoords.size() * sizeof(glm::vec2) +
|
(mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0);
|
||||||
(mesh.blendshapes.isEmpty() ? vertexCount * 2 * sizeof(glm::vec3) : 0);
|
skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4);
|
||||||
skinProgram->setAttributeBuffer(skinLocations->clusterIndices, GL_FLOAT, offset, 4);
|
skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT,
|
||||||
skinProgram->setAttributeBuffer(skinLocations->clusterWeights, GL_FLOAT,
|
offset + vertexCount * sizeof(glm::vec4), 4);
|
||||||
offset + vertexCount * sizeof(glm::vec4), 4);
|
skinProgram->enableAttributeArray(skinLocations->clusterIndices);
|
||||||
skinProgram->enableAttributeArray(skinLocations->clusterIndices);
|
skinProgram->enableAttributeArray(skinLocations->clusterWeights);
|
||||||
skinProgram->enableAttributeArray(skinLocations->clusterWeights);
|
activeProgram = skinProgram;
|
||||||
activeProgram = skinProgram;
|
tangentLocation = skinLocations->tangent;
|
||||||
tangentLocation = skinLocations->tangent;
|
|
||||||
|
} else {
|
||||||
} else {
|
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
||||||
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
|
||||||
program->bind();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
program->bind();
|
program->bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.blendshapes.isEmpty() && mesh.springiness == 0.0f) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
if (!mesh.tangents.isEmpty()) {
|
if (!mesh.tangents.isEmpty()) {
|
||||||
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
||||||
activeProgram->enableAttributeArray(tangentLocation);
|
activeProgram->enableAttributeArray(tangentLocation);
|
||||||
|
@ -1026,38 +943,31 @@ void Model::renderMeshes(float alpha, bool translucent) {
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, (void*)((mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3)));
|
glTexCoordPointer(2, GL_FLOAT, 0, (void*)((mesh.tangents.size() + mesh.colors.size()) * sizeof(glm::vec3)));
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _blendedVertexBufferIDs.at(i));
|
glBindBuffer(GL_ARRAY_BUFFER, _blendedVertexBufferIDs.at(i));
|
||||||
|
|
||||||
if (!state.worldSpaceVertices.isEmpty()) {
|
_blendedVertices.resize(max(_blendedVertices.size(), vertexCount));
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * sizeof(glm::vec3), state.worldSpaceVertices.constData());
|
_blendedNormals.resize(_blendedVertices.size());
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, vertexCount * sizeof(glm::vec3),
|
memcpy(_blendedVertices.data(), mesh.vertices.constData(), vertexCount * sizeof(glm::vec3));
|
||||||
vertexCount * sizeof(glm::vec3), state.worldSpaceNormals.constData());
|
memcpy(_blendedNormals.data(), mesh.normals.constData(), vertexCount * sizeof(glm::vec3));
|
||||||
|
|
||||||
} else {
|
// blend in each coefficient
|
||||||
_blendedVertices.resize(max(_blendedVertices.size(), vertexCount));
|
for (unsigned int j = 0; j < _blendshapeCoefficients.size(); j++) {
|
||||||
_blendedNormals.resize(_blendedVertices.size());
|
float coefficient = _blendshapeCoefficients[j];
|
||||||
memcpy(_blendedVertices.data(), mesh.vertices.constData(), vertexCount * sizeof(glm::vec3));
|
if (coefficient == 0.0f || j >= (unsigned int)mesh.blendshapes.size() || mesh.blendshapes[j].vertices.isEmpty()) {
|
||||||
memcpy(_blendedNormals.data(), mesh.normals.constData(), vertexCount * sizeof(glm::vec3));
|
continue;
|
||||||
|
}
|
||||||
// blend in each coefficient
|
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
|
||||||
for (unsigned int j = 0; j < _blendshapeCoefficients.size(); j++) {
|
float normalCoefficient = coefficient * NORMAL_COEFFICIENT_SCALE;
|
||||||
float coefficient = _blendshapeCoefficients[j];
|
const glm::vec3* vertex = mesh.blendshapes[j].vertices.constData();
|
||||||
if (coefficient == 0.0f || j >= (unsigned int)mesh.blendshapes.size() || mesh.blendshapes[j].vertices.isEmpty()) {
|
const glm::vec3* normal = mesh.blendshapes[j].normals.constData();
|
||||||
continue;
|
for (const int* index = mesh.blendshapes[j].indices.constData(),
|
||||||
}
|
*end = index + mesh.blendshapes[j].indices.size(); index != end; index++, vertex++, normal++) {
|
||||||
const float NORMAL_COEFFICIENT_SCALE = 0.01f;
|
_blendedVertices[*index] += *vertex * coefficient;
|
||||||
float normalCoefficient = coefficient * NORMAL_COEFFICIENT_SCALE;
|
_blendedNormals[*index] += *normal * normalCoefficient;
|
||||||
const glm::vec3* vertex = mesh.blendshapes[j].vertices.constData();
|
|
||||||
const glm::vec3* normal = mesh.blendshapes[j].normals.constData();
|
|
||||||
for (const int* index = mesh.blendshapes[j].indices.constData(),
|
|
||||||
*end = index + mesh.blendshapes[j].indices.size(); index != end; index++, vertex++, normal++) {
|
|
||||||
_blendedVertices[*index] += *vertex * coefficient;
|
|
||||||
_blendedNormals[*index] += *normal * normalCoefficient;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * sizeof(glm::vec3), _blendedVertices.constData());
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, vertexCount * sizeof(glm::vec3),
|
|
||||||
vertexCount * sizeof(glm::vec3), _blendedNormals.constData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * sizeof(glm::vec3), _blendedVertices.constData());
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, vertexCount * sizeof(glm::vec3),
|
||||||
|
vertexCount * sizeof(glm::vec3), _blendedNormals.constData());
|
||||||
}
|
}
|
||||||
glVertexPointer(3, GL_FLOAT, 0, 0);
|
glVertexPointer(3, GL_FLOAT, 0, 0);
|
||||||
glNormalPointer(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3)));
|
glNormalPointer(GL_FLOAT, 0, (void*)(vertexCount * sizeof(glm::vec3)));
|
||||||
|
@ -1126,14 +1036,13 @@ void Model::renderMeshes(float alpha, bool translucent) {
|
||||||
|
|
||||||
activeProgram->disableAttributeArray(tangentLocation);
|
activeProgram->disableAttributeArray(tangentLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.worldSpaceVertices.isEmpty()) {
|
if (state.clusterMatrices.size() > 1) {
|
||||||
if (state.clusterMatrices.size() > 1) {
|
skinProgram->disableAttributeArray(skinLocations->clusterIndices);
|
||||||
skinProgram->disableAttributeArray(skinLocations->clusterIndices);
|
skinProgram->disableAttributeArray(skinLocations->clusterWeights);
|
||||||
skinProgram->disableAttributeArray(skinLocations->clusterWeights);
|
}
|
||||||
}
|
glPopMatrix();
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
activeProgram->release();
|
activeProgram->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,9 +219,6 @@ protected:
|
||||||
class MeshState {
|
class MeshState {
|
||||||
public:
|
public:
|
||||||
QVector<glm::mat4> clusterMatrices;
|
QVector<glm::mat4> clusterMatrices;
|
||||||
QVector<glm::vec3> worldSpaceVertices;
|
|
||||||
QVector<glm::vec3> vertexVelocities;
|
|
||||||
QVector<glm::vec3> worldSpaceNormals;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<MeshState> _meshStates;
|
QVector<MeshState> _meshStates;
|
||||||
|
|
Loading…
Reference in a new issue