mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Merge pull request #8006 from AndrewMeadows/convexification-2
fix bad convex hull simplification
This commit is contained in:
commit
d9542107c2
9 changed files with 161 additions and 79 deletions
|
@ -599,11 +599,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||||
|
|
||||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
ShapeType type = getShapeType();
|
ShapeType type = getShapeType();
|
||||||
if (type != SHAPE_TYPE_COMPOUND) {
|
if (type == SHAPE_TYPE_COMPOUND) {
|
||||||
ModelEntityItem::computeShapeInfo(info);
|
|
||||||
info.setParams(type, 0.5f * getDimensions());
|
|
||||||
adjustShapeInfoByRegistration(info);
|
|
||||||
} else {
|
|
||||||
updateModelBounds();
|
updateModelBounds();
|
||||||
|
|
||||||
// should never fall in here when collision model not fully loaded
|
// should never fall in here when collision model not fully loaded
|
||||||
|
@ -612,25 +608,27 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
const FBXGeometry& renderGeometry = _model->getFBXGeometry();
|
const FBXGeometry& renderGeometry = _model->getFBXGeometry();
|
||||||
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
|
const FBXGeometry& collisionGeometry = _model->getCollisionFBXGeometry();
|
||||||
|
|
||||||
_points.clear();
|
QVector<QVector<glm::vec3>>& points = info.getPoints();
|
||||||
unsigned int i = 0;
|
points.clear();
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
|
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
|
||||||
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
||||||
|
const uint32_t TRIANGLE_STRIDE = 3;
|
||||||
|
const uint32_t QUAD_STRIDE = 4;
|
||||||
foreach (const FBXMesh& mesh, collisionGeometry.meshes) {
|
foreach (const FBXMesh& mesh, collisionGeometry.meshes) {
|
||||||
// each meshPart is a convex hull
|
// each meshPart is a convex hull
|
||||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||||
QVector<glm::vec3> pointsInPart;
|
points.push_back(QVector<glm::vec3>());
|
||||||
|
QVector<glm::vec3>& pointsInPart = points[i];
|
||||||
|
|
||||||
// run through all the triangles and (uniquely) add each point to the hull
|
// run through all the triangles and (uniquely) add each point to the hull
|
||||||
unsigned int triangleCount = meshPart.triangleIndices.size() / 3;
|
uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size();
|
||||||
for (unsigned int j = 0; j < triangleCount; j++) {
|
assert(numIndices % TRIANGLE_STRIDE == 0);
|
||||||
unsigned int p0Index = meshPart.triangleIndices[j*3];
|
for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) {
|
||||||
unsigned int p1Index = meshPart.triangleIndices[j*3+1];
|
glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]];
|
||||||
unsigned int p2Index = meshPart.triangleIndices[j*3+2];
|
glm::vec3 p1 = mesh.vertices[meshPart.triangleIndices[j + 1]];
|
||||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
glm::vec3 p2 = mesh.vertices[meshPart.triangleIndices[j + 2]];
|
||||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
|
||||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
if (!pointsInPart.contains(p0)) {
|
||||||
pointsInPart << p0;
|
pointsInPart << p0;
|
||||||
}
|
}
|
||||||
|
@ -643,17 +641,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// run through all the quads and (uniquely) add each point to the hull
|
// run through all the quads and (uniquely) add each point to the hull
|
||||||
unsigned int quadCount = meshPart.quadIndices.size() / 4;
|
numIndices = (uint32_t)meshPart.quadIndices.size();
|
||||||
assert((unsigned int)meshPart.quadIndices.size() == quadCount*4);
|
assert(numIndices % QUAD_STRIDE == 0);
|
||||||
for (unsigned int j = 0; j < quadCount; j++) {
|
for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) {
|
||||||
unsigned int p0Index = meshPart.quadIndices[j*4];
|
glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]];
|
||||||
unsigned int p1Index = meshPart.quadIndices[j*4+1];
|
glm::vec3 p1 = mesh.vertices[meshPart.quadIndices[j + 1]];
|
||||||
unsigned int p2Index = meshPart.quadIndices[j*4+2];
|
glm::vec3 p2 = mesh.vertices[meshPart.quadIndices[j + 2]];
|
||||||
unsigned int p3Index = meshPart.quadIndices[j*4+3];
|
glm::vec3 p3 = mesh.vertices[meshPart.quadIndices[j + 3]];
|
||||||
glm::vec3 p0 = mesh.vertices[p0Index];
|
|
||||||
glm::vec3 p1 = mesh.vertices[p1Index];
|
|
||||||
glm::vec3 p2 = mesh.vertices[p2Index];
|
|
||||||
glm::vec3 p3 = mesh.vertices[p3Index];
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
if (!pointsInPart.contains(p0)) {
|
||||||
pointsInPart << p0;
|
pointsInPart << p0;
|
||||||
}
|
}
|
||||||
|
@ -670,14 +664,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
|
|
||||||
if (pointsInPart.size() == 0) {
|
if (pointsInPart.size() == 0) {
|
||||||
qCDebug(entitiesrenderer) << "Warning -- meshPart has no faces";
|
qCDebug(entitiesrenderer) << "Warning -- meshPart has no faces";
|
||||||
|
points.pop_back();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
++i;
|
||||||
// add next convex hull
|
|
||||||
QVector<glm::vec3> newMeshPoints;
|
|
||||||
_points << newMeshPoints;
|
|
||||||
// add points to the new convex hull
|
|
||||||
_points[i++] << pointsInPart;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,23 +681,26 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
// multiply each point by scale before handing the point-set off to the physics engine.
|
// multiply each point by scale before handing the point-set off to the physics engine.
|
||||||
// also determine the extents of the collision model.
|
// also determine the extents of the collision model.
|
||||||
AABox box;
|
AABox box;
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
for (int j = 0; j < _points[i].size(); j++) {
|
for (int j = 0; j < points[i].size(); j++) {
|
||||||
// compensate for registration
|
// compensate for registration
|
||||||
_points[i][j] += _model->getOffset();
|
points[i][j] += _model->getOffset();
|
||||||
// scale so the collision points match the model points
|
// scale so the collision points match the model points
|
||||||
_points[i][j] *= scale;
|
points[i][j] *= scale;
|
||||||
// this next subtraction is done so we can give info the offset, which will cause
|
// this next subtraction is done so we can give info the offset, which will cause
|
||||||
// the shape-key to change.
|
// the shape-key to change.
|
||||||
_points[i][j] -= _model->getOffset();
|
points[i][j] -= _model->getOffset();
|
||||||
box += _points[i][j];
|
box += points[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 collisionModelDimensions = box.getDimensions();
|
glm::vec3 collisionModelDimensions = box.getDimensions();
|
||||||
info.setParams(type, collisionModelDimensions, _compoundShapeURL);
|
info.setParams(type, collisionModelDimensions, _compoundShapeURL);
|
||||||
info.setConvexHulls(_points);
|
|
||||||
info.setOffset(_model->getOffset());
|
info.setOffset(_model->getOffset());
|
||||||
|
} else {
|
||||||
|
ModelEntityItem::computeShapeInfo(info);
|
||||||
|
info.setParams(type, 0.5f * getDimensions());
|
||||||
|
adjustShapeInfoByRegistration(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,6 @@ private:
|
||||||
QVariantMap _currentTextures;
|
QVariantMap _currentTextures;
|
||||||
QVariantMap _originalTextures;
|
QVariantMap _originalTextures;
|
||||||
bool _originalTexturesRead = false;
|
bool _originalTexturesRead = false;
|
||||||
QVector<QVector<glm::vec3>> _points;
|
|
||||||
bool _dimensionsInitialized = true;
|
bool _dimensionsInitialized = true;
|
||||||
|
|
||||||
AnimationPropertyGroup _renderAnimationProperties;
|
AnimationPropertyGroup _renderAnimationProperties;
|
||||||
|
|
|
@ -88,7 +88,7 @@ void EntityItemProperties::setLastEdited(quint64 usecTime) {
|
||||||
_lastEdited = usecTime > _created ? usecTime : _created;
|
_lastEdited = usecTime > _created ? usecTime : _created;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* shapeTypeNames[] = {"none", "box", "sphere", "ellipsoid", "plane", "compound", "capsule-x",
|
const char* shapeTypeNames[] = {"none", "box", "sphere", "plane", "compound", "capsule-x",
|
||||||
"capsule-y", "capsule-z", "cylinder-x", "cylinder-y", "cylinder-z"};
|
"capsule-y", "capsule-z", "cylinder-x", "cylinder-y", "cylinder-z"};
|
||||||
|
|
||||||
QHash<QString, ShapeType> stringToShapeTypeLookup;
|
QHash<QString, ShapeType> stringToShapeTypeLookup;
|
||||||
|
@ -101,7 +101,6 @@ void buildStringToShapeTypeLookup() {
|
||||||
addShapeType(SHAPE_TYPE_NONE);
|
addShapeType(SHAPE_TYPE_NONE);
|
||||||
addShapeType(SHAPE_TYPE_BOX);
|
addShapeType(SHAPE_TYPE_BOX);
|
||||||
addShapeType(SHAPE_TYPE_SPHERE);
|
addShapeType(SHAPE_TYPE_SPHERE);
|
||||||
addShapeType(SHAPE_TYPE_ELLIPSOID);
|
|
||||||
addShapeType(SHAPE_TYPE_PLANE);
|
addShapeType(SHAPE_TYPE_PLANE);
|
||||||
addShapeType(SHAPE_TYPE_COMPOUND);
|
addShapeType(SHAPE_TYPE_COMPOUND);
|
||||||
addShapeType(SHAPE_TYPE_CAPSULE_X);
|
addShapeType(SHAPE_TYPE_CAPSULE_X);
|
||||||
|
|
|
@ -60,7 +60,7 @@ class LineEntityItem : public EntityItem {
|
||||||
|
|
||||||
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
|
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
|
||||||
|
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||||
|
|
||||||
// never have a ray intersection pick a LineEntityItem.
|
// never have a ray intersection pick a LineEntityItem.
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
|
|
|
@ -78,7 +78,7 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
|
|
||||||
virtual bool needsToCallUpdate() const { return true; }
|
virtual bool needsToCallUpdate() const { return true; }
|
||||||
|
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||||
|
|
||||||
// never have a ray intersection pick a PolyLineEntityItem.
|
// never have a ray intersection pick a PolyLineEntityItem.
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
|
|
|
@ -17,6 +17,54 @@
|
||||||
#include "ShapeFactory.h"
|
#include "ShapeFactory.h"
|
||||||
#include "BulletUtil.h"
|
#include "BulletUtil.h"
|
||||||
|
|
||||||
|
// These are the same normalized directions used by the btShapeHull class.
|
||||||
|
// 12 points for the face centers of a duodecohedron plus another 30 points
|
||||||
|
// for the midpoints the edges, for a total of 42.
|
||||||
|
const uint32_t NUM_UNIT_SPHERE_DIRECTIONS = 42;
|
||||||
|
static const btVector3 _unitSphereDirections[NUM_UNIT_SPHERE_DIRECTIONS] = {
|
||||||
|
btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
|
||||||
|
btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
|
||||||
|
btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
|
||||||
|
btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
|
||||||
|
btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
|
||||||
|
btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
|
||||||
|
btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
|
||||||
|
btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
|
||||||
|
btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
|
||||||
|
btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
|
||||||
|
btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
|
||||||
|
btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
|
||||||
|
btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
|
||||||
|
btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
|
||||||
|
btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
|
||||||
|
btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
|
||||||
|
btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
|
||||||
|
btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
|
||||||
|
btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
|
||||||
|
btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
|
||||||
|
btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
|
||||||
|
btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
|
||||||
|
btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
|
||||||
|
btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
|
||||||
|
btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
|
||||||
|
btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
|
||||||
|
btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
|
||||||
|
btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
|
||||||
|
btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
|
||||||
|
btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
|
||||||
|
btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
|
||||||
|
btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
|
||||||
|
btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
|
||||||
|
btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
|
||||||
|
btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
|
||||||
|
btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
|
||||||
|
btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
|
||||||
|
btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
|
||||||
|
btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
|
||||||
|
btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
|
||||||
|
btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
|
||||||
|
btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& points) {
|
btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& points) {
|
||||||
|
@ -66,15 +114,40 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& poin
|
||||||
hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false);
|
hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (points.size() > MAX_HULL_POINTS) {
|
uint32_t numPoints = (uint32_t)hull->getNumPoints();
|
||||||
// create hull approximation
|
if (numPoints > MAX_HULL_POINTS) {
|
||||||
btShapeHull shapeHull(hull);
|
// we have too many points, so we compute point projections along canonical unit vectors
|
||||||
shapeHull.buildHull(margin);
|
// and keep the those that project the farthest
|
||||||
|
btVector3 btCenter = glmToBullet(center);
|
||||||
|
btVector3* shapePoints = hull->getUnscaledPoints();
|
||||||
|
std::vector<uint32_t> finalIndices;
|
||||||
|
finalIndices.reserve(NUM_UNIT_SPHERE_DIRECTIONS);
|
||||||
|
for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) {
|
||||||
|
uint32_t bestIndex = 0;
|
||||||
|
btScalar maxDistance = _unitSphereDirections[i].dot(shapePoints[0] - btCenter);
|
||||||
|
for (uint32_t j = 1; j < numPoints; ++j) {
|
||||||
|
btScalar distance = _unitSphereDirections[i].dot(shapePoints[j] - btCenter);
|
||||||
|
if (distance > maxDistance) {
|
||||||
|
maxDistance = distance;
|
||||||
|
bestIndex = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool keep = true;
|
||||||
|
for (uint32_t j = 0; j < finalIndices.size(); ++j) {
|
||||||
|
if (finalIndices[j] == bestIndex) {
|
||||||
|
keep = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keep) {
|
||||||
|
finalIndices.push_back(bestIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we cannot copy Bullet shapes so we must create a new one...
|
// we cannot copy Bullet shapes so we must create a new one...
|
||||||
btConvexHullShape* newHull = new btConvexHullShape();
|
btConvexHullShape* newHull = new btConvexHullShape();
|
||||||
const btVector3* newPoints = shapeHull.getVertexPointer();
|
for (uint32_t i = 0; i < finalIndices.size(); ++i) {
|
||||||
for (int i = 0; i < shapeHull.numVertices(); ++i) {
|
newHull->addPoint(shapePoints[finalIndices[i]], false);
|
||||||
newHull->addPoint(newPoints[i], false);
|
|
||||||
}
|
}
|
||||||
// ...and delete the old one
|
// ...and delete the old one
|
||||||
delete hull;
|
delete hull;
|
||||||
|
|
|
@ -35,7 +35,46 @@ int vec3VectorTypeId = qRegisterMetaType<QVector<glm::vec3> >();
|
||||||
float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f;
|
float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f;
|
||||||
#define HTTP_INVALID_COM "http://invalid.com"
|
#define HTTP_INVALID_COM "http://invalid.com"
|
||||||
|
|
||||||
model::MaterialPointer Model::_collisionHullMaterial;
|
const int NUM_COLLISION_HULL_COLORS = 24;
|
||||||
|
std::vector<model::MaterialPointer> _collisionHullMaterials;
|
||||||
|
|
||||||
|
void initCollisionHullMaterials() {
|
||||||
|
// generates bright colors in red, green, blue, yellow, magenta, and cyan spectrums
|
||||||
|
// (no browns, greys, or dark shades)
|
||||||
|
float component[NUM_COLLISION_HULL_COLORS] = {
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.2f, 0.4f, 0.6f, 0.8f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
0.8f, 0.6f, 0.4f, 0.2f
|
||||||
|
};
|
||||||
|
_collisionHullMaterials.reserve(NUM_COLLISION_HULL_COLORS);
|
||||||
|
|
||||||
|
// each component gets the same cuve
|
||||||
|
// but offset by a multiple of one third the full width
|
||||||
|
int numComponents = 3;
|
||||||
|
int sectionWidth = NUM_COLLISION_HULL_COLORS / numComponents;
|
||||||
|
int greenPhase = sectionWidth;
|
||||||
|
int bluePhase = 2 * sectionWidth;
|
||||||
|
|
||||||
|
// we stride through the colors to scatter adjacent shades
|
||||||
|
// so they don't tend to group together for large models
|
||||||
|
for (int i = 0; i < sectionWidth; ++i) {
|
||||||
|
for (int j = 0; j < numComponents; ++j) {
|
||||||
|
model::MaterialPointer material;
|
||||||
|
material = std::make_shared<model::Material>();
|
||||||
|
int index = j * sectionWidth + i;
|
||||||
|
float red = component[index];
|
||||||
|
float green = component[(index + greenPhase) % NUM_COLLISION_HULL_COLORS];
|
||||||
|
float blue = component[(index + bluePhase) % NUM_COLLISION_HULL_COLORS];
|
||||||
|
material->setAlbedo(glm::vec3(red, green, blue));
|
||||||
|
material->setMetallic(0.02f);
|
||||||
|
material->setRoughness(0.5f);
|
||||||
|
_collisionHullMaterials.push_back(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Model::Model(RigPointer rig, QObject* parent) :
|
Model::Model(RigPointer rig, QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
|
@ -1217,13 +1256,10 @@ void Model::segregateMeshGroups() {
|
||||||
int totalParts = mesh.parts.size();
|
int totalParts = mesh.parts.size();
|
||||||
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
||||||
if (showingCollisionHull) {
|
if (showingCollisionHull) {
|
||||||
if (!_collisionHullMaterial) {
|
if (_collisionHullMaterials.empty()) {
|
||||||
_collisionHullMaterial = std::make_shared<model::Material>();
|
initCollisionHullMaterials();
|
||||||
_collisionHullMaterial->setAlbedo(glm::vec3(1.0f, 0.5f, 0.0f));
|
|
||||||
_collisionHullMaterial->setMetallic(0.02f);
|
|
||||||
_collisionHullMaterial->setRoughness(0.5f);
|
|
||||||
}
|
}
|
||||||
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(networkMesh, partIndex, _collisionHullMaterial, transform, offset);
|
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(networkMesh, partIndex, _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS], transform, offset);
|
||||||
} else {
|
} else {
|
||||||
_modelMeshRenderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset);
|
_modelMeshRenderItemsSet << std::make_shared<ModelMeshPartPayload>(this, i, partIndex, shapeID, transform, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ void ShapeInfo::clear() {
|
||||||
|
|
||||||
void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) {
|
void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) {
|
||||||
_type = type;
|
_type = type;
|
||||||
_points.clear();
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case SHAPE_TYPE_NONE:
|
case SHAPE_TYPE_NONE:
|
||||||
_halfExtents = glm::vec3(0.0f);
|
_halfExtents = glm::vec3(0.0f);
|
||||||
|
@ -52,7 +51,6 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||||
_url = "";
|
_url = "";
|
||||||
_type = SHAPE_TYPE_BOX;
|
_type = SHAPE_TYPE_BOX;
|
||||||
_halfExtents = halfExtents;
|
_halfExtents = halfExtents;
|
||||||
_points.clear();
|
|
||||||
_doubleHashKey.clear();
|
_doubleHashKey.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,15 +58,6 @@ void ShapeInfo::setSphere(float radius) {
|
||||||
_url = "";
|
_url = "";
|
||||||
_type = SHAPE_TYPE_SPHERE;
|
_type = SHAPE_TYPE_SPHERE;
|
||||||
_halfExtents = glm::vec3(radius, radius, radius);
|
_halfExtents = glm::vec3(radius, radius, radius);
|
||||||
_points.clear();
|
|
||||||
_doubleHashKey.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) {
|
|
||||||
_url = "";
|
|
||||||
_type = SHAPE_TYPE_ELLIPSOID;
|
|
||||||
_halfExtents = halfExtents;
|
|
||||||
_points.clear();
|
|
||||||
_doubleHashKey.clear();
|
_doubleHashKey.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +71,6 @@ void ShapeInfo::setCapsuleY(float radius, float halfHeight) {
|
||||||
_url = "";
|
_url = "";
|
||||||
_type = SHAPE_TYPE_CAPSULE_Y;
|
_type = SHAPE_TYPE_CAPSULE_Y;
|
||||||
_halfExtents = glm::vec3(radius, halfHeight, radius);
|
_halfExtents = glm::vec3(radius, halfHeight, radius);
|
||||||
_points.clear();
|
|
||||||
_doubleHashKey.clear();
|
_doubleHashKey.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,10 +134,6 @@ bool ShapeInfo::contains(const glm::vec3& point) const {
|
||||||
switch(_type) {
|
switch(_type) {
|
||||||
case SHAPE_TYPE_SPHERE:
|
case SHAPE_TYPE_SPHERE:
|
||||||
return glm::length(point) <= _halfExtents.x;
|
return glm::length(point) <= _halfExtents.x;
|
||||||
case SHAPE_TYPE_ELLIPSOID: {
|
|
||||||
glm::vec3 scaledPoint = glm::abs(point) / _halfExtents;
|
|
||||||
return glm::length(scaledPoint) <= 1.0f;
|
|
||||||
}
|
|
||||||
case SHAPE_TYPE_CYLINDER_X:
|
case SHAPE_TYPE_CYLINDER_X:
|
||||||
return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z;
|
return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z;
|
||||||
case SHAPE_TYPE_CYLINDER_Y:
|
case SHAPE_TYPE_CYLINDER_Y:
|
||||||
|
|
|
@ -30,7 +30,6 @@ enum ShapeType {
|
||||||
SHAPE_TYPE_NONE,
|
SHAPE_TYPE_NONE,
|
||||||
SHAPE_TYPE_BOX,
|
SHAPE_TYPE_BOX,
|
||||||
SHAPE_TYPE_SPHERE,
|
SHAPE_TYPE_SPHERE,
|
||||||
SHAPE_TYPE_ELLIPSOID,
|
|
||||||
SHAPE_TYPE_PLANE,
|
SHAPE_TYPE_PLANE,
|
||||||
SHAPE_TYPE_COMPOUND,
|
SHAPE_TYPE_COMPOUND,
|
||||||
SHAPE_TYPE_CAPSULE_X,
|
SHAPE_TYPE_CAPSULE_X,
|
||||||
|
@ -39,7 +38,7 @@ enum ShapeType {
|
||||||
SHAPE_TYPE_CYLINDER_X,
|
SHAPE_TYPE_CYLINDER_X,
|
||||||
SHAPE_TYPE_CYLINDER_Y,
|
SHAPE_TYPE_CYLINDER_Y,
|
||||||
SHAPE_TYPE_CYLINDER_Z,
|
SHAPE_TYPE_CYLINDER_Z,
|
||||||
SHAPE_TYPE_LINE
|
SHAPE_TYPE_STATIC_MESH
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShapeInfo {
|
class ShapeInfo {
|
||||||
|
@ -50,7 +49,6 @@ public:
|
||||||
void setParams(ShapeType type, const glm::vec3& halfExtents, QString url="");
|
void setParams(ShapeType type, const glm::vec3& halfExtents, QString url="");
|
||||||
void setBox(const glm::vec3& halfExtents);
|
void setBox(const glm::vec3& halfExtents);
|
||||||
void setSphere(float radius);
|
void setSphere(float radius);
|
||||||
void setEllipsoid(const glm::vec3& halfExtents);
|
|
||||||
void setConvexHulls(const QVector<QVector<glm::vec3>>& points);
|
void setConvexHulls(const QVector<QVector<glm::vec3>>& points);
|
||||||
void setCapsuleY(float radius, float halfHeight);
|
void setCapsuleY(float radius, float halfHeight);
|
||||||
void setOffset(const glm::vec3& offset);
|
void setOffset(const glm::vec3& offset);
|
||||||
|
@ -60,10 +58,10 @@ public:
|
||||||
const glm::vec3& getHalfExtents() const { return _halfExtents; }
|
const glm::vec3& getHalfExtents() const { return _halfExtents; }
|
||||||
const glm::vec3& getOffset() const { return _offset; }
|
const glm::vec3& getOffset() const { return _offset; }
|
||||||
|
|
||||||
|
QVector<QVector<glm::vec3>>& getPoints() { return _points; }
|
||||||
const QVector<QVector<glm::vec3>>& getPoints() const { return _points; }
|
const QVector<QVector<glm::vec3>>& getPoints() const { return _points; }
|
||||||
uint32_t getNumSubShapes() const;
|
uint32_t getNumSubShapes() const;
|
||||||
|
|
||||||
void clearPoints () { _points.clear(); }
|
|
||||||
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
|
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
|
||||||
int getMaxNumPoints() const;
|
int getMaxNumPoints() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue