From 017cb2cb6c88ad483a8bfb612b89e3607ffeed03 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 4 Nov 2015 11:53:42 -0800 Subject: [PATCH 1/7] Getting rid of HTTPS external dependencies --- cmake/externals/boostconfig/CMakeLists.txt | 3 ++- cmake/externals/bullet/CMakeLists.txt | 6 ++++-- cmake/externals/openvr/CMakeLists.txt | 3 ++- cmake/externals/sdl2/CMakeLists.txt | 4 ++-- cmake/externals/sixense/CMakeLists.txt | 8 ++++---- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/cmake/externals/boostconfig/CMakeLists.txt b/cmake/externals/boostconfig/CMakeLists.txt index ed3413a894..0adb349589 100644 --- a/cmake/externals/boostconfig/CMakeLists.txt +++ b/cmake/externals/boostconfig/CMakeLists.txt @@ -4,7 +4,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://github.com/boostorg/config/archive/boost-1.58.0.zip + #URL https://github.com/boostorg/config/archive/boost-1.58.0.zip + URL http://hifi-public.s3.amazonaws.com/dependencies/config-boost-1.58.0.zip URL_MD5 42fa673bae2b7645a22736445e80eb8d CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/externals/bullet/CMakeLists.txt b/cmake/externals/bullet/CMakeLists.txt index 56e6bf0ccc..efe5b694fa 100644 --- a/cmake/externals/bullet/CMakeLists.txt +++ b/cmake/externals/bullet/CMakeLists.txt @@ -17,7 +17,8 @@ include(ExternalProject) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip + # URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip + URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-r2704.zip URL_MD5 f5e8914fc9064ad32e0d62d19d33d977 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 -DUSE_DX11=0 LOG_DOWNLOAD 1 @@ -28,7 +29,8 @@ if (WIN32) else () ExternalProject_Add( ${EXTERNAL_NAME} - URL http://bullet.googlecode.com/files/bullet-2.82-r2704.tgz + #URL http://bullet.googlecode.com/files/bullet-2.82-r2704.tgz + URL http://hifi-public.s3.amazonaws.com/dependencies/bullet-2.82-r2704.tgz URL_MD5 70b3c8d202dee91a0854b4cbc88173e8 CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0 LOG_DOWNLOAD 1 diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt index 2bb84ca637..dea59f41a0 100644 --- a/cmake/externals/openvr/CMakeLists.txt +++ b/cmake/externals/openvr/CMakeLists.txt @@ -7,7 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip + #URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip + URL http://hifi-public.s3.amazonaws.com/dependencies/openvr-0.9.1.zip URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/externals/sdl2/CMakeLists.txt b/cmake/externals/sdl2/CMakeLists.txt index abd436d571..decd1c6906 100644 --- a/cmake/externals/sdl2/CMakeLists.txt +++ b/cmake/externals/sdl2/CMakeLists.txt @@ -7,7 +7,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://www.libsdl.org/release/SDL2-devel-2.0.3-VC.zip + URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-devel-2.0.3-VC.zip URL_MD5 30a333bcbe94bc5016e8799c73e86233 CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -18,7 +18,7 @@ elseif (APPLE) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3.zip + URL http://hifi-public.s3.amazonaws.com/dependencies/SDL2-2.0.3.zip CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DVIDEO_OPENGL=OFF BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build LOG_DOWNLOAD 1 diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index 0cbca087a5..c41694344e 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -4,15 +4,15 @@ set(EXTERNAL_NAME sixense) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -#set(SIXENSE_URL "https://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_062612.zip") +#set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_062612.zip") #set(SIXENSE_URL_MD5 "10cc8dc470d2ac1244a88cf04bc549cc") #set(SIXENSE_NEW_LAYOUT 0) -#set(SIXENSE_URL "https://public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip") +#set(SIXENSE_URL "http://public.s3.amazonaws.com/dependencies/SixenseSDK_071615.zip") #set(SIXENSE_URL_MD5 "752a3901f334124e9cffc2ba4136ef7d") #set(SIXENSE_NEW_LAYOUT 1) -set(SIXENSE_URL "https://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_102215.zip") +set(SIXENSE_URL "http://hifi-public.s3.amazonaws.com/dependencies/SixenseSDK_102215.zip") set(SIXENSE_URL_MD5 "93c3a6795cce777a0f472b09532935f1") set(SIXENSE_NEW_LAYOUT 1) @@ -43,7 +43,7 @@ if (WIN32) endif() if (${SIXENSE_NEW_LAYOUT}) - # for 2015 SDKs (using the 2013 versions may be causing the crash) + # for 2015 SDKs (using the VS2013 versions may be causing the crash, so use the VS2010 versions) set(${EXTERNAL_NAME_UPPER}_DLL_PATH "${SOURCE_DIR}/bin/${ARCH_DIR}/VS2010/release_dll") set(${EXTERNAL_NAME_UPPER}_LIB_PATH "${SOURCE_DIR}/lib/${ARCH_DIR}/VS2010/release_dll") else() From 8b20a3c90368ec6f26697d147c7f871b6744252d Mon Sep 17 00:00:00 2001 From: Alan Z Date: Wed, 4 Nov 2015 14:41:11 -0800 Subject: [PATCH 2/7] Created playaSpawner and fixed cleanup issue --- examples/playa/playaSpawner.js | 142 +++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 examples/playa/playaSpawner.js diff --git a/examples/playa/playaSpawner.js b/examples/playa/playaSpawner.js new file mode 100644 index 0000000000..61101a0e62 --- /dev/null +++ b/examples/playa/playaSpawner.js @@ -0,0 +1,142 @@ +// dustSetSpawner.js +// examples +// +// Created by Eric Levin on 9/2/15 +// Copyright 2015 High Fidelity, Inc. +// +// Spawns a set with blocks and a desert-y ground. When blocks (or anything else is thrown), dust particles will kick up at the point the object hits the ground +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ + + +map = function(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); +} + +orientationOf = function(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} + + +var ground, wall; +var boxes = []; +var dustSystems = []; +var ZERO_VEC = {x: 0, y: 0, z: 0}; + +Script.include("../libraries/utils.js"); + +function spawnGround() { + var groundModelURL = "https://hifi-public.s3.amazonaws.com/alan/Playa/Ground.fbx"; + var groundPosition = Vec3.sum(MyAvatar.position, {x: 0, y: -2, z: 0}); + ground = Entities.addEntity({ + type: "Model", + modelURL: groundModelURL, + shapeType: "box", + position: groundPosition, + dimensions: {x: 900, y: 0.82, z: 900}, + }); + // Script.addEventHandler(ground, "collisionWithEntity", entityCollisionWithGround); + +} + +/*function entityCollisionWithGround(ground, entity, collision) { + var dVelocityMagnitude = Vec3.length(collision.velocityChange); + var position = Entities.getEntityProperties(entity, "position").position; + var particleRadius = map(dVelocityMagnitude, 0.05, 3, 0.5, 2); + var speed = map(dVelocityMagnitude, 0.05, 3, 0.02, 0.09); + var displayTime = 400; + var orientationChange = orientationOf(collision.velocityChange); + var dustEffect = Entities.addEntity({ + type: "ParticleEffect", + name: "Dust-Puff", + position: position, + color: {red: 195, green: 170, blue: 185}, + lifespan: 3, + lifetime: 7,//displayTime/1000 * 2, //So we can fade particle system out gracefully + emitRate: 5, + emitSpeed: speed, + emitAcceleration: ZERO_VEC, + accelerationSpread: ZERO_VEC, + isEmitting: true, + polarStart: Math.PI/2, + polarFinish: Math.PI/2, + emitOrientation: orientationChange, + radiusSpread: 0.1, + radiusStart: particleRadius, + radiusFinish: particleRadius + particleRadius/2, + particleRadius: particleRadius, + alpha: 0.45, + alphaFinish: 0.001, + textures: "https://hifi-public.s3.amazonaws.com/alan/Playa/Particles/Particle-Sprite-Gen.png" + }); + + dustSystems.push(dustEffect); + + Script.setTimeout(function() { + var newRadius = 0.05; + Entities.editEntity(dustEffect, { + alpha: 0.0 + }); + }, displayTime); +}*/ + +function spawnBoxes() { + var boxModelURL = "https://hifi-public.s3.amazonaws.com/alan/Tower-Spawn/Stone-Block.fbx"; + var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; + var numBoxes = 200; + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + for (var i = 0; i < numBoxes; i++) { + var position = Vec3.sum(center, {x: Math.random() * numBoxes, y: Math.random() * 3, z: Math.random() * numBoxes }) + var box = Entities.addEntity({ + type: "Model", + modelURL: boxModelURL, + collisionSoundURL: collisionSoundURL, + shapeType: "box", + position: position, + collisionsWillMove: true, + dimensions: {x: 1, y: 2, z: 3}, + velocity: {x: 0, y: -.01, z: 0}, + gravity: {x: 0, y: -2.5 - Math.random() * 6, z: 0} + }); + + boxes.push(box); + } +} + +spawnGround(); +spawnBoxes(); + + +function cleanup() { + Entities.deleteEntity(ground); + boxes.forEach(function(box){ + Entities.deleteEntity(box); + }); + dustSystems.forEach(function(dustEffect) { + Entities.deleteEntity(dustEffect); + }) +} + +Script.scriptEnding.connect(cleanup); + + From 07b3597ae363f79202a5f59cbf3de353f29c648b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 31 Aug 2015 16:53:30 +0200 Subject: [PATCH 3/7] Fix recording scripts --- examples/acScripts/ControlACs.js | 22 ++- examples/acScripts/ControlledAC.js | 202 ++++++++++++------------ examples/acScripts/PlayRecordingOnAC.js | 47 +++--- examples/utilities/record/recorder.js | 7 +- libraries/avatars/src/Player.cpp | 11 +- libraries/avatars/src/Recorder.h | 1 - 6 files changed, 146 insertions(+), 144 deletions(-) diff --git a/examples/acScripts/ControlACs.js b/examples/acScripts/ControlACs.js index 45c498dc7f..403c0878cb 100644 --- a/examples/acScripts/ControlACs.js +++ b/examples/acScripts/ControlACs.js @@ -16,11 +16,11 @@ var NUM_AC = 3; // This is the number of AC. Their ID need to be unique and betw var NAMES = new Array("Craig", "Clement", "Jeff"); // ACs names ordered by IDs (Default name is "ACx", x = ID + 1)) // Those variables MUST be common to every scripts -var controlVoxelSize = 0.25; -var controlVoxelPosition = { x: 2000 , y: 0, z: 0 }; +var controlEntitySize = 0.25; +var controlEntityPosition = { x: 2000 , y: 0, z: 0 }; // Script. DO NOT MODIFY BEYOND THIS LINE. -Script.include("libraries/toolBars.js"); +Script.include("../libraries/toolBars.js"); var DO_NOTHING = 0; var PLAY = 1; @@ -138,16 +138,22 @@ function sendCommand(id, action) { return; } - if (id === toolBars.length - 1) { + if (id === (toolBars.length - 1)) { for (i = 0; i < NUM_AC; i++) { sendCommand(i, action); } return; } - - // TODO: Fix this to use some mechanism other than voxels - //Voxels.setVoxel(controlVoxelPosition.x + id * controlVoxelSize, controlVoxelPosition.y, controlVoxelPosition.z, - // controlVoxelSize, COLORS[action].red, COLORS[action].green, COLORS[action].blue); + + var position = { x: controlEntityPosition.x + id * controlEntitySize, + y: controlEntityPosition.y, z: controlEntityPosition.z }; + Entities.addEntity({ + type: "Box", + position: position, + dimensions: { x: controlEntitySize, y: controlEntitySize, z: controlEntitySize }, + color: COLORS[action], + lifetime: 5 + }); } function mousePressEvent(event) { diff --git a/examples/acScripts/ControlledAC.js b/examples/acScripts/ControlledAC.js index 78fe3903cd..93c71aa1a1 100644 --- a/examples/acScripts/ControlledAC.js +++ b/examples/acScripts/ControlledAC.js @@ -12,27 +12,25 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // Set the following variables to the values needed -var filename = HIFI_PUBLIC_BUCKET + "ozan/bartender.rec"; +var filename = "/Users/clement/Desktop/recording.hfr"; var playFromCurrentLocation = true; var useDisplayName = true; var useAttachments = true; -var useHeadModel = true; -var useSkeletonModel = true; +var useAvatarModel = true; // ID of the agent. Two agents can't have the same ID. var id = 0; -// Set head and skeleton models -Avatar.faceModelURL = "http://public.highfidelity.io/models/heads/EvilPhilip_v7.fst"; -Avatar.skeletonModelURL = "http://public.highfidelity.io/models/skeletons/Philip_Carl_Body_A-Pose.fst"; +// Set avatar model URL +Avatar.skeletonModelURL = "https://hifi-public.s3.amazonaws.com/marketplace/contents/e21c0b95-e502-4d15-8c41-ea2fc40f1125/3585ddf674869a67d31d5964f7b52de1.fst?1427169998"; // Set position/orientation/scale here if playFromCurrentLocation is true Avatar.position = { x:1, y: 1, z: 1 }; Avatar.orientation = Quat.fromPitchYawRollDegrees(0, 0, 0); Avatar.scale = 1.0; // Those variables MUST be common to every scripts -var controlVoxelSize = 0.25; -var controlVoxelPosition = { x: 2000 , y: 0, z: 0 }; +var controlEntitySize = 0.25; +var controlEntityPosition = { x: 2000, y: 0, z: 0 }; // Script. DO NOT MODIFY BEYOND THIS LINE. var DO_NOTHING = 0; @@ -49,113 +47,111 @@ COLORS[STOP] = { red: STOP, green: 0, blue: 0 }; COLORS[SHOW] = { red: SHOW, green: 0, blue: 0 }; COLORS[HIDE] = { red: HIDE, green: 0, blue: 0 }; -controlVoxelPosition.x += id * controlVoxelSize; - +controlEntityPosition.x += id * controlEntitySize; + Avatar.loadRecording(filename); Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); Avatar.setPlayerUseDisplayName(useDisplayName); Avatar.setPlayerUseAttachments(useAttachments); -Avatar.setPlayerUseHeadModel(useHeadModel); -Avatar.setPlayerUseSkeletonModel(useSkeletonModel); +Avatar.setPlayerUseHeadModel(false); +Avatar.setPlayerUseSkeletonModel(useAvatarModel); -function setupVoxelViewer() { - var voxelViewerOffset = 10; - var voxelViewerPosition = JSON.parse(JSON.stringify(controlVoxelPosition)); - voxelViewerPosition.x -= voxelViewerOffset; - var voxelViewerOrientation = Quat.fromPitchYawRollDegrees(0, -90, 0); - - VoxelViewer.setPosition(voxelViewerPosition); - VoxelViewer.setOrientation(voxelViewerOrientation); - VoxelViewer.queryOctree(); +function setupEntityViewer() { + var entityViewerOffset = 10; + var entityViewerPosition = { x: controlEntityPosition.x - entityViewerOffset, + y: controlEntityPosition.y, z: controlEntityPosition.z }; + var entityViewerOrientation = Quat.fromPitchYawRollDegrees(0, -90, 0); + + EntityViewer.setPosition(entityViewerPosition); + EntityViewer.setOrientation(entityViewerOrientation); + EntityViewer.queryOctree(); } -function getAction(controlVoxel) { - if (controlVoxel.x != controlVoxelPosition.x || - controlVoxel.y != controlVoxelPosition.y || - controlVoxel.z != controlVoxelPosition.z || - controlVoxel.s != controlVoxelSize) { - return DO_NOTHING; - } - - for (i in COLORS) { - if (controlVoxel.red === COLORS[i].red && - controlVoxel.green === COLORS[i].green && - controlVoxel.blue === COLORS[i].blue) { - - // TODO: Fix this to use some mechanism other than voxels - //Voxels.eraseVoxel(controlVoxelPosition.x, controlVoxelPosition.y, controlVoxelPosition.z, controlVoxelSize); - return parseInt(i); +function getAction(controlEntity) { + if (controlEntity === null || + controlEntity.position.x !== controlEntityPosition.x || + controlEntity.position.y !== controlEntityPosition.y || + controlEntity.position.z !== controlEntityPosition.z || + controlEntity.dimensions.x !== controlEntitySize) { + return DO_NOTHING; } - } - - return DO_NOTHING; + + for (i in COLORS) { + if (controlEntity.color.red === COLORS[i].red && + controlEntity.color.green === COLORS[i].green && + controlEntity.color.blue === COLORS[i].blue) { + Entities.deleteEntity(controlEntity.id); + return parseInt(i); + } + } + + return DO_NOTHING; } -count = 300; // This is necessary to wait for the audio mixer to connect +count = 100; // This is necessary to wait for the audio mixer to connect function update(event) { - VoxelViewer.queryOctree(); - if (count > 0) { - count--; - return; - } - - // TODO: Fix this to use some mechanism other than voxels - // Voxels.getVoxelAt(controlVoxelPosition.x, controlVoxelPosition.y, controlVoxelPosition.z, controlVoxelSize); - var controlVoxel = false; - var action = getAction(controlVoxel); - - switch(action) { - case PLAY: - print("Play"); - if (!Agent.isAvatar) { - Agent.isAvatar = true; - } - if (!Avatar.isPlaying()) { - Avatar.startPlaying(); - } - Avatar.setPlayerLoop(false); - break; - case PLAY_LOOP: - print("Play loop"); - if (!Agent.isAvatar) { - Agent.isAvatar = true; - } - if (!Avatar.isPlaying()) { - Avatar.startPlaying(); - } - Avatar.setPlayerLoop(true); - break; - case STOP: - print("Stop"); - if (Avatar.isPlaying()) { - Avatar.stopPlaying(); - } - break; - case SHOW: - print("Show"); - if (!Agent.isAvatar) { - Agent.isAvatar = true; - } - break; - case HIDE: - print("Hide"); - if (Avatar.isPlaying()) { - Avatar.stopPlaying(); - } - Agent.isAvatar = false; - break; - case DO_NOTHING: - break; - default: - print("Unknown action: " + action); - break; - } - - if (Avatar.isPlaying()) { - Avatar.play(); - } + EntityViewer.queryOctree(); + if (count > 0) { + count--; + return; + } + + + var controlEntity = Entities.findClosestEntity(controlEntityPosition, controlEntitySize); + var action = getAction(Entities.getEntityProperties(controlEntity)); + + switch(action) { + case PLAY: + print("Play"); + if (!Agent.isAvatar) { + Agent.isAvatar = true; + } + if (!Avatar.isPlaying()) { + Avatar.startPlaying(); + } + Avatar.setPlayerLoop(false); + break; + case PLAY_LOOP: + print("Play loop"); + if (!Agent.isAvatar) { + Agent.isAvatar = true; + } + if (!Avatar.isPlaying()) { + Avatar.startPlaying(); + } + Avatar.setPlayerLoop(true); + break; + case STOP: + print("Stop"); + if (Avatar.isPlaying()) { + Avatar.stopPlaying(); + } + break; + case SHOW: + print("Show"); + if (!Agent.isAvatar) { + Agent.isAvatar = true; + } + break; + case HIDE: + print("Hide"); + if (Avatar.isPlaying()) { + Avatar.stopPlaying(); + } + Agent.isAvatar = false; + break; + case DO_NOTHING: + break; + default: + print("Unknown action: " + action); + break; + } + + if (Avatar.isPlaying()) { + Avatar.play(); + } } Script.update.connect(update); -setupVoxelViewer(); \ No newline at end of file +setupEntityViewer(); diff --git a/examples/acScripts/PlayRecordingOnAC.js b/examples/acScripts/PlayRecordingOnAC.js index 76f00ab9cd..b7ae2c7329 100644 --- a/examples/acScripts/PlayRecordingOnAC.js +++ b/examples/acScripts/PlayRecordingOnAC.js @@ -14,8 +14,7 @@ var filename = "http://your.recording.url"; var playFromCurrentLocation = true; var loop = true; -Avatar.faceModelURL = "http://public.highfidelity.io/models/heads/EvilPhilip_v7.fst"; -Avatar.skeletonModelURL = "http://public.highfidelity.io/models/skeletons/Philip_Carl_Body_A-Pose.fst"; +Avatar.skeletonModelURL = "https://hifi-public.s3.amazonaws.com/marketplace/contents/e21c0b95-e502-4d15-8c41-ea2fc40f1125/3585ddf674869a67d31d5964f7b52de1.fst?1427169998"; // Set position here if playFromCurrentLocation is true Avatar.position = { x:1, y: 1, z: 1 }; @@ -23,30 +22,34 @@ Avatar.orientation = Quat.fromPitchYawRollDegrees(0, 0, 0); Avatar.scale = 1.0; Agent.isAvatar = true; - + Avatar.loadRecording(filename); count = 300; // This is necessary to wait for the audio mixer to connect function update(event) { - if (count > 0) { - count--; - return; - } - if (count == 0) { - Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); - Avatar.setPlayerLoop(loop); - Avatar.startPlaying(); - Avatar.play(); - Vec3.print("Playing from ", Avatar.position); - - count--; - } - - if (Avatar.isPlaying()) { - Avatar.play(); - } else { - Script.update.disconnect(update); - } + if (count > 0) { + count--; + return; + } + if (count == 0) { + Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); + Avatar.setPlayerLoop(loop); + Avatar.setPlayerUseDisplayName(true); + Avatar.setPlayerUseAttachments(true); + Avatar.setPlayerUseHeadModel(false); + Avatar.setPlayerUseSkeletonModel(true); + Avatar.startPlaying(); + Avatar.play(); + Vec3.print("Playing from ", Avatar.position); + + count--; + } + + if (Avatar.isPlaying()) { + Avatar.play(); + } else { + Script.update.disconnect(update); + } } Script.update.connect(update); diff --git a/examples/utilities/record/recorder.js b/examples/utilities/record/recorder.js index 495a862db1..6d49030a28 100644 --- a/examples/utilities/record/recorder.js +++ b/examples/utilities/record/recorder.js @@ -112,10 +112,9 @@ function setupTimer() { text: (0.00).toFixed(3), backgroundColor: COLOR_OFF, x: 0, y: 0, - width: 0, - height: 0, - alpha: 1.0, - backgroundAlpha: 1.0, + width: 0, height: 0, + leftMargin: 10, topMargin: 10, + alpha: 1.0, backgroundAlpha: 1.0, visible: true }); diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index a425323a41..5e29963e4b 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -397,16 +397,15 @@ bool Player::computeCurrentFrame() { } qint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength()); - while(_currentFrame >= 0 && - _recording->getFrameTimestamp(_currentFrame) > elapsed) { - --_currentFrame; - } - while (_currentFrame < _recording->getFrameNumber() && _recording->getFrameTimestamp(_currentFrame) < elapsed) { ++_currentFrame; } - --_currentFrame; + + while(_currentFrame > 0 && + _recording->getFrameTimestamp(_currentFrame) > elapsed) { + --_currentFrame; + } if (_currentFrame == _recording->getFrameNumber() - 1) { --_currentFrame; diff --git a/libraries/avatars/src/Recorder.h b/libraries/avatars/src/Recorder.h index 2723ebebdb..f81539a417 100644 --- a/libraries/avatars/src/Recorder.h +++ b/libraries/avatars/src/Recorder.h @@ -43,7 +43,6 @@ public slots: void record(); void recordAudio(const QByteArray& audioArray); - private: QElapsedTimer _timer; RecordingPointer _recording; From ffafd3194e7eb5451ac34e3b65dc03fcce029a1b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 5 Nov 2015 15:02:21 -0800 Subject: [PATCH 4/7] Recording audio fixes --- interface/src/avatar/MyAvatar.cpp | 2 +- libraries/audio-client/src/AudioClient.cpp | 11 ++++------- libraries/audio/src/AudioInjector.cpp | 4 ++-- libraries/avatars/src/Recording.cpp | 8 ++++---- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5bd3e82ffd..57af9e732d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -604,7 +604,7 @@ void MyAvatar::startRecording() { // connect to AudioClient's signal so we get input audio auto audioClient = DependencyManager::get(); connect(audioClient.data(), &AudioClient::inputReceived, _recorder.data(), - &Recorder::recordAudio, Qt::BlockingQueuedConnection); + &Recorder::recordAudio, Qt::QueuedConnection); _recorder->startRecording(); } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index d4980596dd..936411d786 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -802,16 +802,14 @@ void AudioClient::handleAudioInput() { _timeSinceLastClip += (float) numNetworkSamples / (float) AudioConstants::SAMPLE_RATE; } - int16_t* inputAudioSamples = new int16_t[inputSamplesRequired]; - _inputRingBuffer.readSamples(inputAudioSamples, inputSamplesRequired); + auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); + _inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired); possibleResampling(_inputToNetworkResampler, - inputAudioSamples, networkAudioSamples, + inputAudioSamples.get(), networkAudioSamples, inputSamplesRequired, numNetworkSamples, _inputFormat, _desiredInputFormat); - delete[] inputAudioSamples; - // Remove DC offset if (!_isStereoInput && !_audioSourceInjectEnabled) { _inputGate.removeDCOffset(networkAudioSamples, numNetworkSamples); @@ -842,8 +840,7 @@ void AudioClient::handleAudioInput() { _lastInputLoudness = fabs(loudness / numNetworkSamples); } - emit inputReceived(QByteArray(reinterpret_cast(networkAudioSamples), - AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * sizeof(AudioConstants::AudioSample))); + emit inputReceived({reinterpret_cast(networkAudioSamples), numNetworkBytes}); } else { // our input loudness is 0, since we're muted diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 334c44c4c5..bd807f8dbd 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -205,7 +205,7 @@ void AudioInjector::injectToMixer() { while (_currentSendOffset < _audioData.size() && !_shouldStop) { - int bytesToCopy = std::min(((_options.stereo) ? 2 : 1) * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL, + int bytesToCopy = std::min((_options.stereo ? 2 : 1) * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL, _audioData.size() - _currentSendOffset); // Measure the loudness of this frame @@ -261,7 +261,7 @@ void AudioInjector::injectToMixer() { // not the first packet and not done // sleep for the appropriate time - int usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; + int usecToSleep = (++nextFrame * (_options.stereo ? 2 : 1) * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000; if (usecToSleep > 0) { usleep(usecToSleep); diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 5514b97b6f..2e2f46552d 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -69,10 +69,10 @@ const RecordingFrame& Recording::getFrame(int i) const { int Recording::numberAudioChannel() const { // Check for stereo audio - int MSEC_PER_SEC = 1000; - int channelLength = (getLength() / MSEC_PER_SEC) * - AudioConstants::SAMPLE_RATE * sizeof(AudioConstants::AudioSample); - return glm::round((float)channelLength / (float)getAudioData().size()); + float MSEC_PER_SEC = 1000.0f; + float channelLength = ((float)getLength() / MSEC_PER_SEC) * AudioConstants::SAMPLE_RATE * + sizeof(AudioConstants::AudioSample); + return glm::round((float)getAudioData().size() / channelLength); } void Recording::addFrame(int timestamp, RecordingFrame &frame) { From 6c35ae48b09bd270598ac9d1713c398f74d75705 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 5 Nov 2015 16:52:38 -0800 Subject: [PATCH 5/7] Don't allocate big samples array in tight loop --- libraries/audio-client/src/AudioClient.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 936411d786..2883bfe332 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -749,8 +749,9 @@ void AudioClient::handleAudioInput() { } float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(); - + int inputSamplesRequired = (int)((float)AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio); + auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); static int leadingBytes = sizeof(quint16) + sizeof(glm::vec3) + sizeof(glm::quat) + sizeof(quint8); int16_t* networkAudioSamples = (int16_t*)(_audioPacket->getPayload() + leadingBytes); @@ -802,9 +803,7 @@ void AudioClient::handleAudioInput() { _timeSinceLastClip += (float) numNetworkSamples / (float) AudioConstants::SAMPLE_RATE; } - auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); _inputRingBuffer.readSamples(inputAudioSamples.get(), inputSamplesRequired); - possibleResampling(_inputToNetworkResampler, inputAudioSamples.get(), networkAudioSamples, inputSamplesRequired, numNetworkSamples, From dbe25651cf3b8a67ad300e8a52799e8ee82c6153 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 5 Nov 2015 16:57:51 -0800 Subject: [PATCH 6/7] constify audio client loop --- libraries/audio-client/src/AudioClient.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 2883bfe332..72e47073f2 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -748,13 +748,13 @@ void AudioClient::handleAudioInput() { _audioPacket = NLPacket::create(PacketType::MicrophoneAudioNoEcho); } - float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(); + const float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(); - int inputSamplesRequired = (int)((float)AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio); - auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); + const int inputSamplesRequired = (int)((float)AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio); + const auto inputAudioSamples = std::unique_ptr(new int16_t[inputSamplesRequired]); - static int leadingBytes = sizeof(quint16) + sizeof(glm::vec3) + sizeof(glm::quat) + sizeof(quint8); - int16_t* networkAudioSamples = (int16_t*)(_audioPacket->getPayload() + leadingBytes); + static const int leadingBytes = sizeof(quint16) + sizeof(glm::vec3) + sizeof(glm::quat) + sizeof(quint8); + int16_t* const networkAudioSamples = (int16_t*)(_audioPacket->getPayload() + leadingBytes); QByteArray inputByteArray = _inputDevice->readAll(); From 715b183a3c8bbe9f97f8ecf8aecd4c46ef60e446 Mon Sep 17 00:00:00 2001 From: AlessandroSigna Date: Thu, 5 Nov 2015 19:10:06 -0800 Subject: [PATCH 7/7] unified two ways to do the mapping in a single JS --- examples/controllers/controllerMappings.js | 68 +++++++++++++--------- examples/controllers/rightClickExample.js | 10 ---- 2 files changed, 39 insertions(+), 39 deletions(-) delete mode 100644 examples/controllers/rightClickExample.js diff --git a/examples/controllers/controllerMappings.js b/examples/controllers/controllerMappings.js index a44833f80a..1bcd05a4cc 100644 --- a/examples/controllers/controllerMappings.js +++ b/examples/controllers/controllerMappings.js @@ -4,68 +4,74 @@ // examples // // Created by Sam Gondelman on 6/2/15 +// Rewritten by Alessandro Signa on 11/05/15 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// This allows to change the input mapping making a sense of how the new mapping works +// This allows to change the input mapping to easly understand of how the new mapping works. +// Two different ways are presented: the first one uses a JSON file to create the mapping, the second one declares the new routes explicitly one at a time. +// You shuold prefer the first method if you have a lot of new routes, the second one if you want to express the action as a function. /* -This function returns a JSON body. It's in charge to modify the mouse/keyboard mapping. The keyboard inputs are mapped directly to actions. +This function returns a JSON body. It's in charge to modify the standard controller and the mouse/keyboard mapping. + +The Standard controller is an abstraction: all the actual controllers are mapped to it. (i.e. Hydra --mapped to-> Standard --mapped to-> Action) +This example will overwrite the mapping of the left axis (Standard.LY, Standard.LX). +It's possible to find all the standard inputs (and their mapping) into standard.json +To try these changes you need a controller, not the keyboard. + +The keyboard/mouse inputs are mapped directly to actions since the keyboard doesn't have its default mapping passing through the Standard controller. If this new mapping contains inputs which are defined in the standard mapping, these will overwrite the old ones(Keyboard.W, Keyboard.RightMouseButton). If this new mapping contains inputs which are not defined in the standard, these will be added to the mapping(Keyboard.M). */ myFirstMapping = function() { return { - "name": "example", + "name": "controllerMapping_First", "channels": [ - { "from": "Keyboard.W", "to": "Actions.YAW_LEFT" }, - { "from": "Keyboard.M", "to": "Actions.YAW_LEFT" }, - - { "from": "Keyboard.RightMouseButton", "to": "Actions.YAW_RIGHT" } - ] -} -} -/* -This JSON is in charge to modify the Standard controller mapping. -The standard controller is an abstraction: all the actual controllers are mapped to it. (i.e. Hydra --mapped to-> Standard --mapped to-> Action) -These new inputs will overwrite the standard ones. -It's possible to find all the standard inputs (and their mapping) into standard.json -To try the mySecondMapping effect you need a controller, not the keyboard. -*/ -mySecondMapping = function() { -return { - "name": "example2", - "channels": [ { "from": "Standard.LY", "to": "Actions.Yaw" }, { "from": "Standard.LX", "to": "Actions.Yaw" }, + + { "from": "Keyboard.W", "to": "Actions.YAW_LEFT" }, + { "from": "Keyboard.M", "to": "Actions.YAW_RIGHT" }, + + { "from": "Keyboard.LeftMouseButton", "to": "Actions.Up" } + ] } } -var tryFirst = true; + +var firstWay = true; var mapping; -if(tryFirst){ +var MAPPING_NAME; + + +if(firstWay){ var myFirstMappingJSON = myFirstMapping(); print('myfirstMappingJSON' + JSON.stringify(myFirstMappingJSON)); mapping = Controller.parseMapping(JSON.stringify(myFirstMappingJSON)); + mapping.enable(); }else{ - var mySecondMappingJSON = mySecondMapping(); - print('mySecondMappingJSON' + JSON.stringify(mySecondMappingJSON)); - mapping = Controller.parseMapping(JSON.stringify(mySecondMappingJSON)); + MAPPING_NAME = "controllerMapping_Second"; + var mapping2 = Controller.newMapping(MAPPING_NAME); + mapping2.from(Controller.Hardware.Keyboard.RightMouseClicked).to(function (value) { + print("Keyboard.RightMouseClicked"); + }); + mapping2.from(Controller.Standard.LX).to(Controller.Actions.Yaw); + Controller.enableMapping(MAPPING_NAME); } -mapping.enable(); /* -//-----------------some info prints----------------------- +//-----------------some info prints that you would like to enable----------------------- Object.keys(Controller.Standard).forEach(function (input) { print("Controller.Standard." + input + ":" + Controller.Standard[input]); }); @@ -94,5 +100,9 @@ Controller.hardwareChanged.connect(function () { Script.scriptEnding.connect(function () { - mapping.disable(); + if(firstWay){ + mapping.disable(); + } else { + Controller.disableMapping(MAPPING_NAME); + } }); \ No newline at end of file diff --git a/examples/controllers/rightClickExample.js b/examples/controllers/rightClickExample.js deleted file mode 100644 index c3e6ea8f3d..0000000000 --- a/examples/controllers/rightClickExample.js +++ /dev/null @@ -1,10 +0,0 @@ -var MAPPING_NAME = "com.highfidelity.rightClickExample"; -var mapping = Controller.newMapping(MAPPING_NAME); -mapping.from(Controller.Hardware.Keyboard.RightMouseClicked).to(function (value) { - print("Keyboard.RightMouseClicked"); -}); -Controller.enableMapping(MAPPING_NAME); - -Script.scriptEnding.connect(function () { - Controller.disableMapping(MAPPING_NAME); -}); \ No newline at end of file