mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:17:02 +02:00
improved collision shapes for fingers
This commit is contained in:
parent
53ee5f2340
commit
58e31abf60
1 changed files with 30 additions and 19 deletions
|
@ -967,19 +967,19 @@ QString getString(const QVariant& value) {
|
||||||
|
|
||||||
class JointShapeInfo {
|
class JointShapeInfo {
|
||||||
public:
|
public:
|
||||||
JointShapeInfo() : numVertices(0), numProjectedVertices(0),
|
JointShapeInfo() : numVertices(0),
|
||||||
sumVertexWeights(0.0f), sumWeightedRadii(0.0f),
|
sumVertexWeights(0.0f), sumWeightedRadii(0.0f), numVertexWeights(0),
|
||||||
averageVertex(0.f), boneBegin(0.f), averageRadius(0.f) {
|
averageVertex(0.f), boneBegin(0.f), averageRadius(0.f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: the points here are in the "joint frame" which has the "jointEnd" at the origin
|
// NOTE: the points here are in the "joint frame" which has the "jointEnd" at the origin
|
||||||
int numVertices; // num vertices from contributing meshes
|
int numVertices; // num vertices from contributing meshes
|
||||||
int numProjectedVertices; // num vertices that successfully project onto bone axis
|
float sumVertexWeights; // sum of all vertex weights
|
||||||
float sumVertexWeights;
|
float sumWeightedRadii; // sum of weighted vertices
|
||||||
float sumWeightedRadii;
|
int numVertexWeights; // num vertices that contributed to sums
|
||||||
glm::vec3 averageVertex; // average of all mesh vertices (in joint frame)
|
glm::vec3 averageVertex;// average of all mesh vertices (in joint frame)
|
||||||
glm::vec3 boneBegin; // parent joint location (in joint frame)
|
glm::vec3 boneBegin; // parent joint location (in joint frame)
|
||||||
float averageRadius; // average distance from mesh points to averageVertex
|
float averageRadius; // average distance from mesh points to averageVertex
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimationCurve {
|
class AnimationCurve {
|
||||||
|
@ -1743,11 +1743,14 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
if (weight > EXPANSION_WEIGHT_THRESHOLD) {
|
if (weight > EXPANSION_WEIGHT_THRESHOLD) {
|
||||||
const glm::vec3& vertex = extracted.mesh.vertices.at(it.value());
|
const glm::vec3& vertex = extracted.mesh.vertices.at(it.value());
|
||||||
float proj = glm::dot(boneDirection, boneEnd - vertex);
|
float proj = glm::dot(boneDirection, boneEnd - vertex);
|
||||||
if (proj > 0.0f && proj < boneLength) {
|
if (proj < 0.0f || proj > boneLength) {
|
||||||
joint.boneRadius = glm::max(joint.boneRadius,
|
weight *= 0.5f;
|
||||||
radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj));
|
|
||||||
++jointShapeInfo.numProjectedVertices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jointShapeInfo.sumVertexWeights += weight;
|
||||||
|
jointShapeInfo.sumWeightedRadii += weight * radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj);
|
||||||
|
++jointShapeInfo.numVertexWeights;
|
||||||
|
|
||||||
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
|
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
|
||||||
jointShapeInfo.averageVertex += vertexInJointFrame;
|
jointShapeInfo.averageVertex += vertexInJointFrame;
|
||||||
++jointShapeInfo.numVertices;
|
++jointShapeInfo.numVertices;
|
||||||
|
@ -1793,11 +1796,15 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
|
|
||||||
glm::vec3 averageVertex(0.f);
|
glm::vec3 averageVertex(0.f);
|
||||||
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
|
||||||
|
float weight = 1.0f;
|
||||||
float proj = glm::dot(boneDirection, boneEnd - vertex);
|
float proj = glm::dot(boneDirection, boneEnd - vertex);
|
||||||
if (proj > 0.0f && proj < boneLength) {
|
if (proj < 0.0f || proj > boneLength) {
|
||||||
joint.boneRadius = glm::max(joint.boneRadius, radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj));
|
weight *= 0.5f;
|
||||||
++jointShapeInfo.numProjectedVertices;
|
|
||||||
}
|
}
|
||||||
|
jointShapeInfo.sumVertexWeights += weight;
|
||||||
|
jointShapeInfo.sumWeightedRadii += weight * radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj);
|
||||||
|
++jointShapeInfo.numVertexWeights;
|
||||||
|
|
||||||
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
|
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
|
||||||
jointShapeInfo.averageVertex += vertexInJointFrame;
|
jointShapeInfo.averageVertex += vertexInJointFrame;
|
||||||
averageVertex += vertex;
|
averageVertex += vertex;
|
||||||
|
@ -1832,9 +1839,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
jointShapeInfo.boneBegin = inverseRotation * (extractTranslation(parentJoint.transform) - extractTranslation(joint.transform));
|
jointShapeInfo.boneBegin = inverseRotation * (extractTranslation(parentJoint.transform) - extractTranslation(joint.transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
// we use a capsule if the joint ANY mesh vertices successfully projected onto the bone
|
if (jointShapeInfo.sumVertexWeights > 0.0f) {
|
||||||
|
joint.boneRadius = jointShapeInfo.sumWeightedRadii / jointShapeInfo.sumVertexWeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we use a capsule if the joint had ANY mesh vertices successfully projected onto the bone
|
||||||
// AND its boneRadius is not too close to zero
|
// AND its boneRadius is not too close to zero
|
||||||
bool collideLikeCapsule = jointShapeInfo.numProjectedVertices > 0
|
bool collideLikeCapsule = jointShapeInfo.numVertexWeights > 0
|
||||||
&& glm::length(jointShapeInfo.boneBegin) > EPSILON;
|
&& glm::length(jointShapeInfo.boneBegin) > EPSILON;
|
||||||
|
|
||||||
if (collideLikeCapsule) {
|
if (collideLikeCapsule) {
|
||||||
|
@ -1850,7 +1861,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
||||||
} else {
|
} else {
|
||||||
joint.shapePosition = glm::vec3(0.f);
|
joint.shapePosition = glm::vec3(0.f);
|
||||||
}
|
}
|
||||||
if (jointShapeInfo.numProjectedVertices == 0
|
if (jointShapeInfo.numVertexWeights == 0
|
||||||
&& jointShapeInfo.numVertices > 0) {
|
&& jointShapeInfo.numVertices > 0) {
|
||||||
// the bone projection algorithm was not able to compute the joint radius
|
// the bone projection algorithm was not able to compute the joint radius
|
||||||
// so we use an alternative measure
|
// so we use an alternative measure
|
||||||
|
|
Loading…
Reference in a new issue