separate new shape types from legacy

This commit is contained in:
Andrew Meadows 2015-02-03 08:34:06 -08:00
parent 0b78156956
commit 28a3c3f469
6 changed files with 67 additions and 59 deletions

View file

@ -760,19 +760,19 @@ void SkeletonModel::buildShapes() {
Shape::Type type = joint.shapeType; Shape::Type type = joint.shapeType;
int parentIndex = joint.parentIndex; int parentIndex = joint.parentIndex;
if (parentIndex == -1 || radius < EPSILON) { if (parentIndex == -1 || radius < EPSILON) {
type = SHAPE_TYPE_UNKNOWN; type = INVALID_SHAPE;
} else if (type == SHAPE_TYPE_CAPSULE && halfHeight < EPSILON) { } else if (type == CAPSULE_SHAPE && halfHeight < EPSILON) {
// this shape is forced to be a sphere // this shape is forced to be a sphere
type = SHAPE_TYPE_SPHERE; type = SPHERE_SHAPE;
} }
Shape* shape = NULL; Shape* shape = NULL;
if (type == SHAPE_TYPE_SPHERE) { if (type == SPHERE_SHAPE) {
shape = new VerletSphereShape(radius, &(points[i])); shape = new VerletSphereShape(radius, &(points[i]));
shape->setEntity(this); shape->setEntity(this);
float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume()); float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume());
points[i].setMass(mass); points[i].setMass(mass);
totalMass += mass; totalMass += mass;
} else if (type == SHAPE_TYPE_CAPSULE) { } else if (type == CAPSULE_SHAPE) {
assert(parentIndex != -1); assert(parentIndex != -1);
shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i])); shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i]));
shape->setEntity(this); shape->setEntity(this);

View file

@ -25,6 +25,7 @@
#include <GeometryUtil.h> #include <GeometryUtil.h>
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <OctalCode.h> #include <OctalCode.h>
#include <Shape.h>
#include "FBXReader.h" #include "FBXReader.h"
@ -1999,7 +2000,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
joint.inverseBindRotation = joint.inverseDefaultRotation; joint.inverseBindRotation = joint.inverseDefaultRotation;
joint.name = model.name; joint.name = model.name;
joint.shapePosition = glm::vec3(0.0f); joint.shapePosition = glm::vec3(0.0f);
joint.shapeType = SHAPE_TYPE_UNKNOWN; joint.shapeType = INVALID_SHAPE;
foreach (const QString& childID, childMap.values(modelID)) { foreach (const QString& childID, childMap.values(modelID)) {
QString type = typeFlags.value(childID); QString type = typeFlags.value(childID);
@ -2421,10 +2422,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
if (collideLikeCapsule) { if (collideLikeCapsule) {
joint.shapeRotation = rotationBetween(defaultCapsuleAxis, jointShapeInfo.boneBegin); joint.shapeRotation = rotationBetween(defaultCapsuleAxis, jointShapeInfo.boneBegin);
joint.shapePosition = 0.5f * jointShapeInfo.boneBegin; joint.shapePosition = 0.5f * jointShapeInfo.boneBegin;
joint.shapeType = SHAPE_TYPE_CAPSULE; joint.shapeType = CAPSULE_SHAPE;
} else { } else {
// collide the joint like a sphere // collide the joint like a sphere
joint.shapeType = SHAPE_TYPE_SPHERE; joint.shapeType = SPHERE_SHAPE;
if (jointShapeInfo.numVertices > 0) { if (jointShapeInfo.numVertices > 0) {
jointShapeInfo.averageVertex /= (float)jointShapeInfo.numVertices; jointShapeInfo.averageVertex /= (float)jointShapeInfo.numVertices;
joint.shapePosition = jointShapeInfo.averageVertex; joint.shapePosition = jointShapeInfo.averageVertex;
@ -2444,8 +2445,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 type to SHAPE_TYPE_UNKNOWN. // by setting its type to INVALID_SHAPE.
joint.shapeType = SHAPE_TYPE_UNKNOWN; joint.shapeType = INVALID_SHAPE;
} }
} }
} }

View file

