improved method for disabling bad joint shapes

This commit is contained in:
Andrew Meadows 2014-04-17 16:22:35 -07:00
parent 3072161a30
commit cfdbdad2d8
3 changed files with 24 additions and 12 deletions

View file

@ -1651,8 +1651,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
if (distanceFromEnd > joint.distanceToParent && distanceFromBegin > joint.distanceToParent) {
// The shape is further from both joint endpoints than the endpoints are from each other
// which probably means the model has a bad transform somewhere. We disable this shape
// by setting its radius to zero.
joint.boneRadius = 0.0f;
// by setting its type to UNKNOWN_SHAPE.
joint.shapeType = Shape::UNKNOWN_SHAPE;
}
}
}

View file

@ -18,6 +18,8 @@
#include <QVariant>
#include <QVector>
#include <Shape.h>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
@ -91,7 +93,7 @@ public:
QString name;
glm::vec3 shapePosition; // in joint frame
glm::quat shapeRotation; // in joint frame
int shapeType;
Shape::Type shapeType;
};

View file

@ -500,7 +500,12 @@ void Model::rebuildShapes() {
float radius = uniformScale * joint.boneRadius;
float halfHeight = 0.5f * uniformScale * joint.distanceToParent;
if (joint.shapeType == Shape::CAPSULE_SHAPE && halfHeight > EPSILON) {
Shape::Type type = joint.shapeType;
if (type == Shape::CAPSULE_SHAPE && halfHeight < EPSILON) {
// this capsule is effectively a sphere
type = Shape::SPHERE_SHAPE;
}
if (type == Shape::CAPSULE_SHAPE) {
CapsuleShape* capsule = new CapsuleShape(radius, halfHeight);
capsule->setPosition(worldPosition);
capsule->setRotation(_jointStates[i].combinedRotation * joint.shapeRotation);
@ -523,18 +528,23 @@ void Model::rebuildShapes() {
totalExtents.addExtents(shapeExtents);
} else {
} else if (type == Shape::SPHERE_SHAPE) {
SphereShape* sphere = new SphereShape(radius, worldPosition);
_jointShapes.push_back(sphere);
if (radius > 0.0f) {
// only include sphere shapes with non-zero radius
glm::vec3 axis = glm::vec3(radius);
shapeExtents.addPoint(worldPosition + axis);
shapeExtents.addPoint(worldPosition - axis);
totalExtents.addExtents(shapeExtents);
}
glm::vec3 axis = glm::vec3(radius);
shapeExtents.addPoint(worldPosition + axis);
shapeExtents.addPoint(worldPosition - axis);
totalExtents.addExtents(shapeExtents);
} else {
// this shape type is not handled and the joint shouldn't collide,
// however we must have a shape for each joint,
// so we make a bogus sphere and put it at the center of the model
// TODO: implement collision groups for more control over what collides with what
SphereShape* sphere = new SphereShape(0.f, _offset);
_jointShapes.push_back(sphere);
}
}
// bounding shape