mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 04:03:35 +02:00
creae collision Geometry from mesh
This commit is contained in:
parent
499150bbed
commit
726928c14c
8 changed files with 64 additions and 16 deletions
|
@ -1,7 +1,7 @@
|
||||||
set(TARGET_NAME entities-renderer)
|
set(TARGET_NAME entities-renderer)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils)
|
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils)
|
||||||
setup_hifi_library(Widgets Network Script)
|
setup_hifi_library(Widgets Network Script)
|
||||||
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils)
|
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils physics)
|
||||||
|
|
||||||
target_bullet()
|
target_bullet()
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <glm/gtx/transform.hpp>
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
#include <AbstractViewStateInterface.h>
|
#include <AbstractViewStateInterface.h>
|
||||||
|
#include <CollisionRenderMeshCache.h>
|
||||||
#include <Model.h>
|
#include <Model.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <render/Scene.h>
|
#include <render/Scene.h>
|
||||||
|
@ -917,8 +918,22 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CollisionRenderMeshCache collisionMeshCache;
|
||||||
|
|
||||||
void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) {
|
void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) {
|
||||||
// TODO: generate collision mesh and update _model
|
const void* key = static_cast<const void*>(shape);
|
||||||
|
if (_collisionMeshKey != key) {
|
||||||
|
if (_collisionMeshKey) {
|
||||||
|
// releasing the shape is not strictly necessary, but
|
||||||
|
// we do it as hint to the cache's garbage collection system
|
||||||
|
collisionMeshCache.releaseMesh(_collisionMeshKey);
|
||||||
|
}
|
||||||
|
_collisionMeshKey = key;
|
||||||
|
model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey);
|
||||||
|
if (_model) {
|
||||||
|
_model->setCollisionMesh(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
|
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
|
||||||
|
|
|
@ -119,6 +119,7 @@ private:
|
||||||
bool getAnimationFrame();
|
bool getAnimationFrame();
|
||||||
|
|
||||||
bool _needsJointSimulation { false };
|
bool _needsJointSimulation { false };
|
||||||
|
const void* _collisionMeshKey { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RenderableModelEntityItem_h
|
#endif // hifi_RenderableModelEntityItem_h
|
||||||
|
|
|
@ -111,13 +111,12 @@ public:
|
||||||
|
|
||||||
QUrl getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); }
|
QUrl getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); }
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished(bool success);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void startWatching();
|
void startWatching();
|
||||||
void stopWatching();
|
void stopWatching();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(bool success);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void resourceFinished(bool success);
|
void resourceFinished(bool success);
|
||||||
void resourceRefreshed();
|
void resourceRefreshed();
|
||||||
|
|
|
@ -67,12 +67,16 @@ void copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
model::MeshPointer createMeshFromShape(const btCollisionShape* shape) {
|
model::MeshPointer createMeshFromShape(const void* pointer) {
|
||||||
model::MeshPointer mesh;
|
model::MeshPointer mesh;
|
||||||
if (!shape) {
|
if (!pointer) {
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pointer must actually be a const btCollisionShape*, but it only
|
||||||
|
// needs to be valid here when its render mesh is created.
|
||||||
|
const btCollisionShape* shape = static_cast<const btCollisionShape*>(pointer);
|
||||||
|
|
||||||
int32_t shapeType = shape->getShapeType();
|
int32_t shapeType = shape->getShapeType();
|
||||||
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE || shape->isConvex()) {
|
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE || shape->isConvex()) {
|
||||||
// create the mesh and allocate buffers for it
|
// create the mesh and allocate buffers for it
|
||||||
|
@ -84,7 +88,7 @@ model::MeshPointer createMeshFromShape(const btCollisionShape* shape) {
|
||||||
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE) {
|
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE) {
|
||||||
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
||||||
int32_t numSubShapes = compoundShape->getNumChildShapes();
|
int32_t numSubShapes = compoundShape->getNumChildShapes();
|
||||||
for (int i = 0; i < numSubShapes; ++i) {
|
for (int32_t i = 0; i < numSubShapes; ++i) {
|
||||||
const btCollisionShape* childShape = compoundShape->getChildShape(i);
|
const btCollisionShape* childShape = compoundShape->getChildShape(i);
|
||||||
if (childShape->isConvex()) {
|
if (childShape->isConvex()) {
|
||||||
const btConvexShape* convexShape = static_cast<const btConvexShape*>(childShape);
|
const btConvexShape* convexShape = static_cast<const btConvexShape*>(childShape);
|
||||||
|
@ -122,6 +126,10 @@ model::MeshPointer CollisionRenderMeshCache::getMesh(CollisionRenderMeshCache::K
|
||||||
mesh = itr->second;
|
mesh = itr->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const uint32_t MAX_NUM_PENDING_GARBAGE = 20;
|
||||||
|
if (_pendingGarbage.size() > MAX_NUM_PENDING_GARBAGE) {
|
||||||
|
collectGarbage();
|
||||||
|
}
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,19 +139,19 @@ bool CollisionRenderMeshCache::releaseMesh(CollisionRenderMeshCache::Key key) {
|
||||||
}
|
}
|
||||||
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
||||||
if (itr != _meshMap.end()) {
|
if (itr != _meshMap.end()) {
|
||||||
|
// we hold at least one reference, and the outer scope also holds at least one
|
||||||
|
// so we assert that the reference count is not 1
|
||||||
assert((*itr).second.use_count() != 1);
|
assert((*itr).second.use_count() != 1);
|
||||||
|
|
||||||
_pendingGarbage.push_back(key);
|
_pendingGarbage.push_back(key);
|
||||||
if ((*itr).second.use_count() == 1) {
|
|
||||||
// we hold all of the references inside the cache so we'll try to delete later
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollisionRenderMeshCache::collectGarbage() {
|
void CollisionRenderMeshCache::collectGarbage() {
|
||||||
int numShapes = _pendingGarbage.size();
|
uint32_t numShapes = _pendingGarbage.size();
|
||||||
for (int i = 0; i < numShapes; ++i) {
|
for (int32_t i = 0; i < numShapes; ++i) {
|
||||||
CollisionRenderMeshCache::Key key = _pendingGarbage[i];
|
CollisionRenderMeshCache::Key key = _pendingGarbage[i];
|
||||||
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
||||||
if (itr != _meshMap.end()) {
|
if (itr != _meshMap.end()) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <model/Geometry.h>
|
#include <model/Geometry.h>
|
||||||
|
|
||||||
|
/*
|
||||||
class btCollisionShape;
|
class btCollisionShape;
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
@ -28,10 +29,11 @@ namespace std {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
class CollisionRenderMeshCache {
|
class CollisionRenderMeshCache {
|
||||||
public:
|
public:
|
||||||
using Key = const btCollisionShape*;
|
using Key = const void*; // must actually be a const btCollisionShape*
|
||||||
|
|
||||||
CollisionRenderMeshCache();
|
CollisionRenderMeshCache();
|
||||||
~CollisionRenderMeshCache();
|
~CollisionRenderMeshCache();
|
||||||
|
|
|
@ -1336,6 +1336,28 @@ bool Model::initWhenReady(render::ScenePointer scene) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CollisionRenderGeometry : public Geometry {
|
||||||
|
public:
|
||||||
|
CollisionRenderGeometry(model::MeshPointer mesh) {
|
||||||
|
_fbxGeometry = std::make_shared<FBXGeometry>();
|
||||||
|
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
|
||||||
|
meshes->push_back(mesh);
|
||||||
|
_meshes = meshes;
|
||||||
|
_meshParts = std::shared_ptr<const GeometryMeshParts>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Model::setCollisionMesh(model::MeshPointer mesh) {
|
||||||
|
_collisionWatcher.stopWatching();
|
||||||
|
_collisionGeometry = std::make_shared<CollisionRenderGeometry>(mesh);
|
||||||
|
|
||||||
|
if (_showCollisionHull) {
|
||||||
|
// TODO: need to trigger:
|
||||||
|
// (a) reconstruction of RenderItems
|
||||||
|
// (b) and reinsertion into scene if we are showing collision geometry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ModelBlender::ModelBlender() :
|
ModelBlender::ModelBlender() :
|
||||||
_pendingBlenders(0) {
|
_pendingBlenders(0) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,7 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void setURLFinished(bool success);
|
void setURLFinished(bool success);
|
||||||
void setCollisionModelURLFinished(bool success);
|
void setCollisionModelURLFinished(bool success);
|
||||||
|
void setCollisionMesh(model::MeshPointer mesh);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -282,7 +283,7 @@ protected:
|
||||||
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
||||||
|
|
||||||
Geometry::Pointer _renderGeometry; // only ever set by its watcher
|
Geometry::Pointer _renderGeometry; // only ever set by its watcher
|
||||||
Geometry::Pointer _collisionGeometry; // only ever set by its watcher
|
Geometry::Pointer _collisionGeometry;
|
||||||
|
|
||||||
GeometryResourceWatcher _renderWatcher;
|
GeometryResourceWatcher _renderWatcher;
|
||||||
GeometryResourceWatcher _collisionWatcher;
|
GeometryResourceWatcher _collisionWatcher;
|
||||||
|
|
Loading…
Reference in a new issue