Merge pull request #6 from AndrewMeadows/bromine

remove avatar bone shapes cruft
This commit is contained in:
Howard Stearns 2015-07-24 12:40:05 -05:00
commit b748dafc80
8 changed files with 13 additions and 198 deletions

View file

@ -40,13 +40,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
}
}
void Hand::resolvePenetrations() {
for (size_t i = 0; i < getNumPalms(); ++i) {
PalmData& palm = getPalms()[i];
palm.resolvePenetrations();
}
}
void Hand::render(RenderArgs* renderArgs, bool isMine) {
gpu::Batch& batch = *renderArgs->_batch;
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE &&

View file

@ -36,8 +36,6 @@ public:
void simulate(float deltaTime, bool isMine);
void render(RenderArgs* renderArgs, bool isMine);
void resolvePenetrations();
private:
// disallow copies of the Hand, copy of owning Avatar is disallowed too
Hand(const Hand&);

View file

@ -188,41 +188,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
_boundingShape.setRotation(_rotation);
}
void SkeletonModel::getHandShapes(int jointIndex, QVector<const Shape*>& shapes) const {
if (jointIndex < 0 || jointIndex >= int(_shapes.size())) {
return;
}
if (jointIndex == getLeftHandJointIndex()
|| jointIndex == getRightHandJointIndex()) {
// get all shapes that have this hand as an ancestor in the skeleton heirarchy
const FBXGeometry& geometry = _geometry->getFBXGeometry();
for (int i = 0; i < _rig->getJointStateCount(); i++) {
const FBXJoint& joint = geometry.joints[i];
int parentIndex = joint.parentIndex;
Shape* shape = _shapes[i];
if (i == jointIndex) {
// this shape is the hand
if (shape) {
shapes.push_back(shape);
}
if (parentIndex != -1 && _shapes[parentIndex]) {
// also add the forearm
shapes.push_back(_shapes[parentIndex]);
}
} else if (shape) {
while (parentIndex != -1) {
if (parentIndex == jointIndex) {
// this shape is a child of the hand
shapes.push_back(shape);
break;
}
parentIndex = geometry.joints[parentIndex].parentIndex;
}
}
}
}
}
void SkeletonModel::renderIKConstraints(gpu::Batch& batch) {
renderJointConstraints(batch, getRightHandJointIndex());
renderJointConstraints(batch, getLeftHandJointIndex());
@ -675,45 +640,12 @@ void SkeletonModel::buildShapes() {
// rootJointIndex == -1 if the avatar model has no skeleton
return;
}
float uniformScale = extractUniformScale(_scale);
for (int i = 0; i < _rig->getJointStateCount(); i++) {
const JointState& state = _rig->getJointState(i);
const FBXJoint& joint = state.getFBXJoint();
float radius = uniformScale * joint.boneRadius;
float halfHeight = 0.5f * uniformScale * joint.distanceToParent;
Shape::Type type = joint.shapeType;
int parentIndex = joint.parentIndex;
if (parentIndex == -1 || radius < EPSILON) {
type = INVALID_SHAPE;
} else if (type == CAPSULE_SHAPE && halfHeight < EPSILON) {
// this shape is forced to be a sphere
type = SPHERE_SHAPE;
}
Shape* shape = NULL;
if (type == SPHERE_SHAPE) {
shape = new SphereShape(radius);
shape->setEntity(this);
} else if (type == CAPSULE_SHAPE) {
assert(parentIndex != -1);
shape = new CapsuleShape(radius, halfHeight);
shape->setEntity(this);
}
if (shape && parentIndex != -1) {
// always disable collisions between joint and its parent
disableCollisions(i, parentIndex);
}
_shapes.push_back(shape);
}
// This method moves the shapes to their default positions in Model frame.
computeBoundingShape(geometry);
}
void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
// compute default joint transforms
int numStates = _rig->getJointStateCount();
assert(numStates == _shapes.size());
QVector<glm::mat4> transforms;
transforms.fill(glm::mat4(), numStates);
@ -734,39 +666,11 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
* joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform;
}
// Each joint contributes its point to the bounding box
// Each joint contributes a sphere at its position
glm::vec3 axis(joint.boneRadius);
glm::vec3 jointPosition = extractTranslation(transforms[i]);
totalExtents.addPoint(jointPosition);
Shape* shape = _shapes[i];
if (!shape) {
continue;
}
// Each joint with a shape contributes to the totalExtents: a box
// that contains the sphere centered at the end of the joint with radius of the bone.
// TODO: skip hand and arm shapes for bounding box calculation
int type = shape->getType();
if (type == CAPSULE_SHAPE) {
// add the two furthest surface points of the capsule
CapsuleShape* capsule = static_cast<CapsuleShape*>(shape);
float radius = capsule->getRadius();
glm::vec3 axis(radius);
Extents shapeExtents;
shapeExtents.reset();
shapeExtents.addPoint(jointPosition + axis);
shapeExtents.addPoint(jointPosition - axis);
totalExtents.addExtents(shapeExtents);
} else if (type == SPHERE_SHAPE) {
float radius = shape->getBoundingRadius();
glm::vec3 axis(radius);
Extents shapeExtents;
shapeExtents.reset();
shapeExtents.addPoint(jointPosition + axis);
shapeExtents.addPoint(jointPosition - axis);
totalExtents.addExtents(shapeExtents);
}
totalExtents.addPoint(jointPosition + axis);
totalExtents.addPoint(jointPosition - axis);
}
// compute bounding shape parameters
@ -782,43 +686,8 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
_boundingRadius = 0.5f * glm::length(diagonal);
}
void SkeletonModel::resetShapePositionsToDefaultPose() {
// DEBUG method.
// Moves shapes to the joint default locations for debug visibility into
// how the bounding shape is computed.
if (!_geometry || _shapes.isEmpty()) {
// geometry or joints have not yet been created
return;
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
if (geometry.joints.isEmpty()) {
return;
}
// The shapes are moved to their default positions in computeBoundingShape().
computeBoundingShape(geometry);
// Then we move them into world frame for rendering at the Model's location.
for (int i = 0; i < _shapes.size(); i++) {
Shape* shape = _shapes[i];
if (shape) {
shape->setTranslation(_translation + _rotation * shape->getTranslation());
shape->setRotation(_rotation * shape->getRotation());
}
}
_boundingShape.setTranslation(_translation + _rotation * _boundingShapeLocalOffset);
_boundingShape.setRotation(_rotation);
}
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
const int BALL_SUBDIVISIONS = 10;
if (_shapes.isEmpty()) {
// the bounding shape has not been properly computed
// so no need to render it
return;
}
auto geometryCache = DependencyManager::get<GeometryCache>();
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();

View file

@ -32,10 +32,6 @@ public:
void simulate(float deltaTime, bool fullUpdate = true);
/// \param jointIndex index of hand joint
/// \param shapes[out] list in which is stored pointers to hand shapes
void getHandShapes(int jointIndex, QVector<const Shape*>& shapes) const;
void renderIKConstraints(gpu::Batch& batch);
/// Returns the index of the left hand joint, or -1 if not found.
@ -106,8 +102,6 @@ public:
const CapsuleShape& getBoundingShape() const { return _boundingShape; }
const glm::vec3 getBoundingShapeOffset() const { return _boundingShapeLocalOffset; }
void resetShapePositionsToDefaultPose(); // DEBUG method
bool hasSkeleton();
float getHeadClipDistance() const { return _headClipDistance; }

View file

@ -1198,7 +1198,7 @@ class JointShapeInfo {
public:
JointShapeInfo() : numVertices(0),
sumVertexWeights(0.0f), sumWeightedRadii(0.0f), numVertexWeights(0),
averageVertex(0.0f), boneBegin(0.0f), averageRadius(0.0f) {
boneBegin(0.0f), averageRadius(0.0f) {
}
// NOTE: the points here are in the "joint frame" which has the "jointEnd" at the origin
@ -1206,9 +1206,8 @@ public:
float sumVertexWeights; // sum of all vertex weights
float sumWeightedRadii; // sum of weighted vertices
int numVertexWeights; // num vertices that contributed to sums
glm::vec3 averageVertex;// average of all mesh vertices (in joint frame)
glm::vec3 boneBegin; // parent joint location (in joint frame)
float averageRadius; // average distance from mesh points to averageVertex
float averageRadius;
};
class AnimationCurve {
@ -2219,8 +2218,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
joint.boneRadius = 0.0f;
joint.inverseBindRotation = joint.inverseDefaultRotation;
joint.name = model.name;
joint.shapePosition = glm::vec3(0.0f);
joint.shapeType = INVALID_SHAPE;
foreach (const QString& childID, childMap.values(modelID)) {
QString type = typeFlags.value(childID);
@ -2490,7 +2487,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
int jointIndex = fbxCluster.jointIndex;
FBXJoint& joint = geometry.joints[jointIndex];
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
glm::quat rotateMeshToJoint = glm::inverse(extractRotation(transformJointToMesh));
glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
glm::vec3 boneBegin = boneEnd;
glm::vec3 boneDirection;
@ -2524,8 +2520,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
jointShapeInfo.sumWeightedRadii += radiusWeight * radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj);
++jointShapeInfo.numVertexWeights;
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
jointShapeInfo.averageVertex += vertexInJointFrame;
++jointShapeInfo.numVertices;
}
@ -2571,7 +2565,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
JointShapeInfo& jointShapeInfo = jointShapeInfos[jointIndex];
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
glm::quat rotateMeshToJoint = glm::inverse(extractRotation(transformJointToMesh));
glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
glm::vec3 boneBegin = boneEnd;
@ -2594,9 +2587,6 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
jointShapeInfo.sumVertexWeights += radiusWeight;
jointShapeInfo.sumWeightedRadii += radiusWeight * radiusScale * glm::distance(vertex, boneEnd - boneDirection * proj);
++jointShapeInfo.numVertexWeights;
glm::vec3 vertexInJointFrame = rotateMeshToJoint * (radiusScale * (vertex - boneEnd));
jointShapeInfo.averageVertex += vertexInJointFrame;
averageVertex += vertex;
}
int numVertices = extracted.mesh.vertices.size();
@ -2622,7 +2612,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
}
// now that all joints have been scanned, compute a collision shape for each joint
// now that all joints have been scanned, compute a radius for each bone
glm::vec3 defaultCapsuleAxis(0.0f, 1.0f, 0.0f);
for (int i = 0; i < geometry.joints.size(); ++i) {
FBXJoint& joint = geometry.joints[i];
@ -2640,40 +2630,20 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
joint.boneRadius = jointShapeInfo.sumWeightedRadii / jointShapeInfo.sumVertexWeights;
}
// we use a capsule if the joint had ANY mesh vertices successfully projected onto the bone
// the joint is "capsule-like" if it had ANY mesh vertices successfully projected onto the bone
// AND its boneRadius is not too close to zero
bool collideLikeCapsule = jointShapeInfo.numVertexWeights > 0
&& glm::length(jointShapeInfo.boneBegin) > EPSILON;
if (collideLikeCapsule) {
joint.shapeRotation = rotationBetween(defaultCapsuleAxis, jointShapeInfo.boneBegin);
joint.shapePosition = 0.5f * jointShapeInfo.boneBegin;
joint.shapeType = CAPSULE_SHAPE;
} else {
// collide the joint like a sphere
joint.shapeType = SPHERE_SHAPE;
if (jointShapeInfo.numVertices > 0) {
jointShapeInfo.averageVertex /= (float)jointShapeInfo.numVertices;
joint.shapePosition = jointShapeInfo.averageVertex;
} else {
joint.shapePosition = glm::vec3(0.0f);
}
if (!collideLikeCapsule) {
// this joint's mesh did not successfully project onto the bone axis
// so it isn't "capsule-like" and we need to estimate its radius a different way:
// the average radius to the average point.
if (jointShapeInfo.numVertexWeights == 0
&& jointShapeInfo.numVertices > 0) {
// the bone projection algorithm was not able to compute the joint radius
// so we use an alternative measure
jointShapeInfo.averageRadius /= (float)jointShapeInfo.numVertices;
joint.boneRadius = jointShapeInfo.averageRadius;
}
float distanceFromEnd = glm::length(joint.shapePosition);
float distanceFromBegin = glm::distance(joint.shapePosition, jointShapeInfo.boneBegin);
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 type to INVALID_SHAPE.
joint.shapeType = INVALID_SHAPE;
}
}
}
geometry.palmDirection = parseVec3(mapping.value("palmDirection", "0, -1, 0").toString());

