From c64b934d335d1ed5c6b4488ca47f193bcdddf8e4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 7 Feb 2014 11:23:04 -0800 Subject: [PATCH 1/9] first cut at ray cast scripting --- libraries/shared/src/RegisteredMetaTypes.cpp | 1 - libraries/shared/src/RegisteredMetaTypes.h | 1 - libraries/voxels/src/VoxelDetail.cpp | 67 +++++++++++++++++++ libraries/voxels/src/VoxelDetail.h | 14 ++++ .../voxels/src/VoxelsScriptingInterface.cpp | 5 ++ .../voxels/src/VoxelsScriptingInterface.h | 10 ++- 6 files changed, 95 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 4bfb2a2de1..0358f169b8 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -81,7 +81,6 @@ QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) QScriptValue direction = vec3toScriptValue(engine, pickRay.direction); obj.setProperty("direction", direction); return obj; - } void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) { diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 91eb3848c7..130a48cdeb 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -46,5 +46,4 @@ Q_DECLARE_METATYPE(PickRay) QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay); void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); - #endif diff --git a/libraries/voxels/src/VoxelDetail.cpp b/libraries/voxels/src/VoxelDetail.cpp index d4ab5cafcb..8d9f7df0c5 100644 --- a/libraries/voxels/src/VoxelDetail.cpp +++ b/libraries/voxels/src/VoxelDetail.cpp @@ -9,6 +9,7 @@ void registerVoxelMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, voxelDetailToScriptValue, voxelDetailFromScriptValue); + qScriptRegisterMetaType(engine, rayToVoxelIntersectionResultToScriptValue, rayToVoxelIntersectionResultFromScriptValue); } QScriptValue voxelDetailToScriptValue(QScriptEngine* engine, const VoxelDetail& voxelDetail) { @@ -33,5 +34,71 @@ void voxelDetailFromScriptValue(const QScriptValue &object, VoxelDetail& voxelDe voxelDetail.blue = object.property("blue").toVariant().toInt(); } +RayToVoxelIntersectionResult::RayToVoxelIntersectionResult() : + intersects(false), + voxel(), + distance(0), + face() +{ +}; + +QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& value) { + QScriptValue obj = engine->newObject(); + obj.setProperty("intersects", value.intersects); + QScriptValue voxelValue = voxelDetailToScriptValue(engine, value.voxel); + obj.setProperty("voxel", voxelValue); + obj.setProperty("distance", value.distance); + + QString faceName = ""; + // handle BoxFace + switch (value.face) { + case MIN_X_FACE: + faceName = "MIN_X_FACE"; + break; + case MAX_X_FACE: + faceName = "MAX_X_FACE"; + break; + case MIN_Y_FACE: + faceName = "MIN_Y_FACE"; + break; + case MAX_Y_FACE: + faceName = "MAX_Y_FACE"; + break; + case MIN_Z_FACE: + faceName = "MIN_Z_FACE"; + break; + case MAX_Z_FACE: + faceName = "MAX_Z_FACE"; + break; + } + obj.setProperty("face", faceName); + return obj; +} + +void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& value) { + value.intersects = object.property("intersects").toVariant().toBool(); + QScriptValue voxelValue = object.property("voxel"); + if (voxelValue.isValid()) { + voxelDetailFromScriptValue(voxelValue, value.voxel); + } + value.distance = object.property("distance").toVariant().toFloat(); + + QString faceName = object.property("face").toVariant().toString(); + if (faceName == "MIN_X_FACE") { + value.face = MIN_X_FACE; + } else if (faceName == "MAX_X_FACE") { + value.face = MAX_X_FACE; + } else if (faceName == "MIN_Y_FACE") { + value.face = MIN_Y_FACE; + } else if (faceName == "MAX_Y_FACE") { + value.face = MAX_Y_FACE; + } else if (faceName == "MIN_Z_FACE") { + value.face = MIN_Z_FACE; + } else { + value.face = MAX_Z_FACE; + }; +} + + diff --git a/libraries/voxels/src/VoxelDetail.h b/libraries/voxels/src/VoxelDetail.h index ca1ff3940b..9da2e40776 100644 --- a/libraries/voxels/src/VoxelDetail.h +++ b/libraries/voxels/src/VoxelDetail.h @@ -12,6 +12,7 @@ #include +#include #include #include "VoxelConstants.h" @@ -32,5 +33,18 @@ void registerVoxelMetaTypes(QScriptEngine* engine); QScriptValue voxelDetailToScriptValue(QScriptEngine* engine, const VoxelDetail& color); void voxelDetailFromScriptValue(const QScriptValue &object, VoxelDetail& color); +class RayToVoxelIntersectionResult { +public: + RayToVoxelIntersectionResult(); + bool intersects; + VoxelDetail voxel; + float distance; + BoxFace face; +}; + +Q_DECLARE_METATYPE(RayToVoxelIntersectionResult) + +QScriptValue rayToVoxelIntersectionResultToScriptValue(QScriptEngine* engine, const RayToVoxelIntersectionResult& results); +void rayToVoxelIntersectionResultFromScriptValue(const QScriptValue& object, RayToVoxelIntersectionResult& results); #endif /* defined(__hifi__VoxelDetail__) */ \ No newline at end of file diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index d82912c44b..34c91c8f60 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -41,3 +41,8 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail); } + +RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) { + RayToVoxelIntersectionResult result; + return result; +} diff --git a/libraries/voxels/src/VoxelsScriptingInterface.h b/libraries/voxels/src/VoxelsScriptingInterface.h index 877383e0b0..f87e8d0a4c 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.h +++ b/libraries/voxels/src/VoxelsScriptingInterface.h @@ -12,18 +12,22 @@ #include #include +#include #include "VoxelConstants.h" #include "VoxelEditPacketSender.h" +#include "VoxelTree.h" /// handles scripting of voxel commands from JS passed to assigned clients class VoxelsScriptingInterface : public OctreeScriptingInterface { Q_OBJECT -public: +public: + VoxelsScriptingInterface() : _tree(NULL) {}; VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); } virtual NodeType_t getServerNodeType() const { return NodeType::VoxelServer; } virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); } + void setVoxelTree(VoxelTree* tree) { _tree = tree; } public slots: /// queues the creation of a voxel which will be sent by calling process on the PacketSender @@ -53,8 +57,12 @@ public slots: /// \param scale the scale of the voxel (in meter units) void eraseVoxel(float x, float y, float z, float scale); + /// If the scripting context has visible voxels, this will determine a ray intersection + RayToVoxelIntersectionResult findRayIntersection(const PickRay& ray); + private: void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails); + VoxelTree* _tree; }; #endif /* defined(__hifi__VoxelsScriptingInterface__) */ From 70a4ff1e751139cb8e2bcade6fd09d97cc1b1d65 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 7 Feb 2014 14:54:50 -0800 Subject: [PATCH 2/9] fix cmake qt issue --- animation-server/CMakeLists.txt | 4 +++- voxel-edit/CMakeLists.txt | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index 5a696afc10..ba3e4e22e6 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -13,9 +13,11 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR}) include(${MACRO_DIR}/SetupHifiProject.cmake) - setup_hifi_project(${TARGET_NAME} TRUE) +find_package(Qt5Script REQUIRED) +qt5_use_modules(${TARGET_NAME} Script) + # link in the shared library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index 38e1dd6efc..e0aa0750d2 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -13,9 +13,11 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR}) include(${MACRO_DIR}/SetupHifiProject.cmake) - setup_hifi_project(${TARGET_NAME} TRUE) +find_package(Qt5Script REQUIRED) +qt5_use_modules(${TARGET_NAME} Script) + # link in the shared library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) From 802f72c732a131c7ae1f4a2376209d22b8ee4247 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 7 Feb 2014 15:06:32 -0800 Subject: [PATCH 3/9] more ray picking and intersection work --- interface/src/Application.cpp | 1 + .../voxels/src/VoxelsScriptingInterface.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 39e1868dd0..13e09eedf3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4101,6 +4101,7 @@ void Application::loadScript(const QString& fileNameString) { // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // we can use the same ones from the application. scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender); + scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree()); scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender); scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree()); diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index 34c91c8f60..af5f8ce3c2 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -44,5 +44,22 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale RayToVoxelIntersectionResult VoxelsScriptingInterface::findRayIntersection(const PickRay& ray) { RayToVoxelIntersectionResult result; + if (_tree) { + if (_tree->tryLockForRead()) { + OctreeElement* element; + result.intersects = _tree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face); + if (result.intersects) { + VoxelTreeElement* voxel = (VoxelTreeElement*)element; + result.voxel.x = voxel->getCorner().x; + result.voxel.y = voxel->getCorner().y; + result.voxel.z = voxel->getCorner().z; + result.voxel.s = voxel->getScale(); + result.voxel.red = voxel->getColor()[0]; + result.voxel.green = voxel->getColor()[1]; + result.voxel.blue = voxel->getColor()[2]; + } + _tree->unlock(); + } + } return result; } From ac05c6d4c322a64d229a0d0c4290f035873311d0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 7 Feb 2014 15:21:16 -0800 Subject: [PATCH 4/9] add example code --- examples/rayPickExample.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 examples/rayPickExample.js diff --git a/examples/rayPickExample.js b/examples/rayPickExample.js new file mode 100644 index 0000000000..1c79d7cd6a --- /dev/null +++ b/examples/rayPickExample.js @@ -0,0 +1,31 @@ +// +// rayPickExample.js +// hifi +// +// Created by Brad Hefta-Gaub on 2/6/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that demonstrates use of the Camera class +// +// + +function mouseMoveEvent(event) { + print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y); + var pickRay = Camera.computePickRay(event.x, event.y); + print("called Camera.computePickRay()"); + print("computePickRay origin=" + pickRay.origin.x + ", " + pickRay.origin.y + ", " + pickRay.origin.z); + print("computePickRay direction=" + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z); + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Voxels.findRayIntersection(pickRay); + if (intersection.intersects) { + print("intersection voxel.red/green/blue=" + intersection.voxel.red + ", " + + intersection.voxel.green + ", " + intersection.voxel.blue); + } +} + +Controller.mouseMoveEvent.connect(mouseMoveEvent); + +function scriptEnding() { +} +Script.scriptEnding.connect(scriptEnding); + From e9070b1d70f43eed9ae924f6470a4c9b769be59f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 7 Feb 2014 15:48:46 -0800 Subject: [PATCH 5/9] add an example of adding a voxel when clicking on a voxel --- examples/addVoxelOnMouseClickExample.js | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 examples/addVoxelOnMouseClickExample.js diff --git a/examples/addVoxelOnMouseClickExample.js b/examples/addVoxelOnMouseClickExample.js new file mode 100644 index 0000000000..244a017ae4 --- /dev/null +++ b/examples/addVoxelOnMouseClickExample.js @@ -0,0 +1,62 @@ +// +// addVoxelOnMouseClickExample.js +// hifi +// +// Created by Brad Hefta-Gaub on 2/6/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that demonstrates use of the Camera and Voxels class to implement +// clicking on a voxel and adding a new voxel on the clicked on face +// +// + +function mousePressEvent(event) { + print("mousePressEvent event.x,y=" + event.x + ", " + event.y); + var pickRay = Camera.computePickRay(event.x, event.y); + var intersection = Voxels.findRayIntersection(pickRay); + if (intersection.intersects) { + + // Note: due to the current C++ "click on voxel" behavior, these values may be the animated color for the voxel + print("clicked on voxel.red/green/blue=" + intersection.voxel.red + ", " + + intersection.voxel.green + ", " + intersection.voxel.blue); + print("clicked on voxel.x/y/z/s=" + intersection.voxel.x + ", " + + intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s); + print("clicked on face=" + intersection.face); + print("clicked on distance=" + intersection.distance); + + var newVoxel = { + x: intersection.voxel.x, + y: intersection.voxel.y, + z: intersection.voxel.z, + s: intersection.voxel.s, + red: 255, + green: 0, + blue: 255 }; + + if (intersection.face == "MIN_X_FACE") { + newVoxel.x -= newVoxel.s; + } else if (intersection.face == "MAX_X_FACE") { + newVoxel.x += newVoxel.s; + } else if (intersection.face == "MIN_Y_FACE") { + newVoxel.y -= newVoxel.s; + } else if (intersection.face == "MAX_Y_FACE") { + newVoxel.y += newVoxel.s; + } else if (intersection.face == "MIN_Z_FACE") { + newVoxel.z -= newVoxel.s; + } else if (intersection.face == "MAX_Z_FACE") { + newVoxel.z += newVoxel.s; + } + + print("Voxels.setVoxel("+newVoxel.x + ", " + + newVoxel.y + ", " + newVoxel.z + ", " + newVoxel.s + ", " + + newVoxel.red + ", " + newVoxel.green + ", " + newVoxel.blue + ")" ); + + Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue); + } +} + +Controller.mousePressEvent.connect(mousePressEvent); + +function scriptEnding() { +} +Script.scriptEnding.connect(scriptEnding); From c0858cdaefb64eb98810908737fdb4ee31e5bb04 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 8 Feb 2014 10:53:33 -0800 Subject: [PATCH 6/9] remove animation server from unix to see if that addresses build buster, temporary solution --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a583d7d951..5baee3d42d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,9 +28,13 @@ IF (APPLE) ENDIF (DARWIN_VERSION GREATER 12) ENDIF(APPLE) +# targets only supported on mac +IF (APPLE) +add_subdirectory(animation-server) +ENDIF(APPLE) + # targets not supported on windows if (NOT WIN32) -add_subdirectory(animation-server) add_subdirectory(data-server) endif (NOT WIN32) From 56c383891c17080493e79647b942a7486f36f767 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 8 Feb 2014 11:44:48 -0800 Subject: [PATCH 7/9] revert animation-servers cmake --- animation-server/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/animation-server/CMakeLists.txt b/animation-server/CMakeLists.txt index ba3e4e22e6..77969e06e5 100644 --- a/animation-server/CMakeLists.txt +++ b/animation-server/CMakeLists.txt @@ -15,9 +15,6 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME} TRUE) -find_package(Qt5Script REQUIRED) -qt5_use_modules(${TARGET_NAME} Script) - # link in the shared library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) From c9fd4b5e6b0c44df475652dc94657fd045b051ac Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 8 Feb 2014 11:45:20 -0800 Subject: [PATCH 8/9] add back animation-server in cmake unix --- CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5baee3d42d..a583d7d951 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,13 +28,9 @@ IF (APPLE) ENDIF (DARWIN_VERSION GREATER 12) ENDIF(APPLE) -# targets only supported on mac -IF (APPLE) -add_subdirectory(animation-server) -ENDIF(APPLE) - # targets not supported on windows if (NOT WIN32) +add_subdirectory(animation-server) add_subdirectory(data-server) endif (NOT WIN32) From 07585dbe5b6c427a3269ba7482a9f9911a12424b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 8 Feb 2014 12:07:24 -0800 Subject: [PATCH 9/9] add scripts to voxels --- libraries/voxels/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index da97e83ec9..8a3b0d7325 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -9,11 +9,12 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cm set(TARGET_NAME voxels) find_package(Qt5Widgets REQUIRED) +find_package(Qt5Script REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Widgets) +qt5_use_modules(${TARGET_NAME} Widgets Script) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR})