From 028b816e5bf4b3ed6c190bcd6b27a23735cd5708 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 3 Mar 2014 22:17:55 -0800 Subject: [PATCH 01/17] smaller damage --- examples/gun.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gun.js b/examples/gun.js index 17587e3810..b50a8f64d8 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -57,12 +57,12 @@ function shootBullet(position, velocity) { damping: 0 }); // Play firing sounds - audioOptions.position = position; + audioOptions.position = position; Audio.playSound(fireSound, audioOptions); } function particleCollisionWithVoxel(particle, voxel) { - var HOLE_SIZE = 0.25; + var HOLE_SIZE = 0.125; var particleProperties = Particles.getParticleProperties(particle); var position = particleProperties.position; Particles.deleteParticle(particle); From 231dc624ff23e9f75d7c227795fabd8e8698bde4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Mar 2014 12:41:24 -0800 Subject: [PATCH 02/17] replace deprecated qt5 macros in cmake with target_link_libraries --- assignment-client/CMakeLists.txt | 8 +++----- domain-server/CMakeLists.txt | 6 +++--- interface/CMakeLists.txt | 14 +++----------- libraries/avatars/CMakeLists.txt | 4 ++-- libraries/embedded-webserver/CMakeLists.txt | 2 +- libraries/metavoxels/CMakeLists.txt | 7 +++---- libraries/octree/CMakeLists.txt | 5 ++--- libraries/particles/CMakeLists.txt | 5 ++--- libraries/script-engine/CMakeLists.txt | 5 ++--- libraries/shared/CMakeLists.txt | 7 +++---- libraries/voxels/CMakeLists.txt | 8 +++----- svo-viewer/CMakeLists.txt | 16 ++++------------ tests/metavoxels/CMakeLists.txt | 8 +++----- voxel-edit/CMakeLists.txt | 7 ++++--- 14 files changed, 38 insertions(+), 64 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 2df3cb1ab9..fe035e3c51 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -8,15 +8,11 @@ set(MACRO_DIR "${ROOT_DIR}/cmake/macros") # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -find_package(Qt5Network REQUIRED) -find_package(Qt5Script REQUIRED) -find_package(Qt5Widgets REQUIRED) +find_package(Qt5 COMPONENTS Network Script Widgets) include("${MACRO_DIR}/SetupHifiProject.cmake") setup_hifi_project(${TARGET_NAME} TRUE) -qt5_use_modules(${TARGET_NAME} Network Script Widgets) - # include glm include("${MACRO_DIR}/IncludeGLM.cmake") include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -40,3 +36,5 @@ endif (UNIX) IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) + +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index a4624dbbf7..eeaa4dc150 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -18,8 +18,6 @@ include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME} TRUE) -qt5_use_modules(${TARGET_NAME} Network) - # remove and then copy the files for the webserver add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E remove_directory @@ -36,4 +34,6 @@ link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) -ENDIF(WIN32) \ No newline at end of file +ENDIF(WIN32) + +target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 646ad3c167..b1268e331e 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -75,15 +75,7 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}") endforeach(EXTERNAL_SOURCE_SUBDIR) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Multimedia REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5OpenGL REQUIRED) -find_package(Qt5Svg REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) -find_package(Qt5Xml REQUIRED) +find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -180,8 +172,6 @@ if (LIBOVR_FOUND AND NOT DISABLE_LIBOVR) target_link_libraries(${TARGET_NAME} "${LIBOVR_LIBRARIES}") endif (LIBOVR_FOUND AND NOT DISABLE_LIBOVR) -qt5_use_modules(${TARGET_NAME} Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) - # include headers for interface and InterfaceConfig. include_directories( "${PROJECT_SOURCE_DIR}/src" @@ -200,6 +190,8 @@ target_link_libraries( ${TARGET_NAME} "${FACESHIFT_LIBRARIES}" "${ZLIB_LIBRARIES}" + Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL + Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools ) if (APPLE) diff --git a/libraries/avatars/CMakeLists.txt b/libraries/avatars/CMakeLists.txt index bcafb32dc6..316f1dca58 100644 --- a/libraries/avatars/CMakeLists.txt +++ b/libraries/avatars/CMakeLists.txt @@ -13,8 +13,6 @@ find_package(Qt5Script REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Script) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -24,3 +22,5 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") # link in the hifi voxels library link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") + +target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file diff --git a/libraries/embedded-webserver/CMakeLists.txt b/libraries/embedded-webserver/CMakeLists.txt index 1ab454bf0a..06dd2d750d 100644 --- a/libraries/embedded-webserver/CMakeLists.txt +++ b/libraries/embedded-webserver/CMakeLists.txt @@ -13,4 +13,4 @@ find_package(Qt5Network REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Network) \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network) \ No newline at end of file diff --git a/libraries/metavoxels/CMakeLists.txt b/libraries/metavoxels/CMakeLists.txt index 617609f1fa..bab03058a0 100644 --- a/libraries/metavoxels/CMakeLists.txt +++ b/libraries/metavoxels/CMakeLists.txt @@ -8,8 +8,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cm set(TARGET_NAME metavoxels) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) +find_package(Qt5 COMPONENTS Network Script Widgets) include(${MACRO_DIR}/AutoMTC.cmake) auto_mtc(${TARGET_NAME} "${ROOT_DIR}") @@ -17,8 +16,8 @@ auto_mtc(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME} "${AUTOMTC_SRC}") -qt5_use_modules(${TARGET_NAME} Network Script Widgets) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) + diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index ac59ca454e..8b8f37bae7 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -13,8 +13,6 @@ find_package(Qt5Widgets REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Widgets) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -24,4 +22,5 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) include_directories("${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index f7d0088c1b..f83e76cf61 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -13,8 +13,6 @@ find_package(Qt5Widgets REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Widgets) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -25,4 +23,5 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) include_directories("${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Particles) diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index d2a838e543..d91814bcec 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -13,8 +13,6 @@ find_package(Qt5Widgets REQUIRED) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Widgets) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -27,4 +25,5 @@ link_hifi_library(particles ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) include_directories("${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) diff --git a/libraries/shared/CMakeLists.txt b/libraries/shared/CMakeLists.txt index 1f23dca926..021d8b33bf 100644 --- a/libraries/shared/CMakeLists.txt +++ b/libraries/shared/CMakeLists.txt @@ -6,14 +6,11 @@ set(MACRO_DIR "${ROOT_DIR}/cmake/macros") set(TARGET_NAME shared) project(${TARGET_NAME}) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) +find_package(Qt5 COMPONENTS Network Widgets) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Network Widgets) - # include GLM include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -31,3 +28,5 @@ if (UNIX AND NOT APPLE) find_package(Threads REQUIRED) target_link_libraries(${TARGET_NAME} "${CMAKE_THREAD_LIBS_INIT}") endif (UNIX AND NOT APPLE) + +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets) \ No newline at end of file diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index 279168ded8..515c6b6f94 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -8,14 +8,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cm set(TARGET_NAME voxels) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Script REQUIRED) +find_package(Qt5 COMPONENTS Widgets Script) include(${MACRO_DIR}/SetupHifiLibrary.cmake) setup_hifi_library(${TARGET_NAME}) -qt5_use_modules(${TARGET_NAME} Widgets Script) - include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -26,4 +23,5 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") # link ZLIB find_package(ZLIB) include_directories("${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") + +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets Qt5::Script) diff --git a/svo-viewer/CMakeLists.txt b/svo-viewer/CMakeLists.txt index c76cc4209b..8eceb0ea43 100644 --- a/svo-viewer/CMakeLists.txt +++ b/svo-viewer/CMakeLists.txt @@ -61,15 +61,7 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) set(APPLICATION_SRCS ${APPLICATION_SRCS} "${SUBDIR_SRCS}") endforeach(EXTERNAL_SOURCE_SUBDIR) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Multimedia REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5OpenGL REQUIRED) -find_package(Qt5Svg REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) -find_package(Qt5Xml REQUIRED) +find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -122,8 +114,6 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") find_package(GLM REQUIRED) find_package(ZLIB) -qt5_use_modules(${TARGET_NAME} Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) - # include headers for interface include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes") @@ -131,7 +121,9 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # use system flag so warnings are supressed include_directories(SYSTEM "${GLM_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" + Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL + Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools) if (APPLE) # link in required OS X frameworks and include the right GL headers diff --git a/tests/metavoxels/CMakeLists.txt b/tests/metavoxels/CMakeLists.txt index 39730ab015..4654d8c353 100644 --- a/tests/metavoxels/CMakeLists.txt +++ b/tests/metavoxels/CMakeLists.txt @@ -8,9 +8,7 @@ set(MACRO_DIR "${ROOT_DIR}/cmake/macros") # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/") -find_package(Qt5Network REQUIRED) -find_package(Qt5Script REQUIRED) -find_package(Qt5Widgets REQUIRED) +find_package(Qt5 COMPONENTS Network Script Widgets) include(${MACRO_DIR}/AutoMTC.cmake) auto_mtc(${TARGET_NAME} "${ROOT_DIR}") @@ -18,8 +16,6 @@ auto_mtc(${TARGET_NAME} "${ROOT_DIR}") include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME} TRUE "${AUTOMTC_SRC}") -qt5_use_modules(${TARGET_NAME} Network Script Widgets) - #include glm include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") @@ -33,3 +29,5 @@ IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) + diff --git a/voxel-edit/CMakeLists.txt b/voxel-edit/CMakeLists.txt index d394cea518..126775b152 100644 --- a/voxel-edit/CMakeLists.txt +++ b/voxel-edit/CMakeLists.txt @@ -12,12 +12,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") +find_package(Qt5Script REQUIRED) + 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}") @@ -31,3 +30,5 @@ link_hifi_library(voxels ${TARGET_NAME} "${ROOT_DIR}") IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) + +target_link_libraries(${TARGET_NAME} Qt5::Script) \ No newline at end of file From a48185053ee611d204caeafab506c34e86aeafc7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 4 Mar 2014 12:42:08 -0800 Subject: [PATCH 03/17] repair a typo in particles link to widgets lib --- libraries/particles/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/particles/CMakeLists.txt b/libraries/particles/CMakeLists.txt index f83e76cf61..8f475647bd 100644 --- a/libraries/particles/CMakeLists.txt +++ b/libraries/particles/CMakeLists.txt @@ -24,4 +24,4 @@ link_hifi_library(octree ${TARGET_NAME} "${ROOT_DIR}") find_package(ZLIB) include_directories("${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Particles) +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}" Qt5::Widgets) From 1357aee01ed87b6bec905dcac767af4ee62c44a4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 4 Mar 2014 13:03:31 -0800 Subject: [PATCH 04/17] Use mipmaps and trilinear filtering for models. Closes #2180. --- interface/src/renderer/TextureCache.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index d5d3b42155..1c58f93510 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -113,7 +113,8 @@ GLuint TextureCache::getFileTextureID(const QString& filename) { glBindTexture(GL_TEXTURE_2D, id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); _fileTextureIDs.insert(filename, id); @@ -335,7 +336,8 @@ void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor glBindTexture(GL_TEXTURE_2D, getID()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } @@ -388,7 +390,8 @@ QSharedPointer DilatableNetworkTexture::getDilatedTexture(float dilatio glBindTexture(GL_TEXTURE_2D, texture->getID()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1, GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } From 3c99cf162d0e70bf29ebd299015ef4370921716c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 4 Mar 2014 13:17:19 -0800 Subject: [PATCH 05/17] Fix was at the wrong spot --- interface/src/Application.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 75c1d9afd6..741ec5381a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -398,17 +398,17 @@ void Application::initializeGL() { // initialize glut for shape drawing; Qt apparently initializes it on OS X #ifndef __APPLE__ - int argc = 0; - glutInit(&argc, 0); - #endif - - #ifdef WIN32 static bool isInitialized = false; if (isInitialized) { return; } else { isInitialized = true; } + int argc = 0; + glutInit(&argc, 0); + #endif + + #ifdef WIN32 GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ From 374af9eeb51db5d17e0561c18e8f004eb04c5681 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Mar 2014 14:40:49 -0800 Subject: [PATCH 06/17] first cut at flocking birds, change willEmitVisualCallback to update --- assignment-client/src/Agent.h | 5 +---- examples/audioBall.js | 4 ++-- examples/bot.js | 4 ++-- examples/cameraExample.js | 5 ++--- examples/clap.js | 4 ++-- examples/collidingParticles.js | 4 ++-- examples/controllerExample.js | 4 ++-- examples/count.js | 6 +++--- examples/drumStick.js | 4 ++-- examples/editParticleExample.js | 4 ++-- examples/editVoxels.js | 4 ++-- examples/findParticleExample.js | 4 ++-- examples/fountain.js | 4 ++-- examples/gameoflife.js | 4 ++-- examples/gun.js | 4 ++-- examples/hydraMove.js | 9 ++++----- examples/lookAtExample.js | 4 ++-- examples/lookWithMouse.js | 4 ++-- examples/lookWithTouch.js | 4 ++-- examples/movingVoxel.js | 4 ++-- examples/multitouchExample.js | 4 ++-- examples/overlaysExample.js | 4 ++-- examples/paintGun.js | 4 ++-- examples/particleBird.js | 4 ++-- examples/particleModelExample.js | 4 ++-- examples/playSound.js | 4 ++-- examples/ribbon.js | 4 ++-- examples/rideAlongWithAParticleExample.js | 4 ++-- examples/seeingVoxelsExample.js | 4 ++-- examples/spaceInvadersExample.js | 4 ++-- examples/toyball.js | 4 ++-- examples/voxelBird.js | 4 ++-- examples/voxelDrumming.js | 11 ++++------- libraries/script-engine/src/Quat.cpp | 6 ++++++ libraries/script-engine/src/Quat.h | 5 ++++- libraries/script-engine/src/ScriptEngine.cpp | 7 ++++++- libraries/script-engine/src/ScriptEngine.h | 3 +-- libraries/script-engine/src/Vec3.cpp | 15 +++++++++++++-- libraries/script-engine/src/Vec3.h | 8 ++++++-- 39 files changed, 106 insertions(+), 86 deletions(-) diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 6d37f66563..1b41636874 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -36,11 +36,8 @@ public: public slots: void run(); - void readPendingDatagrams(); -signals: - void willSendAudioDataCallback(); - void willSendVisualDataCallback(); + private: ScriptEngine _scriptEngine; VoxelEditPacketSender _voxelEditSender; diff --git a/examples/audioBall.js b/examples/audioBall.js index 676b9118b3..0889d9eb31 100644 --- a/examples/audioBall.js +++ b/examples/audioBall.js @@ -18,7 +18,7 @@ var FACTOR = 0.75; var countParticles = 0; // the first time around we want to create the particle and thereafter to modify it. var particleID; -function updateParticle() { +function updateParticle(deltaTime) { // the particle should be placed in front of the user's avatar var avatarFront = Quat.getFront(MyAvatar.orientation); @@ -62,7 +62,7 @@ function updateParticle() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(updateParticle); +Script.update.connect(updateParticle); // register our scriptEnding callback Script.scriptEnding.connect(function scriptEnding() {}); diff --git a/examples/bot.js b/examples/bot.js index a3ae7f3263..8d70cc8656 100644 --- a/examples/bot.js +++ b/examples/bot.js @@ -103,7 +103,7 @@ Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/me Agent.isAvatar = true; -function updateBehavior() { +function updateBehavior(deltaTime) { if (Math.random() < CHANCE_OF_SOUND) { playRandomSound(Avatar.position); } @@ -142,7 +142,7 @@ function updateBehavior() { } } } -Script.willSendVisualDataCallback.connect(updateBehavior); +Script.update.connect(updateBehavior); function loadSounds() { sounds.push(new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail+Party+Snippets/Raws/AB1.raw")); diff --git a/examples/cameraExample.js b/examples/cameraExample.js index d55f376b76..ddfff15935 100644 --- a/examples/cameraExample.js +++ b/examples/cameraExample.js @@ -20,9 +20,8 @@ var joysticksCaptured = false; var THRUST_CONTROLLER = 0; var VIEW_CONTROLLER = 1; -function checkCamera() { +function checkCamera(deltaTime) { if (Camera.getMode() == "independent") { - var deltaTime = 1/60; // approximately our FPS - maybe better to be elapsed time since last call var THRUST_MAG_UP = 800.0; var THRUST_MAG_DOWN = 300.0; var THRUST_MAG_FWD = 500.0; @@ -80,7 +79,7 @@ function checkCamera() { } } -Script.willSendVisualDataCallback.connect(checkCamera); +Script.update.connect(checkCamera); function mouseMoveEvent(event) { print("mouseMoveEvent event.x,y=" + event.x + ", " + event.y); diff --git a/examples/clap.js b/examples/clap.js index 81ccda64b7..ef8b61f05a 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -28,7 +28,7 @@ var clapping = new Array(); clapping[0] = false; clapping[1] = false; -function maybePlaySound() { +function maybePlaySound(deltaTime) { // Set the location and other info for the sound to play var palm1Position = Controller.getSpatialControlPosition(0); var palm2Position = Controller.getSpatialControlPosition(2); @@ -62,4 +62,4 @@ function maybePlaySound() { } // Connect a call back that happens every frame -Script.willSendVisualDataCallback.connect(maybePlaySound); \ No newline at end of file +Script.update.connect(maybePlaySound); \ No newline at end of file diff --git a/examples/collidingParticles.js b/examples/collidingParticles.js index 81ccfe108b..5a1d09b024 100644 --- a/examples/collidingParticles.js +++ b/examples/collidingParticles.js @@ -58,7 +58,7 @@ var color = { green: 255, blue: 0 }; -function draw() { +function draw(deltaTime) { print("hello... draw()... currentIteration=" + currentIteration + "\n"); // on the first iteration, setup a single particle that's slowly moving @@ -150,5 +150,5 @@ function draw() { // register the call back so it fires before each data send print("here...\n"); Particles.setPacketsPerSecond(40000); -Script.willSendVisualDataCallback.connect(draw); +Script.update.connect(draw); print("and here...\n"); diff --git a/examples/controllerExample.js b/examples/controllerExample.js index 43a7b12231..ebb013913e 100644 --- a/examples/controllerExample.js +++ b/examples/controllerExample.js @@ -16,7 +16,7 @@ for (t = 0; t < numberOfTriggers; t++) { triggerPulled[t] = false; } -function checkController() { +function checkController(deltaTime) { var numberOfTriggers = Controller.getNumberOfTriggers(); var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers; @@ -48,7 +48,7 @@ function checkController() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(checkController); +Script.update.connect(checkController); function printKeyEvent(eventName, event) { print(eventName); diff --git a/examples/count.js b/examples/count.js index 29799a8271..e04bc2c94b 100644 --- a/examples/count.js +++ b/examples/count.js @@ -10,8 +10,8 @@ var count = 0; -function displayCount() { - print("count =" + count); +function displayCount(deltaTime) { + print("count =" + count + " deltaTime=" + deltaTime); count++; } @@ -20,7 +20,7 @@ function scriptEnding() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(displayCount); +Script.update.connect(displayCount); // register our scriptEnding callback Script.scriptEnding.connect(scriptEnding); diff --git a/examples/drumStick.js b/examples/drumStick.js index 78de8351db..9b0a8ccbca 100644 --- a/examples/drumStick.js +++ b/examples/drumStick.js @@ -31,7 +31,7 @@ var strokeSpeed = new Array(); strokeSpeed[0] = 0.0; strokeSpeed[1] = 0.0; -function checkSticks() { +function checkSticks(deltaTime) { for (var palm = 0; palm < 2; palm++) { var palmVelocity = Controller.getSpatialControlVelocity(palm * 2 + 1); var speed = length(palmVelocity); @@ -69,4 +69,4 @@ function checkSticks() { } // Connect a call back that happens every frame -Script.willSendVisualDataCallback.connect(checkSticks); \ No newline at end of file +Script.update.connect(checkSticks); \ No newline at end of file diff --git a/examples/editParticleExample.js b/examples/editParticleExample.js index 152bb18fca..b632e0229b 100644 --- a/examples/editParticleExample.js +++ b/examples/editParticleExample.js @@ -42,7 +42,7 @@ var positionDelta = { x: 0.05, y: 0, z: 0 }; var particleID = Particles.addParticle(originalProperties); -function moveParticle() { +function moveParticle(deltaTime) { if (count >= moveUntil) { // delete it... @@ -85,5 +85,5 @@ function moveParticle() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(moveParticle); +Script.update.connect(moveParticle); diff --git a/examples/editVoxels.js b/examples/editVoxels.js index f3e3fcf46e..6680e85e68 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -1329,7 +1329,7 @@ function checkControllers() { } } -function update() { +function update(deltaTime) { var newWindowDimensions = Controller.getViewportDimensions(); if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) { windowDimensions = newWindowDimensions; @@ -1399,6 +1399,6 @@ function scriptEnding() { } Script.scriptEnding.connect(scriptEnding); -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); setupMenus(); diff --git a/examples/findParticleExample.js b/examples/findParticleExample.js index 5eb257d502..4a0e9b832a 100644 --- a/examples/findParticleExample.js +++ b/examples/findParticleExample.js @@ -60,7 +60,7 @@ function printProperties(properties) { } } -function findParticles() { +function findParticles(deltaTime) { // run for a while, then clean up // stop it... @@ -122,7 +122,7 @@ function findParticles() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(findParticles); +Script.update.connect(findParticles); // register our scriptEnding callback Script.scriptEnding.connect(scriptEnding); diff --git a/examples/fountain.js b/examples/fountain.js index 3c943d72a0..8816dab09a 100644 --- a/examples/fountain.js +++ b/examples/fountain.js @@ -41,7 +41,7 @@ var position = { x: 5.0, y: 0.6, z: 5.0 }; Voxels.setVoxel(position.x, 0, position.z, 0.5, 0, 0, 255); var totalParticles = 0; -function makeFountain() { +function makeFountain(deltaTime) { if (Math.random() < 0.10) { //print("Made particle!\n"); var properties = { @@ -64,4 +64,4 @@ function makeFountain() { } } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(makeFountain); \ No newline at end of file +Script.update.connect(makeFountain); \ No newline at end of file diff --git a/examples/gameoflife.js b/examples/gameoflife.js index d72a72c2de..c0122c604a 100644 --- a/examples/gameoflife.js +++ b/examples/gameoflife.js @@ -114,7 +114,7 @@ function sendNextCells() { var sentFirstBoard = false; -function step() { +function step(deltaTime) { if (sentFirstBoard) { // we've already sent the first full board, perform a step in time updateCells(); @@ -127,6 +127,6 @@ function step() { } print("here"); -Script.willSendVisualDataCallback.connect(step); +Script.update.connect(step); Voxels.setPacketsPerSecond(200); print("now here"); diff --git a/examples/gun.js b/examples/gun.js index 17587e3810..2e9bf5655c 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -73,7 +73,7 @@ function particleCollisionWithVoxel(particle, voxel) { Audio.playSound(impactSound, audioOptions); } -function update() { +function update(deltaTime) { // Check for mouseLook movement, update rotation // rotate body yaw for yaw received from mouse @@ -178,7 +178,7 @@ function scriptEnding() { Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel); Script.scriptEnding.connect(scriptEnding); -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); Controller.mousePressEvent.connect(mousePressEvent); Controller.mouseReleaseEvent.connect(mouseReleaseEvent); Controller.mouseMoveEvent.connect(mouseMoveEvent); diff --git a/examples/hydraMove.js b/examples/hydraMove.js index 6ce0ad884e..1f9634a8e6 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -29,7 +29,6 @@ var grabbingWithLeftHand = false; var wasGrabbingWithLeftHand = false; var EPSILON = 0.000001; var velocity = { x: 0, y: 0, z: 0}; -var deltaTime = 1/60; // approximately our FPS - maybe better to be elapsed time since last call var THRUST_MAG_UP = 800.0; var THRUST_MAG_DOWN = 300.0; var THRUST_MAG_FWD = 500.0; @@ -77,7 +76,7 @@ function getAndResetGrabRotation() { } // handles all the grab related behavior: position (crawl), velocity (flick), and rotate (twist) -function handleGrabBehavior() { +function handleGrabBehavior(deltaTime) { // check for and handle grab behaviors grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4); grabbingWithLeftHand = Controller.isButtonPressed(LEFT_BUTTON_4); @@ -156,7 +155,7 @@ function handleGrabBehavior() { } // Main update function that handles flying and grabbing behaviort -function flyWithHydra() { +function flyWithHydra(deltaTime) { var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER); if (thrustJoystickPosition.x != 0 || thrustJoystickPosition.y != 0) { @@ -193,10 +192,10 @@ function flyWithHydra() { var newPitch = MyAvatar.headPitch + (viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime); MyAvatar.headPitch = newPitch; } - handleGrabBehavior(); + handleGrabBehavior(deltaTime); } -Script.willSendVisualDataCallback.connect(flyWithHydra); +Script.update.connect(flyWithHydra); Controller.captureJoystick(THRUST_CONTROLLER); Controller.captureJoystick(VIEW_CONTROLLER); diff --git a/examples/lookAtExample.js b/examples/lookAtExample.js index 6340feda00..46e0863231 100644 --- a/examples/lookAtExample.js +++ b/examples/lookAtExample.js @@ -45,13 +45,13 @@ function releaseMovementKeys() { } var cameraPosition = Camera.getPosition(); -function moveCamera() { +function moveCamera(update) { if (lookingAtSomething) { Camera.setPosition(cameraPosition); } } -Script.willSendVisualDataCallback.connect(moveCamera); +Script.update.connect(moveCamera); function mousePressEvent(event) { diff --git a/examples/lookWithMouse.js b/examples/lookWithMouse.js index 460663c054..878813a94a 100644 --- a/examples/lookWithMouse.js +++ b/examples/lookWithMouse.js @@ -49,7 +49,7 @@ function mouseMoveEvent(event) { } } -function update() { +function update(deltaTime) { if (wantDebugging) { print("update()..."); } @@ -91,5 +91,5 @@ MyAvatar.bodyPitch = 0; MyAvatar.bodyRoll = 0; // would be nice to change to update -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); diff --git a/examples/lookWithTouch.js b/examples/lookWithTouch.js index bb54a055c4..ddc42c04c0 100644 --- a/examples/lookWithTouch.js +++ b/examples/lookWithTouch.js @@ -43,7 +43,7 @@ function touchUpdateEvent(event) { lastY = event.y; } -function update() { +function update(deltaTime) { // rotate body yaw for yaw received from mouse var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.fromVec3( { x: 0, y: yawFromMouse, z: 0 } )); if (wantDebugging) { @@ -82,5 +82,5 @@ MyAvatar.bodyPitch = 0; MyAvatar.bodyRoll = 0; // would be nice to change to update -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); diff --git a/examples/movingVoxel.js b/examples/movingVoxel.js index 14a7e671c6..0ddce48334 100644 --- a/examples/movingVoxel.js +++ b/examples/movingVoxel.js @@ -12,7 +12,7 @@ var colorEdge = { r:255, g:250, b:175 }; var frame = 0; var thisColor = color; -function moveVoxel() { +function moveVoxel(deltaTime) { frame++; if (frame % 3 == 0) { // Get a new position @@ -41,4 +41,4 @@ function moveVoxel() { Voxels.setPacketsPerSecond(300); // Connect a call back that happens every frame -Script.willSendVisualDataCallback.connect(moveVoxel); \ No newline at end of file +Script.update.connect(moveVoxel); \ No newline at end of file diff --git a/examples/multitouchExample.js b/examples/multitouchExample.js index 448d7c3f80..1041651c7b 100644 --- a/examples/multitouchExample.js +++ b/examples/multitouchExample.js @@ -90,7 +90,7 @@ Controller.touchEndEvent.connect(touchEndEvent); -function update() { +function update(deltaTime) { // rotate body yaw for yaw received from multitouch rotate var newOrientation = Quat.multiply(MyAvatar.orientation, Quat.fromVec3( { x: 0, y: yawFromMultiTouch, z: 0 } )); if (wantDebugging) { @@ -110,7 +110,7 @@ function update() { MyAvatar.headPitch = newPitch; pitchFromMultiTouch = 0; } -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); function scriptEnding() { diff --git a/examples/overlaysExample.js b/examples/overlaysExample.js index d97ec9e8fd..60f924338f 100644 --- a/examples/overlaysExample.js +++ b/examples/overlaysExample.js @@ -186,7 +186,7 @@ var toolAVisible = false; var count = 0; // Our update() function is called at approximately 60fps, and we will use it to animate our various overlays -function update() { +function update(deltaTime) { count++; // every second or so, toggle the visibility our our blinking tool @@ -226,7 +226,7 @@ function update() { // update our 3D line to go from origin to our avatar's position Overlays.editOverlay(line3d, { end: MyAvatar.position } ); } -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); // The slider is handled in the mouse event callbacks. diff --git a/examples/paintGun.js b/examples/paintGun.js index 56e916a183..38c99ddfcb 100644 --- a/examples/paintGun.js +++ b/examples/paintGun.js @@ -13,7 +13,7 @@ for (t = 0; t < numberOfTriggers; t++) { triggerPulled[t] = false; } -function checkController() { +function checkController(deltaTime) { var numberOfTriggers = Controller.getNumberOfTriggers(); var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers; @@ -93,4 +93,4 @@ function checkController() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(checkController); +Script.update.connect(checkController); diff --git a/examples/particleBird.js b/examples/particleBird.js index 440a91166c..5cd068bd60 100644 --- a/examples/particleBird.js +++ b/examples/particleBird.js @@ -99,7 +99,7 @@ var properties = { var range = 1.0; // Distance around avatar where I can move // Create the actual bird var particleID = Particles.addParticle(properties); -function moveBird() { +function moveBird(deltaTime) { // check to see if we've been running long enough that our bird is dead var nowTimeInSeconds = new Date().getTime() / 1000; @@ -194,4 +194,4 @@ function moveBird() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(moveBird); +Script.update.connect(moveBird); diff --git a/examples/particleModelExample.js b/examples/particleModelExample.js index 2f36445d1a..c43956cd3e 100644 --- a/examples/particleModelExample.js +++ b/examples/particleModelExample.js @@ -47,7 +47,7 @@ var modelAParticleID = Particles.addParticle(modelPropertiesA); var modelBParticleID = Particles.addParticle(modelPropertiesB); var ballParticleID = Particles.addParticle(ballProperties); -function endAfterAWhile() { +function endAfterAWhile(deltaTime) { // stop it... if (count >= stopAfter) { print("calling Script.stop()"); @@ -60,5 +60,5 @@ function endAfterAWhile() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(endAfterAWhile); +Script.update.connect(endAfterAWhile); diff --git a/examples/playSound.js b/examples/playSound.js index 657f052aa5..18857826ea 100644 --- a/examples/playSound.js +++ b/examples/playSound.js @@ -5,7 +5,7 @@ // First, load the clap sound from a URL var clap = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/bushtit_1.raw"); -function maybePlaySound() { +function maybePlaySound(deltaTime) { if (Math.random() < 0.01) { // Set the location and other info for the sound to play var options = new AudioInjectionOptions();
 @@ -17,4 +17,4 @@ function maybePlaySound() { } // Connect a call back that happens every frame -Script.willSendVisualDataCallback.connect(maybePlaySound); \ No newline at end of file +Script.update.connect(maybePlaySound); \ No newline at end of file diff --git a/examples/ribbon.js b/examples/ribbon.js index 7858c744fe..a6e1edfa4a 100644 --- a/examples/ribbon.js +++ b/examples/ribbon.js @@ -122,7 +122,7 @@ var velocity; var hueAngle = 0; var smoothedOffset; -function step() { +function step(deltaTime) { if (stateHistory.length === 0) { // start at a random position within the bounds, with a random velocity position = randomVector(BOUNDS_MIN, BOUNDS_MAX); @@ -170,4 +170,4 @@ function step() { hueAngle = (hueAngle + 1) % MAX_HUE_ANGLE; } -Script.willSendVisualDataCallback.connect(step); +Script.update.connect(step); diff --git a/examples/rideAlongWithAParticleExample.js b/examples/rideAlongWithAParticleExample.js index b2b6627063..1148b96b4d 100644 --- a/examples/rideAlongWithAParticleExample.js +++ b/examples/rideAlongWithAParticleExample.js @@ -22,7 +22,7 @@ var particleA = Particles.addParticle( lifetime: (lengthOfRide * 60) + 1 }); -function rideWithParticle() { +function rideWithParticle(deltaTime) { if (iteration <= lengthOfRide) { @@ -46,5 +46,5 @@ function rideWithParticle() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(rideWithParticle); +Script.update.connect(rideWithParticle); diff --git a/examples/seeingVoxelsExample.js b/examples/seeingVoxelsExample.js index 93f605755f..62ebd599ee 100644 --- a/examples/seeingVoxelsExample.js +++ b/examples/seeingVoxelsExample.js @@ -31,7 +31,7 @@ function init() { } } -function keepLooking() { +function keepLooking(deltaTime) { //print("count =" + count); if (count == 0) { @@ -63,7 +63,7 @@ function scriptEnding() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(keepLooking); +Script.update.connect(keepLooking); // register our scriptEnding callback Script.scriptEnding.connect(scriptEnding); diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index c817afcdd4..1d7b127904 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -207,7 +207,7 @@ function displayGameOver() { print("Game over..."); } -function update() { +function update(deltaTime) { if (!gameOver) { //print("updating space invaders... iteration="+iteration); iteration++; @@ -257,7 +257,7 @@ function update() { } // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); function cleanupGame() { print("cleaning up game..."); diff --git a/examples/toyball.js b/examples/toyball.js index c5672877f7..36f1aa11e5 100644 --- a/examples/toyball.js +++ b/examples/toyball.js @@ -208,7 +208,7 @@ function checkControllerSide(whichSide) { } -function checkController() { +function checkController(deltaTime) { var numberOfButtons = Controller.getNumberOfButtons(); var numberOfTriggers = Controller.getNumberOfTriggers(); var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); @@ -226,4 +226,4 @@ function checkController() { // register the call back so it fires before each data send -Script.willSendVisualDataCallback.connect(checkController); +Script.update.connect(checkController); diff --git a/examples/voxelBird.js b/examples/voxelBird.js index 254f93c21e..1e33851ff6 100644 --- a/examples/voxelBird.js +++ b/examples/voxelBird.js @@ -73,7 +73,7 @@ var moved = true; var CHANCE_OF_MOVING = 0.05; var CHANCE_OF_TWEETING = 0.05; -function moveBird() { +function moveBird(deltaTime) { frame++; if (frame % 3 == 0) { // Tweeting behavior @@ -130,4 +130,4 @@ function moveBird() { Voxels.setPacketsPerSecond(10000); // Connect a call back that happens every frame -Script.willSendVisualDataCallback.connect(moveBird); \ No newline at end of file +Script.update.connect(moveBird); \ No newline at end of file diff --git a/examples/voxelDrumming.js b/examples/voxelDrumming.js index a2acb05958..178c6734d8 100644 --- a/examples/voxelDrumming.js +++ b/examples/voxelDrumming.js @@ -70,14 +70,13 @@ function clamp(valueToClamp, minValue, maxValue) { return Math.max(minValue, Math.min(maxValue, valueToClamp)); } -function produceCollisionSound(palm, voxelDetail) { +function produceCollisionSound(deltaTime, palm, voxelDetail) { // Collision between finger and a voxel plays sound var palmVelocity = Controller.getSpatialControlVelocity(palm * 2); var speed = Vec3.length(palmVelocity); var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1); - var deltaTime = 1/60; //close enough var LOWEST_FREQUENCY = 100.0; var HERTZ_PER_RGB = 3.0; var DECAY_PER_SAMPLE = 0.0005; @@ -97,9 +96,7 @@ function produceCollisionSound(palm, voxelDetail) { Audio.startDrumSound(volume, frequency, DURATION_MAX, DECAY_PER_SAMPLE, audioOptions); } -function update() { - var deltaTime = 1/60; //close enough - +function update(deltaTime) { // Voxel Drumming with fingertips if enabled if (Menu.isOptionChecked("Voxel Drumming")) { @@ -111,7 +108,7 @@ function update() { if (!isColliding[palm]) { // Collision has just started isColliding[palm] = true; - produceCollisionSound(palm, voxel); + produceCollisionSound(deltaTime, palm, voxel); // Set highlight voxel Overlays.editOverlay(highlightVoxel, @@ -156,7 +153,7 @@ function update() { } // palm loop } // menu item check } -Script.willSendVisualDataCallback.connect(update); +Script.update.connect(update); function scriptEnding() { Overlays.deleteOverlay(highlightVoxel); diff --git a/libraries/script-engine/src/Quat.cpp b/libraries/script-engine/src/Quat.cpp index 7271f06af6..78ea73987b 100644 --- a/libraries/script-engine/src/Quat.cpp +++ b/libraries/script-engine/src/Quat.cpp @@ -11,6 +11,8 @@ #include +#include + #include #include #include "Quat.h" @@ -56,3 +58,7 @@ glm::quat Quat::mix(const glm::quat& q1, const glm::quat& q2, float alpha) { return safeMix(q1, q2, alpha); } +void Quat::print(const QString& lable, const glm::quat& q) { + qDebug() << qPrintable(lable) << q.x << "," << q.y << "," << q.z << "," << q.w; +} + diff --git a/libraries/script-engine/src/Quat.h b/libraries/script-engine/src/Quat.h index ac12aaa351..f006374347 100644 --- a/libraries/script-engine/src/Quat.h +++ b/libraries/script-engine/src/Quat.h @@ -13,7 +13,9 @@ #define __hifi__Quat__ #include -#include + +#include +#include /// Scriptable interface a Quaternion helper class object. Used exclusively in the JavaScript API class Quat : public QObject { @@ -30,6 +32,7 @@ public slots: glm::vec3 safeEulerAngles(const glm::quat& orientation); glm::quat angleAxis(float angle, const glm::vec3& v); glm::quat mix(const glm::quat& q1, const glm::quat& q2, float alpha); + void print(const QString& lable, const glm::quat& q); }; #endif /* defined(__hifi__Quat__) */ diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e08317f8b4..c63d2e9162 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -215,6 +215,8 @@ void ScriptEngine::run() { int thisFrame = 0; NodeList* nodeList = NodeList::getInstance(); + + qint64 lastUpdate = usecTimestampNow(); while (!_isFinished) { int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow(); @@ -259,7 +261,10 @@ void ScriptEngine::run() { nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer); } - emit willSendVisualDataCallback(); + qint64 now = usecTimestampNow(); + float deltaTime = (float)(now - lastUpdate)/(float)USECS_PER_SECOND; + emit update(deltaTime); + lastUpdate = now; if (_engine.hasUncaughtException()) { int line = _engine.uncaughtExceptionLineNumber(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 00906de7b3..6b9ec9c9eb 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -71,8 +71,7 @@ public slots: void clearTimeout(QObject* timer) { stopTimer(reinterpret_cast(timer)); } signals: - void willSendAudioDataCallback(); - void willSendVisualDataCallback(); + void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString); void cleanupMenuItem(const QString& menuItemString); diff --git a/libraries/script-engine/src/Vec3.cpp b/libraries/script-engine/src/Vec3.cpp index 2c5bf172fd..dc5dcd9773 100644 --- a/libraries/script-engine/src/Vec3.cpp +++ b/libraries/script-engine/src/Vec3.cpp @@ -9,10 +9,12 @@ // // +#include + #include "Vec3.h" -glm::vec3 Vec3::multiply(const glm::vec3& v1, const glm::vec3& v2) { - return v1 * v2; +glm::vec3 Vec3::cross(const glm::vec3& v1, const glm::vec3& v2) { + return glm::cross(v1,v2); } glm::vec3 Vec3::multiply(const glm::vec3& v1, float f) { @@ -29,6 +31,15 @@ glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) { glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) { return v1 - v2; } + float Vec3::length(const glm::vec3& v) { return glm::length(v); } + +glm::vec3 Vec3::normalize(const glm::vec3& v) { + return glm::normalize(v); +} + +void Vec3::print(const QString& lable, const glm::vec3& v) { + qDebug() << qPrintable(lable) << v.x << "," << v.y << "," << v.z; +} diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 20ad3f7eaa..cbec55b992 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -14,19 +14,23 @@ #include #include -#include + +#include +#include /// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API class Vec3 : public QObject { Q_OBJECT public slots: - glm::vec3 multiply(const glm::vec3& v1, const glm::vec3& v2); + glm::vec3 cross(const glm::vec3& v1, const glm::vec3& v2); glm::vec3 multiply(const glm::vec3& v1, float f); glm::vec3 multiplyQbyV(const glm::quat& q, const glm::vec3& v); glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2); glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2); float length(const glm::vec3& v); + glm::vec3 normalize(const glm::vec3& v); + void print(const QString& lable, const glm::vec3& v); }; From ed703673b692b9e9d357efca2408872c71c8ea77 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Mar 2014 14:41:06 -0800 Subject: [PATCH 07/17] first cut at flocking birds, change willEmitVisualCallback to update --- domain-server/resources/web/assignment/placeholder.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index 7c84767f31..46a706999f 100644 --- a/domain-server/resources/web/assignment/placeholder.js +++ b/domain-server/resources/web/assignment/placeholder.js @@ -114,7 +114,7 @@ function sendNextCells() { var sentFirstBoard = false; -function step() { +function step(deltaTime) { if (sentFirstBoard) { // we've already sent the first full board, perform a step in time updateCells(); @@ -127,5 +127,5 @@ function step() { } -Script.willSendVisualDataCallback.connect(step); +Script.update.connect(step); Voxels.setPacketsPerSecond(200); \ No newline at end of file From 2c27c6b8c1d6b5ebb4bb072d0d1ae54250e9a8ed Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 4 Mar 2014 15:03:30 -0800 Subject: [PATCH 08/17] adjustable height of bot avatars --- examples/bot.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/bot.js b/examples/bot.js index a3ae7f3263..162dde9dae 100644 --- a/examples/bot.js +++ b/examples/bot.js @@ -18,6 +18,10 @@ function getRandomInt (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } +function printVector(string, vector) { + print(string + " " + vector.x + ", " + vector.y + ", " + vector.z); +} + var CHANCE_OF_MOVING = 0.005; var CHANCE_OF_SOUND = 0.005; var CHANCE_OF_HEAD_TURNING = 0.05; @@ -31,6 +35,7 @@ var X_MIN = 0.0; var X_MAX = 5.0; var Z_MIN = 0.0; var Z_MAX = 5.0; +var Y_PELVIS = 2.5; var MOVE_RANGE_SMALL = 0.5; var MOVE_RANGE_BIG = Math.max(X_MAX - X_MIN, Z_MAX - Z_MIN) / 2.0; @@ -41,7 +46,7 @@ var TURN_RATE = 0.15; var PITCH_RATE = 0.20; var PITCH_RANGE = 30.0; -var firstPosition = { x: getRandomFloat(X_MIN, X_MAX), y: 0, z: getRandomFloat(Z_MIN, Z_MAX) }; +var firstPosition = { x: getRandomFloat(X_MIN, X_MAX), y: Y_PELVIS, z: getRandomFloat(Z_MIN, Z_MAX) }; var targetPosition = { x: 0, y: 0, z: 0 }; var targetDirection = { x: 0, y: 0, z: 0, w: 0 }; var currentDirection = { x: 0, y: 0, z: 0, w: 0 }; @@ -72,9 +77,6 @@ function playRandomSound(position) { } } -// change the avatar's position to the random one -Avatar.position = firstPosition; - // pick an integer between 1 and 20 for the face model for this bot botNumber = getRandomInt(1, 100); @@ -103,6 +105,10 @@ Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/me Agent.isAvatar = true; +// change the avatar's position to the random one +Avatar.position = firstPosition; +printVector("New bot, position = ", Avatar.position); + function updateBehavior() { if (Math.random() < CHANCE_OF_SOUND) { playRandomSound(Avatar.position); @@ -132,6 +138,7 @@ function updateBehavior() { } targetPosition.x = clamp(targetPosition.x, X_MIN, X_MAX); targetPosition.z = clamp(targetPosition.z, Z_MIN, Z_MAX); + targetPosition.y = Y_PELVIS; isMoving = true; } else { From c90d4a9514be17971344c6872dfe8d6a0c87e09a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Mar 2014 15:07:30 -0800 Subject: [PATCH 09/17] fix failed lock causing particle collisions to not work --- libraries/octree/src/Octree.cpp | 79 ++++++++++++++----- libraries/octree/src/Octree.h | 29 ++++--- .../particles/src/ParticleCollisionSystem.cpp | 4 +- 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 05760ef675..4515deb6b5 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -590,16 +590,26 @@ bool findRayIntersectionOp(OctreeElement* node, void* extraData) { } bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - OctreeElement*& node, float& distance, BoxFace& face, bool tryLock) { + OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType) { RayArgs args = { origin / (float)(TREE_SCALE), direction, node, distance, face }; - if (!tryLock) { + bool gotLock = false; + if (lockType == Octree::Lock) { lockForRead(); + gotLock = true; + } else if (lockType == Octree::TryLock) { + gotLock = tryLockForRead(); + if (!gotLock) { + return args.found; // if we wanted to tryLock, and we couldn't then just bail... + } } - if (tryLock && tryLockForRead()) { - recurseTreeWithOperation(findRayIntersectionOp, &args); + + recurseTreeWithOperation(findRayIntersectionOp, &args); + + if (gotLock) { unlock(); } + return args.found; } @@ -635,7 +645,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) { } bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, - void** penetratedObject, bool tryLock) { + void** penetratedObject, Octree::lockType lockType) { SphereArgs args = { center / (float)(TREE_SCALE), @@ -644,17 +654,27 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v false, NULL }; penetration = glm::vec3(0.0f, 0.0f, 0.0f); - - if (!tryLock) { + + bool gotLock = false; + if (lockType == Octree::Lock) { lockForRead(); - } - if (tryLock && tryLockForRead()) { - recurseTreeWithOperation(findSpherePenetrationOp, &args); - if (penetratedObject) { - *penetratedObject = args.penetratedObject; + gotLock = true; + } else if (lockType == Octree::TryLock) { + gotLock = tryLockForRead(); + if (!gotLock) { + return args.found; // if we wanted to tryLock, and we couldn't then just bail... } + } + + recurseTreeWithOperation(findSpherePenetrationOp, &args); + if (penetratedObject) { + *penetratedObject = args.penetratedObject; + } + + if (gotLock) { unlock(); } + return args.found; } @@ -689,7 +709,7 @@ bool findCapsulePenetrationOp(OctreeElement* node, void* extraData) { } bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, - glm::vec3& penetration, bool tryLock) { + glm::vec3& penetration, Octree::lockType lockType) { CapsuleArgs args = { start / (float)(TREE_SCALE), @@ -699,11 +719,20 @@ bool Octree::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end false }; penetration = glm::vec3(0.0f, 0.0f, 0.0f); - if (!tryLock) { + bool gotLock = false; + if (lockType == Octree::Lock) { lockForRead(); + gotLock = true; + } else if (lockType == Octree::TryLock) { + gotLock = tryLockForRead(); + if (!gotLock) { + return args.found; // if we wanted to tryLock, and we couldn't then just bail... + } } - if (tryLock && tryLockForRead()) { - recurseTreeWithOperation(findCapsulePenetrationOp, &args); + + recurseTreeWithOperation(findCapsulePenetrationOp, &args); + + if (gotLock) { unlock(); } return args.found; @@ -732,18 +761,28 @@ bool getElementEnclosingOperation(OctreeElement* element, void* extraData) { return true; // keep looking } -OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, bool tryLock) { +OctreeElement* Octree::getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType) { GetElementEnclosingArgs args; args.point = point; args.element = NULL; - if (!tryLock) { + bool gotLock = false; + if (lockType == Octree::Lock) { lockForRead(); + gotLock = true; + } else if (lockType == Octree::TryLock) { + gotLock = tryLockForRead(); + if (!gotLock) { + return args.element; // if we wanted to tryLock, and we couldn't then just bail... + } } - if (tryLock && tryLockForRead()) { - recurseTreeWithOperation(getElementEnclosingOperation, (void*)&args); + + recurseTreeWithOperation(getElementEnclosingOperation, (void*)&args); + + if (gotLock) { unlock(); } + return args.element; } diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 21a6929034..4c237b5f56 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -221,16 +221,29 @@ public: void clearDirtyBit() { _isDirty = false; } void setDirtyBit() { _isDirty = true; } + // Octree does not currently handle its own locking, caller must use these to lock/unlock + void lockForRead() { _lock.lockForRead(); } + bool tryLockForRead() { return _lock.tryLockForRead(); } + void lockForWrite() { _lock.lockForWrite(); } + bool tryLockForWrite() { return _lock.tryLockForWrite(); } + void unlock() { _lock.unlock(); } + // output hints from the encode process + typedef enum { + Lock, + TryLock, + NoLock + } lockType; + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - OctreeElement*& node, float& distance, BoxFace& face, bool tryLock = true); + OctreeElement*& node, float& distance, BoxFace& face, Octree::lockType lockType = Octree::TryLock); bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, - void** penetratedObject = NULL, bool tryLock = true); + void** penetratedObject = NULL, Octree::lockType lockType = Octree::TryLock); bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, - glm::vec3& penetration, bool tryLock = true); + glm::vec3& penetration, Octree::lockType lockType = Octree::TryLock); - OctreeElement* getElementEnclosingPoint(const glm::vec3& point, bool tryLock = true); + OctreeElement* getElementEnclosingPoint(const glm::vec3& point, Octree::lockType lockType = Octree::TryLock); // Note: this assumes the fileFormat is the HIO individual voxels code files void loadOctreeFile(const char* fileName, bool wantColorRandomizer); @@ -238,13 +251,7 @@ public: // these will read/write files that match the wireformat, excluding the 'V' leading void writeToSVOFile(const char* filename, OctreeElement* node = NULL); bool readFromSVOFile(const char* filename); - - // Octree does not currently handle its own locking, caller must use these to lock/unlock - void lockForRead() { _lock.lockForRead(); } - bool tryLockForRead() { return _lock.tryLockForRead(); } - void lockForWrite() { _lock.lockForWrite(); } - bool tryLockForWrite() { return _lock.tryLockForWrite(); } - void unlock() { _lock.unlock(); } + unsigned long getOctreeElementsCount(); diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 2d272a8f1f..b36b6a3a04 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -58,7 +58,7 @@ bool ParticleCollisionSystem::updateOperation(OctreeElement* element, void* extr void ParticleCollisionSystem::update() { // update all particles - if (_particles->tryLockForWrite()) { + if (_particles->tryLockForRead()) { _particles->recurseTreeWithOperation(updateOperation, this); _particles->unlock(); } @@ -117,7 +117,7 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA) const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; Particle* particleB; - if (_particles->findSpherePenetration(center, radius, penetration, (void**)&particleB)) { + if (_particles->findSpherePenetration(center, radius, penetration, (void**)&particleB, Octree::NoLock)) { // NOTE: 'penetration' is the depth that 'particleA' overlaps 'particleB'. // That is, it points from A into B. From c031359a5467e98bfaac43c7bbf39ec03cf281bf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 4 Mar 2014 16:20:17 -0800 Subject: [PATCH 10/17] fix infinite reloading of missing script files --- 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 98ba3f0dac..c6c6882012 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3479,7 +3479,6 @@ void Application::cleanupScriptMenuItem(const QString& scriptMenuName) { } void Application::loadScript(const QString& fileNameString) { - _activeScripts.append(fileNameString); QByteArray fileNameAscii = fileNameString.toLocal8Bit(); const char* fileName = fileNameAscii.data(); @@ -3489,6 +3488,7 @@ void Application::loadScript(const QString& fileNameString) { return; } qDebug("Loading file %s...", fileName); + _activeScripts.append(fileNameString); // get file length.... unsigned long fileLength = file.tellg(); From 161e04f1a81471e45b03eff5bab2e00b35178064 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 5 Mar 2014 02:20:03 -0800 Subject: [PATCH 11/17] flocking bird JS --- examples/flockingBirds.js | 464 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 examples/flockingBirds.js diff --git a/examples/flockingBirds.js b/examples/flockingBirds.js new file mode 100644 index 0000000000..12b402ab40 --- /dev/null +++ b/examples/flockingBirds.js @@ -0,0 +1,464 @@ +// +// flockingBirds.js +// hifi +// +// Created by Brad Hefta-Gaub on 3/4/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// +// This is an example script that generates particles that act like flocking birds +// +// All birds, even flying solo... +// birds don't like to fall too fast +// if they fall to fast, they will go into a state of thrusting up, until they reach some max upward velocity, then +// go back to gliding +// birds don't like to be below a certain altitude +// if they are below that altitude they will keep thrusting up, until they get ove + +// flocking +// try to align your velocity with velocity of other birds +// try to fly toward center of flock +// but dont get too close +// + +var birdsInFlock = 40; + +var birdLifetime = 60; // 2 minutes +var count=0; // iterations + +var enableFlyTowardPoints = true; // some birds have a point they want to fly to +var enabledClustedFlyTowardPoints = true; // the flyToward points will be generally near each other +var flyToFrames = 10; // number of frames the bird would like to attempt to fly to it's flyTo point +var PROBABILITY_OF_FLY_TOWARD_CHANGE = 0.01; // chance the bird will decide to change its flyTo point +var PROBABILITY_EACH_BIRD_WILL_FLY_TOWARD = 0.2; // chance the bird will decide to flyTo, otherwise it follows +var flyingToCount = 0; // count of birds currently flying to someplace +var flyToCluster = { }; // the point that the cluster of flyTo points is based on when in enabledClustedFlyTowardPoints + +// Bird behaviors +var enableAvoidDropping = true; // birds will resist falling too fast, and will thrust up if falling +var enableAvoidMinHeight = true; // birds will resist being below a certain height and thrust up to get above it +var enableAvoidMaxHeight = true; // birds will resist being above a certain height and will glide to get below it +var enableMatchFlockVelocity = true; // birds will thrust to match the flocks average velocity +var enableThrustTowardCenter = true; // birds will thrust to try to move toward the center of the flock +var enableAvoidOtherBirds = true; // birds will thrust away from all other birds +var startWithVelocity = true; +var flockGravity = { x: 0, y: -1, z: 0}; + +// NOTE: these two features don't seem to be very interesting, they cause odd behaviors +var enableRandomXZThrust = false; // leading birds randomly decide to thrust in some random direction. +var enableSomeBirdsLead = false; // birds randomly decide not fly toward flock, causing other birds to follow +var leaders = 0; // number of birds leading +var PROBABILITY_TO_LEAD = 0.1; // probabolity a bird will choose to lead + +var birds = new Array(); // array of bird state data + + +var flockStartPosition = { x: 100, y: 10, z: 100}; +var flockStartVelocity = { x: 0, y: 0, z: 0}; +var flockStartThrust = { x: 0, y: 0, z: 0}; // slightly upward against gravity +var INITIAL_XY_VELOCITY_SCALE = 2; +var birdRadius = 0.0625; +var baseBirdColor = { red: 0, green: 255, blue: 255 }; +var glidingColor = { red: 255, green: 0, blue: 0 }; +var thrustUpwardColor = { red: 0, green: 255, blue: 0 }; +var thrustXYColor = { red: 128, green: 0, blue: 128 }; // will be added to any other color +var leadingOrflyToColor = { red: 200, green: 200, blue: 255 }; + +var tooClose = birdRadius * 3; // how close birds are willing to be to each other +var droppingTooFast = -1; // birds don't like to fall too fast +var risingTooFast = 1; // birds don't like to climb too fast +var upwardThrustAgainstGravity = -10; // how hard a bird will attempt to thrust up to avoid downward motion +var droppingAdjustFrames = 5; // birds try to correct their min height in only a couple frames +var minHeight = 10; // meters off the ground +var maxHeight = 50; // meters off the ground +var adjustFrames = 10; // typical number of frames a bird will assume for it's adjustments +var PROBABILITY_OF_RANDOM_XZ_THRUST = 0.25; +var RANDOM_XZ_THRUST_SCALE = 5; // random -SCALE...to...+SCALE in X or Z direction +var MAX_XY_VELOCITY = 10; + +// These are multiplied by every frame since a change. so after 50 frames, there's a 50% probability of change +var PROBABILITY_OF_STARTING_XZ_THRUST = 0.0025; +var PROBABILITY_OF_STOPPING_XZ_THRUST = 0.01; + +var FLY_TOWARD_XZ_DISTANCE = 100; +var FLY_TOWARD_Y_DISTANCE = 0; +var FLY_TOWARD_XZ_CLUSTER_DELTA = 5; +var FLY_TOWARD_Y_CLUSTER_DELTA = 0; + +function createBirds() { + if (enabledClustedFlyTowardPoints) { + flyToCluster = { x: flockStartPosition.x + Math.random() * FLY_TOWARD_XZ_DISTANCE, + y: flockStartPosition.y + Math.random() * FLY_TOWARD_Y_DISTANCE, + z: flockStartPosition.z + Math.random() * FLY_TOWARD_XZ_DISTANCE}; + } + + for(var i =0; i < birdsInFlock; i++) { + var velocity; + + position = Vec3.sum(flockStartPosition, { x: Math.random(), y: Math.random(), z: Math.random() }); // add random + + var flyingToward = position; + var isFlyingToward = false; + if (enableFlyTowardPoints) { + if (Math.random() < PROBABILITY_EACH_BIRD_WILL_FLY_TOWARD) { + flyingToCount++; + isFlyingToward = true; + if (enabledClustedFlyTowardPoints) { + flyingToward = { x: flyToCluster.x + Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA, + y: flyToCluster.y + Math.random() * FLY_TOWARD_Y_CLUSTER_DELTA, + z: flyToCluster.z + Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA}; + } else { + flyingToward = { x: flockStartPosition.x + Math.random() * FLY_TOWARD_XZ_DISTANCE, + y: flockStartPosition.y + Math.random() * FLY_TOWARD_Y_DISTANCE, + z: flockStartPosition.z + Math.random() * FLY_TOWARD_XZ_DISTANCE}; + } + } + + Vec3.print("birds["+i+"].flyingToward=",flyingToward); + } + + birds[i] = { + particle: {}, + properties: {}, + thrust: Vec3.sum(flockStartThrust, { x:0, y: 0, z: 0 }), + gliding: true, + xzThrust: { x:0, y: 0, z: 0}, + xzthrustCount: 0, + isLeading: false, + flyingToward: flyingToward, + isFlyingToward: isFlyingToward, + }; + + if (enableSomeBirdsLead) { + if (Math.random() < PROBABILITY_TO_LEAD) { + birds[i].isLeading = true; + } + if (leaders == 0 && i == (birdsInFlock-1)) { + birds[i].isLeading = true; + } + if (birds[i].isLeading) { + leaders++; + velocity = { x: 2, y: 0, z: 2}; + print(">>>>>>THIS BIRD LEADS!!!! i="+i); + } + } + + if (startWithVelocity) { + velocity = Vec3.sum(flockStartVelocity, { x: (Math.random() * INITIAL_XY_VELOCITY_SCALE), + y: 0, + z: (Math.random() * INITIAL_XY_VELOCITY_SCALE) }); // add random + } else { + velocity = { x: 0, y: 0, z: 0}; + } + birds[i].particle = Particles.addParticle({ + position: position, + velocity: velocity, + gravity: flockGravity, + damping: 0, + radius: birdRadius, + color: baseBirdColor, + lifetime: birdLifetime + }); + + } + print("flyingToCount=" + flyingToCount); +} + +var wantDebug = false; +function updateBirds(deltaTime) { + count++; + + // get all our bird properties, and calculate the current flock velocity + var averageVelocity = { x: 0, y: 0, z: 0}; + var averagePosition = { x: 0, y: 0, z: 0}; + var knownBirds = 0; + for(var i =0; i < birdsInFlock; i++) { + // identifyParticle() will check to see that the particle handle we have is in sync with the domain/server + // context. If the handle is for a created particle that now has a known ID it will be updated to be a + // handle with a known ID. + birds[i].particle = Particles.identifyParticle(birds[i].particle); + + if (birds[i].particle.isKnownID) { + birds[i].properties = Particles.getParticleProperties(birds[i].particle); + if (birds[i].properties.isKnownID) { + knownBirds++; + averageVelocity = Vec3.sum(averageVelocity, birds[i].properties.velocity); + averagePosition = Vec3.sum(averagePosition, birds[i].properties.position); + } + } + } + + if (knownBirds == 0 && count > 100) { + Script.stop(); + return; + } + averageVelocity = Vec3.multiply(averageVelocity, (1 / Math.max(1, knownBirds))); + averagePosition = Vec3.multiply(averagePosition, (1 / Math.max(1, knownBirds))); + + if (wantDebug) { + Vec3.print("averagePosition=",averagePosition); + Vec3.print("averageVelocity=",averageVelocity); + print("knownBirds="+knownBirds); + } + + var flyToClusterChanged = false; + if (enabledClustedFlyTowardPoints) { + if (Math.random() < PROBABILITY_OF_FLY_TOWARD_CHANGE) { + flyToClusterChanged = true; + flyToCluster = { x: averagePosition.x + (Math.random() * FLY_TOWARD_XZ_DISTANCE) - FLY_TOWARD_XZ_DISTANCE/2, + y: averagePosition.y + (Math.random() * FLY_TOWARD_Y_DISTANCE) - FLY_TOWARD_Y_DISTANCE/2, + z: averagePosition.z + (Math.random() * FLY_TOWARD_XZ_DISTANCE) - FLY_TOWARD_XZ_DISTANCE/2}; + } + } + + // iterate all birds again, adjust their thrust for various goals + for(var i =0; i < birdsInFlock; i++) { + + birds[i].thrust = { x: 0, y: 0, z: 0 }; // assume no thrust... + + if (birds[i].particle.isKnownID) { + + if (enableFlyTowardPoints) { + // if we're flying toward clusters, and the cluster changed, and this bird is flyingToward + // then we need to update it's flyingToward + if (enabledClustedFlyTowardPoints && flyToClusterChanged && birds[i].isFlyingToward) { + flyingToward = { x: flyToCluster.x + (Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA) - FLY_TOWARD_XZ_CLUSTER_DELTA/2, + y: flyToCluster.y + (Math.random() * FLY_TOWARD_Y_CLUSTER_DELTA) - FLY_TOWARD_Y_CLUSTER_DELTA/2, + z: flyToCluster.z + (Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA) - FLY_TOWARD_XZ_CLUSTER_DELTA/2}; + birds[i].flyingToward = flyingToward; + } + + // there a random chance this bird will decide to change it's flying toward state + if (Math.random() < PROBABILITY_OF_FLY_TOWARD_CHANGE) { + var wasFlyingTo = birds[i].isFlyingToward; + + // there's some chance it will decide it should be flying toward + if (Math.random() < PROBABILITY_EACH_BIRD_WILL_FLY_TOWARD) { + + // if we're flying toward clustered points, then we randomize from the cluster, otherwise we pick + // completely random places based on flocks current averagePosition + if (enabledClustedFlyTowardPoints) { + flyingToward = { x: flyToCluster.x + (Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA) - FLY_TOWARD_XZ_CLUSTER_DELTA/2, + y: flyToCluster.y + (Math.random() * FLY_TOWARD_Y_CLUSTER_DELTA) - FLY_TOWARD_Y_CLUSTER_DELTA/2, + z: flyToCluster.z + (Math.random() * FLY_TOWARD_XZ_CLUSTER_DELTA) - FLY_TOWARD_XZ_CLUSTER_DELTA/2}; + } else { + flyingToward = { x: averagePosition.x + (Math.random() * FLY_TOWARD_XZ_DISTANCE) - FLY_TOWARD_XZ_DISTANCE/2, + y: averagePosition.y + (Math.random() * FLY_TOWARD_Y_DISTANCE) - FLY_TOWARD_Y_DISTANCE/2, + z: averagePosition.z + (Math.random() * FLY_TOWARD_XZ_DISTANCE) - FLY_TOWARD_XZ_DISTANCE/2}; + } + birds[i].flyingToward = flyingToward; + birds[i].isFlyingToward = true; + } else { + birds[i].flyingToward = {}; + birds[i].isFlyingToward = false; + } + + // keep track of our bookkeeping + if (!wasFlyingTo && birds[i].isFlyingToward) { + flyingToCount++; + } + if (wasFlyingTo && !birds[i].isFlyingToward) { + flyingToCount--; + } + print(">>>> CHANGING flyingToCount="+flyingToCount); + if (birds[i].isFlyingToward) { + Vec3.print("... now birds["+i+"].flyingToward=", birds[i].flyingToward); + } + } + + // actually apply the thrust after all that + if (birds[i].isFlyingToward) { + var flyTowardDelta = Vec3.subtract(birds[i].flyingToward, birds[i].properties.position); + var thrustTowardFlyTo = Vec3.multiply(flyTowardDelta, 1/flyToFrames); + birds[i].thrust = Vec3.sum(birds[i].thrust, thrustTowardFlyTo); + } + } + + + // adjust thrust to avoid dropping to fast + if (enableAvoidDropping) { + if (birds[i].gliding) { + if (birds[i].properties.velocity.y < droppingTooFast) { + birds[i].gliding = false; // leave thrusting against gravity till it gets too high + //print("birdGliding["+i+"]=false <<<< try to conteract gravity <<<<<<<<<<<<<<<<<<<<"); + } + } + } + + // if the bird is currently not gliding, check to see if it's rising too fast + if (!birds[i].gliding && birds[i].properties.velocity.y > risingTooFast) { + //Vec3.print("bird rising too fast will glide bird["+i+"]=",birds[i].properties.velocity.y); + birds[i].gliding = true; + } + + // adjust thrust to avoid minHeight, we don't care about rising too fast in this case, so we do it + // after the rising too fast check + if (enableAvoidMinHeight) { + if (birds[i].properties.position.y < minHeight) { + //Vec3.print("**** enableAvoidMinHeight... enable thrust against gravity... bird["+i+"].position=",birds[i].properties.position); + birds[i].gliding = false; + } + } + + // adjust thrust to avoid maxHeight + if (enableAvoidMaxHeight) { + if (birds[i].properties.position.y > maxHeight) { + //Vec3.print("********************* bird above max height will glide bird["+i+"].position=",birds[i].properties.position); + birds[i].gliding = true; + } + } + + // if the bird is currently not gliding, then it is applying a thrust upward against gravity + if (!birds[i].gliding) { + // as long as we're not rising too fast, keep thrusting... + if (birds[i].properties.velocity.y < risingTooFast) { + var thrustAdjust = {x: 0, y: (flockGravity.y * upwardThrustAgainstGravity), z: 0}; + //Vec3.print("bird fighting gravity thrustAdjust for bird["+i+"]=",thrustAdjust); + birds[i].thrust = Vec3.sum(birds[i].thrust, thrustAdjust); + } else { + //print("%%% non-gliding bird, thrusting too much..."); + } + } + + if (enableRandomXZThrust && birds[i].isLeading) { + birds[i].xzThrustCount++; + + // we will randomly decide to enable XY thrust, in which case we will set the thrust and leave it + // that way till we randomly shut it off. + + // if we don't have a thrust, check against probability of starting it, and create a random thrust if + // probability occurs + if (Vec3.length(birds[i].xzThrust) == 0) { + var probabilityToStart = (PROBABILITY_OF_STARTING_XZ_THRUST * birds[i].xzThrustCount); + //print("probabilityToStart=" + probabilityToStart); + if (Math.random() < probabilityToStart) { + var xThrust = (Math.random() * (RANDOM_XZ_THRUST_SCALE * 2)) - RANDOM_XZ_THRUST_SCALE; + var zThrust = (Math.random() * (RANDOM_XZ_THRUST_SCALE * 2)) - RANDOM_XZ_THRUST_SCALE; + + birds[i].xzThrust = { x: zThrust, y: 0, z: zThrust }; + birds[i].xzThrustCount = 0; + //Vec3.print(">>>>>>>>>> STARTING XY THRUST birdXYthrust["+i+"]=", birds[i].xzThrust); + } + } + + // if we're thrusting... then check for probability of stopping + if (Vec3.length(birds[i].xzThrust)) { + var probabilityToStop = (PROBABILITY_OF_STOPPING_XZ_THRUST * birds[i].xzThrustCount); + //print("probabilityToStop=" + probabilityToStop); + if (Math.random() < probabilityToStop) { + birds[i].xzThrust = { x: 0, y: 0, z: 0}; + //Vec3.print(">>>>>>>>>> STOPPING XY THRUST birdXYthrust["+i+"]=", birds[i].xzThrust); + birds[i].xzThrustCount = 0; + } + + if (birds[i].properties.velocity.x > MAX_XY_VELOCITY) { + birds[i].xzThrust.x = 0; + //Vec3.print(">>>>>>>>>> CLEARING X THRUST birdXYthrust["+i+"]=", birds[i].xzThrust); + } + if (birds[i].properties.velocity.z > MAX_XY_VELOCITY) { + birds[i].xzThrust.z = 0; + //Vec3.print(">>>>>>>>>> CLEARING Y THRUST birdXYthrust["+i+"]=", birds[i].xzThrust); + } + + if (Vec3.length(birds[i].xzThrust)) { + birds[i].thrust = Vec3.sum(birds[i].thrust, birds[i].xzThrust); + } + } + } + + // adjust thrust to move their velocity toward average flock velocity + if (enableMatchFlockVelocity) { + if (birds[i].isLeading) { + print("this bird is leading... i="+i); + } else { + var velocityDelta = Vec3.subtract(averageVelocity, birds[i].properties.velocity); + var thrustAdjust = velocityDelta; + birds[i].thrust = Vec3.sum(birds[i].thrust, thrustAdjust); + } + } + + // adjust thrust to move their velocity toward average flock position + if (enableThrustTowardCenter) { + if (birds[i].isLeading) { + print("this bird is leading... i="+i); + } else { + var positionDelta = Vec3.subtract(averagePosition, birds[i].properties.position); + var thrustTowardCenter = Vec3.multiply(positionDelta, 1/adjustFrames); + birds[i].thrust = Vec3.sum(birds[i].thrust, thrustTowardCenter); + } + } + + + // adjust thrust to avoid other birds + if (enableAvoidOtherBirds) { + var sumThrustThisBird = { x: 0, y: 0, z: 0 }; + + for(var j =0; j < birdsInFlock; j++) { + + // if this is not me, and a known bird, then check our position + if (birds[i].properties.isKnownID && j != i) { + var positionMe = birds[i].properties.position; + var positionYou = birds[j].properties.position; + var awayFromYou = Vec3.subtract(positionMe, positionYou); // vector pointing away from "you" + var distance = Vec3.length(awayFromYou); + if (distance < tooClose) { + // NOTE: this was Philip's recommendation for "avoiding" other birds... + // Vme -= Vec3.multiply(Vme, normalize(PositionMe - PositionYou)) + // + // But it doesn't seem to work... Here's my JS implementation... + // + // var velocityMe = birds[i].properties.velocity; + // var thrustAdjust = Vec3.cross(velocityMe, Vec3.normalize(awayFromYou)); + // sumThrustThisBird = Vec3.sum(sumThrustThisBird, thrustAdjust); + // + // Instead I just apply a thrust equal to the vector away from all the birds + sumThrustThisBird = Vec3.sum(sumThrustThisBird, awayFromYou); + } + } + } + birds[i].thrust = Vec3.sum(birds[i].thrust, sumThrustThisBird); + } + } + } + + + // iterate all birds again, apply their thrust + for(var i =0; i < birdsInFlock; i++) { + if (birds[i].particle.isKnownID) { + + var color; + if (birds[i].gliding) { + color = glidingColor; + } else { + color = thrustUpwardColor; + } + if (Vec3.length(birds[i].xzThrust)) { + color = Vec3.sum(color, thrustXYColor); + } + + var velocityMe = birds[i].properties.velocity; + // add thrust to velocity + var newVelocity = Vec3.sum(velocityMe, Vec3.multiply(birds[i].thrust, deltaTime)); + + if (birds[i].isLeading || birds[i].isFlyingToward) { + Vec3.print("this bird is leading/flying toward... i="+i+" velocity=",newVelocity); + color = leadingOrflyToColor; + } + + if (wantDebug) { + Vec3.print("birds["+i+"].position=", birds[i].properties.position); + Vec3.print("birds["+i+"].oldVelocity=", velocityMe); + Vec3.print("birdThrusts["+i+"]=", birds[i].thrust); + Vec3.print("birds["+i+"].newVelocity=", newVelocity); + } + + birds[i].particle = Particles.editParticle(birds[i].particle,{ velocity: newVelocity, color: color }); + + } + } +} + + +createBirds(); +// register the call back for simulation loop +Script.update.connect(updateBirds); + From cba55282db8964b1bbbe7ae5af8ac35e488d22ad Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 5 Mar 2014 02:42:49 -0800 Subject: [PATCH 12/17] cleanup headers --- libraries/octree/src/Octree.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 4515deb6b5..3e7e5dd3c1 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -17,9 +17,7 @@ #include -#include -#include -#include +#include #include "CoverageMap.h" #include From 395263ff3d01372d61388a5832330f07dfef6496 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Mar 2014 09:55:06 -0800 Subject: [PATCH 13/17] add time to the interface logs - closes #2205 --- interface/src/Application.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6c6882012..1e9d206462 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -110,9 +110,11 @@ const QString CUSTOM_URL_SCHEME = "hifi:"; void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { if (message.size() > 0) { - QString messageWithNewLine = message + "\n"; - fprintf(stdout, "%s", messageWithNewLine.toLocal8Bit().constData()); - Application::getInstance()->getLogger()->addMessage(messageWithNewLine.toLocal8Bit().constData()); + QString dateString = QDateTime::currentDateTime().toTimeSpec(Qt::LocalTime).toString(Qt::ISODate); + QString formattedMessage = QString("[%1] %2\n").arg(dateString).arg(message); + + fprintf(stdout, "%s", qPrintable(formattedMessage)); + Application::getInstance()->getLogger()->addMessage(qPrintable(formattedMessage)); } } From c34f76620fd9c02f161db5f2d25072a4f55c0a81 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 5 Mar 2014 10:52:46 -0800 Subject: [PATCH 14/17] fix failed create voxel with key press 0 at startup of editVoxels.js --- examples/editVoxels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index f3e3fcf46e..9a014639f0 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -920,7 +920,7 @@ function keyPressEvent(event) { red: colors[color].red, green: colors[color].green, blue: colors[color].blue }; - Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s); + Voxels.eraseVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s); Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue); setAudioPosition(); playRandomAddSound(audioOptions); From d89cb2bf5e3bfe5ddf4be8b5729445fcb4edb565 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 5 Mar 2014 15:03:54 -0800 Subject: [PATCH 15/17] added penetration support to particle collisions JS callbacks --- examples/collidingParticles.js | 6 ++++-- examples/globalCollisionsExample.js | 10 +++++++-- examples/gun.js | 3 ++- examples/paintGun.js | 3 ++- examples/spaceInvadersExample.js | 3 ++- interface/src/Application.cpp | 8 +++---- libraries/particles/src/Particle.cpp | 8 +++---- libraries/particles/src/Particle.h | 14 +++++++------ .../particles/src/ParticleCollisionSystem.cpp | 21 +++++++++++-------- .../particles/src/ParticleCollisionSystem.h | 8 +++---- .../src/ParticlesScriptingInterface.h | 13 ++++++------ libraries/script-engine/src/Vec3.cpp | 10 +++++++++ libraries/script-engine/src/Vec3.h | 2 ++ 13 files changed, 69 insertions(+), 40 deletions(-) diff --git a/examples/collidingParticles.js b/examples/collidingParticles.js index 81ccfe108b..7f01bfec21 100644 --- a/examples/collidingParticles.js +++ b/examples/collidingParticles.js @@ -30,8 +30,9 @@ var gravity = { var damping = 0.1; var scriptA = " " + - " function collisionWithParticle(other) { " + + " function collisionWithParticle(other, penetration) { " + " print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " + + " Vec3.print('penetration=', penetration); " + " print('myID=' + Particle.getID() + '\\n'); " + " var colorBlack = { red: 0, green: 0, blue: 0 };" + " var otherColor = other.getColor();" + @@ -45,8 +46,9 @@ var scriptA = " " + " "; var scriptB = " " + - " function collisionWithParticle(other) { " + + " function collisionWithParticle(other, penetration) { " + " print('collisionWithParticle(other.getID()=' + other.getID() + ')...'); " + + " Vec3.print('penetration=', penetration); " + " print('myID=' + Particle.getID() + '\\n'); " + " Particle.setScript('Particle.setShouldDie(true);'); " + " } " + diff --git a/examples/globalCollisionsExample.js b/examples/globalCollisionsExample.js index 4db4c808e5..266823f564 100644 --- a/examples/globalCollisionsExample.js +++ b/examples/globalCollisionsExample.js @@ -10,17 +10,23 @@ // -function particleCollisionWithVoxel(particle, voxel) { +print("hello..."); + +function particleCollisionWithVoxel(particle, voxel, penetration) { print("particleCollisionWithVoxel().."); print(" particle.getID()=" + particle.id); print(" voxel color...=" + voxel.red + ", " + voxel.green + ", " + voxel.blue); + Vec3.print('penetration=', penetration); } -function particleCollisionWithParticle(particleA, particleB) { +function particleCollisionWithParticle(particleA, particleB, penetration) { print("particleCollisionWithParticle().."); print(" particleA.getID()=" + particleA.id); print(" particleB.getID()=" + particleB.id); + Vec3.print('penetration=', penetration); } Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel); Particles.particleCollisionWithParticle.connect(particleCollisionWithParticle); + +print("here... hello..."); diff --git a/examples/gun.js b/examples/gun.js index b50a8f64d8..2d838374e6 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -61,7 +61,8 @@ function shootBullet(position, velocity) { Audio.playSound(fireSound, audioOptions); } -function particleCollisionWithVoxel(particle, voxel) { +function particleCollisionWithVoxel(particle, voxel, penetration) { + Vec3.print('particleCollisionWithVoxel() ... penetration=', penetration); var HOLE_SIZE = 0.125; var particleProperties = Particles.getParticleProperties(particle); var position = particleProperties.position; diff --git a/examples/paintGun.js b/examples/paintGun.js index 56e916a183..4885496609 100644 --- a/examples/paintGun.js +++ b/examples/paintGun.js @@ -62,8 +62,9 @@ function checkController() { // This is the script for the particles that this gun shoots. var script = - " function collisionWithVoxel(voxel) { " + + " function collisionWithVoxel(voxel, penetration) { " + " print('collisionWithVoxel(voxel)... '); " + + " Vec3.print('penetration=', penetration); " + " print('myID=' + Particle.getID() + '\\n'); " + " var voxelColor = { red: voxel.red, green: voxel.green, blue: voxel.blue };" + " var voxelAt = { x: voxel.x, y: voxel.y, z: voxel.z };" + diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index c817afcdd4..fa3774f2e3 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -392,8 +392,9 @@ function deleteIfInvader(possibleInvaderParticle) { } } -function particleCollisionWithParticle(particleA, particleB) { +function particleCollisionWithParticle(particleA, particleB, penetration) { print("particleCollisionWithParticle() a.id="+particleA.id + " b.id=" + particleB.id); + Vec3.print('particleCollisionWithParticle() penetration=', penetration); if (missileFired) { myMissile = Particles.identifyParticle(myMissile); if (myMissile.id == particleA.id) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6c6882012..3045cf749b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1560,14 +1560,14 @@ void Application::init() { // connect the _particleCollisionSystem to our script engine's ParticleScriptingInterface connect(&_particleCollisionSystem, - SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&)), + SIGNAL(particleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&)), ScriptEngine::getParticlesScriptingInterface(), - SLOT(forwardParticleCollisionWithVoxel(const ParticleID&, const VoxelDetail&))); + SLOT(forwardParticleCollisionWithVoxel(const ParticleID&, const VoxelDetail&, const glm::vec3&))); connect(&_particleCollisionSystem, - SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&)), + SIGNAL(particleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&)), ScriptEngine::getParticlesScriptingInterface(), - SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&))); + SLOT(forwardParticleCollisionWithParticle(const ParticleID&, const ParticleID&, const glm::vec3&))); _pieMenu.init("./resources/images/hifi-interface-tools-v2-pie.svg", _glWidget->width(), diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index d9f0beb81a..1a0ca7680b 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -884,25 +884,25 @@ void Particle::executeUpdateScripts() { } } -void Particle::collisionWithParticle(Particle* other) { +void Particle::collisionWithParticle(Particle* other, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { ScriptEngine engine(_script); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); ParticleScriptObject otherParticleScriptable(other); - particleScriptable.emitCollisionWithParticle(&otherParticleScriptable); + particleScriptable.emitCollisionWithParticle(&otherParticleScriptable, penetration); endParticleScriptContext(engine, particleScriptable); } } -void Particle::collisionWithVoxel(VoxelDetail* voxelDetails) { +void Particle::collisionWithVoxel(VoxelDetail* voxelDetails, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { ScriptEngine engine(_script); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); - particleScriptable.emitCollisionWithVoxel(*voxelDetails); + particleScriptable.emitCollisionWithVoxel(*voxelDetails, penetration); endParticleScriptContext(engine, particleScriptable); } } diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 84efdd2916..dbe98c5bf6 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -295,8 +295,8 @@ public: void applyHardCollision(const CollisionInfo& collisionInfo); void update(const quint64& now); - void collisionWithParticle(Particle* other); - void collisionWithVoxel(VoxelDetail* voxel); + void collisionWithParticle(Particle* other, const glm::vec3& penetration); + void collisionWithVoxel(VoxelDetail* voxel, const glm::vec3& penetration); void debugDump() const; @@ -371,8 +371,10 @@ public: //~ParticleScriptObject() { qDebug() << "~ParticleScriptObject() this=" << this; } void emitUpdate() { emit update(); } - void emitCollisionWithParticle(QObject* other) { emit collisionWithParticle(other); } - void emitCollisionWithVoxel(const VoxelDetail& voxel) { emit collisionWithVoxel(voxel); } + void emitCollisionWithParticle(QObject* other, const glm::vec3& penetration) + { emit collisionWithParticle(other, penetration); } + void emitCollisionWithVoxel(const VoxelDetail& voxel, const glm::vec3& penetration) + { emit collisionWithVoxel(voxel, penetration); } public slots: unsigned int getID() const { return _particle->getID(); } @@ -417,8 +419,8 @@ public slots: signals: void update(); - void collisionWithVoxel(const VoxelDetail& voxel); - void collisionWithParticle(QObject* other); + void collisionWithVoxel(const VoxelDetail& voxel, const glm::vec3& penetration); + void collisionWithParticle(QObject* other, const glm::vec3& penetration); private: Particle* _particle; diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index b36b6a3a04..f7bf73a637 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -71,15 +71,18 @@ void ParticleCollisionSystem::checkParticle(Particle* particle) { updateCollisionWithAvatars(particle); } -void ParticleCollisionSystem::emitGlobalParticleCollisionWithVoxel(Particle* particle, VoxelDetail* voxelDetails) { +void ParticleCollisionSystem::emitGlobalParticleCollisionWithVoxel(Particle* particle, + VoxelDetail* voxelDetails, const glm::vec3& penetration) { ParticleID particleID = particle->getParticleID(); - emit particleCollisionWithVoxel(particleID, *voxelDetails); + emit particleCollisionWithVoxel(particleID, *voxelDetails, penetration); } -void ParticleCollisionSystem::emitGlobalParticleCollisionWithParticle(Particle* particleA, Particle* particleB) { +void ParticleCollisionSystem::emitGlobalParticleCollisionWithParticle(Particle* particleA, + Particle* particleB, const glm::vec3& penetration) { + ParticleID idA = particleA->getParticleID(); ParticleID idB = particleB->getParticleID(); - emit particleCollisionWithParticle(idA, idB); + emit particleCollisionWithParticle(idA, idB, penetration); } void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { @@ -95,10 +98,10 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { if (_voxels->findSpherePenetration(center, radius, collisionInfo._penetration, (void**)&voxelDetails)) { // let the particles run their collision scripts if they have them - particle->collisionWithVoxel(voxelDetails); + particle->collisionWithVoxel(voxelDetails, collisionInfo._penetration); // let the global script run their collision scripts for particles if they have them - emitGlobalParticleCollisionWithVoxel(particle, voxelDetails); + emitGlobalParticleCollisionWithVoxel(particle, voxelDetails, collisionInfo._penetration); updateCollisionSound(particle, collisionInfo._penetration, COLLISION_FREQUENCY); collisionInfo._penetration /= (float)(TREE_SCALE); @@ -125,9 +128,9 @@ void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particleA) // we don't want to count this as a collision. glm::vec3 relativeVelocity = particleA->getVelocity() - particleB->getVelocity(); if (glm::dot(relativeVelocity, penetration) > 0.0f) { - particleA->collisionWithParticle(particleB); - particleB->collisionWithParticle(particleA); - emitGlobalParticleCollisionWithParticle(particleA, particleB); + particleA->collisionWithParticle(particleB, penetration); + particleB->collisionWithParticle(particleA, penetration * -1.0f); // the penetration is reversed + emitGlobalParticleCollisionWithParticle(particleA, particleB, penetration); glm::vec3 axis = glm::normalize(penetration); glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis; diff --git a/libraries/particles/src/ParticleCollisionSystem.h b/libraries/particles/src/ParticleCollisionSystem.h index 3bff843743..1b30fd31ac 100644 --- a/libraries/particles/src/ParticleCollisionSystem.h +++ b/libraries/particles/src/ParticleCollisionSystem.h @@ -53,13 +53,13 @@ public: void updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency); signals: - void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel); - void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB); + void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const glm::vec3& penetration); + void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration); private: static bool updateOperation(OctreeElement* element, void* extraData); - void emitGlobalParticleCollisionWithVoxel(Particle* particle, VoxelDetail* voxelDetails); - void emitGlobalParticleCollisionWithParticle(Particle* particleA, Particle* particleB); + void emitGlobalParticleCollisionWithVoxel(Particle* particle, VoxelDetail* voxelDetails, const glm::vec3& penetration); + void emitGlobalParticleCollisionWithParticle(Particle* particleA, Particle* particleB, const glm::vec3& penetration); ParticleEditPacketSender* _packetSender; ParticleTree* _particles; diff --git a/libraries/particles/src/ParticlesScriptingInterface.h b/libraries/particles/src/ParticlesScriptingInterface.h index ee21424f11..af5f76a6af 100644 --- a/libraries/particles/src/ParticlesScriptingInterface.h +++ b/libraries/particles/src/ParticlesScriptingInterface.h @@ -29,12 +29,13 @@ public: private slots: /// inbound slots for external collision systems - void forwardParticleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel) { - emit particleCollisionWithVoxel(particleID, voxel); + void forwardParticleCollisionWithVoxel(const ParticleID& particleID, + const VoxelDetail& voxel, const glm::vec3& penetration) { + emit particleCollisionWithVoxel(particleID, voxel, penetration); } - void forwardParticleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB) { - emit particleCollisionWithParticle(idA, idB); + void forwardParticleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration) { + emit particleCollisionWithParticle(idA, idB, penetration); } public slots: @@ -65,8 +66,8 @@ public slots: QVector findParticles(const glm::vec3& center, float radius) const; signals: - void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel); - void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB); + void particleCollisionWithVoxel(const ParticleID& particleID, const VoxelDetail& voxel, const glm::vec3& penetration); + void particleCollisionWithParticle(const ParticleID& idA, const ParticleID& idB, const glm::vec3& penetration); private: void queueParticleMessage(PacketType packetType, ParticleID particleID, const ParticleProperties& properties); diff --git a/libraries/script-engine/src/Vec3.cpp b/libraries/script-engine/src/Vec3.cpp index 2c5bf172fd..542492062a 100644 --- a/libraries/script-engine/src/Vec3.cpp +++ b/libraries/script-engine/src/Vec3.cpp @@ -9,6 +9,8 @@ // // +#include + #include "Vec3.h" glm::vec3 Vec3::multiply(const glm::vec3& v1, const glm::vec3& v2) { @@ -32,3 +34,11 @@ glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) { float Vec3::length(const glm::vec3& v) { return glm::length(v); } + +glm::vec3 Vec3::normalize(const glm::vec3& v) { + return glm::normalize(v); +} + +void Vec3::print(const QString& lable, const glm::vec3& v) { + qDebug() << qPrintable(lable) << v.x << "," << v.y << "," << v.z; +} \ No newline at end of file diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 20ad3f7eaa..c5ba05a74a 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -27,6 +27,8 @@ public slots: glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2); glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2); float length(const glm::vec3& v); + glm::vec3 normalize(const glm::vec3& v); + void print(const QString& lable, const glm::vec3& v); }; From 3930b3e8247e1382f80db5e058ed6838460a0553 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 5 Mar 2014 17:44:08 -0800 Subject: [PATCH 16/17] Display names are great, but not in the shadow map. Closes #2208. --- interface/src/Application.cpp | 4 ++-- interface/src/avatar/Avatar.cpp | 11 +++++++---- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/AvatarManager.cpp | 16 ++++++++-------- interface/src/avatar/AvatarManager.h | 4 ++-- interface/src/avatar/MyAvatar.cpp | 8 ++++---- interface/src/avatar/MyAvatar.h | 2 +- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1e9d206462..7a7420656a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2383,8 +2383,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR); } - bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); - _avatarManager.renderAvatars(forceRenderMyHead, selfAvatarOnly); + bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); + _avatarManager.renderAvatars(mirrorMode, selfAvatarOnly); if (!selfAvatarOnly) { // Render the world box diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ef6975d223..a304fa1c99 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -201,7 +201,7 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render() { +void Avatar::render(bool forShadowMap) { glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); float lengthToTarget = glm::length(toTarget); @@ -209,7 +209,7 @@ void Avatar::render() { // glow when moving in the distance const float GLOW_DISTANCE = 5.0f; - Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f); + Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); // render body if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { @@ -233,7 +233,7 @@ void Avatar::render() { float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; - if ((sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { + if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); @@ -243,7 +243,10 @@ void Avatar::render() { } } const float DISPLAYNAME_DISTANCE = 10.0f; - setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE); + setShowDisplayName(!forShadowMap && lengthToTarget < DISPLAYNAME_DISTANCE); + if (forShadowMap) { + return; + } renderDisplayName(); if (!_chatMessage.empty()) { diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 8de5da8d50..d5c311a274 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -74,7 +74,7 @@ public: void init(); void simulate(float deltaTime); - void render(); + void render(bool forShadowMap = false); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 847baf782f..57e800a401 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -69,7 +69,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { +void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); @@ -83,16 +83,16 @@ void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { avatar->init(); } if (avatar == static_cast(_myAvatar.data())) { - _myAvatar->render(forceRenderMyHead); + _myAvatar->render(forShadowMapOrMirror); } else { - avatar->render(); + avatar->render(forShadowMapOrMirror); } avatar->setDisplayingLookatVectors(renderLookAtVectors); } - renderAvatarFades(); + renderAvatarFades(forShadowMapOrMirror); } else { // just render myAvatar - _myAvatar->render(forceRenderMyHead, true); + _myAvatar->render(forShadowMapOrMirror); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } @@ -115,13 +115,13 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } } -void AvatarManager::renderAvatarFades() { +void AvatarManager::renderAvatarFades(bool forShadowMap) { // render avatar fades - Glower glower; + Glower glower(forShadowMap ? 0.0f : 1.0f); foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { Avatar* avatar = static_cast(fadingAvatar.data()); - avatar->render(); + avatar->render(forShadowMap); } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index db24d5bf4e..c690dfa966 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -29,7 +29,7 @@ public: MyAvatar* getMyAvatar() { return _myAvatar.data(); } void updateOtherAvatars(float deltaTime); - void renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly = false); + void renderAvatars(bool forShadowMapOrMirror = false, bool selfAvatarOnly = false); void clearOtherAvatars(); @@ -45,7 +45,7 @@ private: void processKillAvatar(const QByteArray& datagram); void simulateAvatarFades(float deltaTime); - void renderAvatarFades(); + void renderAvatarFades(bool forShadowMap); // virtual override AvatarHash::iterator erase(const AvatarHash::iterator& iterator); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 51fcad20ae..407a49dcb5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -452,7 +452,7 @@ void MyAvatar::renderDebugBodyPoints() { } -void MyAvatar::render(bool forceRenderHead, bool avatarOnly) { +void MyAvatar::render(bool forShadowMapOrMirror) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early @@ -466,10 +466,10 @@ void MyAvatar::render(bool forceRenderHead, bool avatarOnly) { _skeletonModel.renderCollisionProxies(1.f); } if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(forceRenderHead); + renderBody(forShadowMapOrMirror); } - setShowDisplayName(!avatarOnly); - if (avatarOnly) { + setShowDisplayName(!forShadowMapOrMirror); + if (forShadowMapOrMirror) { return; } renderDisplayName(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index aeb9e6d968..e9dfbd8bd0 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -35,7 +35,7 @@ public: void simulate(float deltaTime); void updateFromGyros(float deltaTime); - void render(bool forceRenderHead, bool avatarOnly = false); + void render(bool forShadowMapOrMirror = false); void renderDebugBodyPoints(); void renderHeadMouse() const; From ad25455f868608909f6114ef0776c0cc440d9232 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 5 Mar 2014 18:06:14 -0800 Subject: [PATCH 17/17] Track hysteresis for next model separately, but just in case, don't use recursion to fall back on hysteresis value. Closes #2209. --- interface/src/renderer/GeometryCache.cpp | 9 ++++++++- interface/src/renderer/Model.cpp | 5 +++-- interface/src/renderer/Model.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 5b13e2da42..88d2a8962d 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -343,7 +343,14 @@ QSharedPointer NetworkGeometry::getLODOrFallback(float distance // if we previously selected a different distance, make sure we've moved far enough to justify switching const float HYSTERESIS_PROPORTION = 0.1f; if (glm::abs(distance - qMax(hysteresis, lodDistance)) / fabsf(hysteresis - lodDistance) < HYSTERESIS_PROPORTION) { - return getLODOrFallback(hysteresis, hysteresis); + lod = _lodParent; + lodDistance = 0.0f; + it = _lods.upperBound(hysteresis); + if (it != _lods.constBegin()) { + it = it - 1; + lod = it.value(); + lodDistance = it.key(); + } } } if (lod->isLoaded()) { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 1aab0a4dab..0cff3aaa87 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -416,6 +416,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo // if so instructed, keep the current geometry until the new one is loaded _nextBaseGeometry = _nextGeometry = Application::getInstance()->getGeometryCache()->getGeometry(url, fallback, delayLoad); + _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) { applyNextGeometry(); } @@ -784,7 +785,7 @@ void Model::applyCollision(CollisionInfo& collision) { QVector Model::updateGeometry(bool delayLoad) { QVector newJointStates; if (_nextGeometry) { - _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _lodHysteresis, delayLoad); + _nextGeometry = _nextGeometry->getLODOrFallback(_lodDistance, _nextLODHysteresis, delayLoad); if (!delayLoad) { _nextGeometry->setLoadPriority(this, -_lodDistance); _nextGeometry->ensureLoading(); @@ -827,7 +828,7 @@ void Model::applyNextGeometry() { // delete our local geometry and custom textures deleteGeometry(); _dilatedTextures.clear(); - _lodHysteresis = NetworkGeometry::NO_HYSTERESIS; + _lodHysteresis = _nextLODHysteresis; // we retain a reference to the base geometry so that its reference count doesn't fall to zero _baseGeometry = _nextBaseGeometry; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 524bd9dc79..ae28a8e4fe 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -247,6 +247,7 @@ private: QSharedPointer _nextGeometry; float _lodDistance; float _lodHysteresis; + float _nextLODHysteresis; float _pupilDilation; std::vector _blendshapeCoefficients;