View file

@ -25,7 +25,6 @@
#include <Extents.h>
#include <Transform.h>
#include <ShapeInfo.h>
#include <model/Geometry.h>
#include <model/Material.h>
@ -78,9 +77,6 @@ public:
glm::quat inverseBindRotation;
glm::mat4 bindTransform;
QString name;
glm::vec3 shapePosition; // in joint frame
glm::quat shapeRotation; // in joint frame
quint8 shapeType;
bool isSkeletonJoint;
};

View file

@ -427,8 +427,6 @@ FBXGeometry OBJReader::readOBJ(QIODevice* device, const QVariantHash& mapping, Q
geometry.joints[0].rotationMin = glm::vec3(0, 0, 0);
geometry.joints[0].rotationMax = glm::vec3(0, 0, 0);
geometry.joints[0].name = "OBJ";
geometry.joints[0].shapePosition = glm::vec3(0, 0, 0);
geometry.joints[0].shapeType = SPHERE_SHAPE;
geometry.joints[0].isSkeletonJoint = true;
geometry.jointIndices["x"] = 1;
@ -604,9 +602,6 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << " inverseBindRotation" << joint.inverseBindRotation;
qCDebug(modelformat) << " bindTransform" << joint.bindTransform;
qCDebug(modelformat) << " name" << joint.name;
qCDebug(modelformat) << " shapePosition" << joint.shapePosition;
qCDebug(modelformat) << " shapeRotation" << joint.shapeRotation;
qCDebug(modelformat) << " shapeType" << joint.shapeType;
qCDebug(modelformat) << " isSkeletonJoint" << joint.isSkeletonJoint;
}

View file

@ -1682,7 +1682,7 @@ NetworkGeometry::NetworkGeometry(const QUrl& url, const QSharedPointer<NetworkGe
// make the minimal amount of dummy geometry to satisfy Model
FBXJoint joint = { false, QVector<int>(), -1, 0.0f, 0.0f, glm::vec3(), glm::mat4(), glm::quat(), glm::quat(),
glm::quat(), glm::mat4(), glm::mat4(), glm::vec3(), glm::vec3(), glm::quat(), glm::quat(),
glm::mat4(), QString(""), glm::vec3(), glm::quat(), SHAPE_TYPE_NONE, false};
glm::mat4(), QString(""), false};
_geometry.joints.append(joint);
_geometry.leftEyeJointIndex = -1;
_geometry.rightEyeJointIndex = -1;