@ -18,12 +18,13 @@
#include <QVariant> #include <QVariant>
#include <QVector> #include <QVector>
#include <Extents.h>
#include <Transform.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include <Extents.h>
#include <Transform.h>
#include <ShapeInfo.h>
#include <model/Geometry.h> #include <model/Geometry.h>
#include <model/Material.h> #include <model/Material.h>
@ -58,12 +59,6 @@ public:
QVector<glm::vec3> normals; QVector<glm::vec3> normals;
}; };
enum ShapeType {
SHAPE_TYPE_SPHERE = 0,
SHAPE_TYPE_CAPSULE = 1,
SHAPE_TYPE_UNKNOWN = 2
};
/// A single joint (transformation node) extracted from an FBX document. /// A single joint (transformation node) extracted from an FBX document.
class FBXJoint { class FBXJoint {
public: public:
@ -88,7 +83,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
ShapeType shapeType; quint8 shapeType;
bool isSkeletonJoint; bool isSkeletonJoint;
}; };

View file

@ -9,7 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <Shape.h> // for FOO_SHAPE types #include <ShapeInfo.h>
#include <SharedUtil.h> // for MILLIMETERS_PER_METER #include <SharedUtil.h> // for MILLIMETERS_PER_METER
#include "ShapeInfoUtil.h" #include "ShapeInfoUtil.h"
@ -18,16 +18,16 @@
int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) { int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) {
int bulletShapeType = INVALID_SHAPE_PROXYTYPE; int bulletShapeType = INVALID_SHAPE_PROXYTYPE;
switch(shapeInfoType) { switch(shapeInfoType) {
case BOX_SHAPE: case SHAPE_TYPE_BOX:
bulletShapeType = BOX_SHAPE_PROXYTYPE; bulletShapeType = BOX_SHAPE_PROXYTYPE;
break; break;
case SPHERE_SHAPE: case SHAPE_TYPE_SPHERE:
bulletShapeType = SPHERE_SHAPE_PROXYTYPE; bulletShapeType = SPHERE_SHAPE_PROXYTYPE;
break; break;
case CAPSULE_SHAPE: case SHAPE_TYPE_CAPSULE:
bulletShapeType = CAPSULE_SHAPE_PROXYTYPE; bulletShapeType = CAPSULE_SHAPE_PROXYTYPE;
break; break;
case CYLINDER_SHAPE: case SHAPE_TYPE_CYLINDER:
bulletShapeType = CYLINDER_SHAPE_PROXYTYPE; bulletShapeType = CYLINDER_SHAPE_PROXYTYPE;
break; break;
} }
@ -35,19 +35,19 @@ int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) {
} }
int ShapeInfoUtil::fromBulletShapeType(int bulletShapeType) { int ShapeInfoUtil::fromBulletShapeType(int bulletShapeType) {
int shapeInfoType = INVALID_SHAPE; int shapeInfoType = SHAPE_TYPE_NONE;
switch(bulletShapeType) { switch(bulletShapeType) {
case BOX_SHAPE_PROXYTYPE: case BOX_SHAPE_PROXYTYPE:
shapeInfoType = BOX_SHAPE; shapeInfoType = SHAPE_TYPE_BOX;
break; break;
case SPHERE_SHAPE_PROXYTYPE: case SPHERE_SHAPE_PROXYTYPE:
shapeInfoType = SPHERE_SHAPE; shapeInfoType = SHAPE_TYPE_SPHERE;
break; break;
case CAPSULE_SHAPE_PROXYTYPE: case CAPSULE_SHAPE_PROXYTYPE:
shapeInfoType = CAPSULE_SHAPE; shapeInfoType = SHAPE_TYPE_CAPSULE;
break; break;
case CYLINDER_SHAPE_PROXYTYPE: case CYLINDER_SHAPE_PROXYTYPE:
shapeInfoType = CYLINDER_SHAPE; shapeInfoType = SHAPE_TYPE_CYLINDER;
break; break;
} }
return shapeInfoType; return shapeInfoType;
@ -57,24 +57,24 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf
if (shape) { if (shape) {
int type = ShapeInfoUtil::fromBulletShapeType(shape->getShapeType()); int type = ShapeInfoUtil::fromBulletShapeType(shape->getShapeType());
switch(type) { switch(type) {
case BOX_SHAPE: { case SHAPE_TYPE_BOX: {
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape); const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
info.setBox(bulletToGLM(boxShape->getHalfExtentsWithMargin())); info.setBox(bulletToGLM(boxShape->getHalfExtentsWithMargin()));
} }
break; break;
case SPHERE_SHAPE: { case SHAPE_TYPE_SPHERE: {
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape); const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
info.setSphere(sphereShape->getRadius()); info.setSphere(sphereShape->getRadius());
} }
break; break;
case CYLINDER_SHAPE: { case SHAPE_TYPE_CYLINDER: {
// NOTE: we only support cylinders along yAxis // NOTE: we only support cylinders along yAxis
const btCylinderShape* cylinderShape = static_cast<const btCylinderShape*>(shape); const btCylinderShape* cylinderShape = static_cast<const btCylinderShape*>(shape);
btVector3 halfExtents = cylinderShape->getHalfExtentsWithMargin(); btVector3 halfExtents = cylinderShape->getHalfExtentsWithMargin();
info.setCylinder(halfExtents.getX(), halfExtents.getY()); info.setCylinder(halfExtents.getX(), halfExtents.getY());
} }
break; break;
case CAPSULE_SHAPE: { case SHAPE_TYPE_CAPSULE: {
// NOTE: we only support capsules along yAxis // NOTE: we only support capsules along yAxis
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape); const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
info.setCapsule(capsuleShape->getRadius(), capsuleShape->getHalfHeight()); info.setCapsule(capsuleShape->getRadius(), capsuleShape->getHalfHeight());
@ -93,23 +93,23 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
btCollisionShape* shape = NULL; btCollisionShape* shape = NULL;
const QVector<glm::vec3>& data = info.getData(); const QVector<glm::vec3>& data = info.getData();
switch(info.getType()) { switch(info.getType()) {
case BOX_SHAPE: { case SHAPE_TYPE_BOX: {
// data[0] is halfExtents // data[0] is halfExtents
shape = new btBoxShape(glmToBullet(data[0])); shape = new btBoxShape(glmToBullet(data[0]));
} }
break; break;
case SPHERE_SHAPE: { case SHAPE_TYPE_SPHERE: {
float radius = data[0].z; float radius = data[0].z;
shape = new btSphereShape(radius); shape = new btSphereShape(radius);
} }
break; break;
case CYLINDER_SHAPE: { case SHAPE_TYPE_CYLINDER: {
// NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X // NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X
// data[0] = btVector3(radius, halfHeight, unused) // data[0] = btVector3(radius, halfHeight, unused)
shape = new btCylinderShape(glmToBullet(data[0])); shape = new btCylinderShape(glmToBullet(data[0]));
} }
break; break;
case CAPSULE_SHAPE: { case SHAPE_TYPE_CAPSULE: {
float radius = data[0].x; float radius = data[0].x;
float height = 2.0f * data[0].y; float height = 2.0f * data[0].y;
shape = new btCapsuleShape(radius, height); shape = new btCapsuleShape(radius, height);

View file

@ -17,26 +17,26 @@
#include "ShapeInfo.h" #include "ShapeInfo.h"
void ShapeInfo::clear() { void ShapeInfo::clear() {
_type = INVALID_SHAPE; _type = SHAPE_TYPE_NONE;
_data.clear(); _data.clear();
} }
void ShapeInfo::setBox(const glm::vec3& halfExtents) { void ShapeInfo::setBox(const glm::vec3& halfExtents) {
_type = BOX_SHAPE; _type = SHAPE_TYPE_BOX;
_data.clear(); _data.clear();
// _data[0] = < halfX, halfY, halfZ > // _data[0] = < halfX, halfY, halfZ >
_data.push_back(halfExtents); _data.push_back(halfExtents);
} }
void ShapeInfo::setSphere(float radius) { void ShapeInfo::setSphere(float radius) {
_type = SPHERE_SHAPE; _type = SHAPE_TYPE_SPHERE;
_data.clear(); _data.clear();
// _data[0] = < radius, radius, radius > // _data[0] = < radius, radius, radius >
_data.push_back(glm::vec3(radius)); _data.push_back(glm::vec3(radius));
} }
void ShapeInfo::setCylinder(float radius, float halfHeight) { void ShapeInfo::setCylinder(float radius, float halfHeight) {
_type = CYLINDER_SHAPE; _type = SHAPE_TYPE_CYLINDER;
_data.clear(); _data.clear();
// _data[0] = < radius, halfHeight, radius > // _data[0] = < radius, halfHeight, radius >
// NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X // NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X
@ -44,7 +44,7 @@ void ShapeInfo::setCylinder(float radius, float halfHeight) {
} }
void ShapeInfo::setCapsule(float radius, float halfHeight) { void ShapeInfo::setCapsule(float radius, float halfHeight) {
_type = CAPSULE_SHAPE; _type = SHAPE_TYPE_CAPSULE;
_data.clear(); _data.clear();
// _data[0] = < radius, halfHeight, radius > // _data[0] = < radius, halfHeight, radius >
_data.push_back(glm::vec3(radius, halfHeight, radius)); _data.push_back(glm::vec3(radius, halfHeight, radius));
@ -52,10 +52,10 @@ void ShapeInfo::setCapsule(float radius, float halfHeight) {
glm::vec3 ShapeInfo::getBoundingBoxDiagonal() const { glm::vec3 ShapeInfo::getBoundingBoxDiagonal() const {
switch(_type) { switch(_type) {
case BOX_SHAPE: case SHAPE_TYPE_BOX:
case SPHERE_SHAPE: case SHAPE_TYPE_SPHERE:
case CYLINDER_SHAPE: case SHAPE_TYPE_CYLINDER:
case CAPSULE_SHAPE: case SHAPE_TYPE_CAPSULE:
return 2.0f * _data[0]; return 2.0f * _data[0];
default: default:
break; break;
@ -67,22 +67,22 @@ float ShapeInfo::computeVolume() const {
const float DEFAULT_VOLUME = 1.0f; const float DEFAULT_VOLUME = 1.0f;
float volume = DEFAULT_VOLUME; float volume = DEFAULT_VOLUME;
switch(_type) { switch(_type) {
case BOX_SHAPE: { case SHAPE_TYPE_BOX: {
// factor of 8.0 because the components of _data[0] are all halfExtents // factor of 8.0 because the components of _data[0] are all halfExtents
volume = 8.0f * _data[0].x * _data[0].y * _data[0].z; volume = 8.0f * _data[0].x * _data[0].y * _data[0].z;
break; break;
} }
case SPHERE_SHAPE: { case SHAPE_TYPE_SPHERE: {
float radius = _data[0].x; float radius = _data[0].x;
volume = 4.0f * PI * radius * radius * radius / 3.0f; volume = 4.0f * PI * radius * radius * radius / 3.0f;
break; break;
} }
case CYLINDER_SHAPE: { case SHAPE_TYPE_CYLINDER: {
float radius = _data[0].x; float radius = _data[0].x;
volume = PI * radius * radius * 2.0f * _data[0].y; volume = PI * radius * radius * 2.0f * _data[0].y;
break; break;
} }
case CAPSULE_SHAPE: { case SHAPE_TYPE_CAPSULE: {
float radius = _data[0].x; float radius = _data[0].x;
volume = PI * radius * radius * (2.0f * _data[0].y + 4.0f * radius / 3.0f); volume = PI * radius * radius * (2.0f * _data[0].y + 4.0f * radius / 3.0f);
break; break;

View file

@ -17,9 +17,21 @@
#include "Shape.h" #include "Shape.h"
enum ShapeType {
SHAPE_TYPE_NONE,
SHAPE_TYPE_BOX,
SHAPE_TYPE_SPHERE,
SHAPE_TYPE_ELLIPSOID,
SHAPE_TYPE_CYLINDER,
SHAPE_TYPE_CAPSULE,
SHAPE_TYPE_CONVEX_HULL,
SHAPE_TYPE_PLANE,
SHAPE_TYPE_COMPOUND
};
class ShapeInfo { class ShapeInfo {
public: public:
ShapeInfo() : _type(INVALID_SHAPE) {} ShapeInfo() : _type(SHAPE_TYPE_NONE) {}
void clear(); void clear();