From 769194f046fd35d00070782b1ab911e4ea2bfaa3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 Mar 2015 13:41:14 -0700 Subject: [PATCH 01/54] first stab at compound hull collisions --- .../src/RenderableModelEntityItem.cpp | 9 ++++--- .../src/RenderableModelEntityItem.h | 2 +- libraries/physics/src/ShapeInfoUtil.cpp | 24 +++++++++++++++---- libraries/shared/src/ShapeInfo.cpp | 2 +- libraries/shared/src/ShapeInfo.h | 8 +++---- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d4eefc0986..6d32b78689 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -295,12 +295,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); _points.clear(); + unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { - _points << mesh.vertices; + _points[i++] << mesh.vertices; } info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); - info.setConvexHull(_points); + info.setConvexHulls(_points); } } @@ -308,7 +309,9 @@ ShapeType RenderableModelEntityItem::getShapeType() const { // XXX make hull an option in edit.js ? if (!_model || _model->getCollisionURL().isEmpty()) { return _shapeType; - } else { + } else if (_points.size() == 1) { return SHAPE_TYPE_CONVEX_HULL; + } else { + return SHAPE_TYPE_COMPOUND; } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index f02dd537fb..63249f136c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -66,7 +66,7 @@ private: QString _currentTextures; QStringList _originalTextures; bool _originalTexturesRead; - QVector _points; + QVector> _points; }; #endif // hifi_RenderableModelEntityItem_h diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 116be984b9..2f7c0c59bd 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -70,12 +70,12 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf const btConvexHullShape* convexHullShape = static_cast(shape); const int numPoints = convexHullShape->getNumPoints(); const btVector3* btPoints = convexHullShape->getUnscaledPoints(); - QVector points; + QVector> points; for (int i = 0; i < numPoints; i++) { glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); - points << point; + points[0] << point; } - info.setConvexHull(points); + info.setConvexHulls(points); } break; default: { @@ -109,13 +109,27 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { break; case SHAPE_TYPE_CONVEX_HULL: { shape = new btConvexHullShape(); - const QVector& points = info.getPoints(); - foreach (glm::vec3 point, points) { + const QVector>& points = info.getPoints(); + foreach (glm::vec3 point, points[0]) { btVector3 btPoint(point[0], point[1], point[2]); static_cast(shape)->addPoint(btPoint); } } break; + case SHAPE_TYPE_COMPOUND: { + shape = new btCompoundShape(); + const QVector>& points = info.getPoints(); + foreach (QVector hullPoints, info.getPoints()) { + auto hull = new btConvexHullShape(); + foreach (glm::vec3 point, hullPoints) { + btVector3 btPoint(point[0], point[1], point[2]); + hull->addPoint(btPoint); + } + btTransform trans; + static_cast(shape)->addChildShape (trans, hull); + } + } + break; } return shape; } diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 61432830e7..afa19bcd24 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -64,7 +64,7 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { _doubleHashKey.clear(); } -void ShapeInfo::setConvexHull(const QVector& points) { +void ShapeInfo::setConvexHulls(const QVector>& points) { _type = SHAPE_TYPE_CONVEX_HULL; _points = points; } diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 0a55f7c51d..4dce121d64 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -44,14 +44,14 @@ public: void setBox(const glm::vec3& halfExtents); void setSphere(float radius); void setEllipsoid(const glm::vec3& halfExtents); - void setConvexHull(const QVector& points); + void setConvexHulls(const QVector>& points); void setCapsuleY(float radius, float halfHeight); const int getType() const { return _type; } const glm::vec3& getHalfExtents() const { return _halfExtents; } - const QVector& getPoints() const { return _points; } + const QVector>& getPoints() const { return _points; } void clearPoints () { _points.clear(); } void appendToPoints (const QVector& newPoints) { _points << newPoints; } @@ -64,8 +64,8 @@ protected: ShapeType _type = SHAPE_TYPE_NONE; glm::vec3 _halfExtents = glm::vec3(0.0f); DoubleHashKey _doubleHashKey; - QVector _points; // points for convex collision hull - QUrl _url; // url for model of convex collision hull + QVector> _points; // points for convex collision hulls + QUrl _url; // url for model of convex collision hulls }; #endif // hifi_ShapeInfo_h From 86d09a1607a2fee57fee73c2a01026be71560620 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Mar 2015 08:55:49 -0700 Subject: [PATCH 02/54] more compound shape stuff --- .../src/RenderableModelEntityItem.cpp | 2 ++ libraries/physics/src/ShapeInfoUtil.cpp | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 6d32b78689..fed01883bd 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -297,6 +297,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { + QVector newMeshPoints; + _points << newMeshPoints; _points[i++] << mesh.vertices; } diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 2f7c0c59bd..a5834f407a 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -29,6 +29,9 @@ int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) { case SHAPE_TYPE_CONVEX_HULL: bulletShapeType = CONVEX_HULL_SHAPE_PROXYTYPE; break; + case SHAPE_TYPE_COMPOUND: + bulletShapeType = COMPOUND_SHAPE_PROXYTYPE; + break; } return bulletShapeType; } @@ -48,6 +51,9 @@ int ShapeInfoUtil::fromBulletShapeType(int bulletShapeType) { case CONVEX_HULL_SHAPE_PROXYTYPE: shapeInfoType = SHAPE_TYPE_CONVEX_HULL; break; + case COMPOUND_SHAPE_PROXYTYPE: + shapeInfoType = SHAPE_TYPE_COMPOUND; + break; } return shapeInfoType; } @@ -78,6 +84,26 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf info.setConvexHulls(points); } break; + case SHAPE_TYPE_COMPOUND: { + const btCompoundShape* compoundShape = static_cast(shape); + const int numChildShapes = compoundShape->getNumChildShapes(); + QVector> points; + for (int i = 0; i < numChildShapes; i ++) { + const btCollisionShape* childShape = compoundShape->getChildShape(i); + const btConvexHullShape* convexHullShape = static_cast(childShape); + const int numPoints = convexHullShape->getNumPoints(); + const btVector3* btPoints = convexHullShape->getUnscaledPoints(); + + QVector childPoints; + for (int j = 0; j < numPoints; j++) { + glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); + childPoints << point; + } + points << childPoints; + } + info.setConvexHulls(points); + } + break; default: { info.clear(); } From bfc5cf99d6ef92de7ee6734394483fa90a416b95 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 21 Mar 2015 16:11:47 -0700 Subject: [PATCH 03/54] more code for compound hull collisions --- .../src/RenderableModelEntityItem.cpp | 31 +++++++++++++++++-- libraries/physics/src/ShapeInfoUtil.cpp | 12 +++++++ libraries/shared/src/ShapeInfo.cpp | 10 +++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index fed01883bd..86332c8c07 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -297,9 +297,34 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { - QVector newMeshPoints; - _points << newMeshPoints; - _points[i++] << mesh.vertices; + + foreach (const FBXMeshPart &meshPart, mesh.parts) { + QVector pointsInPart; + unsigned int triangleCount = meshPart.triangleIndices.size() / 3; + for (unsigned int i = 0; i < triangleCount; i++) { + unsigned int p0Index = meshPart.triangleIndices[i*3]; + unsigned int p1Index = meshPart.triangleIndices[i*3+1]; + unsigned int p2Index = meshPart.triangleIndices[i*3+2]; + + glm::vec3 p0 = mesh.vertices[p0Index]; + glm::vec3 p1 = mesh.vertices[p1Index]; + glm::vec3 p2 = mesh.vertices[p2Index]; + + if (!pointsInPart.contains(p0)) { + pointsInPart << p0; + } + if (!pointsInPart.contains(p1)) { + pointsInPart << p1; + } + if (!pointsInPart.contains(p2)) { + pointsInPart << p2; + } + } + + QVector newMeshPoints; + _points << newMeshPoints; + _points[i++] << pointsInPart; + } } info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index a5834f407a..b48bff763c 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -116,6 +116,9 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { btCollisionShape* shape = NULL; + + qDebug() << "\n\nHERE" << info.getType(); + switch(info.getType()) { case SHAPE_TYPE_BOX: { shape = new btBoxShape(glmToBullet(info.getHalfExtents())); @@ -145,8 +148,14 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { case SHAPE_TYPE_COMPOUND: { shape = new btCompoundShape(); const QVector>& points = info.getPoints(); + + qDebug() << "\n\nSHAPE_TYPE_COMPOUND" << info.getPoints().size() << "hulls."; + foreach (QVector hullPoints, info.getPoints()) { auto hull = new btConvexHullShape(); + + qDebug() << " SHAPE_TYPE_COMPOUND" << hullPoints.size() << "points in hull."; + foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); hull->addPoint(btPoint); @@ -155,6 +164,9 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { static_cast(shape)->addChildShape (trans, hull); } } + + qDebug() << "DONE, getNumChildShapes =" << static_cast(shape)->getNumChildShapes(); + break; } return shape; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index afa19bcd24..09677cf36c 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -40,6 +40,10 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString _url = QUrl(url); _halfExtents = halfExtents; break; + case SHAPE_TYPE_COMPOUND: + _url = QUrl(url); + _halfExtents = halfExtents; + break; default: _halfExtents = halfExtents; break; @@ -65,7 +69,11 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { } void ShapeInfo::setConvexHulls(const QVector>& points) { - _type = SHAPE_TYPE_CONVEX_HULL; + if (points.size() == 1) { + _type = SHAPE_TYPE_CONVEX_HULL; + } else { + _type = SHAPE_TYPE_COMPOUND; + } _points = points; } From cb6abfb2e6fbd6a53f8aafa8345831e18bed01d5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 23 Mar 2015 12:05:56 -0700 Subject: [PATCH 04/54] Display notification if domain connection refused --- examples/notifications.js | 9 ++++++++- interface/src/Application.cpp | 11 ++++++++++- interface/src/Application.h | 6 ++++++ interface/src/DatagramProcessor.cpp | 1 + interface/src/scripting/WindowScriptingInterface.cpp | 1 + interface/src/scripting/WindowScriptingInterface.h | 1 + 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/examples/notifications.js b/examples/notifications.js index 0c2a06c878..f6819f60b7 100644 --- a/examples/notifications.js +++ b/examples/notifications.js @@ -91,10 +91,12 @@ var NotificationType = { MUTE_TOGGLE: 1, SNAPSHOT: 2, WINDOW_RESIZE: 3, + CONNECTION_REFUSED: 4, properties: [ { text: "Mute Toggle" }, { text: "Snapshot" }, - { text: "Window Resize" } + { text: "Window Resize" }, + { text: "Connection Refused" } ], getTypeFromMenuItem: function(menuItemName) { if (menuItemName.substr(menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length) !== NOTIFICATION_MENU_ITEM_POST) { @@ -489,6 +491,10 @@ function onMuteStateChanged() { createNotification(muteString, NotificationType.MUTE_TOGGLE); } +function onDomainConnectionRefused(reason) { + createNotification("Connection refused: " + reason, NotificationType.CONNECTION_REFUSED ); +} + // handles mouse clicks on buttons function mousePressEvent(event) { var pickRay, @@ -582,5 +588,6 @@ Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); Menu.menuItemEvent.connect(menuItemEvent); +Window.domainConnectionRefused.connect(onDomainConnectionRefused); setup(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ff41e1b6f..70b99f7daa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -297,7 +297,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastSendDownstreamAudioStats(usecTimestampNow()), _isVSyncOn(true), _aboutToQuit(false), - _notifiedPacketVersionMismatchThisDomain(false) + _notifiedPacketVersionMismatchThisDomain(false), + _domainConnectionRefusals(QList()) { #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); @@ -3288,6 +3289,14 @@ void Application::clearDomainOctreeDetails() { void Application::domainChanged(const QString& domainHostname) { updateWindowTitle(); clearDomainOctreeDetails(); + _domainConnectionRefusals.clear(); +} + +void Application::domainConnectionDenied(const QString& reason) { + if (!_domainConnectionRefusals.contains(reason)) { + _domainConnectionRefusals.append(reason); + emit domainConnectionRefused(reason); + } } void Application::connectedToDomain(const QString& hostname) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 4038b21739..b0e7690f0a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -332,6 +332,8 @@ signals: void svoImportRequested(const QString& url); + void domainConnectionRefused(const QString& reason); + public slots: void domainChanged(const QString& domainHostname); void updateWindowTitle(); @@ -382,6 +384,8 @@ public slots: void setActiveFaceTracker(); + void domainConnectionDenied(const QString& reason); + private slots: void clearDomainOctreeDetails(); void checkFPS(); @@ -606,6 +610,8 @@ private: int _menuBarHeight; QHash _acceptedExtensions; + + QList _domainConnectionRefusals; }; #endif // hifi_Application_h diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 475ce406bb..9ac2b51097 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -127,6 +127,7 @@ void DatagramProcessor::processDatagrams() { // and check and signal for an access token so that we can make sure they are logged in qDebug() << "The domain-server denied a connection request: " << reason; qDebug() << "You may need to re-log to generate a keypair so you can provide a username signature."; + application->domainConnectionDenied(reason); AccountManager::getInstance().checkAndSignalForAccessToken(); break; } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 7f4b5ddf45..a5b8128d1e 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -33,6 +33,7 @@ WindowScriptingInterface::WindowScriptingInterface() : const DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); connect(&domainHandler, &DomainHandler::hostnameChanged, this, &WindowScriptingInterface::domainChanged); connect(Application::getInstance(), &Application::svoImportRequested, this, &WindowScriptingInterface::svoImportRequested); + connect(Application::getInstance(), &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused); } WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height, bool isToolWindow) { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 6a812f14e3..9bc8a834bd 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -62,6 +62,7 @@ signals: void inlineButtonClicked(const QString& name); void nonBlockingFormClosed(); void svoImportRequested(const QString& url); + void domainConnectionRefused(const QString& reason); private slots: QScriptValue showAlert(const QString& message); From f31ac8b968238f795e9c6b4f18f44122a757f0a9 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Mar 2015 15:10:28 -0700 Subject: [PATCH 05/54] compound covex hull collisions work --- libraries/physics/src/ShapeInfoUtil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index b48bff763c..07fedb35ad 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -161,6 +161,7 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { hull->addPoint(btPoint); } btTransform trans; + trans.setIdentity(); static_cast(shape)->addChildShape (trans, hull); } } From c8ad82917e974d23c08d9732e8195cee0fc6d0e4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Mar 2015 16:54:36 -0700 Subject: [PATCH 06/54] clean up some debugging spew. take dimensions into account when scaling points used for collision hull creation --- .../src/RenderableModelEntityItem.cpp | 47 +++++++++++++++++-- .../src/RenderableModelEntityItem.h | 2 + libraries/entities/src/EntityItem.h | 11 ++++- libraries/physics/src/ShapeInfoUtil.cpp | 15 ++---- libraries/shared/src/ShapeInfo.cpp | 7 +++ 5 files changed, 64 insertions(+), 18 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 86332c8c07..bb3f00d154 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -266,6 +266,14 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking); } +void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { + if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { + _dimensions = value; + _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); + } + _model->setScaleToFit(true, _dimensions); +} + bool RenderableModelEntityItem::isReadyToComputeShape() { if (!_model) { @@ -294,6 +302,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); + AABox aaBox; _points.clear(); unsigned int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { @@ -301,15 +310,29 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { foreach (const FBXMeshPart &meshPart, mesh.parts) { QVector pointsInPart; unsigned int triangleCount = meshPart.triangleIndices.size() / 3; - for (unsigned int i = 0; i < triangleCount; i++) { - unsigned int p0Index = meshPart.triangleIndices[i*3]; - unsigned int p1Index = meshPart.triangleIndices[i*3+1]; - unsigned int p2Index = meshPart.triangleIndices[i*3+2]; + assert((unsigned int)meshPart.triangleIndices.size() == triangleCount*3); + for (unsigned int j = 0; j < triangleCount; j++) { + unsigned int p0Index = meshPart.triangleIndices[j*3]; + unsigned int p1Index = meshPart.triangleIndices[j*3+1]; + unsigned int p2Index = meshPart.triangleIndices[j*3+2]; + + assert(p0Index < (unsigned int)mesh.vertices.size()); + assert(p1Index < (unsigned int)mesh.vertices.size()); + assert(p2Index < (unsigned int)mesh.vertices.size()); + + // glm::vec3 p0 = mesh.vertices[p0Index] * scale[0]; + // glm::vec3 p1 = mesh.vertices[p1Index] * scale[1]; + // glm::vec3 p2 = mesh.vertices[p2Index] * scale[2]; + glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; + aaBox += p0; + aaBox += p1; + aaBox += p2; + if (!pointsInPart.contains(p0)) { pointsInPart << p0; } @@ -327,7 +350,21 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } } - info.setParams(getShapeType(), 0.5f * getDimensions(), _collisionModelURL); + // make sure we aren't about to divide by zero + glm::vec3 aaBoxDim = aaBox.getDimensions(); + aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim); + + // scale = dimensions / aabox + glm::vec3 scale = _dimensions / aaBoxDim; + + // multiply each point by scale before handing the point-set off to the physics engine + for (int i = 0; i < _points.size(); i++) { + for (int j = 0; j < _points[i].size(); j++) { + _points[i][j] *= scale; + } + } + + info.setParams(getShapeType(), _dimensions, _collisionModelURL); info.setConvexHulls(_points); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 63249f136c..8742fb50eb 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -52,6 +52,8 @@ public: bool needsToCallUpdate() const; + virtual void updateDimensions(const glm::vec3& value); + bool isReadyToComputeShape(); void computeShapeInfo(ShapeInfo& info); ShapeType getShapeType() const; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 88287f8965..49e450c45e 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -40,6 +40,15 @@ class EntityTreeElementExtraEncodeData; #define debugTreeVector(V) V << "[" << V << " in meters ]" +extern const float MIN_POSITION_DELTA; +extern const float MIN_DIMENSIONS_DELTA; +extern const float MIN_ALIGNMENT_DOT; +extern const float MIN_VELOCITY_DELTA; +extern const float MIN_DAMPING_DELTA; +extern const float MIN_GRAVITY_DELTA; +extern const float MIN_SPIN_DELTA; + + /// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available /// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate /// one directly, instead you must only construct one of it's derived classes with additional features. @@ -270,7 +279,7 @@ public: void updatePositionInDomainUnits(const glm::vec3& value); void updatePosition(const glm::vec3& value); void updateDimensionsInDomainUnits(const glm::vec3& value); - void updateDimensions(const glm::vec3& value); + virtual void updateDimensions(const glm::vec3& value); void updateRotation(const glm::quat& rotation); void updateDensity(float value); void updateMass(float value); diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 07fedb35ad..1073fbae3f 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -77,10 +77,12 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf const int numPoints = convexHullShape->getNumPoints(); const btVector3* btPoints = convexHullShape->getUnscaledPoints(); QVector> points; + QVector childPoints; for (int i = 0; i < numPoints; i++) { glm::vec3 point(btPoints->getX(), btPoints->getY(), btPoints->getZ()); - points[0] << point; + childPoints << point; } + points << childPoints; info.setConvexHulls(points); } break; @@ -116,9 +118,6 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { btCollisionShape* shape = NULL; - - qDebug() << "\n\nHERE" << info.getType(); - switch(info.getType()) { case SHAPE_TYPE_BOX: { shape = new btBoxShape(glmToBullet(info.getHalfExtents())); @@ -149,13 +148,8 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { shape = new btCompoundShape(); const QVector>& points = info.getPoints(); - qDebug() << "\n\nSHAPE_TYPE_COMPOUND" << info.getPoints().size() << "hulls."; - foreach (QVector hullPoints, info.getPoints()) { auto hull = new btConvexHullShape(); - - qDebug() << " SHAPE_TYPE_COMPOUND" << hullPoints.size() << "points in hull."; - foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); hull->addPoint(btPoint); @@ -165,9 +159,6 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { static_cast(shape)->addChildShape (trans, hull); } } - - qDebug() << "DONE, getNumChildShapes =" << static_cast(shape)->getNumChildShapes(); - break; } return shape; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 09677cf36c..73dd945f73 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -38,6 +38,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } case SHAPE_TYPE_CONVEX_HULL: _url = QUrl(url); + // halfExtents aren't used by convex-hull or compound convex-hull except as part of + // the generation of the key for the ShapeManager. _halfExtents = halfExtents; break; case SHAPE_TYPE_COMPOUND: @@ -51,18 +53,21 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } void ShapeInfo::setBox(const glm::vec3& halfExtents) { + _url = ""; _type = SHAPE_TYPE_BOX; _halfExtents = halfExtents; _doubleHashKey.clear(); } void ShapeInfo::setSphere(float radius) { + _url = ""; _type = SHAPE_TYPE_SPHERE; _halfExtents = glm::vec3(radius, radius, radius); _doubleHashKey.clear(); } void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { + _url = ""; _type = SHAPE_TYPE_ELLIPSOID; _halfExtents = halfExtents; _doubleHashKey.clear(); @@ -75,9 +80,11 @@ void ShapeInfo::setConvexHulls(const QVector>& points) { _type = SHAPE_TYPE_COMPOUND; } _points = points; + _doubleHashKey.clear(); } void ShapeInfo::setCapsuleY(float radius, float halfHeight) { + _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; _halfExtents = glm::vec3(radius, halfHeight, radius); _doubleHashKey.clear(); From 6e3be260137bbd129d8ed3a19b4d0de5ad3d5344 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 15:28:21 -0700 Subject: [PATCH 07/54] attempting to figure out why physics motion object doesn't get updated when collision model url changes --- .../src/RenderableModelEntityItem.cpp | 49 ++++++++++ .../src/RenderableModelEntityItem.h | 6 ++ libraries/entities/src/EntitySimulation.cpp | 10 +-- libraries/entities/src/EntitySimulation.h | 6 +- libraries/entities/src/EntityTree.cpp | 6 ++ libraries/entities/src/EntityTree.h | 4 +- libraries/entities/src/EntityTreeElement.h | 1 + libraries/entities/src/ModelEntityItem.cpp | 14 ++- libraries/entities/src/ModelEntityItem.h | 6 +- .../entities/src/SimpleEntitySimulation.cpp | 3 +- .../entities/src/SimpleEntitySimulation.h | 2 +- libraries/physics/src/EntityMotionState.cpp | 8 +- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/ObjectMotionState.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 89 ++++++++++++++----- libraries/physics/src/PhysicsEngine.h | 4 +- 16 files changed, 172 insertions(+), 40 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bb3f00d154..0a7d672189 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -22,6 +22,7 @@ #include "EntityTreeRenderer.h" #include "RenderableModelEntityItem.h" + EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return new RenderableModelEntityItem(entityID, properties); } @@ -266,6 +267,50 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking); } +// void RenderableModelEntityItem::setCollisionModelURL(const QString& url) { + +// // XXX PhysicsEngine::entityChangedInternal(this); +// // EntityTree* x = this->getElement()->_myTree; +// // EntityTreeRenderer* _myRenderer; + +// qDebug() << "--------------------------------"; +// this->ModelEntityItem::setCollisionModelURL(url); + +// if ((_dirtyFlags & (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) == +// (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) { + +// EntityTreeElement* element = this->getElement(); +// if (element) { +// qDebug() << "element =" << element; +// EntityTree* tree = element->getTree(); +// qDebug() << "tree =" << tree; +// tree->reconfigureEntity(this); +// } +// } +// } + + +void RenderableModelEntityItem::setCollisionModelURL(const QString& url) { + ModelEntityItem::setCollisionModelURL(url); + _model->setCollisionModelURL(QUrl(url)); +} + + +bool RenderableModelEntityItem::hasCollisionModel() const { + // return !_collisionModelURL.isEmpty(); + return ! _model->getCollisionURL().isEmpty(); +} + + +const QString& RenderableModelEntityItem::getCollisionModelURL() const { + // return _collisionModelURL; + _collisionModelURL = _model->getCollisionURL().toString(); + return _collisionModelURL; +} + + + + void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { _dimensions = value; @@ -288,6 +333,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); if (! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) { // we have a _collisionModelURL AND a collisionNetworkGeometry AND it's fully loaded. + // _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); return true; } @@ -296,9 +342,12 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { } void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { + qDebug() << "RenderableModelEntityItem::computeShapeInfo"; if (_model->getCollisionURL().isEmpty()) { + qDebug() << " _model->getCollisionURL().isEmpty()"; info.setParams(getShapeType(), 0.5f * getDimensions()); } else { + qDebug() << " _model->getCollisionURL() wasn't empty."; const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 8742fb50eb..3586bd9941 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -49,9 +49,15 @@ public: void** intersectedObject, bool precisionPicking) const; Model* getModel(EntityTreeRenderer* renderer); + // virtual void setCollisionModelURL(const QString& url); bool needsToCallUpdate() const; + virtual void setCollisionModelURL(const QString& url); + virtual bool hasCollisionModel() const; + virtual const QString& getCollisionModelURL() const; + + virtual void updateDimensions(const glm::vec3& value); bool isReadyToComputeShape(); diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index b093dbe4f4..555f2061e8 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -126,11 +126,11 @@ void EntitySimulation::addEntity(EntityItem* entity) { if (entity->needsToCallUpdate()) { _updateableEntities.insert(entity); } - addEntityInternal(entity); - - // DirtyFlags are used to signal changes to entities that have already been added, - // so we can clear them for this entity which has just been added. - entity->clearDirtyFlags(); + if (addEntityInternal(entity)) { + // DirtyFlags are used to signal changes to entities that have already been added, + // so we can clear them for this entity which has just been added. + entity->clearDirtyFlags(); + } } void EntitySimulation::removeEntity(EntityItem* entity) { diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 1eb4fdc951..9dd86011fa 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -63,6 +63,10 @@ public: EntityTree* getEntityTree() { return _entityTree; } + /* virtual void reconfigureEntity(EntityItem* entity) { */ + /* qDebug() << "EntitySimulation::reconfigureEntity"; */ + /* } */ + signals: void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); @@ -74,7 +78,7 @@ protected: // NOTE: updateEntitiesInternal() should clear all dirty flags on each changed entity as side effect virtual void updateEntitiesInternal(const quint64& now) = 0; - virtual void addEntityInternal(EntityItem* entity) = 0; + virtual bool addEntityInternal(EntityItem* entity) = 0; virtual void removeEntityInternal(EntityItem* entity) = 0; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 3ccff46a04..da7194e4bc 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -315,6 +315,12 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } } +void EntityTree::reconfigureEntity(EntityItem* entity) { + qDebug() << "EntityTree::reconfigureEntity"; + // _simulation->reconfigureEntity(entity); + _simulation->entityChanged(entity); +} + void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) { const RemovedEntities& entities = theOperator.getEntities(); if (_simulation) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8536e74e9a..25cc0b0bf4 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -95,7 +95,8 @@ public: void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = false); - void removeEntityFromSimulation(EntityItem* entity); + // void removeEntityFromSimulation(EntityItem* entity); + void reconfigureEntity(EntityItem* entity); /// \param position point of query in world-frame (meters) /// \param targetRadius radius of query (meters) @@ -161,6 +162,7 @@ public: void emitEntityScriptChanging(const EntityItemID& entityItemID); void setSimulation(EntitySimulation* simulation); + EntitySimulation* getSimulation() { return _simulation; } bool wantEditLogging() const { return _wantEditLogging; } void setWantEditLogging(bool value) { _wantEditLogging = value; } diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 0b28dd30d0..e93e00cc1c 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -147,6 +147,7 @@ public: bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; } void setTree(EntityTree* tree) { _myTree = tree; } + EntityTree* getTree() { return _myTree; } bool updateEntity(const EntityItem& entity); void addEntityItem(EntityItem* entity); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 181f537daa..13eaf0449f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -74,7 +74,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); if (somethingChanged) { - bool wantDebug = false; + bool wantDebug = true; if (wantDebug) { uint64_t now = usecTimestampNow(); int elapsed = now - getLastEdited(); @@ -281,6 +281,18 @@ void ModelEntityItem::updateShapeType(ShapeType type) { } } +void ModelEntityItem::setCollisionModelURL(const QString& url) +{ + if (_collisionModelURL != url) { + + qDebug() << "\n\n----"; + qDebug() << "ModelEntityItem::setCollisionModelURL"; + + _collisionModelURL = url; + _dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS; + } +} + void ModelEntityItem::setAnimationURL(const QString& url) { _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; _animationURL = url; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 081cb429ed..9e34de445b 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -57,13 +57,13 @@ public: const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } bool hasModel() const { return !_modelURL.isEmpty(); } - bool hasCollisionModel() const { return !_collisionModelURL.isEmpty(); } + virtual bool hasCollisionModel() const { return !_collisionModelURL.isEmpty(); } static const QString DEFAULT_MODEL_URL; const QString& getModelURL() const { return _modelURL; } static const QString DEFAULT_COLLISION_MODEL_URL; - const QString& getCollisionModelURL() const { return _collisionModelURL; } + virtual const QString& getCollisionModelURL() const { return _collisionModelURL; } bool hasAnimation() const { return !_animationURL.isEmpty(); } static const QString DEFAULT_ANIMATION_URL; @@ -78,7 +78,7 @@ public: // model related properties void setModelURL(const QString& url) { _modelURL = url; } - void setCollisionModelURL(const QString& url) { _collisionModelURL = url; } + virtual void setCollisionModelURL(const QString& url); void setAnimationURL(const QString& url); static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value); diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 6d45768c26..ee62c00246 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -29,12 +29,13 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { } } -void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { +bool SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { if (entity->isMoving()) { _movingEntities.insert(entity); } else if (entity->getCollisionsWillMove()) { _movableButStoppedEntities.insert(entity); } + return true; } void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 92b6a28215..6a748c3e1f 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -23,7 +23,7 @@ public: protected: virtual void updateEntitiesInternal(const quint64& now); - virtual void addEntityInternal(EntityItem* entity); + virtual bool addEntityInternal(EntityItem* entity); virtual void removeEntityInternal(EntityItem* entity); virtual void entityChangedInternal(EntityItem* entity); virtual void clearEntitiesInternal(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index cd0769255b..3ca016c5d8 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -168,8 +168,12 @@ void EntityMotionState::updateObjectVelocities() { } } -void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { - _entity->computeShapeInfo(shapeInfo); +bool EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { + if (_entity->isReadyToComputeShape()) { + _entity->computeShapeInfo(shapeInfo); + return true; + } + return false; } float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 7214626fc4..1910e92150 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -53,7 +53,7 @@ public: virtual void updateObjectEasy(uint32_t flags, uint32_t frame); virtual void updateObjectVelocities(); - virtual void computeShapeInfo(ShapeInfo& shapeInfo); + virtual bool computeShapeInfo(ShapeInfo& shapeInfo); virtual float computeMass(const ShapeInfo& shapeInfo) const; virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index fb402a178d..12d1d14c2d 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -67,7 +67,7 @@ public: MotionStateType getType() const { return _type; } virtual MotionType getMotionType() const { return _motionType; } - virtual void computeShapeInfo(ShapeInfo& info) = 0; + virtual bool computeShapeInfo(ShapeInfo& info) = 0; virtual float computeMass(const ShapeInfo& shapeInfo) const = 0; void setFriction(float friction); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index a46ba9f819..7dd989c9ab 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -58,31 +58,49 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { } } -void PhysicsEngine::addEntityInternal(EntityItem* entity) { +bool PhysicsEngine::addEntityInternal(EntityItem* entity) { + + qDebug() << "PhysicsEngine::addEntityInternal"; + assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { - if (entity->isReadyToComputeShape()) { - ShapeInfo shapeInfo; - entity->computeShapeInfo(shapeInfo); - btCollisionShape* shape = _shapeManager.getShape(shapeInfo); - if (shape) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - addObject(shapeInfo, shape, motionState); - } else if (entity->isMoving()) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - - motionState->setKinematic(true, _numSubsteps); - _nonPhysicalKinematicObjects.insert(motionState); - // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. - //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; - } + qDebug() << " PhysicsEngine::addEntityInternal no physicsInfo"; + if (! entity->isReadyToComputeShape()) { + qDebug() << " PhysicsEngine::addEntityInternal not ready to compute"; + return false; } + qDebug() << " PhysicsEngine::addEntityInternal ready to compute"; + ShapeInfo shapeInfo; + entity->computeShapeInfo(shapeInfo); + + DoubleHashKey hkey = shapeInfo.getHash(); + qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2(); + + btCollisionShape* shape = _shapeManager.getShape(shapeInfo); + if (shape) { + qDebug() << " got a shape"; + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); + addObject(shapeInfo, shape, motionState); + } else if (entity->isMoving()) { + qDebug() << " no shape but is moving"; + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); + + motionState->setKinematic(true, _numSubsteps); + _nonPhysicalKinematicObjects.insert(motionState); + // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. + //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; + } else { + qDebug() << " no shape and not moving"; + } + } else { + qDebug() << " PhysicsEngine::addEntityInternal already had physicsInfo"; } + return true; } void PhysicsEngine::removeEntityInternal(EntityItem* entity) { @@ -105,18 +123,28 @@ void PhysicsEngine::removeEntityInternal(EntityItem* entity) { } void PhysicsEngine::entityChangedInternal(EntityItem* entity) { + + qDebug() << "PhysicsEngine::entityChangedInternal"; + // queue incoming changes: from external sources (script, EntityServer, etc) to physics engine assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (physicsInfo) { + qDebug() << " PhysicsEngine::entityChangedInternal had physicsInfo"; ObjectMotionState* motionState = static_cast(physicsInfo); _incomingChanges.insert(motionState); } else { + qDebug() << " PhysicsEngine::entityChangedInternal had no physicsInfo"; // try to add this entity again (maybe something changed such that it will work this time) addEntity(entity); } } +// void PhysicsEngine::reconfigureEntity(EntityItem* entity) { +// qDebug() << "PhysicsEngine::reconfigureEntity"; +// entityChangedInternal(entity); +// } + void PhysicsEngine::sortEntitiesThatMovedInternal() { // entities that have been simulated forward (hence in the _entitiesToBeSorted list) // also need to be put in the outgoingPackets list @@ -509,8 +537,20 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio // get new shape btCollisionShape* oldShape = body->getCollisionShape(); ShapeInfo shapeInfo; - motionState->computeShapeInfo(shapeInfo); + + + bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); + qDebug() << "\n\n---"; + qDebug() << "PhysicsEngine::updateObjectHard #1 computeShapeInfoResult =" << computeShapeInfoResult; + + btCollisionShape* newShape = _shapeManager.getShape(shapeInfo); + + DoubleHashKey hkey = shapeInfo.getHash(); + qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2(); + qDebug() << " newShape =" << newShape; + + if (!newShape) { // FAIL! we are unable to support these changes! _shapeManager.releaseShape(oldShape); @@ -563,7 +603,12 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio if (! (flags & EntityItem::DIRTY_MASS)) { // always update mass properties when going dynamic (unless it's already been done above) ShapeInfo shapeInfo; - motionState->computeShapeInfo(shapeInfo); + bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); + + qDebug() << "\n\n---"; + qDebug() << "PhysicsEngine::updateObjectHard #2 computeShapeInfoResult =" << computeShapeInfoResult; + + float mass = motionState->computeMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); body->getCollisionShape()->calculateLocalInertia(mass, inertia); diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index cb637c60b9..68161f5c12 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -60,7 +60,7 @@ public: // overrides for EntitySimulation void updateEntitiesInternal(const quint64& now); - void addEntityInternal(EntityItem* entity); + bool addEntityInternal(EntityItem* entity); void removeEntityInternal(EntityItem* entity); void entityChangedInternal(EntityItem* entity); void sortEntitiesThatMovedInternal(); @@ -88,6 +88,8 @@ public: void setAvatarData(AvatarData *avatarData); + // virtual void reconfigureEntity(EntityItem* entity); + private: /// \param motionState pointer to Object's MotionState void removeObjectFromBullet(ObjectMotionState* motionState); From 1eeb2e89f803008a892ec93382aefbfc68e0303a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:23:51 -0700 Subject: [PATCH 08/54] remove some debug spam --- .../src/RenderableModelEntityItem.cpp | 45 ++++-------------- libraries/entities/src/ModelEntityItem.cpp | 6 +-- libraries/physics/src/EntityMotionState.cpp | 4 +- libraries/physics/src/EntityMotionState.h | 2 +- libraries/physics/src/ObjectMotionState.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 47 +------------------ 6 files changed, 15 insertions(+), 91 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 0a7d672189..88827d066c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -267,50 +267,26 @@ bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& ori return _model->findRayIntersectionAgainstSubMeshes(origin, direction, distance, face, extraInfo, precisionPicking); } -// void RenderableModelEntityItem::setCollisionModelURL(const QString& url) { - -// // XXX PhysicsEngine::entityChangedInternal(this); -// // EntityTree* x = this->getElement()->_myTree; -// // EntityTreeRenderer* _myRenderer; - -// qDebug() << "--------------------------------"; -// this->ModelEntityItem::setCollisionModelURL(url); - -// if ((_dirtyFlags & (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) == -// (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS)) { - -// EntityTreeElement* element = this->getElement(); -// if (element) { -// qDebug() << "element =" << element; -// EntityTree* tree = element->getTree(); -// qDebug() << "tree =" << tree; -// tree->reconfigureEntity(this); -// } -// } -// } - - void RenderableModelEntityItem::setCollisionModelURL(const QString& url) { ModelEntityItem::setCollisionModelURL(url); - _model->setCollisionModelURL(QUrl(url)); + if (_model) { + _model->setCollisionModelURL(QUrl(url)); + } } - bool RenderableModelEntityItem::hasCollisionModel() const { - // return !_collisionModelURL.isEmpty(); - return ! _model->getCollisionURL().isEmpty(); + if (_model) { + return ! _model->getCollisionURL().isEmpty(); + } else { + return !_collisionModelURL.isEmpty(); + } } - const QString& RenderableModelEntityItem::getCollisionModelURL() const { - // return _collisionModelURL; - _collisionModelURL = _model->getCollisionURL().toString(); + assert (!_model || _collisionModelURL == _model->getCollisionURL().toString()); return _collisionModelURL; } - - - void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { _dimensions = value; @@ -342,12 +318,9 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { } void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { - qDebug() << "RenderableModelEntityItem::computeShapeInfo"; if (_model->getCollisionURL().isEmpty()) { - qDebug() << " _model->getCollisionURL().isEmpty()"; info.setParams(getShapeType(), 0.5f * getDimensions()); } else { - qDebug() << " _model->getCollisionURL() wasn't empty."; const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& fbxGeometry = collisionNetworkGeometry->getFBXGeometry(); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 13eaf0449f..f135f617f4 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -74,7 +74,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); if (somethingChanged) { - bool wantDebug = true; + bool wantDebug = false; if (wantDebug) { uint64_t now = usecTimestampNow(); int elapsed = now - getLastEdited(); @@ -284,10 +284,6 @@ void ModelEntityItem::updateShapeType(ShapeType type) { void ModelEntityItem::setCollisionModelURL(const QString& url) { if (_collisionModelURL != url) { - - qDebug() << "\n\n----"; - qDebug() << "ModelEntityItem::setCollisionModelURL"; - _collisionModelURL = url; _dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 3ca016c5d8..35eb006655 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -168,12 +168,10 @@ void EntityMotionState::updateObjectVelocities() { } } -bool EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { +void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { if (_entity->isReadyToComputeShape()) { _entity->computeShapeInfo(shapeInfo); - return true; } - return false; } float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 1910e92150..7214626fc4 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -53,7 +53,7 @@ public: virtual void updateObjectEasy(uint32_t flags, uint32_t frame); virtual void updateObjectVelocities(); - virtual bool computeShapeInfo(ShapeInfo& shapeInfo); + virtual void computeShapeInfo(ShapeInfo& shapeInfo); virtual float computeMass(const ShapeInfo& shapeInfo) const; virtual void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame); diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 12d1d14c2d..fb402a178d 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -67,7 +67,7 @@ public: MotionStateType getType() const { return _type; } virtual MotionType getMotionType() const { return _motionType; } - virtual bool computeShapeInfo(ShapeInfo& info) = 0; + virtual void computeShapeInfo(ShapeInfo& info) = 0; virtual float computeMass(const ShapeInfo& shapeInfo) const = 0; void setFriction(float friction); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 7dd989c9ab..5f668b4f37 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -59,33 +59,21 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { } bool PhysicsEngine::addEntityInternal(EntityItem* entity) { - - qDebug() << "PhysicsEngine::addEntityInternal"; - assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { - qDebug() << " PhysicsEngine::addEntityInternal no physicsInfo"; if (! entity->isReadyToComputeShape()) { - qDebug() << " PhysicsEngine::addEntityInternal not ready to compute"; return false; } - qDebug() << " PhysicsEngine::addEntityInternal ready to compute"; ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); - - DoubleHashKey hkey = shapeInfo.getHash(); - qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2(); - btCollisionShape* shape = _shapeManager.getShape(shapeInfo); if (shape) { - qDebug() << " got a shape"; EntityMotionState* motionState = new EntityMotionState(entity); entity->setPhysicsInfo(static_cast(motionState)); _entityMotionStates.insert(motionState); addObject(shapeInfo, shape, motionState); } else if (entity->isMoving()) { - qDebug() << " no shape but is moving"; EntityMotionState* motionState = new EntityMotionState(entity); entity->setPhysicsInfo(static_cast(motionState)); _entityMotionStates.insert(motionState); @@ -94,11 +82,7 @@ bool PhysicsEngine::addEntityInternal(EntityItem* entity) { _nonPhysicalKinematicObjects.insert(motionState); // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; - } else { - qDebug() << " no shape and not moving"; } - } else { - qDebug() << " PhysicsEngine::addEntityInternal already had physicsInfo"; } return true; } @@ -123,28 +107,18 @@ void PhysicsEngine::removeEntityInternal(EntityItem* entity) { } void PhysicsEngine::entityChangedInternal(EntityItem* entity) { - - qDebug() << "PhysicsEngine::entityChangedInternal"; - // queue incoming changes: from external sources (script, EntityServer, etc) to physics engine assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (physicsInfo) { - qDebug() << " PhysicsEngine::entityChangedInternal had physicsInfo"; ObjectMotionState* motionState = static_cast(physicsInfo); _incomingChanges.insert(motionState); } else { - qDebug() << " PhysicsEngine::entityChangedInternal had no physicsInfo"; // try to add this entity again (maybe something changed such that it will work this time) addEntity(entity); } } -// void PhysicsEngine::reconfigureEntity(EntityItem* entity) { -// qDebug() << "PhysicsEngine::reconfigureEntity"; -// entityChangedInternal(entity); -// } - void PhysicsEngine::sortEntitiesThatMovedInternal() { // entities that have been simulated forward (hence in the _entitiesToBeSorted list) // also need to be put in the outgoingPackets list @@ -537,20 +511,8 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio // get new shape btCollisionShape* oldShape = body->getCollisionShape(); ShapeInfo shapeInfo; - - - bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); - qDebug() << "\n\n---"; - qDebug() << "PhysicsEngine::updateObjectHard #1 computeShapeInfoResult =" << computeShapeInfoResult; - - + motionState->computeShapeInfo(shapeInfo); btCollisionShape* newShape = _shapeManager.getShape(shapeInfo); - - DoubleHashKey hkey = shapeInfo.getHash(); - qDebug() << " shapeInfo hash:" << hkey.getHash() << hkey.getHash2(); - qDebug() << " newShape =" << newShape; - - if (!newShape) { // FAIL! we are unable to support these changes! _shapeManager.releaseShape(oldShape); @@ -603,12 +565,7 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio if (! (flags & EntityItem::DIRTY_MASS)) { // always update mass properties when going dynamic (unless it's already been done above) ShapeInfo shapeInfo; - bool computeShapeInfoResult = motionState->computeShapeInfo(shapeInfo); - - qDebug() << "\n\n---"; - qDebug() << "PhysicsEngine::updateObjectHard #2 computeShapeInfoResult =" << computeShapeInfoResult; - - + motionState->computeShapeInfo(shapeInfo); float mass = motionState->computeMass(shapeInfo); btVector3 inertia(0.0f, 0.0f, 0.0f); body->getCollisionShape()->calculateLocalInertia(mass, inertia); From 8d2c9425096a9d09768d2fed747738557ad087de Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:38:11 -0700 Subject: [PATCH 09/54] diff minimization --- .../src/RenderableModelEntityItem.cpp | 7 ------- .../entities-renderer/src/RenderableModelEntityItem.h | 2 -- libraries/entities/src/EntitySimulation.cpp | 10 +++++----- libraries/entities/src/EntitySimulation.h | 2 +- libraries/entities/src/SimpleEntitySimulation.cpp | 3 +-- libraries/entities/src/SimpleEntitySimulation.h | 2 +- libraries/physics/src/PhysicsEngine.cpp | 6 +++--- libraries/physics/src/PhysicsEngine.h | 2 +- 8 files changed, 12 insertions(+), 22 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 88827d066c..025da1d285 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -22,7 +22,6 @@ #include "EntityTreeRenderer.h" #include "RenderableModelEntityItem.h" - EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return new RenderableModelEntityItem(entityID, properties); } @@ -309,7 +308,6 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); if (! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) { // we have a _collisionModelURL AND a collisionNetworkGeometry AND it's fully loaded. - // _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); return true; } @@ -342,11 +340,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { assert(p1Index < (unsigned int)mesh.vertices.size()); assert(p2Index < (unsigned int)mesh.vertices.size()); - // glm::vec3 p0 = mesh.vertices[p0Index] * scale[0]; - // glm::vec3 p1 = mesh.vertices[p1Index] * scale[1]; - // glm::vec3 p2 = mesh.vertices[p2Index] * scale[2]; - - glm::vec3 p0 = mesh.vertices[p0Index]; glm::vec3 p1 = mesh.vertices[p1Index]; glm::vec3 p2 = mesh.vertices[p2Index]; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 3586bd9941..90535954b4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -49,7 +49,6 @@ public: void** intersectedObject, bool precisionPicking) const; Model* getModel(EntityTreeRenderer* renderer); - // virtual void setCollisionModelURL(const QString& url); bool needsToCallUpdate() const; @@ -57,7 +56,6 @@ public: virtual bool hasCollisionModel() const; virtual const QString& getCollisionModelURL() const; - virtual void updateDimensions(const glm::vec3& value); bool isReadyToComputeShape(); diff --git a/libraries/entities/src/EntitySimulation.cpp b/libraries/entities/src/EntitySimulation.cpp index 555f2061e8..b093dbe4f4 100644 --- a/libraries/entities/src/EntitySimulation.cpp +++ b/libraries/entities/src/EntitySimulation.cpp @@ -126,11 +126,11 @@ void EntitySimulation::addEntity(EntityItem* entity) { if (entity->needsToCallUpdate()) { _updateableEntities.insert(entity); } - if (addEntityInternal(entity)) { - // DirtyFlags are used to signal changes to entities that have already been added, - // so we can clear them for this entity which has just been added. - entity->clearDirtyFlags(); - } + addEntityInternal(entity); + + // DirtyFlags are used to signal changes to entities that have already been added, + // so we can clear them for this entity which has just been added. + entity->clearDirtyFlags(); } void EntitySimulation::removeEntity(EntityItem* entity) { diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 9dd86011fa..68b42e5ac9 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -78,7 +78,7 @@ protected: // NOTE: updateEntitiesInternal() should clear all dirty flags on each changed entity as side effect virtual void updateEntitiesInternal(const quint64& now) = 0; - virtual bool addEntityInternal(EntityItem* entity) = 0; + virtual void addEntityInternal(EntityItem* entity) = 0; virtual void removeEntityInternal(EntityItem* entity) = 0; diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index ee62c00246..6d45768c26 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -29,13 +29,12 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { } } -bool SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { +void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) { if (entity->isMoving()) { _movingEntities.insert(entity); } else if (entity->getCollisionsWillMove()) { _movableButStoppedEntities.insert(entity); } - return true; } void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 6a748c3e1f..92b6a28215 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -23,7 +23,7 @@ public: protected: virtual void updateEntitiesInternal(const quint64& now); - virtual bool addEntityInternal(EntityItem* entity); + virtual void addEntityInternal(EntityItem* entity); virtual void removeEntityInternal(EntityItem* entity); virtual void entityChangedInternal(EntityItem* entity); virtual void clearEntitiesInternal(); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 5f668b4f37..37b7035101 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -58,12 +58,12 @@ void PhysicsEngine::updateEntitiesInternal(const quint64& now) { } } -bool PhysicsEngine::addEntityInternal(EntityItem* entity) { +void PhysicsEngine::addEntityInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { if (! entity->isReadyToComputeShape()) { - return false; + return; } ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); @@ -84,7 +84,7 @@ bool PhysicsEngine::addEntityInternal(EntityItem* entity) { //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; } } - return true; + return; } void PhysicsEngine::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 68161f5c12..a8c9edf2f8 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -60,7 +60,7 @@ public: // overrides for EntitySimulation void updateEntitiesInternal(const quint64& now); - bool addEntityInternal(EntityItem* entity); + void addEntityInternal(EntityItem* entity); void removeEntityInternal(EntityItem* entity); void entityChangedInternal(EntityItem* entity); void sortEntitiesThatMovedInternal(); From 2f47f7c7bad1361fd5a7884827ba20b31105f9cd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:51:42 -0700 Subject: [PATCH 10/54] diff minimization --- .../src/RenderableModelEntityItem.cpp | 1 - libraries/entities/src/EntitySimulation.h | 4 -- libraries/entities/src/EntityTree.cpp | 6 --- libraries/entities/src/EntityTree.h | 3 -- libraries/entities/src/EntityTreeElement.h | 1 - libraries/physics/src/PhysicsEngine.cpp | 38 +++++++++---------- libraries/physics/src/PhysicsEngine.h | 2 - 7 files changed, 18 insertions(+), 37 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 025da1d285..aab9786762 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -369,7 +369,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { glm::vec3 aaBoxDim = aaBox.getDimensions(); aaBoxDim = glm::clamp(aaBoxDim, glm::vec3(FLT_EPSILON), aaBoxDim); - // scale = dimensions / aabox glm::vec3 scale = _dimensions / aaBoxDim; // multiply each point by scale before handing the point-set off to the physics engine diff --git a/libraries/entities/src/EntitySimulation.h b/libraries/entities/src/EntitySimulation.h index 68b42e5ac9..1eb4fdc951 100644 --- a/libraries/entities/src/EntitySimulation.h +++ b/libraries/entities/src/EntitySimulation.h @@ -63,10 +63,6 @@ public: EntityTree* getEntityTree() { return _entityTree; } - /* virtual void reconfigureEntity(EntityItem* entity) { */ - /* qDebug() << "EntitySimulation::reconfigureEntity"; */ - /* } */ - signals: void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index da7194e4bc..3ccff46a04 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -315,12 +315,6 @@ void EntityTree::deleteEntities(QSet entityIDs, bool force, bool i } } -void EntityTree::reconfigureEntity(EntityItem* entity) { - qDebug() << "EntityTree::reconfigureEntity"; - // _simulation->reconfigureEntity(entity); - _simulation->entityChanged(entity); -} - void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator) { const RemovedEntities& entities = theOperator.getEntities(); if (_simulation) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 25cc0b0bf4..29fecc88b4 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -95,8 +95,6 @@ public: void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = false); - // void removeEntityFromSimulation(EntityItem* entity); - void reconfigureEntity(EntityItem* entity); /// \param position point of query in world-frame (meters) /// \param targetRadius radius of query (meters) @@ -162,7 +160,6 @@ public: void emitEntityScriptChanging(const EntityItemID& entityItemID); void setSimulation(EntitySimulation* simulation); - EntitySimulation* getSimulation() { return _simulation; } bool wantEditLogging() const { return _wantEditLogging; } void setWantEditLogging(bool value) { _wantEditLogging = value; } diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index e93e00cc1c..0b28dd30d0 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -147,7 +147,6 @@ public: bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; } void setTree(EntityTree* tree) { _myTree = tree; } - EntityTree* getTree() { return _myTree; } bool updateEntity(const EntityItem& entity); void addEntityItem(EntityItem* entity); diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 37b7035101..a46ba9f819 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -62,29 +62,27 @@ void PhysicsEngine::addEntityInternal(EntityItem* entity) { assert(entity); void* physicsInfo = entity->getPhysicsInfo(); if (!physicsInfo) { - if (! entity->isReadyToComputeShape()) { - return; - } - ShapeInfo shapeInfo; - entity->computeShapeInfo(shapeInfo); - btCollisionShape* shape = _shapeManager.getShape(shapeInfo); - if (shape) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); - addObject(shapeInfo, shape, motionState); - } else if (entity->isMoving()) { - EntityMotionState* motionState = new EntityMotionState(entity); - entity->setPhysicsInfo(static_cast(motionState)); - _entityMotionStates.insert(motionState); + if (entity->isReadyToComputeShape()) { + ShapeInfo shapeInfo; + entity->computeShapeInfo(shapeInfo); + btCollisionShape* shape = _shapeManager.getShape(shapeInfo); + if (shape) { + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); + addObject(shapeInfo, shape, motionState); + } else if (entity->isMoving()) { + EntityMotionState* motionState = new EntityMotionState(entity); + entity->setPhysicsInfo(static_cast(motionState)); + _entityMotionStates.insert(motionState); - motionState->setKinematic(true, _numSubsteps); - _nonPhysicalKinematicObjects.insert(motionState); - // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. - //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; + motionState->setKinematic(true, _numSubsteps); + _nonPhysicalKinematicObjects.insert(motionState); + // We failed to add the entity to the simulation. Probably because we couldn't create a shape for it. + //qDebug() << "failed to add entity " << entity->getEntityItemID() << " to physics engine"; + } } } - return; } void PhysicsEngine::removeEntityInternal(EntityItem* entity) { diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index a8c9edf2f8..cb637c60b9 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -88,8 +88,6 @@ public: void setAvatarData(AvatarData *avatarData); - // virtual void reconfigureEntity(EntityItem* entity); - private: /// \param motionState pointer to Object's MotionState void removeObjectFromBullet(ObjectMotionState* motionState); From dccedeadff030cd721caae413bca87804141b33e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Mar 2015 16:59:12 -0700 Subject: [PATCH 11/54] diff minimization --- .../src/RenderableModelEntityItem.cpp | 8 -------- .../entities-renderer/src/RenderableModelEntityItem.h | 2 -- libraries/entities/src/EntityItem.h | 11 +---------- 3 files changed, 1 insertion(+), 20 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index aab9786762..43dbb95b6d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -286,14 +286,6 @@ const QString& RenderableModelEntityItem::getCollisionModelURL() const { return _collisionModelURL; } -void RenderableModelEntityItem::updateDimensions(const glm::vec3& value) { - if (glm::distance(_dimensions, value) > MIN_DIMENSIONS_DELTA) { - _dimensions = value; - _dirtyFlags |= (EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS); - } - _model->setScaleToFit(true, _dimensions); -} - bool RenderableModelEntityItem::isReadyToComputeShape() { if (!_model) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 90535954b4..9146a04cf8 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -56,8 +56,6 @@ public: virtual bool hasCollisionModel() const; virtual const QString& getCollisionModelURL() const; - virtual void updateDimensions(const glm::vec3& value); - bool isReadyToComputeShape(); void computeShapeInfo(ShapeInfo& info); ShapeType getShapeType() const; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 49e450c45e..88287f8965 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -40,15 +40,6 @@ class EntityTreeElementExtraEncodeData; #define debugTreeVector(V) V << "[" << V << " in meters ]" -extern const float MIN_POSITION_DELTA; -extern const float MIN_DIMENSIONS_DELTA; -extern const float MIN_ALIGNMENT_DOT; -extern const float MIN_VELOCITY_DELTA; -extern const float MIN_DAMPING_DELTA; -extern const float MIN_GRAVITY_DELTA; -extern const float MIN_SPIN_DELTA; - - /// EntityItem class this is the base class for all entity types. It handles the basic properties and functionality available /// to all other entity types. In particular: postion, size, rotation, age, lifetime, velocity, gravity. You can not instantiate /// one directly, instead you must only construct one of it's derived classes with additional features. @@ -279,7 +270,7 @@ public: void updatePositionInDomainUnits(const glm::vec3& value); void updatePosition(const glm::vec3& value); void updateDimensionsInDomainUnits(const glm::vec3& value); - virtual void updateDimensions(const glm::vec3& value); + void updateDimensions(const glm::vec3& value); void updateRotation(const glm::quat& rotation); void updateDensity(float value); void updateMass(float value); From 719dae61a9a8d015a12f2685439b38bc6951f7e2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 06:51:00 -0700 Subject: [PATCH 12/54] when a compound shape is deleted, delete the children, as well --- libraries/physics/src/ShapeInfoUtil.h | 2 ++ libraries/physics/src/ShapeManager.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/libraries/physics/src/ShapeInfoUtil.h b/libraries/physics/src/ShapeInfoUtil.h index fb59f30c69..9585161440 100644 --- a/libraries/physics/src/ShapeInfoUtil.h +++ b/libraries/physics/src/ShapeInfoUtil.h @@ -20,6 +20,8 @@ // translates between ShapeInfo and btShape namespace ShapeInfoUtil { + + // XXX is collectInfoFromShape no longer strictly needed? void collectInfoFromShape(const btCollisionShape* shape, ShapeInfo& info); btCollisionShape* createShapeFromInfo(const ShapeInfo& info); diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 513fbfa7a5..9b3b2f6d35 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -100,6 +100,18 @@ void ShapeManager::collectGarbage() { DoubleHashKey& key = _pendingGarbage[i]; ShapeReference* shapeRef = _shapeMap.find(key); if (shapeRef && shapeRef->refCount == 0) { + // if the shape we're about to delete is compound, delete the children first. + auto shapeType = ShapeInfoUtil::fromBulletShapeType(shapeRef->shape->getShapeType()); + if (shapeType == SHAPE_TYPE_COMPOUND) { + const btCompoundShape* compoundShape = static_cast(shapeRef->shape); + const int numChildShapes = compoundShape->getNumChildShapes(); + QVector> points; + for (int i = 0; i < numChildShapes; i ++) { + const btCollisionShape* childShape = compoundShape->getChildShape(i); + delete childShape; + } + } + delete shapeRef->shape; _shapeMap.remove(key); } From 429a258df031ff8ba1d4a68db9965217ca9f6652 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 25 Mar 2015 14:38:27 -0700 Subject: [PATCH 13/54] enable hover when far above floor --- libraries/physics/src/CharacterController.cpp | 65 ++++++++++++++++--- libraries/physics/src/CharacterController.h | 2 + 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index e84df7d644..84dcf25212 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -40,6 +40,24 @@ static btVector3 getNormalizedVector(const btVector3& v) { return n; } +class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { +public: + btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : + btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { + m_me = me; + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) { + if (rayResult.m_collisionObject == m_me) { + return 1.0; + } + return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); + } +protected: + btCollisionObject* m_me; +}; + + class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: btKinematicClosestNotMeConvexResultCallback(btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) @@ -215,6 +233,7 @@ CharacterController::CharacterController(AvatarData* avatarData) { _jumpSpeed = 7.0f; _wasOnGround = false; _wasJumping = false; + _isHovering = true; setMaxSlope(btRadians(45.0f)); _lastStepUp = 0.0f; _pendingFlags = 0; @@ -325,6 +344,27 @@ bool CharacterController::recoverFromPenetration(btCollisionWorld* collisionWorl return penetration; } +void CharacterController::scanDown(btCollisionWorld* world) { + // we test with downward raycast and if we don't find floor close enough then turn on "hover" + btKinematicClosestNotMeRayResultCallback callback(_ghostObject); + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + + btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); + btVector3 start = _currentPosition; + const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight; // closest possible floor for disabling hover + const btScalar MIN_HOVER_HEIGHT = 2.0f + _halfHeight; // distance to floor for enabling hover + btVector3 end = start - MAX_SCAN_HEIGHT * up; + + world->rayTest(start, end, callback); + bool wasHovering = _isHovering; + if (!callback.hasHit()) { + _isHovering = true; + } else if (_isHovering && callback.m_closestHitFraction * MAX_SCAN_HEIGHT < MIN_HOVER_HEIGHT) { + _isHovering = false; + } +} + void CharacterController::stepUp(btCollisionWorld* world) { // phase 1: up @@ -495,7 +535,6 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; _currentPosition = _targetPosition; - btVector3 oldPosition = _currentPosition; step = (- _stepHeight) * up; _targetPosition = _currentPosition + step; @@ -510,7 +549,7 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _wasJumping = false; } else { // nothing to step down on, so remove the stepUp effect - _currentPosition = oldPosition - _lastStepUp * up; + //_currentPosition = oldPosition; _lastStepUp = 0.0f; } } else { @@ -581,14 +620,19 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar return; // no motion } - _wasOnGround = onGround(); - // Update fall velocity. - _verticalVelocity -= _gravity * dt; - if (_verticalVelocity > _jumpSpeed) { - _verticalVelocity = _jumpSpeed; - } else if (_verticalVelocity < -_maxFallSpeed) { - _verticalVelocity = -_maxFallSpeed; + if (_isHovering) { + _wasOnGround = false; + const btScalar HOVER_RELAXATION_TIMESCALE = 1.0f; + _verticalVelocity *= (1.0f - dt / HOVER_RELAXATION_TIMESCALE); + } else { + _wasOnGround = onGround(); + _verticalVelocity -= _gravity * dt; + if (_verticalVelocity > _jumpSpeed) { + _verticalVelocity = _jumpSpeed; + } else if (_verticalVelocity < -_maxFallSpeed) { + _verticalVelocity = -_maxFallSpeed; + } } _verticalOffset = _verticalVelocity * dt; @@ -600,6 +644,8 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // (2) step the character forward // (3) step the character down looking for new ledges, the original floor, or a floor one step below where we started + scanDown(collisionWorld); + stepUp(collisionWorld); // compute substep and decrement total interval @@ -711,6 +757,7 @@ void CharacterController::setEnabled(bool enabled) { // Don't bother clearing REMOVE bit since it might be paired with an UPDATE_SHAPE bit. // Setting the ADD bit here works for all cases so we don't even bother checking other bits. _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; + _isHovering = true; } else { // Always set REMOVE bit when going disabled, and we always clear the ADD bit just in case // it was previously set by something else (e.g. an UPDATE_SHAPE event). diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 323529b1cd..f604e60c31 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -82,6 +82,7 @@ protected: bool _enabled; bool _wasOnGround; bool _wasJumping; + bool _isHovering; btScalar _velocityTimeInterval; uint32_t _pendingFlags; @@ -95,6 +96,7 @@ protected: btVector3 perpindicularComponent(const btVector3& direction, const btVector3& normal); bool recoverFromPenetration(btCollisionWorld* collisionWorld); + void scanDown(btCollisionWorld* collisionWorld); void stepUp(btCollisionWorld* collisionWorld); void updateTargetPositionBasedOnCollision(const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); void stepForward(btCollisionWorld* collisionWorld, const btVector3& walkMove); From dd9290bd5900ac5383cba268be3470545ec45a5c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:28 -0700 Subject: [PATCH 14/54] clear points for non-hull shapes --- libraries/shared/src/ShapeInfo.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 73dd945f73..5fe1fc230d 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -23,6 +23,7 @@ void ShapeInfo::clear() { void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) { _type = type; + _points.clear(); switch(type) { case SHAPE_TYPE_NONE: _halfExtents = glm::vec3(0.0f); @@ -56,6 +57,7 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) { _url = ""; _type = SHAPE_TYPE_BOX; _halfExtents = halfExtents; + _points.clear(); _doubleHashKey.clear(); } @@ -63,6 +65,7 @@ void ShapeInfo::setSphere(float radius) { _url = ""; _type = SHAPE_TYPE_SPHERE; _halfExtents = glm::vec3(radius, radius, radius); + _points.clear(); _doubleHashKey.clear(); } @@ -70,6 +73,7 @@ void ShapeInfo::setEllipsoid(const glm::vec3& halfExtents) { _url = ""; _type = SHAPE_TYPE_ELLIPSOID; _halfExtents = halfExtents; + _points.clear(); _doubleHashKey.clear(); } @@ -87,6 +91,7 @@ void ShapeInfo::setCapsuleY(float radius, float halfHeight) { _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; _halfExtents = glm::vec3(radius, halfHeight, radius); + _points.clear(); _doubleHashKey.clear(); } From a3a54e8d7d8fe8059234699efe9202ed7f26361d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:36 -0700 Subject: [PATCH 15/54] style --- libraries/entities/src/ModelEntityItem.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index f135f617f4..55d809e70e 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -281,8 +281,7 @@ void ModelEntityItem::updateShapeType(ShapeType type) { } } -void ModelEntityItem::setCollisionModelURL(const QString& url) -{ +void ModelEntityItem::setCollisionModelURL(const QString& url) { if (_collisionModelURL != url) { _collisionModelURL = url; _dirtyFlags |= EntityItem::DIRTY_SHAPE | EntityItem::DIRTY_MASS; From 923951143c062c15edbeec5f31c29e605d20d8da Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Mar 2015 15:21:53 -0700 Subject: [PATCH 16/54] comment out line that's killing cmake for me --- tools/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5c7c306a62..ba2938aaa6 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -8,5 +8,5 @@ set_target_properties(scribe PROPERTIES FOLDER "Tools") find_package(VHACD) if(VHACD_FOUND) add_subdirectory(vhacd) -set_target_properties(vhacd PROPERTIES FOLDER "Tools") +# set_target_properties(vhacd PROPERTIES FOLDER "Tools") endif() From 858dbeb674445c9f1530bec5f84dd5482ea932f7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Mar 2015 13:23:15 -0700 Subject: [PATCH 17/54] remove one line of cruft --- libraries/physics/src/CharacterController.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 84dcf25212..fb2457083a 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -357,7 +357,6 @@ void CharacterController::scanDown(btCollisionWorld* world) { btVector3 end = start - MAX_SCAN_HEIGHT * up; world->rayTest(start, end, callback); - bool wasHovering = _isHovering; if (!callback.hasHit()) { _isHovering = true; } else if (_isHovering && callback.m_closestHitFraction * MAX_SCAN_HEIGHT < MIN_HOVER_HEIGHT) { From 0ef4022e9400abbdb3b06d49b01937259007c8b7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Mar 2015 15:14:46 -0700 Subject: [PATCH 18/54] tweak gravity and step heights of controller --- libraries/physics/src/CharacterController.cpp | 25 ++++++++----------- libraries/physics/src/CharacterController.h | 3 ++- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 84dcf25212..f243deffaa 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -228,9 +228,9 @@ CharacterController::CharacterController(AvatarData* avatarData) { _velocityTimeInterval = 0.0f; _verticalVelocity = 0.0f; _verticalOffset = 0.0f; - _gravity = 9.8f; + _gravity = 5.0f; // slower than Earth's _maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. - _jumpSpeed = 7.0f; + _jumpSpeed = 5.0f; _wasOnGround = false; _wasJumping = false; _isHovering = true; @@ -352,8 +352,8 @@ void CharacterController::scanDown(btCollisionWorld* world) { btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); btVector3 start = _currentPosition; - const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight; // closest possible floor for disabling hover - const btScalar MIN_HOVER_HEIGHT = 2.0f + _halfHeight; // distance to floor for enabling hover + const btScalar MAX_SCAN_HEIGHT = 20.0f + _halfHeight + _radius; // closest possible floor for disabling hover + const btScalar MIN_HOVER_HEIGHT = 3.0f + _halfHeight + _radius; // distance to floor for enabling hover btVector3 end = start - MAX_SCAN_HEIGHT * up; world->rayTest(start, end, callback); @@ -374,7 +374,7 @@ void CharacterController::stepUp(btCollisionWorld* world) { btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); start.setOrigin(_currentPosition + up * (_convexShape->getMargin() + _addedMargin)); - _targetPosition = _currentPosition + up * _stepHeight; + _targetPosition = _currentPosition + up * _stepUpHeight; end.setIdentity(); end.setOrigin(_targetPosition); @@ -392,15 +392,15 @@ void CharacterController::stepUp(btCollisionWorld* world) { // Only modify the position if the hit was a slope and not a wall or ceiling. if (callback.m_hitNormalWorld.dot(up) > 0.0f) { - _lastStepUp = _stepHeight * callback.m_closestHitFraction; + _lastStepUp = _stepUpHeight * callback.m_closestHitFraction; _currentPosition.setInterpolate3(_currentPosition, _targetPosition, callback.m_closestHitFraction); } else { - _lastStepUp = _stepHeight; + _lastStepUp = _stepUpHeight; _currentPosition = _targetPosition; } } else { _currentPosition = _targetPosition; - _lastStepUp = _stepHeight; + _lastStepUp = _stepUpHeight; } } @@ -524,6 +524,7 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _wasJumping = false; } else if (!_wasJumping) { // sweep again for floor within downStep threshold + step = -_stepDownHeight * up; StepDownConvexResultCallback callback2 (_ghostObject, up, _currentPosition, step, @@ -535,7 +536,6 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; _currentPosition = _targetPosition; - step = (- _stepHeight) * up; _targetPosition = _currentPosition + step; start.setOrigin(_currentPosition); @@ -549,7 +549,6 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _wasJumping = false; } else { // nothing to step down on, so remove the stepUp effect - //_currentPosition = oldPosition; _lastStepUp = 0.0f; } } else { @@ -819,10 +818,8 @@ void CharacterController::updateShapeIfNecessary() { _ghostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()), glmToBullet(_avatarData->getPosition()))); // stepHeight affects the heights of ledges that the character can ascend - // however the actual ledge height is some function of _stepHeight - // due to character shape and this CharacterController algorithm - // (the function is approximately 2*_stepHeight) - _stepHeight = 0.1f * (_radius + _halfHeight) + 0.1f; + _stepUpHeight = _radius + 0.25f * _halfHeight + 0.1f; + _stepDownHeight = _radius; // create new shape _convexShape = new btCapsuleShape(_radius, 2.0f * _halfHeight); diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index f604e60c31..b31c4855ea 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -59,7 +59,8 @@ protected: btScalar _maxSlopeCosine; // Cosine equivalent of _maxSlopeRadians (calculated once when set, for optimization) btScalar _gravity; - btScalar _stepHeight; // height of stepUp prior to stepForward + btScalar _stepUpHeight; // height of stepUp prior to stepForward + btScalar _stepDownHeight; // height of stepDown btScalar _addedMargin;//@todo: remove this and fix the code From 8a951e0dd3fc8bba4dc08c078c53743a31226dfb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Mar 2015 15:16:57 -0700 Subject: [PATCH 19/54] minor cleanup --- libraries/physics/src/CharacterController.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index f243deffaa..34c2f51b03 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -43,18 +43,18 @@ static btVector3 getNormalizedVector(const btVector3& v) { class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { public: btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : - btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { - m_me = me; + btCollisionWorld::ClosestRayResultCallback(btVector3(0.0f, 0.0f, 0.0f), btVector3(0.0f, 0.0f, 0.0f)) { + _me = me; } virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) { - if (rayResult.m_collisionObject == m_me) { - return 1.0; + if (rayResult.m_collisionObject == _me) { + return 1.0f; } return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); } protected: - btCollisionObject* m_me; + btCollisionObject* _me; }; @@ -357,7 +357,6 @@ void CharacterController::scanDown(btCollisionWorld* world) { btVector3 end = start - MAX_SCAN_HEIGHT * up; world->rayTest(start, end, callback); - bool wasHovering = _isHovering; if (!callback.hasHit()) { _isHovering = true; } else if (_isHovering && callback.m_closestHitFraction * MAX_SCAN_HEIGHT < MIN_HOVER_HEIGHT) { From 43b30c7ffab6f19e29b29d9d9c2771039f8ad104 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Mar 2015 18:35:31 -0700 Subject: [PATCH 20/54] quiet compiler --- assignment-client/src/avatars/AvatarMixer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 176fd51eea..39ae9a85ad 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -149,7 +149,8 @@ void AvatarMixer::broadcastAvatarData() { // about a given otherNode to this node // FIXME does this mean we should sort the othernodes by distance before iterating // over them? - float outputBandwidth = node->getOutboundBandwidth(); + // float outputBandwidth = + node->getOutboundBandwidth(); // this is an AGENT we have received head data from // send back a packet with other active node data to this node From 7da87d6e156bd93802261d8941e9c1ec7126671b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Mar 2015 18:37:55 -0700 Subject: [PATCH 21/54] set up a way to request ResourceCache downloads from a non-networking thread. --- interface/src/Application.cpp | 12 ++++- interface/src/Application.h | 2 + libraries/networking/src/ResourceCache.cpp | 49 ++++++++++++-------- libraries/networking/src/ResourceCache.h | 12 ++++- libraries/render-utils/src/GeometryCache.cpp | 4 +- libraries/render-utils/src/GeometryCache.h | 3 +- libraries/render-utils/src/Model.cpp | 16 ++++++- libraries/render-utils/src/Model.h | 4 +- 8 files changed, 73 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc8fa08c4e..a69fc3659d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -344,6 +344,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // put the NodeList and datagram processing on the node thread nodeList->moveToThread(nodeThread); + // geometry background downloads need to happen on the Datagram Processor Thread. The idle loop will + // emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background + // downloads. + QSharedPointer geometryCacheP = DependencyManager::get(); + ResourceCache *geometryCache = geometryCacheP.data(); + connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); + // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); @@ -1569,6 +1576,9 @@ void Application::idle() { idleTimer->start(2); } } + + // check for any requested background downloads. + emit checkBackgroundDownloads(); } void Application::setFullscreen(bool fullscreen) { @@ -3140,7 +3150,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); - bool eyeRelativeCamera = false; + // bool eyeRelativeCamera = false; if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + diff --git a/interface/src/Application.h b/interface/src/Application.h index 7764f297d3..54dbf60f3f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -333,6 +333,8 @@ signals: void svoImportRequested(const QString& url); + void checkBackgroundDownloads(); + public slots: void domainChanged(const QString& domainHostname); void updateWindowTitle(); diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index b574eb1aeb..f6dfb94903 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "NetworkAccessManager.h" #include "ResourceCache.h" @@ -48,32 +49,42 @@ void ResourceCache::refresh(const QUrl& url) { } } +void ResourceCache::getResourceAsynchronously(const QUrl& url) { + qDebug() << "ResourceCache::getResourceAsynchronously" << url.toString(); + _resourcesToBeGottenLock.lockForWrite(); + _resourcesToBeGotten.enqueue(QUrl(url)); + _resourcesToBeGottenLock.unlock(); +} + +void ResourceCache::checkAsynchronousGets() { + assert(QThread::currentThread() == thread()); + _resourcesToBeGottenLock.lockForRead(); + if (_resourcesToBeGotten.isEmpty()) { + _resourcesToBeGottenLock.unlock(); + return; + } + QUrl url = _resourcesToBeGotten.dequeue(); + _resourcesToBeGottenLock.unlock(); + getResource(url); +} + QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, - bool delayLoad, void* extra, bool block) { + bool delayLoad, void* extra) { + QSharedPointer resource = _resources.value(url); + if (!resource.isNull()) { + return resource; + } + if (QThread::currentThread() != thread()) { - // This will re-call this method in the main thread. If block is true and the main thread - // is waiting on a lock, we'll deadlock here. - if (block) { - QSharedPointer result; - QMetaObject::invokeMethod(this, "getResource", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(QSharedPointer, result), Q_ARG(const QUrl&, url), - Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra)); - return result; - } else { - // Queue the re-invocation of this method, but if the main thread is blocked, don't wait. The - // return value may be NULL -- it's expected that this will be called again later, in order - // to receive the actual Resource. - QMetaObject::invokeMethod(this, "getResource", Qt::QueuedConnection, - Q_ARG(const QUrl&, url), - Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra)); - return _resources.value(url); - } + assert(delayLoad); + getResourceAsynchronously(url); + return QSharedPointer(); } if (!url.isValid() && !url.isEmpty() && fallback.isValid()) { return getResource(fallback, QUrl(), delayLoad); } - QSharedPointer resource = _resources.value(url); + if (resource.isNull()) { resource = createResource(url, fallback.isValid() ? getResource(fallback, QUrl(), true) : QSharedPointer(), delayLoad, extra); diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index d4aa9a7fd9..c7aceb2e1a 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include @@ -79,6 +81,9 @@ public: void refresh(const QUrl& url); +public slots: + void checkAsynchronousGets(); + protected: qint64 _unusedResourcesMaxSize = DEFAULT_UNUSED_MAX_SIZE; qint64 _unusedResourcesSize = 0; @@ -89,7 +94,7 @@ protected: /// \param delayLoad if true, don't load the resource immediately; wait until load is first requested /// \param extra extra data to pass to the creator, if appropriate Q_INVOKABLE QSharedPointer getResource(const QUrl& url, const QUrl& fallback = QUrl(), - bool delayLoad = false, void* extra = NULL, bool block = true); + bool delayLoad = false, void* extra = NULL); /// Creates a new resource. virtual QSharedPointer createResource(const QUrl& url, @@ -109,6 +114,11 @@ private: int _lastLRUKey = 0; static int _requestLimit; + + void getResourceAsynchronously(const QUrl& url); + QReadWriteLock _resourcesToBeGottenLock; + QQueue _resourcesToBeGotten; + }; /// Base class for resources. diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 29f76291ea..c18dfa4d5f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1770,8 +1770,8 @@ void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2, } -QSharedPointer GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad, bool block) { - return getResource(url, fallback, delayLoad, NULL, block).staticCast(); +QSharedPointer GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) { + return getResource(url, fallback, delayLoad, NULL).staticCast(); } QSharedPointer GeometryCache::createResource(const QUrl& url, diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index a64d041fc1..37156a6c71 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -203,8 +203,7 @@ public: /// Loads geometry from the specified URL. /// \param fallback a fallback URL to load if the desired one is unavailable /// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested - QSharedPointer getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), - bool delayLoad = false, bool block = true); + QSharedPointer getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false); protected: diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 873f458ccf..81c9f9448c 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -325,6 +325,8 @@ void Model::init() { _skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel)); makeResult = gpu::Shader::makeProgram(*_skinTranslucentProgram, slotBindings); initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations); + + (void) makeResult; // quiet compiler } } @@ -1032,12 +1034,22 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo } } -void Model::setCollisionModelURL(const QUrl& url, const QUrl& fallback, bool delayLoad) { + +const QSharedPointer Model::getCollisionGeometry(bool delayLoad) +{ + if (_collisionGeometry.isNull() && !_collisionUrl.isEmpty()) { + _collisionGeometry = DependencyManager::get()->getGeometry(_collisionUrl, QUrl(), delayLoad); + } + + return _collisionGeometry; +} + +void Model::setCollisionModelURL(const QUrl& url) { if (_collisionUrl == url) { return; } _collisionUrl = url; - _collisionGeometry = DependencyManager::get()->getGeometry(url, fallback, delayLoad); + _collisionGeometry = DependencyManager::get()->getGeometry(url, QUrl(), true); } bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 05db20b056..3b4cbdd450 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -109,7 +109,7 @@ public: const QUrl& getURL() const { return _url; } // Set the model to use for collisions - Q_INVOKABLE void setCollisionModelURL(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false); + Q_INVOKABLE void setCollisionModelURL(const QUrl& url); const QUrl& getCollisionURL() const { return _collisionUrl; } /// Sets the distance parameter used for LOD computations. @@ -134,7 +134,7 @@ public: const QSharedPointer& getGeometry() const { return _geometry; } /// Returns a reference to the shared collision geometry. - const QSharedPointer getCollisionGeometry() {return _collisionGeometry; } + const QSharedPointer getCollisionGeometry(bool delayLoad = true); /// Returns the number of joint states in the model. int getJointStateCount() const { return _jointStates.size(); } From 821ac605f5dc8cd93cf8460f456defe05b099041 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 26 Mar 2015 19:48:52 -0700 Subject: [PATCH 22/54] smoother motion on steps faster motion when "flying" cleanup of MyAvatar::updatePosition() --- interface/src/avatar/MyAvatar.cpp | 136 +++--------------- interface/src/avatar/MyAvatar.h | 1 - libraries/physics/src/CharacterController.cpp | 55 ++++--- libraries/physics/src/CharacterController.h | 6 +- 4 files changed, 63 insertions(+), 135 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2f42544f28..aa36748f0c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -174,11 +174,7 @@ void MyAvatar::simulate(float deltaTime) { { PerformanceTimer perfTimer("transform"); updateOrientation(deltaTime); - if (isPhysicsEnabled()) { - updatePositionWithPhysics(deltaTime); - } else { - updatePosition(deltaTime); - } + updatePosition(deltaTime); } { @@ -1258,128 +1254,38 @@ glm::vec3 MyAvatar::applyScriptedMotor(float deltaTime, const glm::vec3& localVe return localVelocity + motorEfficiency * deltaVelocity; } -const float NEARBY_FLOOR_THRESHOLD = 5.0f; - void MyAvatar::updatePosition(float deltaTime) { - - // check for floor by casting a ray straight down from avatar's position - float heightAboveFloor = FLT_MAX; - bool hasFloor = false; - const CapsuleShape& boundingShape = _skeletonModel.getBoundingShape(); - const float maxFloorDistance = boundingShape.getBoundingRadius() * NEARBY_FLOOR_THRESHOLD; - - RayIntersectionInfo intersection; - // NOTE: avatar is center of PhysicsSimulation, so rayStart is the origin for the purposes of the raycast - intersection._rayStart = glm::vec3(0.0f); - intersection._rayDirection = - _worldUpDirection; - intersection._rayLength = 4.0f * boundingShape.getBoundingRadius(); - - // velocity is initialized to the measured _velocity but will be modified by friction, external thrust, etc - glm::vec3 velocity = _velocity; - - bool pushingUp = (_driveKeys[UP] - _driveKeys[DOWN] > 0.0f) || _scriptedMotorVelocity.y > 0.0f; - if (_motionBehaviors & AVATAR_MOTION_STAND_ON_NEARBY_FLOORS) { - const float MAX_SPEED_UNDER_GRAVITY = 2.0f * _scale * MAX_WALKING_SPEED; - if (pushingUp || glm::length2(velocity) > MAX_SPEED_UNDER_GRAVITY * MAX_SPEED_UNDER_GRAVITY) { - // we're pushing up or moving quickly, so disable gravity - setLocalGravity(glm::vec3(0.0f)); - hasFloor = false; - } else { - if (heightAboveFloor > maxFloorDistance) { - // disable local gravity when floor is too far away - setLocalGravity(glm::vec3(0.0f)); - hasFloor = false; - } else { - // enable gravity - setLocalGravity(-_worldUpDirection); - } - } - } - - bool zeroDownwardVelocity = false; - bool gravityEnabled = (glm::length2(_gravity) > EPSILON); - if (gravityEnabled) { - const float SLOP = 0.002f; - if (heightAboveFloor < SLOP) { - if (heightAboveFloor < 0.0) { - // Gravity is in effect so we assume that the avatar is colliding against the world and we need - // to lift avatar out of floor, but we don't want to do it too fast (keep it smooth). - float distanceToLift = glm::min(-heightAboveFloor, MAX_WALKING_SPEED * deltaTime); - - // We don't use applyPositionDelta() for this lift distance because we don't want the avatar - // to come flying out of the floor. Instead we update position directly, and set a boolean - // that will remind us later to zero any downward component of the velocity. - _position += distanceToLift * _worldUpDirection; - } - zeroDownwardVelocity = true; - } - if (!zeroDownwardVelocity) { - velocity += (deltaTime * GRAVITY_EARTH) * _gravity; - } - } - - // rotate velocity into camera frame - glm::quat rotation = getHead()->getCameraOrientation(); - glm::vec3 localVelocity = glm::inverse(rotation) * velocity; - - // apply motors in camera frame - glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, hasFloor); - newLocalVelocity = applyScriptedMotor(deltaTime, newLocalVelocity); - - // rotate back into world-frame - velocity = rotation * newLocalVelocity; - - // apply thrust - velocity += _thrust * deltaTime; - _thrust = glm::vec3(0.0f); - - // remove downward velocity so we don't push into floor - if (zeroDownwardVelocity) { - float verticalSpeed = glm::dot(velocity, _worldUpDirection); - if (verticalSpeed < 0.0f || !pushingUp) { - velocity -= verticalSpeed * _worldUpDirection; - } - } - - // cap avatar speed - float speed = glm::length(velocity); - if (speed > MAX_AVATAR_SPEED) { - velocity *= MAX_AVATAR_SPEED / speed; - speed = MAX_AVATAR_SPEED; - } - - // update position - if (speed > MIN_AVATAR_SPEED) { - applyPositionDelta(deltaTime * velocity); - } - - // update _moving flag based on speed - const float MOVING_SPEED_THRESHOLD = 0.01f; - _moving = speed > MOVING_SPEED_THRESHOLD; - - measureMotionDerivatives(deltaTime); -} - -void MyAvatar::updatePositionWithPhysics(float deltaTime) { // rotate velocity into camera frame glm::quat rotation = getHead()->getCameraOrientation(); glm::vec3 localVelocity = glm::inverse(rotation) * _velocity; - bool hasFloor = false; - glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, hasFloor); + bool isOnGround = _characterController.onGround(); + glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, isOnGround); newLocalVelocity = applyScriptedMotor(deltaTime, newLocalVelocity); - // cap avatar speed - float speed = glm::length(newLocalVelocity); - if (speed > MAX_WALKING_SPEED) { - newLocalVelocity *= MAX_WALKING_SPEED / speed; - } - // rotate back into world-frame _velocity = rotation * newLocalVelocity; _velocity += _thrust * deltaTime; _thrust = glm::vec3(0.0f); + + // cap avatar speed + float speed = glm::length(_velocity); + if (speed > MAX_AVATAR_SPEED) { + _velocity *= MAX_AVATAR_SPEED / speed; + speed = MAX_AVATAR_SPEED; + } + + if (speed > MIN_AVATAR_SPEED && !isPhysicsEnabled()) { + // update position ourselves + applyPositionDelta(deltaTime * _velocity); + measureMotionDerivatives(deltaTime); + } // else physics will move avatar later + + // update _moving flag based on speed + const float MOVING_SPEED_THRESHOLD = 0.01f; + _moving = speed > MOVING_SPEED_THRESHOLD; + } void MyAvatar::updateCollisionSound(const glm::vec3 &penetration, float deltaTime, float frequency) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index a37d1c6a30..320a3179bc 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -234,7 +234,6 @@ private: glm::vec3 applyKeyboardMotor(float deltaTime, const glm::vec3& velocity, bool walkingOnFloor); glm::vec3 applyScriptedMotor(float deltaTime, const glm::vec3& velocity); void updatePosition(float deltaTime); - void updatePositionWithPhysics(float deltaTime); void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency); void maybeUpdateBillboard(); void setGravity(const glm::vec3& gravity); diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 34c2f51b03..aa0d109732 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -231,8 +231,8 @@ CharacterController::CharacterController(AvatarData* avatarData) { _gravity = 5.0f; // slower than Earth's _maxFallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s. _jumpSpeed = 5.0f; - _wasOnGround = false; - _wasJumping = false; + _isOnGround = false; + _isJumping = false; _isHovering = true; setMaxSlope(btRadians(45.0f)); _lastStepUp = 0.0f; @@ -450,12 +450,12 @@ void CharacterController::stepForward(btCollisionWorld* collisionWorld, const bt btScalar margin = _convexShape->getMargin(); _convexShape->setMargin(margin + _addedMargin); - const btScalar MIN_STEP_DISTANCE = 0.0001f; + const btScalar MIN_STEP_DISTANCE_SQUARED = 1.0e-6f; btVector3 step = _targetPosition - _currentPosition; btScalar stepLength2 = step.length2(); int maxIter = 10; - while (stepLength2 > MIN_STEP_DISTANCE && maxIter-- > 0) { + while (stepLength2 > MIN_STEP_DISTANCE_SQUARED && maxIter-- > 0) { start.setOrigin(_currentPosition); end.setOrigin(_targetPosition); @@ -516,12 +516,14 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt end.setOrigin(_targetPosition); _ghostObject->convexSweepTest(_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + _isOnGround = false; if (callback.hasHit()) { _currentPosition += callback.m_closestHitFraction * step; _verticalVelocity = 0.0f; _verticalOffset = 0.0f; - _wasJumping = false; - } else if (!_wasJumping) { + _isJumping = false; + _isOnGround = true; + } else if (!_isJumping) { // sweep again for floor within downStep threshold step = -_stepDownHeight * up; StepDownConvexResultCallback callback2 (_ghostObject, @@ -545,9 +547,10 @@ void CharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt _currentPosition += callback2.m_closestHitFraction * step; _verticalVelocity = 0.0f; _verticalOffset = 0.0f; - _wasJumping = false; + _isJumping = false; + _isOnGround = true; } else { - // nothing to step down on, so remove the stepUp effect + // nothing to step down on _lastStepUp = 0.0f; } } else { @@ -571,8 +574,8 @@ void CharacterController::setVelocityForTimeInterval(const btVector3& velocity, void CharacterController::reset(btCollisionWorld* collisionWorld) { _verticalVelocity = 0.0; _verticalOffset = 0.0; - _wasOnGround = false; - _wasJumping = false; + _isOnGround = false; + _isJumping = false; _walkDirection.setValue(0,0,0); _velocityTimeInterval = 0.0; @@ -620,11 +623,9 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // Update fall velocity. if (_isHovering) { - _wasOnGround = false; const btScalar HOVER_RELAXATION_TIMESCALE = 1.0f; _verticalVelocity *= (1.0f - dt / HOVER_RELAXATION_TIMESCALE); } else { - _wasOnGround = onGround(); _verticalVelocity -= _gravity * dt; if (_verticalVelocity > _jumpSpeed) { _verticalVelocity = _jumpSpeed; @@ -649,6 +650,7 @@ void CharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar // compute substep and decrement total interval btScalar dtMoving = (dt < _velocityTimeInterval) ? dt : _velocityTimeInterval; _velocityTimeInterval -= dt; + _stepDt += dt; // stepForward substep btVector3 move = _walkDirection * dtMoving; @@ -673,7 +675,7 @@ void CharacterController::setMaxJumpHeight(btScalar maxJumpHeight) { } bool CharacterController::canJump() const { - return onGround(); + return _isOnGround; } void CharacterController::jump() { @@ -698,7 +700,7 @@ btScalar CharacterController::getMaxSlope() const { } bool CharacterController::onGround() const { - return _enabled && _verticalVelocity == 0.0f && _verticalOffset == 0.0f; + return _isOnGround; } void CharacterController::debugDraw(btIDebugDraw* debugDrawer) { @@ -761,6 +763,7 @@ void CharacterController::setEnabled(bool enabled) { // it was previously set by something else (e.g. an UPDATE_SHAPE event). _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; + _isOnGround = false; } _enabled = enabled; } @@ -842,9 +845,12 @@ void CharacterController::preSimulation(btScalar timeStep) { _pendingFlags &= ~ PENDING_FLAG_JUMP; if (canJump()) { _verticalVelocity = _jumpSpeed; - _wasJumping = true; + _isJumping = true; } } + // remember last position so we can throttle the total motion from the next step + _lastPosition = position; + _stepDt = 0.0f; } } @@ -852,9 +858,24 @@ void CharacterController::postSimulation() { if (_enabled) { const btTransform& avatarTransform = _ghostObject->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); - glm::vec3 offset = rotation * _shapeLocalOffset; + glm::vec3 position = bulletToGLM(avatarTransform.getOrigin()); + + // cap the velocity of the step so that the character doesn't POP! so hard on steps + glm::vec3 finalStep = position - _lastPosition; + btVector3 finalVelocity = _walkDirection; + btVector3 up = quatRotate(_currentRotation, LOCAL_UP_AXIS); + finalVelocity += _verticalVelocity * up; + const btScalar MAX_RESOLUTION_SPEED = 5.0f; // m/sec + btScalar maxStepLength = glm::max(MAX_RESOLUTION_SPEED, 2.0f * finalVelocity.length()) * _stepDt; + btScalar stepLength = glm::length(finalStep); + if (stepLength > maxStepLength) { + position = _lastPosition + (maxStepLength / stepLength) * finalStep; + // NOTE: we don't need to move ghostObject to throttled position unless + // we want to support do async ray-traces/collision-queries against character + } + _avatarData->setOrientation(rotation); - _avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()) - offset); + _avatarData->setPosition(position - rotation * _shapeLocalOffset); } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index b31c4855ea..ec7d9426f4 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -72,6 +72,7 @@ protected: btVector3 _currentPosition; btQuaternion _currentRotation; btVector3 _targetPosition; + glm::vec3 _lastPosition; btScalar _lastStepUp; ///keep track of the contact manifolds @@ -81,10 +82,11 @@ protected: btVector3 _floorNormal; // points from object to character bool _enabled; - bool _wasOnGround; - bool _wasJumping; + bool _isOnGround; + bool _isJumping; bool _isHovering; btScalar _velocityTimeInterval; + btScalar _stepDt; uint32_t _pendingFlags; glm::vec3 _shapeLocalOffset; From b9b2c30bba5f78cad7fb3a38eb9a46a3e4108005 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 27 Mar 2015 09:01:44 -0700 Subject: [PATCH 23/54] use QObject::deleteLater() not explicit delete --- libraries/networking/src/AccountManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 5858c0926d..46c6418c63 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -282,7 +282,7 @@ void AccountManager::processReply() { } else { passErrorToCallback(requestReply); } - delete requestReply; + requestReply->deleteLater(); } void AccountManager::passSuccessToCallback(QNetworkReply* requestReply) { From 087248dffca654f6dc2444af5ca86715300672c5 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 13:14:20 -0700 Subject: [PATCH 24/54] fix locking in ResourceCache::checkAsynchronousGets --- libraries/networking/src/ResourceCache.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index f6dfb94903..739e587f5f 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -58,14 +58,12 @@ void ResourceCache::getResourceAsynchronously(const QUrl& url) { void ResourceCache::checkAsynchronousGets() { assert(QThread::currentThread() == thread()); - _resourcesToBeGottenLock.lockForRead(); - if (_resourcesToBeGotten.isEmpty()) { + if (!_resourcesToBeGotten.isEmpty()) { + _resourcesToBeGottenLock.lockForWrite(); + QUrl url = _resourcesToBeGotten.dequeue(); _resourcesToBeGottenLock.unlock(); - return; + getResource(url); } - QUrl url = _resourcesToBeGotten.dequeue(); - _resourcesToBeGottenLock.unlock(); - getResource(url); } QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, From 81cb1e98bae3d195be27c6211a3d66495f60b2f5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 27 Mar 2015 13:35:58 -0700 Subject: [PATCH 25/54] Rename attribution to marketplaceID --- libraries/entities/src/EntityItem.cpp | 18 +++++++++--------- libraries/entities/src/EntityItem.h | 6 +++--- .../entities/src/EntityItemProperties.cpp | 14 +++++++------- libraries/entities/src/EntityItemProperties.h | 8 ++++---- .../src/EntityItemPropertiesDefaults.h | 2 +- libraries/networking/src/PacketHeaders.cpp | 2 +- libraries/networking/src/PacketHeaders.h | 4 ++-- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index d54e7e6cc1..a73f652282 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -57,7 +57,7 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) { _collisionsWillMove = ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE; _locked = ENTITY_ITEM_DEFAULT_LOCKED; _userData = ENTITY_ITEM_DEFAULT_USER_DATA; - _attribution = ENTITY_ITEM_DEFAULT_ATTRIBUTION; + _marketplaceID = ENTITY_ITEM_DEFAULT_MARKETPLACE_ID; } EntityItem::EntityItem(const EntityItemID& entityItemID) { @@ -117,7 +117,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_COLLISIONS_WILL_MOVE; requestedProperties += PROP_LOCKED; requestedProperties += PROP_USER_DATA; - requestedProperties += PROP_ATTRIBUTION; + requestedProperties += PROP_MARKETPLACE_ID; return requestedProperties; } @@ -240,7 +240,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, appendValue, getCollisionsWillMove()); APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, getLocked()); APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, getUserData()); - APPEND_ENTITY_PROPERTY(PROP_ATTRIBUTION, appendValue, getAttribution()); + APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, getMarketplaceID()); appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -555,8 +555,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_LOCKED, bool, _locked); READ_ENTITY_PROPERTY_STRING(PROP_USER_DATA, setUserData); - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_ATTRIBUTION) { - READ_ENTITY_PROPERTY_STRING(PROP_ATTRIBUTION, setAttribution); + if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) { + READ_ENTITY_PROPERTY_STRING(PROP_MARKETPLACE_ID, setMarketplaceID); } bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); @@ -568,8 +568,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // by doing this parsing here... but it's not likely going to fully recover the content. // // TODO: Remove this conde once we've sufficiently migrated content past this damaged version - if (args.bitstreamVersion == VERSION_ENTITIES_HAS_ATTRIBUTION_DAMAGED) { - READ_ENTITY_PROPERTY_STRING(PROP_ATTRIBUTION, setAttribution); + if (args.bitstreamVersion == VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED) { + READ_ENTITY_PROPERTY_STRING(PROP_MARKETPLACE_ID, setMarketplaceID); } if (overwriteLocalData && (getDirtyFlags() & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY))) { @@ -838,7 +838,7 @@ EntityItemProperties EntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionsWillMove, getCollisionsWillMove); COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked); COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(attribution, getAttribution); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(marketplaceID, getMarketplaceID); properties._defaultSettings = false; @@ -867,7 +867,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionsWillMove, updateCollisionsWillMove); SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked); SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(attribution, setAttribution); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(marketplaceID, setMarketplaceID); if (somethingChanged) { somethingChangedNotification(); // notify derived classes that something has changed diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 88287f8965..840bc54a2f 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -251,8 +251,8 @@ public: const QString& getUserData() const { return _userData; } void setUserData(const QString& value) { _userData = value; } - const QString& getAttribution() const { return _attribution; } - void setAttribution(const QString& value) { _attribution = value; } + const QString& getMarketplaceID() const { return _marketplaceID; } + void setMarketplaceID(const QString& value) { _marketplaceID = value; } // TODO: get rid of users of getRadius()... float getRadius() const; @@ -342,7 +342,7 @@ protected: bool _collisionsWillMove; bool _locked; QString _userData; - QString _attribution; + QString _marketplaceID; // NOTE: Damping is applied like this: v *= pow(1 - damping, dt) // diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 32352f557d..6e6e897230 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -70,7 +70,7 @@ EntityItemProperties::EntityItemProperties() : CONSTRUCT_PROPERTY(emitStrength, ParticleEffectEntityItem::DEFAULT_EMIT_STRENGTH), CONSTRUCT_PROPERTY(localGravity, ParticleEffectEntityItem::DEFAULT_LOCAL_GRAVITY), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), - CONSTRUCT_PROPERTY(attribution, ENTITY_ITEM_DEFAULT_ATTRIBUTION), + CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), _id(UNKNOWN_ENTITY_ID), _idSet(false), @@ -260,7 +260,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_STRENGTH, emitStrength); CHECK_PROPERTY_CHANGE(PROP_LOCAL_GRAVITY, localGravity); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); - CHECK_PROPERTY_CHANGE(PROP_ATTRIBUTION, attribution); + CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); return changedProperties; } @@ -323,7 +323,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(emitStrength); COPY_PROPERTY_TO_QSCRIPTVALUE(localGravity); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); - COPY_PROPERTY_TO_QSCRIPTVALUE(attribution); + COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); // Sitting properties support QScriptValue sittingPoints = engine->newObject(); @@ -405,7 +405,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(emitStrength, setEmitStrength); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localGravity, setLocalGravity); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(particleRadius, setParticleRadius); - COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(attribution, setAttribution); + COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(marketplaceID, setMarketplaceID); _lastEdited = usecTimestampNow(); } @@ -591,7 +591,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, appendValue, properties.getParticleRadius()); } - APPEND_ENTITY_PROPERTY(PROP_ATTRIBUTION, appendValue, properties.getAttribution()); + APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, properties.getMarketplaceID()); } if (propertyCount > 0) { int endOfEntityItemData = packetData->getUncompressedByteOffset(); @@ -822,7 +822,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); } - READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ATTRIBUTION, setAttribution); + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MARKETPLACE_ID, setMarketplaceID); return valid; } @@ -905,7 +905,7 @@ void EntityItemProperties::markAllChanged() { _localGravityChanged = true; _particleRadiusChanged = true; - _attributionChanged = true; + _marketplaceIDChanged = true; } /// The maximum bounding cube for the entity, independent of it's rotation. diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 39e290e602..3f492d649c 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -94,11 +94,11 @@ enum EntityPropertyList { PROP_PARTICLE_RADIUS, PROP_COLLISION_MODEL_URL, - PROP_ATTRIBUTION, + PROP_MARKETPLACE_ID, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties ABOVE this line and then modify PROP_LAST_ITEM below - PROP_LAST_ITEM = PROP_ATTRIBUTION, + PROP_LAST_ITEM = PROP_MARKETPLACE_ID, //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -205,7 +205,7 @@ public: DEFINE_PROPERTY(PROP_EMIT_STRENGTH, EmitStrength, emitStrength, float); DEFINE_PROPERTY(PROP_LOCAL_GRAVITY, LocalGravity, localGravity, float); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); - DEFINE_PROPERTY_REF(PROP_ATTRIBUTION, Attribution, attribution, QString); + DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); public: float getMaxDimension() const { return glm::max(_dimensions.x, _dimensions.y, _dimensions.z); } @@ -333,7 +333,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitStrength, emitStrength, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalGravity, localGravity, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, Attribution, attribution, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); debug << " last edited:" << properties.getLastEdited() << "\n"; debug << " edited ago:" << properties.getEditedAgo() << "\n"; diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index e57aea3d85..aa7c77ede4 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -22,7 +22,7 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3(0.0f); const bool ENTITY_ITEM_DEFAULT_LOCKED = false; const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString(""); -const QString ENTITY_ITEM_DEFAULT_ATTRIBUTION = QString(""); +const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString(""); const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f; const float ENTITY_ITEM_DEFAULT_GLOW_LEVEL = 0.0f; diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index abac09d238..78a27af686 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -74,7 +74,7 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: - return VERSION_ENTITIES_HAS_ATTRIBUTION; + return VERSION_ENTITIES_HAS_MARKETPLACE_ID; case PacketTypeEntityErase: return 2; case PacketTypeAudioStreamStats: diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 5822f2af3a..924d219b75 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -132,8 +132,8 @@ const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = const PacketVersion VERSION_ENTITIES_HAS_PARTICLES = 10; const PacketVersion VERSION_ENTITIES_USE_METERS_AND_RADIANS = 11; const PacketVersion VERSION_ENTITIES_HAS_COLLISION_MODEL = 12; -const PacketVersion VERSION_ENTITIES_HAS_ATTRIBUTION_DAMAGED = 13; -const PacketVersion VERSION_ENTITIES_HAS_ATTRIBUTION = 14; +const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED = 13; +const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID = 14; const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; #endif // hifi_PacketHeaders_h From be5fdbf2175afc894166c1d12d1a559706519f94 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 27 Mar 2015 13:36:20 -0700 Subject: [PATCH 26/54] enable avatar collisions by default also remove old gravity features --- interface/src/Application.cpp | 11 ---- interface/src/Menu.cpp | 4 +- interface/src/Menu.h | 3 +- interface/src/avatar/MyAvatar.cpp | 50 ++----------------- interface/src/avatar/MyAvatar.h | 11 +--- libraries/avatars/src/AvatarData.h | 12 +---- libraries/physics/src/CharacterController.cpp | 30 ++++++----- libraries/physics/src/CharacterController.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 4 -- 9 files changed, 27 insertions(+), 99 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8cd36b501f..99777d22bf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -987,12 +987,6 @@ void Application::keyPressEvent(QKeyEvent* event) { resetSensors(); break; - case Qt::Key_G: - if (isShifted) { - Menu::getInstance()->triggerOption(MenuOption::ObeyEnvironmentalGravity); - } - break; - case Qt::Key_A: if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::Atmosphere); @@ -1165,10 +1159,6 @@ void Application::keyPressEvent(QKeyEvent* event) { break; } - case Qt::Key_Comma: { - _myAvatar->togglePhysicsEnabled(); - } - default: event->ignore(); break; @@ -2192,7 +2182,6 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("physics"); - _myAvatar->preSimulation(); _physicsEngine.stepSimulation(); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2ec5c12ca0..5867dd29e2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -201,9 +201,7 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::NamesAboveHeads, 0, true); addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::GlowWhenSpeaking, 0, true); addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::BlueSpeechSphere, 0, true); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, false, - avatar, SLOT(updateMotionBehavior())); - addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::StandOnNearbyFloors, 0, true, + addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::EnableCharacterController, 0, true, avatar, SLOT(updateMotionBehavior())); addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ShiftHipsForIdleAnimations, 0, false, avatar, SLOT(updateMotionBehavior())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b3d2d548df..a4e644f20f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -153,6 +153,7 @@ namespace MenuOption { const QString EchoServerAudio = "Echo Server Audio"; const QString EditEntitiesHelp = "Edit Entities Help..."; const QString Enable3DTVMode = "Enable 3DTV Mode"; + const QString EnableCharacterController = "Enable avatar collisions"; const QString EnableGlowEffect = "Enable Glow Effect (Warning: Poor Oculus Performance)"; const QString EnableVRMode = "Enable VR Mode"; const QString Entities = "Entities"; @@ -185,7 +186,6 @@ namespace MenuOption { const QString MuteAudio = "Mute Microphone"; const QString MuteEnvironment = "Mute Environment"; const QString NoFaceTracking = "None"; - const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity"; const QString OctreeStats = "Entity Statistics"; const QString OffAxisProjection = "Off-Axis Projection"; const QString OnlyDisplayTopTen = "Only Display Top Ten"; @@ -236,7 +236,6 @@ namespace MenuOption { const QString SixenseEnabled = "Enable Hydra Support"; const QString SixenseMouseInput = "Enable Sixense Mouse Input"; const QString SixenseLasers = "Enable Sixense UI Lasers"; - const QString StandOnNearbyFloors = "Stand on nearby floors"; const QString ShiftHipsForIdleAnimations = "Shift hips for idle animations"; const QString Stars = "Stars"; const QString Stats = "Stats"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index aa36748f0c..26b777b35b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -81,7 +81,6 @@ MyAvatar::MyAvatar() : _scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE), _scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME), _motionBehaviors(AVATAR_MOTION_DEFAULTS), - _enablePhysics(false), _characterController(this), _lookAtTargetAvatar(), _shouldRender(true), @@ -101,6 +100,7 @@ MyAvatar::MyAvatar() : // connect to AddressManager signal for location jumps connect(DependencyManager::get().data(), &AddressManager::locationChangeRequired, this, &MyAvatar::goToLocation); + _characterController.setEnabled(true); } MyAvatar::~MyAvatar() { @@ -147,10 +147,6 @@ void MyAvatar::update(float deltaTime) { head->setAudioLoudness(audio->getLastInputLoudness()); head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness()); - if (_motionBehaviors & AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY) { - setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition())); - } - simulate(deltaTime); if (_feetTouchFloor) { _skeletonModel.updateStandingFoot(); @@ -480,26 +476,6 @@ void MyAvatar::loadLastRecording() { _player->loadRecording(_recorder->getRecording()); } -void MyAvatar::setLocalGravity(glm::vec3 gravity) { - _motionBehaviors |= AVATAR_MOTION_OBEY_LOCAL_GRAVITY; - // Environmental and Local gravities are incompatible. Since Local is being set here - // the environmental setting must be removed. - _motionBehaviors &= ~AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY; - setGravity(gravity); -} - -void MyAvatar::setGravity(const glm::vec3& gravity) { - _gravity = gravity; - - // use the gravity to determine the new world up direction, if possible - float gravityLength = glm::length(gravity); - if (gravityLength > EPSILON) { - _worldUpDirection = _gravity / -gravityLength; - } - // NOTE: the else case here it to leave _worldUpDirection unchanged - // so it continues to point opposite to the previous gravity setting. -} - AnimationHandlePointer MyAvatar::addAnimationHandle() { AnimationHandlePointer handle = _skeletonModel.createAnimationHandle(); _animationHandles.append(handle); @@ -1276,7 +1252,7 @@ void MyAvatar::updatePosition(float deltaTime) { speed = MAX_AVATAR_SPEED; } - if (speed > MIN_AVATAR_SPEED && !isPhysicsEnabled()) { + if (speed > MIN_AVATAR_SPEED && !_characterController.isEnabled()) { // update position ourselves applyPositionDelta(deltaTime * _velocity); measureMotionDerivatives(deltaTime); @@ -1402,23 +1378,6 @@ void MyAvatar::goToLocation(const glm::vec3& newPosition, void MyAvatar::updateMotionBehavior() { Menu* menu = Menu::getInstance(); - if (menu->isOptionChecked(MenuOption::ObeyEnvironmentalGravity)) { - _motionBehaviors |= AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY; - // Environmental and Local gravities are incompatible. Environmental setting trumps local. - _motionBehaviors &= ~AVATAR_MOTION_OBEY_LOCAL_GRAVITY; - } else { - _motionBehaviors &= ~AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY; - } - if (! (_motionBehaviors & (AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | AVATAR_MOTION_OBEY_LOCAL_GRAVITY))) { - setGravity(glm::vec3(0.0f)); - } - if (menu->isOptionChecked(MenuOption::StandOnNearbyFloors)) { - _motionBehaviors |= AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; - // standing on floors requires collision with voxels - // TODO: determine what to do with this now that voxels are gone - } else { - _motionBehaviors &= ~AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; - } if (menu->isOptionChecked(MenuOption::KeyboardMotorControl)) { _motionBehaviors |= AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED; } else { @@ -1429,6 +1388,7 @@ void MyAvatar::updateMotionBehavior() { } else { _motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; } + _characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController)); _feetTouchFloor = menu->isOptionChecked(MenuOption::ShiftHipsForIdleAnimations); } @@ -1487,10 +1447,6 @@ glm::vec3 MyAvatar::getLaserPointerTipPosition(const PalmData* palm) { return palm->getPosition(); } -void MyAvatar::preSimulation() { - _characterController.setEnabled(_enablePhysics); -} - void MyAvatar::clearDriveKeys() { for (int i = 0; i < MAX_DRIVE_KEYS; ++i) { _driveKeys[i] = 0.0f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 320a3179bc..99c0bdb5df 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -25,7 +25,7 @@ class MyAvatar : public Avatar { Q_PROPERTY(glm::vec3 motorVelocity READ getScriptedMotorVelocity WRITE setScriptedMotorVelocity) Q_PROPERTY(float motorTimescale READ getScriptedMotorTimescale WRITE setScriptedMotorTimescale) Q_PROPERTY(QString motorReferenceFrame READ getScriptedMotorFrame WRITE setScriptedMotorFrame) - Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setLocalGravity) + //TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity) public: MyAvatar(); @@ -44,13 +44,11 @@ public: // setters void setLeanScale(float scale) { _leanScale = scale; } - void setLocalGravity(glm::vec3 gravity); void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; } void setRealWorldFieldOfView(float realWorldFov) { _realWorldFieldOfView.set(realWorldFov); } // getters float getLeanScale() const { return _leanScale; } - glm::vec3 getGravity() const { return _gravity; } Q_INVOKABLE glm::vec3 getDefaultEyePosition() const; bool getShouldRenderLocally() const { return _shouldRender; } float getRealWorldFieldOfView() { return _realWorldFieldOfView.get(); } @@ -148,11 +146,6 @@ public: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } - - void togglePhysicsEnabled() { _enablePhysics = !_enablePhysics; } - bool isPhysicsEnabled() { return _enablePhysics; } - void setPhysicsEnabled(bool enablePhysics) { _enablePhysics = enablePhysics; } - void preSimulation(); public slots: void increaseSize(); @@ -209,7 +202,6 @@ private: int _scriptedMotorFrame; quint32 _motionBehaviors; - bool _enablePhysics; CharacterController _characterController; QWeakPointer _lookAtTargetAvatar; @@ -236,7 +228,6 @@ private: void updatePosition(float deltaTime); void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency); void maybeUpdateBillboard(); - void setGravity(const glm::vec3& gravity); }; #endif // hifi_MyAvatar_h diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a2feb98798..2bbd2ee386 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -61,21 +61,13 @@ typedef unsigned long long quint64; const quint32 AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED = 1U << 0; const quint32 AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED = 1U << 1; -const quint32 AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY = 1U << 2; -const quint32 AVATAR_MOTION_OBEY_LOCAL_GRAVITY = 1U << 3; -const quint32 AVATAR_MOTION_STAND_ON_NEARBY_FLOORS = 1U << 4; - const quint32 AVATAR_MOTION_DEFAULTS = AVATAR_MOTION_KEYBOARD_MOTOR_ENABLED | - AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED | - AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; + AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; // these bits will be expanded as features are exposed const quint32 AVATAR_MOTION_SCRIPTABLE_BITS = - AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED | - AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY | - AVATAR_MOTION_OBEY_LOCAL_GRAVITY | - AVATAR_MOTION_STAND_ON_NEARBY_FLOORS; + AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; // Bitset of state flags - we store the key state, hand state, faceshift, chat circling, and existance of diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index aa0d109732..40b9076a6a 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -217,9 +217,7 @@ CharacterController::CharacterController(AvatarData* avatarData) { assert(avatarData); _avatarData = avatarData; - // cache the "PhysicsEnabled" state of _avatarData _enabled = false; - _ghostObject = NULL; _convexShape = NULL; @@ -730,10 +728,12 @@ void CharacterController::setLocalBoundingBox(const glm::vec3& corner, const glm if (radiusDelta < FLT_EPSILON && heightDelta < FLT_EPSILON) { // shape hasn't changed --> nothing to do } else { - // we always need to: REMOVE when UPDATE_SHAPE, to avoid deleting shapes out from under the PhysicsEngine - _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION - | PENDING_FLAG_UPDATE_SHAPE; - // but only need to ADD back when we happen to be enabled + if (_dynamicsWorld) { + // must REMOVE from world prior to shape update + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + } + _pendingFlags |= PENDING_FLAG_UPDATE_SHAPE; + // only need to ADD back when we happen to be enabled if (_enabled) { _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; } @@ -759,9 +759,9 @@ void CharacterController::setEnabled(bool enabled) { _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION; _isHovering = true; } else { - // Always set REMOVE bit when going disabled, and we always clear the ADD bit just in case - // it was previously set by something else (e.g. an UPDATE_SHAPE event). - _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + if (_dynamicsWorld) { + _pendingFlags |= PENDING_FLAG_REMOVE_FROM_SIMULATION; + } _pendingFlags &= ~ PENDING_FLAG_ADD_TO_SIMULATION; _isOnGround = false; } @@ -777,17 +777,23 @@ void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { } _dynamicsWorld = world; if (_dynamicsWorld) { - _pendingFlags &= ~ (PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_JUMP); + _pendingFlags &= ~ PENDING_FLAG_JUMP; _dynamicsWorld->addCollisionObject(getGhostObject(), btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); _dynamicsWorld->addAction(this); reset(_dynamicsWorld); + } + } + if (_dynamicsWorld) { + if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { + // shouldn't fall in here, but if we do make sure both ADD and REMOVE bits are still set + _pendingFlags |= PENDING_FLAG_ADD_TO_SIMULATION | PENDING_FLAG_REMOVE_FROM_SIMULATION; } else { - _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; + _pendingFlags &= ~PENDING_FLAG_ADD_TO_SIMULATION; } } else { - _pendingFlags &= ~ (PENDING_FLAG_REMOVE_FROM_SIMULATION | PENDING_FLAG_ADD_TO_SIMULATION); + _pendingFlags &= ~ PENDING_FLAG_REMOVE_FROM_SIMULATION; } } diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index ec7d9426f4..6751277c83 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -166,6 +166,7 @@ public: bool needsRemoval() const; bool needsAddition() const; void setEnabled(bool enabled); + bool isEnabled() const { return _enabled; } void setDynamicsWorld(btDynamicsWorld* world); void setLocalBoundingBox(const glm::vec3& corner, const glm::vec3& scale); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 716af1d188..831db73a0a 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -360,10 +360,6 @@ void ScriptEngine::init() { globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE))); globalObject().setProperty("COLLISION_GROUP_ENVIRONMENT", newVariant(QVariant(COLLISION_GROUP_ENVIRONMENT))); globalObject().setProperty("COLLISION_GROUP_AVATARS", newVariant(QVariant(COLLISION_GROUP_AVATARS))); - - globalObject().setProperty("AVATAR_MOTION_OBEY_LOCAL_GRAVITY", newVariant(QVariant(AVATAR_MOTION_OBEY_LOCAL_GRAVITY))); - globalObject().setProperty("AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY", newVariant(QVariant(AVATAR_MOTION_OBEY_ENVIRONMENTAL_GRAVITY))); - } QScriptValue ScriptEngine::registerGlobalObject(const QString& name, QObject* object) { From 1bdfa3abb5f9efeb2468d740e5fc0dd633453535 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 27 Mar 2015 13:36:22 -0700 Subject: [PATCH 27/54] Update right-click menu to look for marketplaceID --- examples/edit.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index 2529b617d9..1ea7647a54 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -718,13 +718,8 @@ function mouseClickEvent(event) { var result = findClickedEntity(event); if (result) { var properties = Entities.getEntityProperties(result.entityID); - var data = {}; - try { - data = JSON.parse(properties.attribution); - } catch (e) { - } - if (data.marketplaceID) { - propertyMenu.marketplaceID = data.marketplaceID; + if (properties.marketplaceID) { + propertyMenu.marketplaceID = properties.marketplaceID; propertyMenu.updateMenuItemText(showMenuItem, "Show in Marketplace"); } else { propertyMenu.marketplaceID = null; From ed62356f65bb5e42809ad28921cd37ef7488bb3c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 27 Mar 2015 13:36:56 -0700 Subject: [PATCH 28/54] Remove attribution field from edit properties window --- examples/html/entityProperties.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index dc632d76fd..596bf5c9d5 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -140,7 +140,6 @@ var elLifetime = document.getElementById("property-lifetime"); var elScriptURL = document.getElementById("property-script-url"); var elUserData = document.getElementById("property-user-data"); - var elAttribution = document.getElementById("property-attribution"); var elBoxSections = document.querySelectorAll(".box-section"); var elBoxColorRed = document.getElementById("property-box-red"); @@ -264,7 +263,6 @@ elLifetime.value = properties.lifetime; elScriptURL.value = properties.script; elUserData.value = properties.userData; - elAttribution.value = properties.attribution; if (properties.type != "Box") { for (var i = 0; i < elBoxSections.length; i++) { @@ -395,7 +393,6 @@ elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime')); elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script')); elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData')); - elAttribution.addEventListener('change', createEmitTextPropertyUpdateFunction('attribution')); var boxColorChangeFunction = createEmitColorPropertyUpdateFunction( 'color', elBoxColorRed, elBoxColorGreen, elBoxColorBlue); @@ -630,13 +627,6 @@ -
-
Attribution
-
- -
-
-
Color
From bee8c0e2377f5e3a9a06f538cb894084a2ccf189 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 27 Mar 2015 13:56:03 -0700 Subject: [PATCH 29/54] "hover" if the "jump" key is held down long enough --- libraries/physics/src/CharacterController.cpp | 15 +++++++++++++++ libraries/physics/src/CharacterController.h | 1 + 2 files changed, 16 insertions(+) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 40b9076a6a..09c6b5599f 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -232,6 +232,7 @@ CharacterController::CharacterController(AvatarData* avatarData) { _isOnGround = false; _isJumping = false; _isHovering = true; + _jumpToHoverStart = 0; setMaxSlope(btRadians(45.0f)); _lastStepUp = 0.0f; _pendingFlags = 0; @@ -678,6 +679,20 @@ bool CharacterController::canJump() const { void CharacterController::jump() { _pendingFlags |= PENDING_FLAG_JUMP; + + // check for case where user is holding down "jump" key... + // we'll eventually tansition to "hover" + if (!_isHovering) { + if (!_isJumping) { + _jumpToHoverStart = usecTimestampNow(); + } else { + quint64 now = usecTimestampNow(); + const quint64 JUMP_TO_HOVER_PERIOD = USECS_PER_SECOND; + if (now - _jumpToHoverStart < JUMP_TO_HOVER_PERIOD) { + _isHovering = true; + } + } + } } void CharacterController::setGravity(btScalar gravity) { diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index 6751277c83..eeaa5836dd 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -85,6 +85,7 @@ protected: bool _isOnGround; bool _isJumping; bool _isHovering; + quint64 _jumpToHoverStart; btScalar _velocityTimeInterval; btScalar _stepDt; uint32_t _pendingFlags; From 1ee797efa4f1258b4567b81a6b7ec8b90fed03ac Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 27 Mar 2015 13:59:52 -0700 Subject: [PATCH 30/54] Fix authorization of API calls in XMLHttpRequest --- libraries/script-engine/src/XMLHttpRequestClass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 8755527860..f408e2001d 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -207,7 +207,7 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a notImplemented(); } } else { - if (url.toLower().left(33) == "https://metaverse.highfidelity.com/api/") { + if (url.toLower().left(39) == "https://metaverse.highfidelity.com/api/") { AccountManager& accountManager = AccountManager::getInstance(); if (accountManager.hasValidAccessToken()) { From cfa30594cc5187889968d79916c06ca6a902dddd Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 14:24:36 -0700 Subject: [PATCH 31/54] make obj reader handle faces with more than 4 vertices --- libraries/fbx/src/OBJReader.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 0aaf8772a2..db2733f27b 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -249,7 +249,20 @@ bool parseOBJGroup(OBJTokenizer &tokenizer, const QVariantHash& mapping, } else if (indices.count() == 4) { meshPart.quadIndices << indices; } else { - qDebug() << "no support for more than 4 vertices on a face in OBJ files"; + // some obj writers (maya) will write a face with lots of points. + for (int i = 1; i < indices.count() - 1; i++) { + // break the face into triangles + meshPart.triangleIndices.append(indices[0]); + meshPart.triangleIndices.append(indices[i]); + meshPart.triangleIndices.append(indices[i+1]); + } + if (indices.count() == normalIndices.count()) { + for (int i = 1; i < normalIndices.count() - 1; i++) { + faceNormalIndexes.append(normalIndices[0]); + faceNormalIndexes.append(normalIndices[i]); + faceNormalIndexes.append(normalIndices[i+1]); + } + } } } else { // something we don't (yet) care about From 0fd17b3303865a587b2f251ec20594e03eb59040 Mon Sep 17 00:00:00 2001 From: Grayson Stebbins Date: Fri, 27 Mar 2015 14:40:16 -0700 Subject: [PATCH 32/54] editEntities.js --> edit.js --- interface/resources/html/interface-welcome.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/html/interface-welcome.html b/interface/resources/html/interface-welcome.html index ed905eb392..26ae6ff5c0 100644 --- a/interface/resources/html/interface-welcome.html +++ b/interface/resources/html/interface-welcome.html @@ -138,7 +138,7 @@

Import models

- Use the editEntitles.js script to
+ Use the edit.js script to
add FBX models in-world. You
can use grids and fine tune
placement-related parameters
From 1821683453f8bab2f83850aa71154ba062af0c1c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Mar 2015 14:44:35 -0700 Subject: [PATCH 33/54] fix bug in default avatars --- libraries/avatars/src/AvatarData.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a2feb98798..20366e590f 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -365,8 +365,8 @@ protected: HeadData* _headData; HandData* _handData; - QUrl _faceModelURL = DEFAULT_HEAD_MODEL_URL; - QUrl _skeletonModelURL = DEFAULT_BODY_MODEL_URL; + QUrl _faceModelURL; // These need to be empty so that on first time setting them they will not short circuit + QUrl _skeletonModelURL; // These need to be empty so that on first time setting them they will not short circuit QVector _attachmentData; QString _displayName; From c45676041941ae3e2c6985f10f895a3df5155ff6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 27 Mar 2015 15:24:55 -0700 Subject: [PATCH 34/54] Extract API URL into a const --- libraries/script-engine/src/XMLHttpRequestClass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index f408e2001d..3054472a3c 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -22,6 +22,8 @@ #include "XMLHttpRequestClass.h" #include "ScriptEngine.h" +const QString METAVERSE_API_URL = "https://metaverse.highfidelity.com/api/"; + Q_DECLARE_METATYPE(QByteArray*) XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : @@ -207,7 +209,7 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a notImplemented(); } } else { - if (url.toLower().left(39) == "https://metaverse.highfidelity.com/api/") { + if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { AccountManager& accountManager = AccountManager::getInstance(); if (accountManager.hasValidAccessToken()) { From 90f51e7d4c5d18f1df7c9c4cc07150f74ec3fc49 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Mar 2015 16:15:54 -0700 Subject: [PATCH 35/54] print a warning when ShapeManager is skipping over a too-large or too-small shape --- libraries/physics/src/ShapeManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 9b3b2f6d35..2a8705561d 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include "ShapeInfoUtil.h" @@ -35,6 +37,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e4f; // 100 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { + qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; } DoubleHashKey key = info.getHash(); From a765b4c8a5858a030e63bc8984f307324b40390a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Mar 2015 18:56:55 -0700 Subject: [PATCH 36/54] fix to preload getting called when you change a script --- libraries/entities/src/EntityTree.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 3ccff46a04..266aa2bdce 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -148,6 +148,7 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro } } } else { + QString entityScriptBefore = entity->getScript(); uint32_t preFlags = entity->getDirtyFlags(); UpdateEntityOperator theOperator(this, containingElement, entity, properties); recurseTreeWithOperator(&theOperator); @@ -166,6 +167,11 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro entity->clearDirtyFlags(); } } + + QString entityScriptAfter = entity->getScript(); + if (entityScriptBefore != entityScriptAfter) { + emitEntityScriptChanging(entity->getEntityItemID()); // the entity script has changed + } } // TODO: this final containingElement check should eventually be removed (or wrapped in an #ifdef DEBUG). From 9428857194d6c0c7781f7709f607b0510d7a8939 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:10:16 -0700 Subject: [PATCH 37/54] quiet compiler, remove extra-assignment/typo --- assignment-client/src/avatars/AvatarMixer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 176fd51eea..dae6af3fc5 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -149,7 +149,8 @@ void AvatarMixer::broadcastAvatarData() { // about a given otherNode to this node // FIXME does this mean we should sort the othernodes by distance before iterating // over them? - float outputBandwidth = node->getOutboundBandwidth(); + // float outputBandwidth = + node->getOutboundBandwidth(); // this is an AGENT we have received head data from // send back a packet with other active node data to this node @@ -169,7 +170,7 @@ void AvatarMixer::broadcastAvatarData() { return true; }, [&](const SharedNodePointer& otherNode) { - AvatarMixerClientData* otherNodeData = otherNodeData = reinterpret_cast(otherNode->getLinkedData()); + AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); MutexTryLocker lock(otherNodeData->getMutex()); if (!lock.isLocked()) { return; From 986bc71e938f8843a07bc6d8851ab648d9bb33a1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:10:26 -0700 Subject: [PATCH 38/54] quiet compiler --- interface/src/scripting/ControllerScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 35c24346d2..7d6012c880 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -353,7 +353,7 @@ void InputController::update() { // TODO for now the InputController is only supporting a JointTracker from a MotionTracker MotionTracker* motionTracker = dynamic_cast< MotionTracker*> (DeviceTracker::getDevice(_deviceTrackerId)); if (motionTracker) { - if (_subTrackerId < motionTracker->numJointTrackers()) { + if ((int)_subTrackerId < motionTracker->numJointTrackers()) { const MotionTracker::JointTracker* joint = motionTracker->getJointTracker(_subTrackerId); if (joint->isActive()) { From fc1e45fc58a82c42eeb4460d5ecde11e62636419 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:10:46 -0700 Subject: [PATCH 39/54] valgrind says this is used before it's initialized --- interface/src/ui/ApplicationOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index d9adaf02e6..633eafc202 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -139,6 +139,7 @@ ApplicationOverlay::ApplicationOverlay() : _magnifier(true), _alpha(1.0f), _oculusUIRadius(1.0f), + _trailingAudioLoudness(0.0f), _crosshairTexture(0), _previousBorderWidth(-1), _previousBorderHeight(-1), From faa3ed6c292ec8b6dc682f929c49c2ead6021a11 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:11:23 -0700 Subject: [PATCH 40/54] valgrind wants [] --- libraries/audio/src/AudioBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index 4849289743..621b7b1b8c 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -90,7 +90,7 @@ void AudioFrameBuffer< T >::deallocateFrames() { for (uint32_t i = 0; i < _channelCountMax; ++i) { delete _frameBuffer[i]; } - delete _frameBuffer; + delete[] _frameBuffer; } _frameBuffer = NULL; } From 78b46cff2be0bfe3e722489a7f9448a384dbbd1a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:11:36 -0700 Subject: [PATCH 41/54] quiet compiler --- libraries/audio/src/AudioFilterBank.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioFilterBank.h b/libraries/audio/src/AudioFilterBank.h index 723fa6b270..7b3b45f56b 100644 --- a/libraries/audio/src/AudioFilterBank.h +++ b/libraries/audio/src/AudioFilterBank.h @@ -88,7 +88,7 @@ public: } void loadProfile(int profileIndex) { - if (profileIndex >= 0 && profileIndex < _profileCount) { + if (profileIndex >= 0 && profileIndex < (int)_profileCount) { for (uint32_t i = 0; i < _filterCount; ++i) { FilterParameter p = _profiles[profileIndex][i]; From 96bfc5339182177f7a3fcf7f19b056adba4a022e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:11:56 -0700 Subject: [PATCH 42/54] prototype has no code and isn't used --- libraries/entities/src/EntityTree.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 8536e74e9a..29fecc88b4 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -95,7 +95,6 @@ public: void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false); void deleteEntities(QSet entityIDs, bool force = false, bool ignoreWarnings = false); - void removeEntityFromSimulation(EntityItem* entity); /// \param position point of query in world-frame (meters) /// \param targetRadius radius of query (meters) From 1e166eef0f647e7b9a0f451cc7c1d86023fc467e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:12:55 -0700 Subject: [PATCH 43/54] valgrind says _ghostObject is used before it's initialized --- libraries/physics/src/CharacterController.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 09c6b5599f..ba0cfb3c80 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -235,7 +235,9 @@ CharacterController::CharacterController(AvatarData* avatarData) { _jumpToHoverStart = 0; setMaxSlope(btRadians(45.0f)); _lastStepUp = 0.0f; - _pendingFlags = 0; + + _pendingFlags = PENDING_FLAG_UPDATE_SHAPE; + updateShapeIfNecessary(); } CharacterController::~CharacterController() { From a47ae9212b6406f7cb8abb7a14bf9eaa146b388a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:13:31 -0700 Subject: [PATCH 44/54] quiet compiler --- libraries/render-utils/src/DeferredLightingEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 13bf947d71..ffa84adbdf 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -134,7 +134,7 @@ void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radi void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color, float intensity, const glm::quat& orientation, float exponent, float cutoff) { - int lightID = _pointLights.size() + _spotLights.size() + _globalLights.size(); + unsigned int lightID = _pointLights.size() + _spotLights.size() + _globalLights.size(); if (lightID >= _allocatedLights.size()) { _allocatedLights.push_back(model::LightPointer(new model::Light())); } From 43c3c621a8e9db8359a4a3c522de5275b53f3243 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 28 Mar 2015 17:14:39 -0700 Subject: [PATCH 45/54] I can't set VHACD_ROOT_DIR and run cmake with this line. --- tools/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5c7c306a62..ba2938aaa6 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -8,5 +8,5 @@ set_target_properties(scribe PROPERTIES FOLDER "Tools") find_package(VHACD) if(VHACD_FOUND) add_subdirectory(vhacd) -set_target_properties(vhacd PROPERTIES FOLDER "Tools") +# set_target_properties(vhacd PROPERTIES FOLDER "Tools") endif() From 2dd33e5334d771c0d8cbdf361a41d086c87e3ae4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Mar 2015 05:40:16 -0700 Subject: [PATCH 46/54] don't include build-ext in tags --- tools/refresh-tags.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/refresh-tags.sh b/tools/refresh-tags.sh index d3157fa179..e8040dac81 100755 --- a/tools/refresh-tags.sh +++ b/tools/refresh-tags.sh @@ -2,13 +2,13 @@ rm -f TAGS -find . -name *.h -print | while read I +find . -name *.h -print | grep -v build-ext |while read I do etags --append "$I" done -find . -name *.cpp -print | grep -v 'moc_' | while read I +find . -name *.cpp -print | grep -v 'moc_' | grep -v build-ext | while read I do etags --append "$I" done From 26230cf493f35cfe53b39942eee8f23b0a17f003 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Mar 2015 05:40:39 -0700 Subject: [PATCH 47/54] uninitialized variable (quiet valgrind) --- libraries/shared/src/SimpleMovingAverage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/shared/src/SimpleMovingAverage.cpp b/libraries/shared/src/SimpleMovingAverage.cpp index 64198d2a06..90a9509c91 100644 --- a/libraries/shared/src/SimpleMovingAverage.cpp +++ b/libraries/shared/src/SimpleMovingAverage.cpp @@ -14,6 +14,7 @@ SimpleMovingAverage::SimpleMovingAverage(int numSamplesToAverage) : _numSamples(0), + _lastEventTimestamp(0), _average(0.0f), _eventDeltaAverage(0.0f), WEIGHTING(1.0f / numSamplesToAverage), From 4bf86bb824a800ad31f9be54b3a8b3322b1b535a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 29 Mar 2015 17:59:57 -0700 Subject: [PATCH 48/54] another [] needed after delete --- libraries/audio/src/AudioBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index 621b7b1b8c..d2f7c50c91 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -88,7 +88,7 @@ template< typename T > void AudioFrameBuffer< T >::deallocateFrames() { if (_frameBuffer) { for (uint32_t i = 0; i < _channelCountMax; ++i) { - delete _frameBuffer[i]; + delete[] _frameBuffer[i]; } delete[] _frameBuffer; } From 7de15cda87b779606c71cc4c7fe4d5b7a22e8a04 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 09:30:13 -0700 Subject: [PATCH 49/54] quiet compiler --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 99777d22bf..e9ea5bebf8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3125,7 +3125,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); - bool eyeRelativeCamera = false; + // bool eyeRelativeCamera = false; if (billboard) { _mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees _mirrorCamera.setPosition(_myAvatar->getPosition() + From 7137b4137554605cd27d26faca9e6da8ba4f210b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 09:30:37 -0700 Subject: [PATCH 50/54] free these so it's easier to see other leaks in valgrind --- libraries/physics/src/PhysicsEngine.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 9ca718e19a..f7dc90e72f 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -29,6 +29,12 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) PhysicsEngine::~PhysicsEngine() { // TODO: delete engine components... if we ever plan to create more than one instance + delete _collisionConfig; + delete _collisionDispatcher; + delete _broadphaseFilter; + delete _constraintSolver; + delete _dynamicsWorld; + // delete _ghostPairCallback; } // begin EntitySimulation overrides From adf076a63077fed8168233629cefc20ebe3c0322 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 09:56:30 -0700 Subject: [PATCH 51/54] optimizations when creating convex hull shapes --- libraries/physics/src/ShapeInfoUtil.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index 1073fbae3f..8900c5a0dc 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -136,28 +136,32 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) { } break; case SHAPE_TYPE_CONVEX_HULL: { - shape = new btConvexHullShape(); + auto hull = new btConvexHullShape(); const QVector>& points = info.getPoints(); foreach (glm::vec3 point, points[0]) { btVector3 btPoint(point[0], point[1], point[2]); - static_cast(shape)->addPoint(btPoint); + hull->addPoint(btPoint, false); } + hull->recalcLocalAabb(); + shape = hull; } break; case SHAPE_TYPE_COMPOUND: { - shape = new btCompoundShape(); + auto compound = new btCompoundShape(); const QVector>& points = info.getPoints(); - foreach (QVector hullPoints, info.getPoints()) { + btTransform trans; + trans.setIdentity(); + foreach (QVector hullPoints, points) { auto hull = new btConvexHullShape(); foreach (glm::vec3 point, hullPoints) { btVector3 btPoint(point[0], point[1], point[2]); - hull->addPoint(btPoint); + hull->addPoint(btPoint, false); } - btTransform trans; - trans.setIdentity(); - static_cast(shape)->addChildShape (trans, hull); + hull->recalcLocalAabb(); + compound->addChildShape (trans, hull); } + shape = compound; } break; } From da9ceac9ae086287c0c23e6fd2ffc59e6eba3d81 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 30 Mar 2015 11:06:02 -0700 Subject: [PATCH 52/54] fix crash for bad avatar body on login --- libraries/physics/src/CharacterController.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index 09c6b5599f..518e49ed81 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -786,14 +786,17 @@ void CharacterController::setEnabled(bool enabled) { void CharacterController::setDynamicsWorld(btDynamicsWorld* world) { if (_dynamicsWorld != world) { - if (_dynamicsWorld) { - _dynamicsWorld->removeCollisionObject(getGhostObject()); - _dynamicsWorld->removeAction(this); + if (_dynamicsWorld) { + if (_ghostObject) { + _dynamicsWorld->removeCollisionObject(_ghostObject); + _dynamicsWorld->removeAction(this); + } + _dynamicsWorld = NULL; } - _dynamicsWorld = world; - if (_dynamicsWorld) { + if (world && _ghostObject) { + _dynamicsWorld = world; _pendingFlags &= ~ PENDING_FLAG_JUMP; - _dynamicsWorld->addCollisionObject(getGhostObject(), + _dynamicsWorld->addCollisionObject(_ghostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); _dynamicsWorld->addAction(this); @@ -876,7 +879,7 @@ void CharacterController::preSimulation(btScalar timeStep) { } void CharacterController::postSimulation() { - if (_enabled) { + if (_enabled && _ghostObject) { const btTransform& avatarTransform = _ghostObject->getWorldTransform(); glm::quat rotation = bulletToGLM(avatarTransform.getRotation()); glm::vec3 position = bulletToGLM(avatarTransform.getOrigin()); From 8a5192c1d93af5fa65964dc75963a2967dd6265a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 11:22:31 -0700 Subject: [PATCH 53/54] attempt to handle registration point in hull collisions --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 43dbb95b6d..eb6706e27f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -366,6 +366,9 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // multiply each point by scale before handing the point-set off to the physics engine for (int i = 0; i < _points.size(); i++) { for (int j = 0; j < _points[i].size(); j++) { + // compensate for registraion + _points[i][j] += _model->getOffset(); + // scale so the collision points match the model points _points[i][j] *= scale; } } From e730109c51eea2bd22981cbe7a66be6866ec2b02 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 30 Mar 2015 11:46:48 -0700 Subject: [PATCH 54/54] quiet debuging spew --- libraries/physics/src/ShapeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 2a8705561d..b4d322a4a3 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -37,7 +37,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) { const float MIN_SHAPE_DIAGONAL_SQUARED = 3.0e-4f; // 1 cm cube const float MAX_SHAPE_DIAGONAL_SQUARED = 3.0e4f; // 100 m cube if (diagonal < MIN_SHAPE_DIAGONAL_SQUARED || diagonal > MAX_SHAPE_DIAGONAL_SQUARED) { - qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; + // qDebug() << "ShapeManager::getShape -- not making shape due to size" << diagonal; return NULL; } DoubleHashKey key = info.getHash();