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) { if (distanceFromEnd > joint.distanceToParent && distanceFromBegin > joint.distanceToParent) {
// The shape is further from both joint endpoints than the endpoints are from each other // 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 // which probably means the model has a bad transform somewhere. We disable this shape
// by setting its radius to zero. // by setting its type to UNKNOWN_SHAPE.
joint.boneRadius = 0.0f; joint.shapeType = Shape::UNKNOWN_SHAPE;
} }
} }
} }

View file

@ -18,6 +18,8 @@
#include <QVariant> #include <QVariant>
#include <QVector> #include <QVector>
#include <Shape.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
@ -91,7 +93,7 @@ public:
QString name; QString name;
glm::vec3 shapePosition; // in joint frame glm::vec3 shapePosition; // in joint frame
glm::quat shapeRotation; // 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 radius = uniformScale * joint.boneRadius;
float halfHeight = 0.5f * uniformScale * joint.distanceToParent; 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); CapsuleShape* capsule = new CapsuleShape(radius, halfHeight);
capsule->setPosition(worldPosition); capsule->setPosition(worldPosition);
capsule->setRotation(_jointStates[i].combinedRotation * joint.shapeRotation); capsule->setRotation(_jointStates[i].combinedRotation * joint.shapeRotation);
@ -523,18 +528,23 @@ void Model::rebuildShapes() {
totalExtents.addExtents(shapeExtents); totalExtents.addExtents(shapeExtents);
} else { } else if (type == Shape::SPHERE_SHAPE) {
SphereShape* sphere = new SphereShape(radius, worldPosition); SphereShape* sphere = new SphereShape(radius, worldPosition);
_jointShapes.push_back(sphere); _jointShapes.push_back(sphere);
if (radius > 0.0f) { glm::vec3 axis = glm::vec3(radius);
// only include sphere shapes with non-zero radius shapeExtents.addPoint(worldPosition + axis);
glm::vec3 axis = glm::vec3(radius); shapeExtents.addPoint(worldPosition - axis);
shapeExtents.addPoint(worldPosition + axis); totalExtents.addExtents(shapeExtents);
shapeExtents.addPoint(worldPosition - axis); } else {
totalExtents.addExtents(shapeExtents); // 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 // bounding shape