creae collision Geometry from mesh

This commit is contained in:
Andrew Meadows 2016-07-19 09:38:54 -07:00
parent 499150bbed
commit 726928c14c
8 changed files with 64 additions and 16 deletions

View file

@ -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()

View file

@ -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 {

View file

@ -119,6 +119,7 @@ private:
bool getAnimationFrame();
bool _needsJointSimulation { false };
const void* _collisionMeshKey { nullptr };
};
#endif // hifi_RenderableModelEntityItem_h

View file

@ -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();

View file

@ -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()) {

View file

@ -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();

View file

@ -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) {
}

View file

@ -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;