mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:24:22 +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)
|
||||
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils)
|
||||
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()
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include <AbstractViewStateInterface.h>
|
||||
#include <CollisionRenderMeshCache.h>
|
||||
#include <Model.h>
|
||||
#include <PerfStat.h>
|
||||
#include <render/Scene.h>
|
||||
|
@ -917,8 +918,22 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
|||
}
|
||||
}
|
||||
|
||||
static CollisionRenderMeshCache collisionMeshCache;
|
||||
|
||||
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 {
|
||||
|
|
|
@ -119,6 +119,7 @@ private:
|
|||
bool getAnimationFrame();
|
||||
|
||||
bool _needsJointSimulation { false };
|
||||
const void* _collisionMeshKey { nullptr };
|
||||
};
|
||||
|
||||
#endif // hifi_RenderableModelEntityItem_h
|
||||
|
|
|
@ -111,13 +111,12 @@ public:
|
|||
|
||||
QUrl getURL() const { return (bool)_resource ? _resource->getURL() : QUrl(); }
|
||||
|
||||
signals:
|
||||
void finished(bool success);
|
||||
|
||||
private:
|
||||
void startWatching();
|
||||
void stopWatching();
|
||||
|
||||
signals:
|
||||
void finished(bool success);
|
||||
|
||||
private slots:
|
||||
void resourceFinished(bool success);
|
||||
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;
|
||||
if (!shape) {
|
||||
if (!pointer) {
|
||||
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();
|
||||
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE || shape->isConvex()) {
|
||||
// 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) {
|
||||
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
||||
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);
|
||||
if (childShape->isConvex()) {
|
||||
const btConvexShape* convexShape = static_cast<const btConvexShape*>(childShape);
|
||||
|
@ -122,6 +126,10 @@ model::MeshPointer CollisionRenderMeshCache::getMesh(CollisionRenderMeshCache::K
|
|||
mesh = itr->second;
|
||||
}
|
||||
}
|
||||
const uint32_t MAX_NUM_PENDING_GARBAGE = 20;
|
||||
if (_pendingGarbage.size() > MAX_NUM_PENDING_GARBAGE) {
|
||||
collectGarbage();
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
@ -131,19 +139,19 @@ bool CollisionRenderMeshCache::releaseMesh(CollisionRenderMeshCache::Key key) {
|
|||
}
|
||||
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
||||
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);
|
||||
|
||||
_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 false;
|
||||
}
|
||||
|
||||
void CollisionRenderMeshCache::collectGarbage() {
|
||||
int numShapes = _pendingGarbage.size();
|
||||
for (int i = 0; i < numShapes; ++i) {
|
||||
uint32_t numShapes = _pendingGarbage.size();
|
||||
for (int32_t i = 0; i < numShapes; ++i) {
|
||||
CollisionRenderMeshCache::Key key = _pendingGarbage[i];
|
||||
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
||||
if (itr != _meshMap.end()) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <model/Geometry.h>
|
||||
|
||||
/*
|
||||
class btCollisionShape;
|
||||
|
||||
namespace std {
|
||||
|
@ -28,10 +29,11 @@ namespace std {
|
|||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
class CollisionRenderMeshCache {
|
||||
public:
|
||||
using Key = const btCollisionShape*;
|
||||
using Key = const void*; // must actually be a const btCollisionShape*
|
||||
|
||||
CollisionRenderMeshCache();
|
||||
~CollisionRenderMeshCache();
|
||||
|
|
|
@ -1336,6 +1336,28 @@ bool Model::initWhenReady(render::ScenePointer scene) {
|
|||
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() :
|
||||
_pendingBlenders(0) {
|
||||
}
|
||||
|
|
|
@ -249,6 +249,7 @@ public slots:
|
|||
signals:
|
||||
void setURLFinished(bool success);
|
||||
void setCollisionModelURLFinished(bool success);
|
||||
void setCollisionMesh(model::MeshPointer mesh);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -282,7 +283,7 @@ protected:
|
|||
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
||||
|
||||
Geometry::Pointer _renderGeometry; // only ever set by its watcher
|
||||
Geometry::Pointer _collisionGeometry; // only ever set by its watcher
|
||||
Geometry::Pointer _collisionGeometry;
|
||||
|
||||
GeometryResourceWatcher _renderWatcher;
|
||||
GeometryResourceWatcher _collisionWatcher;
|
||||
|
|
Loading…
Reference in a new issue