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

View file

@ -25,6 +25,7 @@
#include <GeometryUtil.h>
#include <GLMHelpers.h>
#include <OctalCode.h>
#include <Shape.h>
#include "FBXReader.h"
@ -1716,13 +1717,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
#endif
}
material.id = getID(object.properties);
material._material = model::MaterialPointer(new model::Material());
material._material->setEmissive(material.emissive);
material._material->setDiffuse(material.diffuse);
material._material->setSpecular(material.specular);
material._material->setShininess(material.shininess);
material._material->setOpacity(material.opacity);
material._material = model::MaterialPointer(new model::Material());
material._material->setEmissive(material.emissive);
material._material->setDiffuse(material.diffuse);
material._material->setSpecular(material.specular);
material._material->setShininess(material.shininess);
material._material->setOpacity(material.opacity);
materials.insert(material.id, material);
@ -1999,7 +2000,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
joint.inverseBindRotation = joint.inverseDefaultRotation;
joint.name = model.name;
joint.shapePosition = glm::vec3(0.0f);
joint.shapeType = SHAPE_TYPE_UNKNOWN;
joint.shapeType = INVALID_SHAPE;
foreach (const QString& childID, childMap.values(modelID)) {
QString type = typeFlags.value(childID);
@ -2421,10 +2422,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
if (collideLikeCapsule) {
joint.shapeRotation = rotationBetween(defaultCapsuleAxis, jointShapeInfo.boneBegin);
joint.shapePosition = 0.5f * jointShapeInfo.boneBegin;
joint.shapeType = SHAPE_TYPE_CAPSULE;
joint.shapeType = CAPSULE_SHAPE;
} else {
// collide the joint like a sphere
joint.shapeType = SHAPE_TYPE_SPHERE;
joint.shapeType = SPHERE_SHAPE;
if (jointShapeInfo.numVertices > 0) {
jointShapeInfo.averageVertex /= (float)jointShapeInfo.numVertices;
joint.shapePosition = jointShapeInfo.averageVertex;
@ -2444,8 +2445,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 type to SHAPE_TYPE_UNKNOWN.
joint.shapeType = SHAPE_TYPE_UNKNOWN;
// by setting its type to INVALID_SHAPE.
joint.shapeType = INVALID_SHAPE;
}
}
}

View file

@ -18,12 +18,13 @@
#include <QVariant>
#include <QVector>
#include <Extents.h>
#include <Transform.h>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <Extents.h>
#include <Transform.h>
#include <ShapeInfo.h>
#include <model/Geometry.h>
#include <model/Material.h>
@ -58,12 +59,6 @@ public:
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.
class FBXJoint {
public:
@ -88,7 +83,7 @@ public:
QString name;
glm::vec3 shapePosition; // in joint frame
glm::quat shapeRotation; // in joint frame
ShapeType shapeType;
quint8 shapeType;
bool isSkeletonJoint;
};

View file

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

View file

@ -17,26 +17,26 @@
#include "ShapeInfo.h"
void ShapeInfo::clear() {
_type = INVALID_SHAPE;
_type = SHAPE_TYPE_NONE;
_data.clear();
}
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
_type = BOX_SHAPE;
_type = SHAPE_TYPE_BOX;
_data.clear();
// _data[0] = < halfX, halfY, halfZ >
_data.push_back(halfExtents);
}
void ShapeInfo::setSphere(float radius) {
_type = SPHERE_SHAPE;
_type = SHAPE_TYPE_SPHERE;
_data.clear();
// _data[0] = < radius, radius, radius >
_data.push_back(glm::vec3(radius));
}
void ShapeInfo::setCylinder(float radius, float halfHeight) {
_type = CYLINDER_SHAPE;
_type = SHAPE_TYPE_CYLINDER;
_data.clear();
// _data[0] = < radius, halfHeight, radius >
// 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) {
_type = CAPSULE_SHAPE;
_type = SHAPE_TYPE_CAPSULE;
_data.clear();
// _data[0] = < 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 {
switch(_type) {
case BOX_SHAPE:
case SPHERE_SHAPE:
case CYLINDER_SHAPE:
case CAPSULE_SHAPE:
case SHAPE_TYPE_BOX:
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_CYLINDER:
case SHAPE_TYPE_CAPSULE:
return 2.0f * _data[0];
default:
break;
@ -67,22 +67,22 @@ float ShapeInfo::computeVolume() const {
const float DEFAULT_VOLUME = 1.0f;
float volume = DEFAULT_VOLUME;
switch(_type) {
case BOX_SHAPE: {
case SHAPE_TYPE_BOX: {
// 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;
break;
}
case SPHERE_SHAPE: {
case SHAPE_TYPE_SPHERE: {
float radius = _data[0].x;
volume = 4.0f * PI * radius * radius * radius / 3.0f;
break;
}
case CYLINDER_SHAPE: {
case SHAPE_TYPE_CYLINDER: {
float radius = _data[0].x;
volume = PI * radius * radius * 2.0f * _data[0].y;
break;
}
case CAPSULE_SHAPE: {
case SHAPE_TYPE_CAPSULE: {
float radius = _data[0].x;
volume = PI * radius * radius * (2.0f * _data[0].y + 4.0f * radius / 3.0f);
break;

View file

@ -17,9 +17,21 @@
#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 {
public:
ShapeInfo() : _type(INVALID_SHAPE) {}
ShapeInfo() : _type(SHAPE_TYPE_NONE) {}
void clear();