From 8d4d4a555c15f130b43c693dc0af451c36fce72d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 20 Oct 2015 15:56:24 -0700 Subject: [PATCH 01/10] Add kinematicGrab option in handControllerGrab.js --- examples/controllers/handControllerGrab.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index d2ad2aa4be..a586188f8b 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -497,7 +497,8 @@ function MyController(hand, triggerAction) { timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, relativeRotation: this.offsetRotation, - lifetime: ACTION_LIFETIME + lifetime: ACTION_LIFETIME, + kinematic: (grabbableData.kinematicGrab && (grabbableData.kinematicGrab === true)) }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; From 014e62e25a2766cdc8261a9ba0f778c4f8758f51 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 Oct 2015 17:11:37 -0700 Subject: [PATCH 02/10] allow assignment client to use AssetClient for ATP downloads --- assignment-client/src/Agent.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index d9109703cb..fb9b2a94a0 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,8 @@ Agent::Agent(NLPacket& packet) : DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION, false)) { DependencyManager::get()->setPacketSender(&_entityEditSender); - + + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -110,11 +112,12 @@ void Agent::run() { ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent); auto nodeList = DependencyManager::get(); - nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() - << NodeType::AudioMixer - << NodeType::AvatarMixer - << NodeType::EntityServer - ); + nodeList->addSetOfNodeTypesToNodeInterestSet({ + NodeType::AudioMixer, + NodeType::AvatarMixer, + NodeType::EntityServer, + NodeType::AssetServer + }); _pingTimer = new QTimer(this); connect(_pingTimer, SIGNAL(timeout()), SLOT(sendPingRequests())); From bfd96194040b880d91c1b22b61274fea44fb717f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 21 Oct 2015 10:10:04 -0700 Subject: [PATCH 03/10] add simple script that spawns a bat when run --- examples/toys/baseball.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 examples/toys/baseball.js diff --git a/examples/toys/baseball.js b/examples/toys/baseball.js new file mode 100644 index 0000000000..79a8a2fd61 --- /dev/null +++ b/examples/toys/baseball.js @@ -0,0 +1,30 @@ +// +// baseball.js +// examples/toys +// +// Created by Stephen Birarda on 10/20/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var BAT_MODEL = "atp:c47deaae09cca927f6bc9cca0e8bbe77fc618f8c3f2b49899406a63a59f885cb.fbx"; +var BAT_COLLISION_SHAPE = "atp:9eafceb7510c41d50661130090de7e0632aa4da236ebda84a0059a4be2130e0c.obj"; + +function createNewBat() { + // move entity three units in front of the avatar + var batPosition = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: -0.3, z: -2 })); + + var wand = Entities.addEntity({ + name: 'Bat', + type: "Model", + modelURL: BAT_MODEL, + position: batPosition, + collisionsWillMove: true, + compoundShapeURL: BAT_COLLISION_SHAPE + }); +} + +createNewBat(); From 1e39c9359f363cbde506ba5411e1bf3bf8da161f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 21 Oct 2015 11:53:38 -0700 Subject: [PATCH 04/10] don't force parenting of AssetRequest/AssetUpload --- libraries/networking/src/AssetClient.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/networking/src/AssetClient.cpp b/libraries/networking/src/AssetClient.cpp index b7f1205847..6a1b46340c 100644 --- a/libraries/networking/src/AssetClient.cpp +++ b/libraries/networking/src/AssetClient.cpp @@ -89,7 +89,6 @@ AssetRequest* AssetClient::createRequest(const QString& hash, const QString& ext // Move to the AssetClient thread in case we are not currently on that thread (which will usually be the case) request->moveToThread(thread()); - request->setParent(this); return request; } else { @@ -105,7 +104,6 @@ AssetUpload* AssetClient::createUpload(const QString& filename) { auto upload = new AssetUpload(filename); upload->moveToThread(thread()); - upload->setParent(this); return upload; } else { @@ -118,7 +116,6 @@ AssetUpload* AssetClient::createUpload(const QByteArray& data, const QString& ex auto upload = new AssetUpload(data, extension); upload->moveToThread(thread()); - upload->setParent(this); return upload; } else { From a9bad8de664f07501287a648d4005af6f3e77801 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 Oct 2015 11:12:02 -0700 Subject: [PATCH 05/10] add a script for ambient crowd noise --- examples/acScripts/baseballCrowd.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 examples/acScripts/baseballCrowd.js diff --git a/examples/acScripts/baseballCrowd.js b/examples/acScripts/baseballCrowd.js new file mode 100644 index 0000000000..5007c64b16 --- /dev/null +++ b/examples/acScripts/baseballCrowd.js @@ -0,0 +1,21 @@ +// +// baseballCrowd.js +// examples/acScripts +// +// Created by Stephen Birarda on 10/20/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var crowd1 = SoundCache.getSound("atp:0e921b644464d56d5b412ea2ea1d83f8ff3f7506c4b0471ea336a4770daf3b82.wav"); + +function maybePlaySound(deltaTime) { + if (crowd1.downloaded && !crowd1.isPlaying) { + Audio.playSound(crowd1, { position: { x: 0, y: 0, z: 0}, loop: true}); + Script.update.disconnect(maybePlaySound); + } +} + +Script.update.connect(maybePlaySound); From 695f0a75b0b0cd9bc9f0f4ff6ec6c9fb57f50ba7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 Oct 2015 11:12:51 -0700 Subject: [PATCH 06/10] fixes for builds with qt 5.5 --- libraries/render-utils/src/GlWindow.cpp | 6 ++-- libraries/ui/src/VrMenu.cpp | 40 +++++++++---------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/libraries/render-utils/src/GlWindow.cpp b/libraries/render-utils/src/GlWindow.cpp index 78ac046b59..248b9305e2 100644 --- a/libraries/render-utils/src/GlWindow.cpp +++ b/libraries/render-utils/src/GlWindow.cpp @@ -43,11 +43,9 @@ bool GlWindow::makeCurrent() { qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); }); - #ifndef QT_NO_DEBUG - QOpenGLContext * currentContext = - #endif - QOpenGLContext::currentContext(); + QOpenGLContext * currentContext = QOpenGLContext::currentContext(); Q_ASSERT(_context == currentContext); + return makeCurrentResult; } diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index a2cc7f0214..57df4d5306 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -108,13 +108,10 @@ void VrMenu::addMenu(QMenu* menu) { Q_ASSERT(false); } QVariant returnedValue; - #ifndef QT_NO_DEBUG - bool invokeResult = - #endif - QMetaObject::invokeMethod(this, "addMenu", Qt::DirectConnection, - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, QVariant::fromValue(qmlParent)), - Q_ARG(QVariant, QVariant::fromValue(menu->title()))); + bool invokeResult = QMetaObject::invokeMethod(this, "addMenu", Qt::DirectConnection, + Q_RETURN_ARG(QVariant, returnedValue), + Q_ARG(QVariant, QVariant::fromValue(qmlParent)), + Q_ARG(QVariant, QVariant::fromValue(menu->title()))); Q_ASSERT(invokeResult); QObject* result = returnedValue.value(); Q_ASSERT(result); @@ -150,13 +147,11 @@ void VrMenu::addAction(QMenu* menu, QAction* action) { QObject* menuQml = findMenuObject(userData->uuid.toString()); Q_ASSERT(menuQml); QVariant returnedValue; - #ifndef QT_NO_DEBUG - bool invokeResult = - #endif - QMetaObject::invokeMethod(this, "addItem", Qt::DirectConnection, - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, QVariant::fromValue(menuQml)), - Q_ARG(QVariant, QVariant::fromValue(action->text()))); + + bool invokeResult = QMetaObject::invokeMethod(this, "addItem", Qt::DirectConnection, + Q_RETURN_ARG(QVariant, returnedValue), + Q_ARG(QVariant, QVariant::fromValue(menuQml)), + Q_ARG(QVariant, QVariant::fromValue(action->text()))); Q_ASSERT(invokeResult); QObject* result = returnedValue.value(); Q_ASSERT(result); @@ -173,14 +168,11 @@ void VrMenu::insertAction(QAction* before, QAction* action) { } QObject* menu = beforeQml->parent(); QVariant returnedValue; - #ifndef QT_NO_DEBUG - bool invokeResult = - #endif - QMetaObject::invokeMethod(this, "insertItem", Qt::DirectConnection, - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, QVariant::fromValue(menu)), - Q_ARG(QVariant, QVariant::fromValue(beforeQml)), - Q_ARG(QVariant, QVariant::fromValue(action->text()))); + bool invokeResult = QMetaObject::invokeMethod(this, "insertItem", Qt::DirectConnection, + Q_RETURN_ARG(QVariant, returnedValue), + Q_ARG(QVariant, QVariant::fromValue(menu)), + Q_ARG(QVariant, QVariant::fromValue(beforeQml)), + Q_ARG(QVariant, QVariant::fromValue(action->text()))); Q_ASSERT(invokeResult); QObject* result = returnedValue.value(); Q_ASSERT(result); @@ -199,9 +191,5 @@ void VrMenu::removeAction(QAction* action) { bool invokeResult = QMetaObject::invokeMethod(this, "removeItem", Qt::DirectConnection, Q_ARG(QVariant, QVariant::fromValue(menu)), Q_ARG(QVariant, QVariant::fromValue(item))); -#ifndef QT_NO_DEBUG Q_ASSERT(invokeResult); -#else - Q_UNUSED(invokeResult); -#endif } From a44ac4cbfd13e54aa68bf101334a00f21f30dc45 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 22 Oct 2015 11:40:56 -0700 Subject: [PATCH 07/10] Fiing the dark colors for surfaces without texture --- libraries/render-utils/src/MeshPartPayload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 80327b7e54..30b72891dd 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -147,7 +147,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locatio batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); } } else { - batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getWhiteTexture()); } // Normal map From ea917f85f472332cc2ccc953cf1b10b17f36e09c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 22 Oct 2015 12:56:45 -0700 Subject: [PATCH 08/10] added ability to set keyhole radius on EntityViewer --- libraries/octree/src/OctreeHeadlessViewer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 605db15cd2..cebfa5a928 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -46,6 +46,7 @@ public slots: // setters for camera attributes void setPosition(const glm::vec3& position) { _viewFrustum.setPosition(position); } void setOrientation(const glm::quat& orientation) { _viewFrustum.setOrientation(orientation); } + void setKeyholeRadius(float keyholdRadius) { _viewFrustum.setKeyholeRadius(keyholdRadius); } // setters for LOD and PPS void setVoxelSizeScale(float sizeScale) { _voxelSizeScale = sizeScale; } From cfa47d2fc62d42c81568a2fddb08ef61d980605f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 Oct 2015 14:45:08 -0700 Subject: [PATCH 09/10] use triggers to swing with robot --- examples/toys/baseball.js | 59 +++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 15 deletions(-) mode change 100644 => 100755 examples/toys/baseball.js diff --git a/examples/toys/baseball.js b/examples/toys/baseball.js old mode 100644 new mode 100755 index 79a8a2fd61..5863708a86 --- a/examples/toys/baseball.js +++ b/examples/toys/baseball.js @@ -9,22 +9,51 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var BAT_MODEL = "atp:c47deaae09cca927f6bc9cca0e8bbe77fc618f8c3f2b49899406a63a59f885cb.fbx"; -var BAT_COLLISION_SHAPE = "atp:9eafceb7510c41d50661130090de7e0632aa4da236ebda84a0059a4be2130e0c.obj"; +var ROBOT_MODEL = "atp:ea02100c2ee63a8b9c0495557f32041be18ec94def157592e84a816665ce2f6e.fbx"; +var ROBOT_POSITION = { x: -0.54, y: 1.21, z: 2.57 } -function createNewBat() { - // move entity three units in front of the avatar - var batPosition = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: -0.3, z: -2 })); +var lastTriggerValue = 0.0; - var wand = Entities.addEntity({ - name: 'Bat', - type: "Model", - modelURL: BAT_MODEL, - position: batPosition, - collisionsWillMove: true, - compoundShapeURL: BAT_COLLISION_SHAPE - }); +function checkTriggers() { + var rightTrigger = Controller.getTriggerValue(1); + + if (rightTrigger == 0) { + if (lastTriggerValue > 0) { + // the trigger was just released, play out to the last frame of the swing + Entities.editEntity(robot, { + animation: { + running: true, + currentFrame: 21, + lastFrame: 115 + } + }); + } + } else { + if (lastTriggerValue == 0) { + // the trigger was just depressed, start the swing + Entities.editEntity(robot, { + animation: { + running: true, + currentFrame: 0, + lastFrame: 21 + } + }); + } + } + + lastTriggerValue = rightTrigger; } -createNewBat(); +// add the fresh bat at home plate +var robot = Entities.addEntity({ + name: 'Robot', + type: "Model", + modelURL: ROBOT_MODEL, + position: ROBOT_POSITION, + animation: { + url: ROBOT_MODEL + } +}); + +// hook the update so we can check controller triggers +Script.update.connect(checkTriggers); From 4f6da68a1fc8ccc08c4efdff48988cc49120c954 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 22 Oct 2015 16:25:28 -0700 Subject: [PATCH 10/10] add getJointPosition and getJointRotation for entities --- examples/toys/baseball.js | 57 ++++++++-- .../src/RenderableModelEntityItem.cpp | 25 ++++ .../src/RenderableModelEntityItem.h | 3 + .../entities/src/EntityScriptingInterface.cpp | 107 ++++++++---------- .../entities/src/EntityScriptingInterface.h | 6 + libraries/entities/src/ModelEntityItem.h | 3 + 6 files changed, 132 insertions(+), 69 deletions(-) diff --git a/examples/toys/baseball.js b/examples/toys/baseball.js index 5863708a86..f3f26a1f4b 100755 --- a/examples/toys/baseball.js +++ b/examples/toys/baseball.js @@ -12,6 +12,27 @@ var ROBOT_MODEL = "atp:ea02100c2ee63a8b9c0495557f32041be18ec94def157592e84a816665ce2f6e.fbx"; var ROBOT_POSITION = { x: -0.54, y: 1.21, z: 2.57 } +var BAT_MODEL = "atp:07bdd769a57ff15ebe9331ae4e2c2eae8886a6792b4790cce03b4716eb3a81c7.fbx" +var BAT_COLLISION_MODEL = "atp:1211ee12bc8ab0bb744e8582e15e728a00ca70a808550fc46d7284799b9a868a.obj" + +// add the fresh robot at home plate +var robot = Entities.addEntity({ + name: 'Robot', + type: 'Model', + modelURL: ROBOT_MODEL, + position: ROBOT_POSITION, + animation: { + url: ROBOT_MODEL + } +}); + +// add the bat +var bat = Entities.addEntity({ + name: 'Bat', + type: 'Model', + modelURL: BAT_MODEL +}) + var lastTriggerValue = 0.0; function checkTriggers() { @@ -35,7 +56,7 @@ function checkTriggers() { animation: { running: true, currentFrame: 0, - lastFrame: 21 + lastFrame: 21 } }); } @@ -44,16 +65,28 @@ function checkTriggers() { lastTriggerValue = rightTrigger; } -// add the fresh bat at home plate -var robot = Entities.addEntity({ - name: 'Robot', - type: "Model", - modelURL: ROBOT_MODEL, - position: ROBOT_POSITION, - animation: { - url: ROBOT_MODEL - } -}); +var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position +var ACTION_LIFETIME = 15; // seconds + +function moveBat() { + var forearmPosition = Entities.getJointPosition(robot, 40); + var forearmRotation = Entities.getJointRotation(robot, 40); + + Vec3.print("forearmPosition=", forearmPosition); + + Entities.addAction("spring", bat, { + targetPosition: forearmPosition, + targetRotation: forearmRotation, + tag: "bat-to-forearm", + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + lifetime: ACTION_LIFETIME + }); +} + +function update() { + checkTriggers(); +} // hook the update so we can check controller triggers -Script.update.connect(checkTriggers); +Script.update.connect(update); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e604bdb925..a7c2ff09f4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -575,3 +575,28 @@ bool RenderableModelEntityItem::contains(const glm::vec3& point) const { return false; } + +glm::vec3 RenderableModelEntityItem::getJointPosition(int jointIndex) const { + glm::vec3 position; + + if (_model) { + if (!_model->getJointPositionInWorldFrame(jointIndex, position)) { + position = glm::vec3(); + } + } + + return position; +} + +glm::quat RenderableModelEntityItem::getJointRotation(int jointIndex) const { + glm::quat rotation; + + if (_model) { + if (!_model->getJointRotationInWorldFrame(jointIndex, rotation)) { + rotation = glm::quat(); + } + } + + return rotation; +} + diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 4dc1cced48..64629ad291 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -67,6 +67,9 @@ public: void computeShapeInfo(ShapeInfo& info); virtual bool contains(const glm::vec3& point) const; + + virtual glm::vec3 getJointPosition(int jointIndex) const override; + virtual glm::quat getJointRotation(int jointIndex) const override; private: void remapTextures(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 01d46e0a91..f18e216bb3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -681,82 +681,75 @@ QVariantMap EntityScriptingInterface::getActionArguments(const QUuid& entityID, return result; } -glm::vec3 EntityScriptingInterface::voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords) { +EntityItemPointer EntityScriptingInterface::checkForTreeEntityAndTypeMatch(const QUuid& entityID, + EntityTypes::EntityType entityType) { if (!_entityTree) { - return glm::vec3(0.0f); + return EntityItemPointer(); } - + EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); if (!entity) { - qCDebug(entities) << "EntityScriptingInterface::voxelCoordsToWorldCoords no entity with ID" << entityID; + qDebug() << "EntityScriptingInterface::checkForTreeEntityAndTypeMatch - no entity with ID" << entityID; + return entity; + } + + if (entityType != EntityTypes::Unknown && entity->getType() != entityType) { + return EntityItemPointer(); + } + + return entity; +} + +glm::vec3 EntityScriptingInterface::voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::PolyVox)) { + auto polyVoxEntity = std::dynamic_pointer_cast(entity); + return polyVoxEntity->voxelCoordsToWorldCoords(voxelCoords); + } else { return glm::vec3(0.0f); } - - EntityTypes::EntityType entityType = entity->getType(); - if (entityType != EntityTypes::PolyVox) { - return glm::vec3(0.0f); - } - - auto polyVoxEntity = std::dynamic_pointer_cast(entity); - return polyVoxEntity->voxelCoordsToWorldCoords(voxelCoords); } glm::vec3 EntityScriptingInterface::worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords) { - if (!_entityTree) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::PolyVox)) { + auto polyVoxEntity = std::dynamic_pointer_cast(entity); + return polyVoxEntity->worldCoordsToVoxelCoords(worldCoords); + } else { return glm::vec3(0.0f); } - - EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); - if (!entity) { - qCDebug(entities) << "EntityScriptingInterface::worldCoordsToVoxelCoords no entity with ID" << entityID; - return glm::vec3(0.0f); - } - - EntityTypes::EntityType entityType = entity->getType(); - if (entityType != EntityTypes::PolyVox) { - return glm::vec3(0.0f); - } - - auto polyVoxEntity = std::dynamic_pointer_cast(entity); - return polyVoxEntity->worldCoordsToVoxelCoords(worldCoords); } glm::vec3 EntityScriptingInterface::voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords) { - if (!_entityTree) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::PolyVox)) { + auto polyVoxEntity = std::dynamic_pointer_cast(entity); + return polyVoxEntity->voxelCoordsToLocalCoords(voxelCoords); + } else { return glm::vec3(0.0f); } - - EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); - if (!entity) { - qCDebug(entities) << "EntityScriptingInterface::voxelCoordsToLocalCoords no entity with ID" << entityID; - return glm::vec3(0.0f); - } - - EntityTypes::EntityType entityType = entity->getType(); - if (entityType != EntityTypes::PolyVox) { - return glm::vec3(0.0f); - } - - auto polyVoxEntity = std::dynamic_pointer_cast(entity); - return polyVoxEntity->voxelCoordsToLocalCoords(voxelCoords); } glm::vec3 EntityScriptingInterface::localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords) { - if (!_entityTree) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::PolyVox)) { + auto polyVoxEntity = std::dynamic_pointer_cast(entity); + return polyVoxEntity->localCoordsToVoxelCoords(localCoords); + } else { return glm::vec3(0.0f); } - - EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID); - if (!entity) { - qCDebug(entities) << "EntityScriptingInterface::localCoordsToVoxelCoords no entity with ID" << entityID; - return glm::vec3(0.0f); - } - - EntityTypes::EntityType entityType = entity->getType(); - if (entityType != EntityTypes::PolyVox) { - return glm::vec3(0.0f); - } - - auto polyVoxEntity = std::dynamic_pointer_cast(entity); - return polyVoxEntity->localCoordsToVoxelCoords(localCoords); +} + +glm::vec3 EntityScriptingInterface::getJointPosition(const QUuid& entityID, int jointIndex) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto modelEntity = std::dynamic_pointer_cast(entity); + return modelEntity->getJointPosition(jointIndex); + } else { + return glm::vec3(0.0f); + } +} + +glm::quat EntityScriptingInterface::getJointRotation(const QUuid& entityID, int jointIndex) { + if (auto entity = checkForTreeEntityAndTypeMatch(entityID, EntityTypes::Model)) { + auto modelEntity = std::dynamic_pointer_cast(entity); + return modelEntity->getJointRotation(jointIndex); + } else { + return glm::quat(); + } } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index d764cd7bab..4578c2d7ff 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -150,6 +150,9 @@ public slots: Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords); Q_INVOKABLE glm::vec3 voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords); Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); + + Q_INVOKABLE glm::vec3 getJointPosition(const QUuid& entityID, int jointIndex); + Q_INVOKABLE glm::quat getJointRotation(const QUuid& entityID, int jointIndex); signals: void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); @@ -182,6 +185,9 @@ private: bool setVoxels(QUuid entityID, std::function actor); bool setPoints(QUuid entityID, std::function actor); void queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties); + + EntityItemPointer checkForTreeEntityAndTypeMatch(const QUuid& entityID, + EntityTypes::EntityType entityType = EntityTypes::Unknown); /// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index e8ffcab3e7..66d46bcf4c 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -120,6 +120,9 @@ public: virtual bool shouldBePhysical() const; static void cleanupLoadedAnimations(); + + virtual glm::vec3 getJointPosition(int jointIndex) const { return glm::vec3(); } + virtual glm::quat getJointRotation(int jointIndex) const { return glm::quat(); } private: void setAnimationSettings(const QString& value); // only called for old bitstream format