mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 21:43:03 +02:00
Remove CollisionPick::computeShapeInfo
This commit is contained in:
parent
7af0940846
commit
921eed1ec1
2 changed files with 3 additions and 232 deletions
|
@ -121,8 +121,9 @@ bool CollisionPick::isLoaded() const {
|
||||||
bool CollisionPick::getShapeInfoReady(const CollisionRegion& pick) {
|
bool CollisionPick::getShapeInfoReady(const CollisionRegion& pick) {
|
||||||
if (_mathPick.shouldComputeShapeInfo()) {
|
if (_mathPick.shouldComputeShapeInfo()) {
|
||||||
if (_cachedResource && _cachedResource->isLoaded()) {
|
if (_cachedResource && _cachedResource->isLoaded()) {
|
||||||
computeShapeInfo(pick, *_mathPick.shapeInfo, _cachedResource);
|
// TODO: Model CollisionPick support
|
||||||
_mathPick.loaded = true;
|
//computeShapeInfo(pick, *_mathPick.shapeInfo, _cachedResource);
|
||||||
|
//_mathPick.loaded = true;
|
||||||
} else {
|
} else {
|
||||||
_mathPick.loaded = false;
|
_mathPick.loaded = false;
|
||||||
}
|
}
|
||||||
|
@ -147,235 +148,6 @@ void CollisionPick::computeShapeInfoDimensionsOnly(const CollisionRegion& pick,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<ModelResource> resource) {
|
|
||||||
// This code was copied and modified from RenderableModelEntityItem::computeShapeInfo
|
|
||||||
// TODO: Move to some shared code area (in entities-renderer? model-networking?)
|
|
||||||
// after we verify this is working and do a diff comparison with RenderableModelEntityItem::computeShapeInfo
|
|
||||||
// to consolidate the code.
|
|
||||||
// We may also want to make computeShapeInfo always abstract away from the gpu model mesh, like it does here.
|
|
||||||
const uint32_t TRIANGLE_STRIDE = 3;
|
|
||||||
const uint32_t QUAD_STRIDE = 4;
|
|
||||||
|
|
||||||
ShapeType type = shapeInfo.getType();
|
|
||||||
glm::vec3 dimensions = pick.transform.getScale();
|
|
||||||
if (type == SHAPE_TYPE_COMPOUND) {
|
|
||||||
// should never fall in here when collision model not fully loaded
|
|
||||||
// TODO: assert that all geometries exist and are loaded
|
|
||||||
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
|
||||||
const HFMModel& collisionModel = resource->getHFMModel();
|
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.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
|
|
||||||
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
|
|
||||||
foreach (const HFMMesh& mesh, collisionModel.meshes) {
|
|
||||||
// each meshPart is a convex hull
|
|
||||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
|
||||||
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();
|
|
||||||
// TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
|
|
||||||
//assert(numIndices % TRIANGLE_STRIDE == 0);
|
|
||||||
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < numIndices; j += TRIANGLE_STRIDE) {
|
|
||||||
glm::vec3 p0 = mesh.vertices[meshPart.triangleIndices[j]];
|
|
||||||
glm::vec3 p1 = mesh.vertices[meshPart.triangleIndices[j + 1]];
|
|
||||||
glm::vec3 p2 = mesh.vertices[meshPart.triangleIndices[j + 2]];
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
|
||||||
pointsInPart << p0;
|
|
||||||
}
|
|
||||||
if (!pointsInPart.contains(p1)) {
|
|
||||||
pointsInPart << p1;
|
|
||||||
}
|
|
||||||
if (!pointsInPart.contains(p2)) {
|
|
||||||
pointsInPart << p2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// run through all the quads and (uniquely) add each point to the hull
|
|
||||||
numIndices = (uint32_t)meshPart.quadIndices.size();
|
|
||||||
// TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
|
|
||||||
//assert(numIndices % QUAD_STRIDE == 0);
|
|
||||||
numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < numIndices; j += QUAD_STRIDE) {
|
|
||||||
glm::vec3 p0 = mesh.vertices[meshPart.quadIndices[j]];
|
|
||||||
glm::vec3 p1 = mesh.vertices[meshPart.quadIndices[j + 1]];
|
|
||||||
glm::vec3 p2 = mesh.vertices[meshPart.quadIndices[j + 2]];
|
|
||||||
glm::vec3 p3 = mesh.vertices[meshPart.quadIndices[j + 3]];
|
|
||||||
if (!pointsInPart.contains(p0)) {
|
|
||||||
pointsInPart << p0;
|
|
||||||
}
|
|
||||||
if (!pointsInPart.contains(p1)) {
|
|
||||||
pointsInPart << p1;
|
|
||||||
}
|
|
||||||
if (!pointsInPart.contains(p2)) {
|
|
||||||
pointsInPart << p2;
|
|
||||||
}
|
|
||||||
if (!pointsInPart.contains(p3)) {
|
|
||||||
pointsInPart << p3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pointsInPart.size() == 0) {
|
|
||||||
qCDebug(scriptengine) << "Warning -- meshPart has no faces";
|
|
||||||
pointCollection.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We expect that the collision model will have the same units and will be displaced
|
|
||||||
// from its origin in the same way the visual model is. The visual model has
|
|
||||||
// been centered and probably scaled. We take the scaling and offset which were applied
|
|
||||||
// to the visual model and apply them to the collision model (without regard for the
|
|
||||||
// collision model's extents).
|
|
||||||
|
|
||||||
glm::vec3 scaleToFit = dimensions / resource->getHFMModel().getUnscaledMeshExtents().size();
|
|
||||||
// multiply each point by scale
|
|
||||||
for (int32_t i = 0; i < pointCollection.size(); i++) {
|
|
||||||
for (int32_t j = 0; j < pointCollection[i].size(); j++) {
|
|
||||||
// back compensate for registration so we can apply that offset to the shapeInfo later
|
|
||||||
pointCollection[i][j] = scaleToFit * pointCollection[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shapeInfo.setParams(type, dimensions, resource->getURL().toString());
|
|
||||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
|
||||||
const HFMModel& hfmModel = resource->getHFMModel();
|
|
||||||
uint32_t numHFMMeshes = (uint32_t)hfmModel.meshes.size();
|
|
||||||
int totalNumVertices = 0;
|
|
||||||
for (uint32_t i = 0; i < numHFMMeshes; i++) {
|
|
||||||
const HFMMesh& mesh = hfmModel.meshes.at(i);
|
|
||||||
totalNumVertices += mesh.vertices.size();
|
|
||||||
}
|
|
||||||
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
|
|
||||||
if (totalNumVertices > MAX_VERTICES_PER_STATIC_MESH) {
|
|
||||||
qWarning() << "model" << "has too many vertices" << totalNumVertices << "and will collide as a box.";
|
|
||||||
shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& meshes = resource->getHFMModel().meshes;
|
|
||||||
int32_t numMeshes = (int32_t)(meshes.size());
|
|
||||||
|
|
||||||
const int MAX_ALLOWED_MESH_COUNT = 1000;
|
|
||||||
if (numMeshes > MAX_ALLOWED_MESH_COUNT) {
|
|
||||||
// too many will cause the deadlock timer to throw...
|
|
||||||
shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
|
||||||
pointCollection.clear();
|
|
||||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
|
||||||
pointCollection.resize(numMeshes);
|
|
||||||
} else {
|
|
||||||
pointCollection.resize(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShapeInfo::TriangleIndices& triangleIndices = shapeInfo.getTriangleIndices();
|
|
||||||
triangleIndices.clear();
|
|
||||||
|
|
||||||
Extents extents;
|
|
||||||
int32_t meshCount = 0;
|
|
||||||
int32_t pointListIndex = 0;
|
|
||||||
for (auto& mesh : meshes) {
|
|
||||||
if (!mesh.vertices.size()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QVector<glm::vec3> vertices = mesh.vertices;
|
|
||||||
|
|
||||||
ShapeInfo::PointList& points = pointCollection[pointListIndex];
|
|
||||||
|
|
||||||
// reserve room
|
|
||||||
int32_t sizeToReserve = (int32_t)(vertices.count());
|
|
||||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
|
||||||
// a list of points for each mesh
|
|
||||||
pointListIndex++;
|
|
||||||
} else {
|
|
||||||
// only one list of points
|
|
||||||
sizeToReserve += (int32_t)points.size();
|
|
||||||
}
|
|
||||||
points.reserve(sizeToReserve);
|
|
||||||
|
|
||||||
// copy points
|
|
||||||
const glm::vec3* vertexItr = vertices.cbegin();
|
|
||||||
while (vertexItr != vertices.cend()) {
|
|
||||||
glm::vec3 point = *vertexItr;
|
|
||||||
points.push_back(point);
|
|
||||||
extents.addPoint(point);
|
|
||||||
++vertexItr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == SHAPE_TYPE_STATIC_MESH) {
|
|
||||||
// copy into triangleIndices
|
|
||||||
size_t triangleIndicesCount = 0;
|
|
||||||
for (const HFMMeshPart& meshPart : mesh.parts) {
|
|
||||||
triangleIndicesCount += meshPart.triangleIndices.count();
|
|
||||||
}
|
|
||||||
triangleIndices.reserve((int)triangleIndicesCount);
|
|
||||||
|
|
||||||
for (const HFMMeshPart& meshPart : mesh.parts) {
|
|
||||||
const int* indexItr = meshPart.triangleIndices.cbegin();
|
|
||||||
while (indexItr != meshPart.triangleIndices.cend()) {
|
|
||||||
triangleIndices.push_back(*indexItr);
|
|
||||||
++indexItr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
|
||||||
// for each mesh copy unique part indices, separated by special bogus (flag) index values
|
|
||||||
for (const HFMMeshPart& meshPart : mesh.parts) {
|
|
||||||
// collect unique list of indices for this part
|
|
||||||
std::set<int32_t> uniqueIndices;
|
|
||||||
auto numIndices = meshPart.triangleIndices.count();
|
|
||||||
// TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
|
|
||||||
//assert(numIndices% TRIANGLE_STRIDE == 0);
|
|
||||||
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXSerializer
|
|
||||||
|
|
||||||
auto indexItr = meshPart.triangleIndices.cbegin();
|
|
||||||
while (indexItr != meshPart.triangleIndices.cend()) {
|
|
||||||
uniqueIndices.insert(*indexItr);
|
|
||||||
++indexItr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store uniqueIndices in triangleIndices
|
|
||||||
triangleIndices.reserve(triangleIndices.size() + (int32_t)uniqueIndices.size());
|
|
||||||
for (auto index : uniqueIndices) {
|
|
||||||
triangleIndices.push_back(index);
|
|
||||||
}
|
|
||||||
// flag end of part
|
|
||||||
triangleIndices.push_back(END_OF_MESH_PART);
|
|
||||||
}
|
|
||||||
// flag end of mesh
|
|
||||||
triangleIndices.push_back(END_OF_MESH);
|
|
||||||
}
|
|
||||||
++meshCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// scale and shift
|
|
||||||
glm::vec3 extentsSize = extents.size();
|
|
||||||
glm::vec3 scaleToFit = dimensions / extentsSize;
|
|
||||||
for (int32_t i = 0; i < 3; ++i) {
|
|
||||||
if (extentsSize[i] < 1.0e-6f) {
|
|
||||||
scaleToFit[i] = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto points : pointCollection) {
|
|
||||||
for (int32_t i = 0; i < points.size(); ++i) {
|
|
||||||
points[i] = (points[i] * scaleToFit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shapeInfo.setParams(type, 0.5f * dimensions, resource->getURL().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, bool scaleWithParent, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine) :
|
CollisionPick::CollisionPick(const PickFilter& filter, float maxDistance, bool enabled, bool scaleWithParent, CollisionRegion collisionRegion, PhysicsEnginePointer physicsEngine) :
|
||||||
Pick(collisionRegion, filter, maxDistance, enabled),
|
Pick(collisionRegion, filter, maxDistance, enabled),
|
||||||
_scaleWithParent(scaleWithParent),
|
_scaleWithParent(scaleWithParent),
|
||||||
|
|
|
@ -63,7 +63,6 @@ protected:
|
||||||
bool isLoaded() const;
|
bool isLoaded() const;
|
||||||
// Returns true if _mathPick.shapeInfo is valid. Otherwise, attempts to get the _mathPick ready for use.
|
// Returns true if _mathPick.shapeInfo is valid. Otherwise, attempts to get the _mathPick ready for use.
|
||||||
bool getShapeInfoReady(const CollisionRegion& pick);
|
bool getShapeInfoReady(const CollisionRegion& pick);
|
||||||
void computeShapeInfo(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<ModelResource> resource);
|
|
||||||
void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<ModelResource> resource);
|
void computeShapeInfoDimensionsOnly(const CollisionRegion& pick, ShapeInfo& shapeInfo, QSharedPointer<ModelResource> resource);
|
||||||
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
|
void filterIntersections(std::vector<ContactTestResult>& intersections) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue