ShapeInfo name changes

This commit is contained in:
Andrew Meadows 2016-06-09 16:14:49 -07:00
parent 57760bca7d
commit d64729372a
8 changed files with 70 additions and 59 deletions

View file

@ -608,8 +608,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
const FBXGeometry& renderGeometry = _model->getFBXGeometry();
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
QVector<QVector<glm::vec3>>& points = info.getPoints();
points.clear();
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
pointCollection.clear();
uint32_t i = 0;
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
@ -619,8 +619,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
foreach (const FBXMesh& mesh, collisionGeometry.meshes) {
// each meshPart is a convex hull
foreach (const FBXMeshPart &meshPart, mesh.parts) {
points.push_back(QVector<glm::vec3>());
QVector<glm::vec3>& pointsInPart = points[i];
pointCollection.push_back(QVector<glm::vec3>());
ShapeInfo::PointList& pointsInPart = pointCollection[i];
// run through all the triangles and (uniquely) add each point to the hull
uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size();
@ -664,7 +664,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
if (pointsInPart.size() == 0) {
qCDebug(entitiesrenderer) << "Warning -- meshPart has no faces";
points.pop_back();
pointCollection.pop_back();
continue;
}
++i;
@ -681,16 +681,16 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
// multiply each point by scale before handing the point-set off to the physics engine.
// also determine the extents of the collision model.
AABox box;
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < points[i].size(); j++) {
for (int i = 0; i < pointCollection.size(); i++) {
for (int j = 0; j < pointCollection[i].size(); j++) {
// compensate for registration
points[i][j] += _model->getOffset();
pointCollection[i][j] += _model->getOffset();
// scale so the collision points match the model points
points[i][j] *= scale;
pointCollection[i][j] *= scale;
// this next subtraction is done so we can give info the offset, which will cause
// the shape-key to change.
points[i][j] -= _model->getOffset();
box += points[i][j];
pointCollection[i][j] -= _model->getOffset();
box += pointCollection[i][j];
}
}

View file

@ -1198,7 +1198,7 @@ void RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
QtConcurrent::run([entity, voxelSurfaceStyle, voxelVolumeSize, mesh] {
auto polyVoxEntity = std::static_pointer_cast<RenderablePolyVoxEntityItem>(entity);
QVector<QVector<glm::vec3>> points;
QVector<QVector<glm::vec3>> pointCollection;
AABox box;
glm::mat4 vtoM = std::static_pointer_cast<RenderablePolyVoxEntityItem>(entity)->voxelToLocalMatrix();
@ -1241,9 +1241,9 @@ void RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
pointsInPart << p3Model;
// add next convex hull
QVector<glm::vec3> newMeshPoints;
points << newMeshPoints;
pointCollection << newMeshPoints;
// add points to the new convex hull
points[i++] << pointsInPart;
pointCollection[i++] << pointsInPart;
}
} else {
unsigned int i = 0;
@ -1299,19 +1299,19 @@ void RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
// add next convex hull
QVector<glm::vec3> newMeshPoints;
points << newMeshPoints;
pointCollection << newMeshPoints;
// add points to the new convex hull
points[i++] << pointsInPart;
pointCollection[i++] << pointsInPart;
}
});
}
polyVoxEntity->setCollisionPoints(points, box);
polyVoxEntity->setCollisionPoints(pointCollection, box);
});
}
void RenderablePolyVoxEntityItem::setCollisionPoints(const QVector<QVector<glm::vec3>> points, AABox box) {
void RenderablePolyVoxEntityItem::setCollisionPoints(ShapeInfo::PointCollection pointCollection, AABox box) {
// this catches the payload from computeShapeInfoWorker
if (points.isEmpty()) {
if (pointCollection.isEmpty()) {
EntityItem::computeShapeInfo(_shapeInfo);
return;
}
@ -1325,7 +1325,7 @@ void RenderablePolyVoxEntityItem::setCollisionPoints(const QVector<QVector<glm::
QString::number(_registrationPoint.y) + "," +
QString::number(_registrationPoint.z);
_shapeInfo.setParams(SHAPE_TYPE_COMPOUND, collisionModelDimensions, shapeKey);
_shapeInfo.setConvexHulls(points);
_shapeInfo.setPointCollection(pointCollection);
_meshDirty = false;
});
}

View file

@ -123,7 +123,7 @@ public:
std::function<void(int, int, int, uint8_t)> thunk);
void setMesh(model::MeshPointer mesh);
void setCollisionPoints(const QVector<QVector<glm::vec3>> points, AABox box);
void setCollisionPoints(ShapeInfo::PointCollection points, AABox box);
PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData; }
uint8_t getVoxelInternal(int x, int y, int z);

View file

@ -217,7 +217,7 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re
} else if (entity->isReadyToComputeShape()) {
ShapeInfo shapeInfo;
entity->computeShapeInfo(shapeInfo);
int numPoints = shapeInfo.getMaxNumPoints();
int numPoints = shapeInfo.getLargestSubshapePointCount();
if (numPoints > MAX_HULL_POINTS) {
qWarning() << "convex hull with" << numPoints
<< "points for entity" << entity->getName()

View file

@ -179,15 +179,15 @@ btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) {
}
break;
case SHAPE_TYPE_COMPOUND: {
const QVector<QVector<glm::vec3>>& points = info.getPoints();
const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
uint32_t numSubShapes = info.getNumSubShapes();
if (numSubShapes == 1) {
shape = createConvexHull(info.getPoints()[0]);
shape = createConvexHull(pointCollection[0]);
} else {
auto compound = new btCompoundShape();
btTransform trans;
trans.setIdentity();
foreach (QVector<glm::vec3> hullPoints, points) {
foreach (const ShapeInfo::PointList& hullPoints, pointCollection) {
btConvexHullShape* hull = createConvexHull(hullPoints);
compound->addChildShape (trans, hull);
}

View file

@ -16,9 +16,13 @@
#include "NumericalConstants.h" // for MILLIMETERS_PER_METER
void ShapeInfo::clear() {
_type = SHAPE_TYPE_NONE;
_halfExtents = _offset = glm::vec3(0.0f);
_url.clear();
_pointCollection.clear();
_triangleIndices.clear();
_halfExtents = glm::vec3(0.0f);
_offset = glm::vec3(0.0f);
_doubleHashKey.clear();
_type = SHAPE_TYPE_NONE;
}
void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) {
@ -61,9 +65,9 @@ void ShapeInfo::setSphere(float radius) {
_doubleHashKey.clear();
}
void ShapeInfo::setConvexHulls(const QVector<QVector<glm::vec3>>& points) {
_points = points;
_type = (_points.size() > 0) ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_NONE;
void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollection) {
_pointCollection = pointCollection;
_type = (_pointCollection.size() > 0) ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_NONE;
_doubleHashKey.clear();
}
@ -83,15 +87,15 @@ uint32_t ShapeInfo::getNumSubShapes() const {
if (_type == SHAPE_TYPE_NONE) {
return 0;
} else if (_type == SHAPE_TYPE_COMPOUND) {
return _points.size();
return _pointCollection.size();
}
return 1;
}
int ShapeInfo::getMaxNumPoints() const {
int ShapeInfo::getLargestSubshapePointCount() const {
int numPoints = 0;
for (int i = 0; i < _points.size(); ++i) {
int n = _points[i].size();
for (int i = 0; i < _pointCollection.size(); ++i) {
int n = _pointCollection[i].size();
if (n > numPoints) {
numPoints = n;
}
@ -187,23 +191,23 @@ const DoubleHashKey& ShapeInfo::getHash() const {
// TODO?: provide lookup table for hash/hash2 of _type rather than recompute?
uint32_t primeIndex = 0;
key.computeHash((uint32_t)_type, primeIndex++);
// compute hash1
// compute hash1
uint32_t hash = key.getHash();
for (int j = 0; j < 3; ++j) {
// NOTE: 0.49f is used to bump the float up almost half a millimeter
// so the cast to int produces a round() effect rather than a floor()
hash ^= DoubleHashKey::hashFunction(
(uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f),
(uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f),
primeIndex++);
if (useOffset) {
hash ^= DoubleHashKey::hashFunction(
(uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f),
(uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f),
primeIndex++);
}
}
key.setHash(hash);
// compute hash2
hash = key.getHash2();
for (int j = 0; j < 3; ++j) {
@ -224,14 +228,16 @@ const DoubleHashKey& ShapeInfo::getHash() const {
}
key.setHash2(hash);
QString url = _url.toString();
if (!url.isEmpty()) {
// fold the urlHash into both parts
QByteArray baUrl = url.toLocal8Bit();
const char *cUrl = baUrl.data();
uint32_t urlHash = qChecksum(cUrl, baUrl.count());
key.setHash(key.getHash() ^ urlHash);
key.setHash2(key.getHash2() ^ urlHash);
if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_MESH) {
QString url = _url.toString();
if (!url.isEmpty()) {
// fold the urlHash into both parts
QByteArray baUrl = url.toLocal8Bit();
const char *cUrl = baUrl.data();
uint32_t urlHash = qChecksum(cUrl, baUrl.count());
key.setHash(key.getHash() ^ urlHash);
key.setHash2(key.getHash2() ^ urlHash);
}
}
}
return _doubleHashKey;

View file

@ -38,18 +38,23 @@ enum ShapeType {
SHAPE_TYPE_CYLINDER_X,
SHAPE_TYPE_CYLINDER_Y,
SHAPE_TYPE_CYLINDER_Z,
SHAPE_TYPE_STATIC_MESH
SHAPE_TYPE_MESH
};
class ShapeInfo {
public:
using PointList = QVector<glm::vec3>;
using PointCollection = QVector<PointList>;
using TriangleIndices = QVector<uint32_t>;
void clear();
void setParams(ShapeType type, const glm::vec3& halfExtents, QString url="");
void setBox(const glm::vec3& halfExtents);
void setSphere(float radius);
void setConvexHulls(const QVector<QVector<glm::vec3>>& points);
void setPointCollection(const PointCollection& pointCollection);
void setCapsuleY(float radius, float halfHeight);
void setOffset(const glm::vec3& offset);
@ -58,12 +63,11 @@ public:
const glm::vec3& getHalfExtents() const { return _halfExtents; }
const glm::vec3& getOffset() const { return _offset; }
QVector<QVector<glm::vec3>>& getPoints() { return _points; }
const QVector<QVector<glm::vec3>>& getPoints() const { return _points; }
PointCollection& getPointCollection() { return _pointCollection; }
const PointCollection& getPointCollection() const { return _pointCollection; }
uint32_t getNumSubShapes() const;
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
int getMaxNumPoints() const;
int getLargestSubshapePointCount() const;
float computeVolume() const;
@ -75,7 +79,8 @@ public:
protected:
QUrl _url; // url for model of convex collision hulls
QVector<QVector<glm::vec3>> _points; // points for convex collision hulls
PointCollection _pointCollection;
TriangleIndices _triangleIndices;
glm::vec3 _halfExtents = glm::vec3(0.0f);
glm::vec3 _offset = glm::vec3(0.0f);
DoubleHashKey _doubleHashKey;

View file

@ -194,23 +194,23 @@ void ShapeManagerTests::addCompoundShape() {
int numHullPoints = tetrahedron.size();
// compute the points of the hulls
QVector< QVector<glm::vec3> > hulls;
ShapeInfo::PointCollection pointCollection;
int numHulls = 5;
glm::vec3 offsetNormal(1.0f, 0.0f, 0.0f);
for (int i = 0; i < numHulls; ++i) {
glm::vec3 offset = (float)(i - numHulls/2) * offsetNormal;
QVector<glm::vec3> hull;
ShapeInfo::PointList pointList;
float radius = (float)(i + 1);
for (int j = 0; j < numHullPoints; ++j) {
glm::vec3 point = radius * tetrahedron[j] + offset;
hull.push_back(point);
pointList.push_back(point);
}
hulls.push_back(hull);
pointCollection.push_back(pointList);
}
// create the ShapeInfo
ShapeInfo info;
info.setConvexHulls(hulls);
info.setPointCollection(hulls);
// create the shape
ShapeManager shapeManager;