mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 16:41:02 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into temp0
This commit is contained in:
commit
f09b58c255
91 changed files with 877 additions and 379 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
#include <SoundCache.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <VoxelConstants.h>
|
#include <VoxelConstants.h>
|
||||||
|
|
||||||
|
@ -217,6 +218,8 @@ void Agent::run() {
|
||||||
_scriptEngine.registerGlobalObject("Agent", this);
|
_scriptEngine.registerGlobalObject("Agent", this);
|
||||||
|
|
||||||
_scriptEngine.init(); // must be done before we set up the viewers
|
_scriptEngine.init(); // must be done before we set up the viewers
|
||||||
|
|
||||||
|
_scriptEngine.registerGlobalObject("SoundCache", &SoundCache::getInstance());
|
||||||
|
|
||||||
_scriptEngine.registerGlobalObject("VoxelViewer", &_voxelViewer);
|
_scriptEngine.registerGlobalObject("VoxelViewer", &_voxelViewer);
|
||||||
// connect the VoxelViewer and the VoxelScriptingInterface to each other
|
// connect the VoxelViewer and the VoxelScriptingInterface to each other
|
||||||
|
|
|
@ -774,7 +774,8 @@ void AudioMixer::run() {
|
||||||
nodeData->checkBuffersBeforeFrameSend();
|
nodeData->checkBuffersBeforeFrameSend();
|
||||||
|
|
||||||
// if the stream should be muted, send mute packet
|
// if the stream should be muted, send mute packet
|
||||||
if (shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) {
|
if (nodeData->getAvatarAudioStream()
|
||||||
|
&& shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) {
|
||||||
static const int TIME_BETWEEN_MUTES = 5; // in secs
|
static const int TIME_BETWEEN_MUTES = 5; // in secs
|
||||||
if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() >
|
if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() >
|
||||||
TIME_BETWEEN_MUTES * USECS_PER_SECOND) {
|
TIME_BETWEEN_MUTES * USECS_PER_SECOND) {
|
||||||
|
|
|
@ -34,22 +34,22 @@ var guitarModel = HIFI_PUBLIC_BUCKET + "models/attachments/guitar.fst";
|
||||||
|
|
||||||
var chords = new Array();
|
var chords = new Array();
|
||||||
// Nylon string guitar
|
// Nylon string guitar
|
||||||
chords[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw");
|
chords[1] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw");
|
||||||
chords[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+B.raw");
|
chords[2] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+B.raw");
|
||||||
chords[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+E.raw");
|
chords[3] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+E.raw");
|
||||||
chords[4] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+G.raw");
|
chords[4] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+G.raw");
|
||||||
|
|
||||||
// Electric guitar
|
// Electric guitar
|
||||||
chords[5] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+A+short.raw");
|
chords[5] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+A+short.raw");
|
||||||
chords[6] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+B+short.raw");
|
chords[6] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+B+short.raw");
|
||||||
chords[7] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+E+short.raw");
|
chords[7] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+E+short.raw");
|
||||||
chords[8] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+G+short.raw");
|
chords[8] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+G+short.raw");
|
||||||
|
|
||||||
// Steel Guitar
|
// Steel Guitar
|
||||||
chords[9] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+A.raw");
|
chords[9] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+A.raw");
|
||||||
chords[10] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+B.raw");
|
chords[10] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+B.raw");
|
||||||
chords[11] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+E.raw");
|
chords[11] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+E.raw");
|
||||||
chords[12] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+G.raw");
|
chords[12] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+G.raw");
|
||||||
|
|
||||||
var NUM_CHORDS = 4;
|
var NUM_CHORDS = 4;
|
||||||
var NUM_GUITARS = 3;
|
var NUM_GUITARS = 3;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
Script.include("libraries/globals.js");
|
Script.include("libraries/globals.js");
|
||||||
|
|
||||||
var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw");
|
var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw");
|
||||||
var CHANCE_OF_PLAYING_SOUND = 0.01;
|
var CHANCE_OF_PLAYING_SOUND = 0.01;
|
||||||
|
|
||||||
var FACTOR = 0.05;
|
var FACTOR = 0.05;
|
||||||
|
|
|
@ -24,28 +24,28 @@ var audioOptions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
var hitSounds = new Array();
|
var hitSounds = new Array();
|
||||||
hitSounds[0] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit1.raw");
|
hitSounds[0] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit1.raw");
|
||||||
hitSounds[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit2.raw");
|
hitSounds[1] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit2.raw");
|
||||||
hitSounds[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit3.raw");
|
hitSounds[2] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit3.raw");
|
||||||
hitSounds[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit4.raw");
|
hitSounds[3] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit4.raw");
|
||||||
hitSounds[4] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit5.raw");
|
hitSounds[4] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit5.raw");
|
||||||
hitSounds[5] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit6.raw");
|
hitSounds[5] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit6.raw");
|
||||||
hitSounds[6] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit7.raw");
|
hitSounds[6] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit7.raw");
|
||||||
hitSounds[7] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit8.raw");
|
hitSounds[7] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit8.raw");
|
||||||
hitSounds[8] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit9.raw");
|
hitSounds[8] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit9.raw");
|
||||||
hitSounds[9] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit10.raw");
|
hitSounds[9] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit10.raw");
|
||||||
hitSounds[10] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit11.raw");
|
hitSounds[10] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit11.raw");
|
||||||
hitSounds[11] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit12.raw");
|
hitSounds[11] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit12.raw");
|
||||||
hitSounds[12] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit13.raw");
|
hitSounds[12] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit13.raw");
|
||||||
hitSounds[13] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit14.raw");
|
hitSounds[13] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit14.raw");
|
||||||
hitSounds[14] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit15.raw");
|
hitSounds[14] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit15.raw");
|
||||||
hitSounds[15] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit16.raw");
|
hitSounds[15] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit16.raw");
|
||||||
hitSounds[16] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit17.raw");
|
hitSounds[16] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit17.raw");
|
||||||
hitSounds[17] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit18.raw");
|
hitSounds[17] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit18.raw");
|
||||||
hitSounds[18] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit19.raw");
|
hitSounds[18] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit19.raw");
|
||||||
hitSounds[19] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit20.raw");
|
hitSounds[19] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit20.raw");
|
||||||
hitSounds[20] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit21.raw");
|
hitSounds[20] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit21.raw");
|
||||||
hitSounds[21] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit22.raw");
|
hitSounds[21] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit22.raw");
|
||||||
|
|
||||||
function playHitSound(mySessionID, theirSessionID, collision) {
|
function playHitSound(mySessionID, theirSessionID, collision) {
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
|
|
|
@ -67,7 +67,7 @@ function maybePlaySound(deltaTime) {
|
||||||
lifetime: 10
|
lifetime: 10
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
playing.push({ audioId: Audio.playSound(birds[whichBird].sound, options), entityId: entityId, lightId: lightId, color: birds[whichBird].color });
|
playing.push({ audioId: Audio.playSound(birds[whichBird].sound, options), entityId: entityId, lightId: lightId, color: birds[whichBird].color });
|
||||||
}
|
}
|
||||||
if (playing.length != numPlaying) {
|
if (playing.length != numPlaying) {
|
||||||
|
@ -159,8 +159,9 @@ function loadBirds() {
|
||||||
var SOUND_BASE_URL = "http://public.highfidelity.io/sounds/Animals/";
|
var SOUND_BASE_URL = "http://public.highfidelity.io/sounds/Animals/";
|
||||||
|
|
||||||
for (var i = 0; i < sound_filenames.length; i++) {
|
for (var i = 0; i < sound_filenames.length; i++) {
|
||||||
birds.push({ sound: new Sound(SOUND_BASE_URL + sound_filenames[i]),
|
birds.push({
|
||||||
color: colors[i]
|
sound: SoundCache.getSound(SOUND_BASE_URL + sound_filenames[i]),
|
||||||
} );
|
color: colors[i]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -228,6 +228,6 @@ function loadSounds() {
|
||||||
var SOUND_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Raws/";
|
var SOUND_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Raws/";
|
||||||
|
|
||||||
for (var i = 0; i < sound_filenames.length; i++) {
|
for (var i = 0; i < sound_filenames.length; i++) {
|
||||||
sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i]));
|
sounds.push(SoundCache.getSound(SOUND_BASE_URL + sound_filenames[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,11 +151,11 @@ function loadSounds() {
|
||||||
var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/";
|
var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/";
|
||||||
|
|
||||||
for (var i = 0; i < sound_filenames.length; i++) {
|
for (var i = 0; i < sound_filenames.length; i++) {
|
||||||
sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i]));
|
sounds.push(SoundCache.getSound(SOUND_BASE_URL + sound_filenames[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < footstep_filenames.length; i++) {
|
for (var i = 0; i < footstep_filenames.length; i++) {
|
||||||
footstepSounds.push(new Sound(FOOTSTEP_BASE_URL + footstep_filenames[i]));
|
footstepSounds.push(SoundCache.getSound(FOOTSTEP_BASE_URL + footstep_filenames[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,11 +113,11 @@ function loadSounds() {
|
||||||
var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/";
|
var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/";
|
||||||
|
|
||||||
for (var i = 0; i < sound_filenames.length; i++) {
|
for (var i = 0; i < sound_filenames.length; i++) {
|
||||||
sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i]));
|
sounds.push(SoundCache.getSound(SOUND_BASE_URL + sound_filenames[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < footstep_filenames.length; i++) {
|
for (var i = 0; i < footstep_filenames.length; i++) {
|
||||||
footstepSounds.push(new Sound(FOOTSTEP_BASE_URL + footstep_filenames[i]));
|
footstepSounds.push(SoundCache.getSound(FOOTSTEP_BASE_URL + footstep_filenames[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,16 @@ var lastClapFrame = 0;
|
||||||
var lastAnimFrame = 0;
|
var lastAnimFrame = 0;
|
||||||
|
|
||||||
var claps = [];
|
var claps = [];
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav"));
|
||||||
claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav"));
|
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav"));
|
||||||
var numberOfSounds = claps.length;
|
var numberOfSounds = claps.length;
|
||||||
|
|
||||||
var clappingNow = false;
|
var clappingNow = false;
|
||||||
|
|
|
@ -28,8 +28,8 @@ function vMinus(a, b) {
|
||||||
|
|
||||||
// First, load two percussion sounds to be used on the sticks
|
// First, load two percussion sounds to be used on the sticks
|
||||||
|
|
||||||
var drum1 = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomHi.raw");
|
var drum1 = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomHi.raw");
|
||||||
var drum2 = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomLo.raw");
|
var drum2 = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomLo.raw");
|
||||||
|
|
||||||
// State Machine:
|
// State Machine:
|
||||||
// 0 = not triggered
|
// 0 = not triggered
|
||||||
|
|
|
@ -78,7 +78,7 @@ function SoundArray() {
|
||||||
this.audioOptions = audioOptions
|
this.audioOptions = audioOptions
|
||||||
this.sounds = new Array();
|
this.sounds = new Array();
|
||||||
this.addSound = function (soundURL) {
|
this.addSound = function (soundURL) {
|
||||||
this.sounds[this.sounds.length] = new Sound(soundURL);
|
this.sounds[this.sounds.length] = SoundCache.getSound(soundURL);
|
||||||
}
|
}
|
||||||
this.play = function (index) {
|
this.play = function (index) {
|
||||||
if (0 <= index && index < this.sounds.length) {
|
if (0 <= index && index < this.sounds.length) {
|
||||||
|
@ -319,7 +319,7 @@ function ScaleSelector() {
|
||||||
width: this.SECOND_PART, height: this.height,
|
width: this.SECOND_PART, height: this.height,
|
||||||
topMargin: 13,
|
topMargin: 13,
|
||||||
text: this.scale.toString(),
|
text: this.scale.toString(),
|
||||||
alpha: 0.0,
|
alpha: 0.9,
|
||||||
visible: editToolsOn
|
visible: editToolsOn
|
||||||
});
|
});
|
||||||
this.powerOverlay = Overlays.addOverlay("text", {
|
this.powerOverlay = Overlays.addOverlay("text", {
|
||||||
|
|
|
@ -70,23 +70,23 @@ function addBird()
|
||||||
var size;
|
var size;
|
||||||
var which = Math.random();
|
var which = Math.random();
|
||||||
if (which < 0.2) {
|
if (which < 0.2) {
|
||||||
tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw");
|
tweet = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw");
|
||||||
color = { red: 100, green: 50, blue: 120 };
|
color = { red: 100, green: 50, blue: 120 };
|
||||||
size = 0.08;
|
size = 0.08;
|
||||||
} else if (which < 0.4) {
|
} else if (which < 0.4) {
|
||||||
tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/rosyfacedlovebird.raw");
|
tweet = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/rosyfacedlovebird.raw");
|
||||||
color = { red: 100, green: 150, blue: 75 };
|
color = { red: 100, green: 150, blue: 75 };
|
||||||
size = 0.09;
|
size = 0.09;
|
||||||
} else if (which < 0.6) {
|
} else if (which < 0.6) {
|
||||||
tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/saysphoebe.raw");
|
tweet = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/saysphoebe.raw");
|
||||||
color = { red: 84, green: 121, blue: 36 };
|
color = { red: 84, green: 121, blue: 36 };
|
||||||
size = 0.05;
|
size = 0.05;
|
||||||
} else if (which < 0.8) {
|
} else if (which < 0.8) {
|
||||||
tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw");
|
tweet = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw");
|
||||||
color = { red: 23, green: 197, blue: 230 };
|
color = { red: 23, green: 197, blue: 230 };
|
||||||
size = 0.12;
|
size = 0.12;
|
||||||
} else {
|
} else {
|
||||||
tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/westernscreechowl.raw");
|
tweet = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/westernscreechowl.raw");
|
||||||
color = { red: 50, green: 67, blue: 144 };
|
color = { red: 50, green: 67, blue: 144 };
|
||||||
size = 0.15;
|
size = 0.15;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
this.preload = function(entityID) {
|
this.preload = function(entityID) {
|
||||||
print("preload("+entityID.id+")");
|
print("preload("+entityID.id+")");
|
||||||
bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
|
bird = SoundCache.getSound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clickDownOnEntity = function(entityID, mouseEvent) {
|
this.clickDownOnEntity = function(entityID, mouseEvent) {
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
this.preload = function(entityID) {
|
this.preload = function(entityID) {
|
||||||
print("preload("+entityID.id+")");
|
print("preload("+entityID.id+")");
|
||||||
bird = new Sound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
|
bird = SoundCache.getSound("http://s3.amazonaws.com/hifi-public/sounds/Animals/bushtit_1.raw");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.enterEntity = function(entityID) {
|
this.enterEntity = function(entityID) {
|
||||||
|
|
|
@ -160,9 +160,9 @@ var rightMouseControl = new MouseControl("RIGHT");
|
||||||
var mouseControls = [leftMouseControl, middleMouseControl, rightMouseControl];
|
var mouseControls = [leftMouseControl, middleMouseControl, rightMouseControl];
|
||||||
var currentMouseControl = false;
|
var currentMouseControl = false;
|
||||||
|
|
||||||
var newSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
|
var newSound = SoundCache.getSound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
|
||||||
var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
|
var catchSound = SoundCache.getSound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
|
||||||
var throwSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw");
|
var throwSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw");
|
||||||
|
|
||||||
var simulatedFrisbees = [];
|
var simulatedFrisbees = [];
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,11 @@ var RELOAD_INTERVAL = 5;
|
||||||
var showScore = false;
|
var showScore = false;
|
||||||
|
|
||||||
// Load some sound to use for loading and firing
|
// Load some sound to use for loading and firing
|
||||||
var fireSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw");
|
var fireSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw");
|
||||||
var loadSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw");
|
var loadSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw");
|
||||||
var impactSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw");
|
var impactSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw");
|
||||||
var targetHitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
var targetHitSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
||||||
var targetLaunchSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
var targetLaunchSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
||||||
|
|
||||||
var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst";
|
var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst";
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,11 @@ var RELOAD_INTERVAL = 5;
|
||||||
var showScore = false;
|
var showScore = false;
|
||||||
|
|
||||||
// Load some sound to use for loading and firing
|
// Load some sound to use for loading and firing
|
||||||
var fireSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw");
|
var fireSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw");
|
||||||
var loadSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw");
|
var loadSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw");
|
||||||
var impactSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw");
|
var impactSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw");
|
||||||
var targetHitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
var targetHitSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
||||||
var targetLaunchSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
var targetLaunchSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
||||||
|
|
||||||
var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst";
|
var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst";
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ function activateWarp() {
|
||||||
|
|
||||||
var WATCH_AVATAR_DISTANCE = 2.5;
|
var WATCH_AVATAR_DISTANCE = 2.5;
|
||||||
|
|
||||||
var sound = new Sound("http://public.highfidelity.io/sounds/Footsteps/FootstepW2Right-12db.wav");
|
var sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW2Right-12db.wav");
|
||||||
function playSound() {
|
function playSound() {
|
||||||
Audio.playSound(sound, {
|
Audio.playSound(sound, {
|
||||||
position: MyAvatar.position
|
position: MyAvatar.position
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
Script.include("libraries/globals.js");
|
Script.include("libraries/globals.js");
|
||||||
|
|
||||||
var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav");
|
var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav");
|
||||||
|
|
||||||
var soundPlaying = false;
|
var soundPlaying = false;
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,16 @@ var leapHands = (function () {
|
||||||
LEAP_ON_HMD_MENU_ITEM = "Leap Motion on HMD",
|
LEAP_ON_HMD_MENU_ITEM = "Leap Motion on HMD",
|
||||||
LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip
|
LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip
|
||||||
HMD_OFFSET = 0.070, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief
|
HMD_OFFSET = 0.070, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief
|
||||||
|
hasHandAndWristJoints,
|
||||||
|
handToWristOffset = [], // For avatars without a wrist joint we control an estimate of a proper hand joint position
|
||||||
|
HAND_OFFSET = 0.4, // Relative distance of wrist to hand versus wrist to index finger knuckle
|
||||||
hands,
|
hands,
|
||||||
wrists,
|
wrists,
|
||||||
NUM_HANDS = 2, // 0 = left; 1 = right
|
NUM_HANDS = 2, // 0 = left; 1 = right
|
||||||
fingers,
|
fingers,
|
||||||
NUM_FINGERS = 5, // 0 = thumb; ...; 4 = pinky
|
NUM_FINGERS = 5, // 0 = thumb; ...; 4 = pinky
|
||||||
THUMB = 0,
|
THUMB = 0,
|
||||||
|
MIDDLE_FINGER = 2,
|
||||||
NUM_FINGER_JOINTS = 3, // 0 = metacarpal(hand)-proximal(finger) joint; ...; 2 = intermediate-distal joint
|
NUM_FINGER_JOINTS = 3, // 0 = metacarpal(hand)-proximal(finger) joint; ...; 2 = intermediate-distal joint
|
||||||
MAX_HAND_INACTIVE_COUNT = 20,
|
MAX_HAND_INACTIVE_COUNT = 20,
|
||||||
calibrationStatus,
|
calibrationStatus,
|
||||||
|
@ -123,30 +127,41 @@ var leapHands = (function () {
|
||||||
|
|
||||||
function finishCalibration() {
|
function finishCalibration() {
|
||||||
var avatarPosition,
|
var avatarPosition,
|
||||||
avatarOrientation,
|
handPosition,
|
||||||
avatarHandPosition,
|
middleFingerPosition,
|
||||||
leapHandHeight,
|
leapHandHeight,
|
||||||
h;
|
h;
|
||||||
|
|
||||||
if (hands[0].controller.isActive() && hands[1].controller.isActive()) {
|
if (!isOnHMD) {
|
||||||
leapHandHeight = (hands[0].controller.getAbsTranslation().y + hands[1].controller.getAbsTranslation().y) / 2.0;
|
if (hands[0].controller.isActive() && hands[1].controller.isActive()) {
|
||||||
} else {
|
leapHandHeight = (hands[0].controller.getAbsTranslation().y + hands[1].controller.getAbsTranslation().y) / 2.0;
|
||||||
calibrationStatus = UNCALIBRATED;
|
} else {
|
||||||
return;
|
calibrationStatus = UNCALIBRATED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avatarPosition = MyAvatar.position;
|
avatarPosition = MyAvatar.position;
|
||||||
avatarOrientation = MyAvatar.orientation;
|
|
||||||
|
|
||||||
for (h = 0; h < NUM_HANDS; h += 1) {
|
for (h = 0; h < NUM_HANDS; h += 1) {
|
||||||
avatarHandPosition = MyAvatar.getJointPosition(hands[h].jointName);
|
handPosition = MyAvatar.getJointPosition(hands[h].jointName);
|
||||||
hands[h].zeroPosition = {
|
if (!hasHandAndWristJoints) {
|
||||||
x: avatarHandPosition.x - avatarPosition.x,
|
middleFingerPosition = MyAvatar.getJointPosition(fingers[h][MIDDLE_FINGER][0].jointName);
|
||||||
y: avatarHandPosition.y - avatarPosition.y,
|
handToWristOffset[h] = Vec3.multiply(Vec3.subtract(handPosition, middleFingerPosition), 1.0 - HAND_OFFSET);
|
||||||
z: avatarPosition.z - avatarHandPosition.z
|
}
|
||||||
};
|
|
||||||
hands[h].zeroPosition = Vec3.multiplyQbyV(MyAvatar.orientation, hands[h].zeroPosition);
|
if (isOnHMD) {
|
||||||
hands[h].zeroPosition.y = hands[h].zeroPosition.y - leapHandHeight;
|
// Offset of Leap Motion origin from physical eye position
|
||||||
|
hands[h].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET };
|
||||||
|
} else {
|
||||||
|
hands[h].zeroPosition = {
|
||||||
|
x: handPosition.x - avatarPosition.x,
|
||||||
|
y: handPosition.y - avatarPosition.y,
|
||||||
|
z: avatarPosition.z - handPosition.z
|
||||||
|
};
|
||||||
|
hands[h].zeroPosition = Vec3.multiplyQbyV(MyAvatar.orientation, hands[h].zeroPosition);
|
||||||
|
hands[h].zeroPosition.y = hands[h].zeroPosition.y - leapHandHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyAvatar.clearJointData("LeftHand");
|
MyAvatar.clearJointData("LeftHand");
|
||||||
|
@ -161,6 +176,8 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function calibrate() {
|
function calibrate() {
|
||||||
|
var jointNames,
|
||||||
|
i;
|
||||||
|
|
||||||
calibrationStatus = CALIBRATING;
|
calibrationStatus = CALIBRATING;
|
||||||
|
|
||||||
|
@ -168,6 +185,13 @@ var leapHands = (function () {
|
||||||
avatarFaceModelURL = MyAvatar.faceModelURL;
|
avatarFaceModelURL = MyAvatar.faceModelURL;
|
||||||
avatarSkeletonModelURL = MyAvatar.skeletonModelURL;
|
avatarSkeletonModelURL = MyAvatar.skeletonModelURL;
|
||||||
|
|
||||||
|
// Does this skeleton have both wrist and hand joints?
|
||||||
|
hasHandAndWristJoints = false;
|
||||||
|
jointNames = MyAvatar.getJointNames();
|
||||||
|
for (i = 0; i < jointNames.length; i += 1) {
|
||||||
|
hasHandAndWristJoints = hasHandAndWristJoints || jointNames[i].toLowerCase() === "leftwrist";
|
||||||
|
}
|
||||||
|
|
||||||
// Set avatar arms vertical, forearms horizontal, as "zero" position for calibration
|
// Set avatar arms vertical, forearms horizontal, as "zero" position for calibration
|
||||||
MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, -90.0));
|
MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, -90.0));
|
||||||
MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
||||||
|
@ -176,6 +200,7 @@ var leapHands = (function () {
|
||||||
MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0));
|
||||||
MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
|
||||||
// Wait for arms to assume their positions before calculating
|
// Wait for arms to assume their positions before calculating
|
||||||
Script.setTimeout(finishCalibration, CALIBRATION_TIME);
|
Script.setTimeout(finishCalibration, CALIBRATION_TIME);
|
||||||
}
|
}
|
||||||
|
@ -195,37 +220,34 @@ var leapHands = (function () {
|
||||||
|
|
||||||
function setIsOnHMD() {
|
function setIsOnHMD() {
|
||||||
isOnHMD = Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM);
|
isOnHMD = Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM);
|
||||||
if (isOnHMD) {
|
print("Leap Motion: " + (isOnHMD ? "Is on HMD" : "Is on desk"));
|
||||||
print("Leap Motion: Is on HMD");
|
|
||||||
|
|
||||||
// Offset of Leap Motion origin from physical eye position
|
|
||||||
hands[0].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET };
|
|
||||||
hands[1].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET };
|
|
||||||
|
|
||||||
calibrationStatus = CALIBRATED;
|
|
||||||
} else {
|
|
||||||
print("Leap Motion: Is on desk");
|
|
||||||
calibrationStatus = UNCALIBRATED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSettings() {
|
function checkSettings() {
|
||||||
// There is no "scale changed" event so we need check periodically.
|
if (calibrationStatus > UNCALIBRATED && (MyAvatar.scale !== avatarScale
|
||||||
if (!isOnHMD && calibrationStatus > UNCALIBRATED && (MyAvatar.scale !== avatarScale
|
|
||||||
|| MyAvatar.faceModelURL !== avatarFaceModelURL
|
|| MyAvatar.faceModelURL !== avatarFaceModelURL
|
||||||
|| MyAvatar.skeletonModelURL !== avatarSkeletonModelURL)) {
|
|| MyAvatar.skeletonModelURL !== avatarSkeletonModelURL
|
||||||
print("Leap Motion: Recalibrate because avatar body or scale changed");
|
|| Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM) !== isOnHMD)) {
|
||||||
|
print("Leap Motion: Recalibrate...");
|
||||||
calibrationStatus = UNCALIBRATED;
|
calibrationStatus = UNCALIBRATED;
|
||||||
}
|
|
||||||
|
|
||||||
// There is a "menu changed" event but we may as well check here.
|
|
||||||
if (isOnHMD !== Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM)) {
|
|
||||||
setIsOnHMD();
|
setIsOnHMD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
|
|
||||||
|
wrists = [
|
||||||
|
{
|
||||||
|
jointName: "LeftWrist",
|
||||||
|
controller: Controller.createInputController("Spatial", "joint_L_wrist")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
jointName: "RightWrist",
|
||||||
|
controller: Controller.createInputController("Spatial", "joint_R_wrist")
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
hands = [
|
hands = [
|
||||||
{
|
{
|
||||||
jointName: "LeftHand",
|
jointName: "LeftHand",
|
||||||
|
@ -239,11 +261,6 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
wrists = [
|
|
||||||
{ controller: Controller.createInputController("Spatial", "joint_L_wrist") },
|
|
||||||
{ controller: Controller.createInputController("Spatial", "joint_R_wrist") }
|
|
||||||
];
|
|
||||||
|
|
||||||
// The Leap controller's first joint is the hand-metacarpal joint but this joint's data is not used because it's too
|
// The Leap controller's first joint is the hand-metacarpal joint but this joint's data is not used because it's too
|
||||||
// dependent on the model skeleton exactly matching the Leap skeleton; using just the second and subsequent joints
|
// dependent on the model skeleton exactly matching the Leap skeleton; using just the second and subsequent joints
|
||||||
// seems to work better over all.
|
// seems to work better over all.
|
||||||
|
@ -306,6 +323,8 @@ var leapHands = (function () {
|
||||||
setIsOnHMD();
|
setIsOnHMD();
|
||||||
|
|
||||||
settingsTimer = Script.setInterval(checkSettings, 2000);
|
settingsTimer = Script.setInterval(checkSettings, 2000);
|
||||||
|
|
||||||
|
calibrationStatus = UNCALIBRATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveHands() {
|
function moveHands() {
|
||||||
|
@ -314,6 +333,7 @@ var leapHands = (function () {
|
||||||
j,
|
j,
|
||||||
side,
|
side,
|
||||||
handOffset,
|
handOffset,
|
||||||
|
wristOffset,
|
||||||
handRotation,
|
handRotation,
|
||||||
locRotation,
|
locRotation,
|
||||||
cameraOrientation,
|
cameraOrientation,
|
||||||
|
@ -330,10 +350,18 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand position ...
|
// Hand position ...
|
||||||
|
handOffset = hands[h].controller.getAbsTranslation();
|
||||||
|
handRotation = hands[h].controller.getAbsRotation();
|
||||||
|
|
||||||
if (isOnHMD) {
|
if (isOnHMD) {
|
||||||
|
|
||||||
|
// Adjust to control wrist position if "hand" joint is at wrist ...
|
||||||
|
if (!hasHandAndWristJoints) {
|
||||||
|
wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]);
|
||||||
|
handOffset = Vec3.sum(handOffset, wristOffset);
|
||||||
|
}
|
||||||
|
|
||||||
// Hand offset in camera coordinates ...
|
// Hand offset in camera coordinates ...
|
||||||
handOffset = hands[h].controller.getAbsTranslation();
|
|
||||||
handOffset = {
|
handOffset = {
|
||||||
x: hands[h].zeroPosition.x - handOffset.x,
|
x: hands[h].zeroPosition.x - handOffset.x,
|
||||||
y: hands[h].zeroPosition.y - handOffset.z,
|
y: hands[h].zeroPosition.y - handOffset.z,
|
||||||
|
@ -353,7 +381,6 @@ var leapHands = (function () {
|
||||||
handOffset.x = -handOffset.x;
|
handOffset.x = -handOffset.x;
|
||||||
|
|
||||||
// Hand rotation in camera coordinates ...
|
// Hand rotation in camera coordinates ...
|
||||||
handRotation = wrists[h].controller.getAbsRotation();
|
|
||||||
handRotation = {
|
handRotation = {
|
||||||
x: handRotation.z,
|
x: handRotation.z,
|
||||||
y: handRotation.y,
|
y: handRotation.y,
|
||||||
|
@ -361,6 +388,7 @@ var leapHands = (function () {
|
||||||
w: handRotation.w
|
w: handRotation.w
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hand rotation in avatar coordinates ...
|
||||||
if (h === 0) {
|
if (h === 0) {
|
||||||
handRotation.x = -handRotation.x;
|
handRotation.x = -handRotation.x;
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation);
|
handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation);
|
||||||
|
@ -371,7 +399,6 @@ var leapHands = (function () {
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 0, z: 1 }), handRotation);
|
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 0, z: 1 }), handRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand rotation in avatar coordinates ...
|
|
||||||
cameraOrientation.x = -cameraOrientation.x;
|
cameraOrientation.x = -cameraOrientation.x;
|
||||||
cameraOrientation.z = -cameraOrientation.z;
|
cameraOrientation.z = -cameraOrientation.z;
|
||||||
handRotation = Quat.multiply(cameraOrientation, handRotation);
|
handRotation = Quat.multiply(cameraOrientation, handRotation);
|
||||||
|
@ -379,14 +406,20 @@ var leapHands = (function () {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
handOffset = hands[h].controller.getAbsTranslation();
|
// Adjust to control wrist position if "hand" joint is at wrist ...
|
||||||
|
if (!hasHandAndWristJoints) {
|
||||||
|
wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]);
|
||||||
|
handOffset = Vec3.sum(handOffset, wristOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hand offset in camera coordinates ...
|
||||||
handOffset = {
|
handOffset = {
|
||||||
x: -handOffset.x,
|
x: -handOffset.x,
|
||||||
y: hands[h].zeroPosition.y + handOffset.y,
|
y: hands[h].zeroPosition.y + handOffset.y,
|
||||||
z: hands[h].zeroPosition.z - handOffset.z
|
z: hands[h].zeroPosition.z - handOffset.z
|
||||||
};
|
};
|
||||||
|
|
||||||
handRotation = wrists[h].controller.getAbsRotation();
|
// Hand rotation in camera coordinates ...
|
||||||
handRotation = {
|
handRotation = {
|
||||||
x: handRotation.z,
|
x: handRotation.z,
|
||||||
y: handRotation.y,
|
y: handRotation.y,
|
||||||
|
@ -394,6 +427,7 @@ var leapHands = (function () {
|
||||||
w: handRotation.w
|
w: handRotation.w
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hand rotation in avatar coordinates ...
|
||||||
if (h === 0) {
|
if (h === 0) {
|
||||||
handRotation.x = -handRotation.x;
|
handRotation.x = -handRotation.x;
|
||||||
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }),
|
||||||
|
@ -405,9 +439,10 @@ var leapHands = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set hand position and orientation ...
|
||||||
MyAvatar.setJointModelPositionAndOrientation(hands[h].jointName, handOffset, handRotation, true);
|
MyAvatar.setJointModelPositionAndOrientation(hands[h].jointName, handOffset, handRotation, true);
|
||||||
|
|
||||||
// Finger joints ...
|
// Set finger joints ...
|
||||||
for (i = 0; i < NUM_FINGERS; i += 1) {
|
for (i = 0; i < NUM_FINGERS; i += 1) {
|
||||||
for (j = 0; j < NUM_FINGER_JOINTS; j += 1) {
|
for (j = 0; j < NUM_FINGER_JOINTS; j += 1) {
|
||||||
if (fingers[h][i][j].controller !== null) {
|
if (fingers[h][i][j].controller !== null) {
|
||||||
|
|
|
@ -335,12 +335,12 @@ walkAssets = (function () {
|
||||||
|
|
||||||
// read in the sounds
|
// read in the sounds
|
||||||
var _footsteps = [];
|
var _footsteps = [];
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW2Left-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW2Left-12db.wav"));
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW2Right-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW2Right-12db.wav"));
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW3Left-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW3Left-12db.wav"));
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW3Right-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW3Right-12db.wav"));
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW5Left-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW5Left-12db.wav"));
|
||||||
_footsteps.push(new Sound(_pathToSounds+"FootstepW5Right-12db.wav"));
|
_footsteps.push(SoundCache.getSound(_pathToSounds+"FootstepW5Right-12db.wav"));
|
||||||
|
|
||||||
// load the animation datafiles
|
// load the animation datafiles
|
||||||
Script.include(pathToAssets+"animations/dd-female-standard-walk-animation.js");
|
Script.include(pathToAssets+"animations/dd-female-standard-walk-animation.js");
|
||||||
|
|
|
@ -39,11 +39,11 @@ var ORB_SHIFT = { x: 0, y: -1.4, z: -0.8};
|
||||||
|
|
||||||
var HELMET_ATTACHMENT_URL = HIFI_PUBLIC_BUCKET + "models/attachments/IronManMaskOnly.fbx"
|
var HELMET_ATTACHMENT_URL = HIFI_PUBLIC_BUCKET + "models/attachments/IronManMaskOnly.fbx"
|
||||||
|
|
||||||
var droneSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/drone.raw")
|
var droneSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/drone.raw")
|
||||||
var currentDrone = null;
|
var currentDrone = null;
|
||||||
|
|
||||||
var latinSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/latin.raw")
|
var latinSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/latin.raw")
|
||||||
var elevatorSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/elevator.raw")
|
var elevatorSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/elevator.raw")
|
||||||
var currentMusak = null;
|
var currentMusak = null;
|
||||||
|
|
||||||
function reticlePosition() {
|
function reticlePosition() {
|
||||||
|
|
|
@ -167,6 +167,48 @@ var clipboardPreview = Overlays.addOverlay("clipboard", {
|
||||||
visible: true
|
visible: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Demonstrate retrieving overlay properties
|
||||||
|
print("Text overlay text property value =\n" + Overlays.getProperty(text, "text"));
|
||||||
|
print("Text overlay alpha =\n" + Overlays.getProperty(text, "alpha"));
|
||||||
|
print("Text overlay visible =\n" + Overlays.getProperty(text, "visible"));
|
||||||
|
print("Text overlay font size =\n" + Overlays.getProperty(text, "font").size);
|
||||||
|
print("Text overlay anchor =\n" + Overlays.getProperty(text, "anchor"));
|
||||||
|
print("Text overlay unknown property value =\n" + Overlays.getProperty(text, "unknown")); // value = undefined
|
||||||
|
var sliderBounds = Overlays.getProperty(slider, "bounds");
|
||||||
|
print("Slider overlay bounds =\n"
|
||||||
|
+ "x: " + sliderBounds.x + "\n"
|
||||||
|
+ "y: " + sliderBounds.y + "\n"
|
||||||
|
+ "width: " + sliderBounds.width + "\n"
|
||||||
|
+ "height: " + sliderBounds.height
|
||||||
|
);
|
||||||
|
|
||||||
|
var cubePosition = Overlays.getProperty(cube, "position");
|
||||||
|
print("Cube overlay position =\n"
|
||||||
|
+ "x: " + cubePosition.x + "\n"
|
||||||
|
+ "y: " + cubePosition.y + "\n"
|
||||||
|
+ "z: " + cubePosition.z
|
||||||
|
);
|
||||||
|
var cubeColor = Overlays.getProperty(cube, "color");
|
||||||
|
print("Cube overlay color =\n"
|
||||||
|
+ "red: " + cubeColor.red + "\n"
|
||||||
|
+ "green: " + cubeColor.green + "\n"
|
||||||
|
+ "blue: " + cubeColor.blue
|
||||||
|
);
|
||||||
|
var modelOverlayProperties = {
|
||||||
|
textures: {
|
||||||
|
filename1: "http://url1",
|
||||||
|
filename2: "http://url2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var modelOverlay = Overlays.addOverlay("model", modelOverlayProperties);
|
||||||
|
var textures = Overlays.getProperty(modelOverlay, "textures");
|
||||||
|
var textureValues = "";
|
||||||
|
for (key in textures) {
|
||||||
|
textureValues += "\n" + key + ": " + textures[key];
|
||||||
|
}
|
||||||
|
print("Model overlay textures =" + textureValues);
|
||||||
|
Overlays.deleteOverlay(modelOverlay);
|
||||||
|
print("Unknown overlay property =\n" + Overlays.getProperty(1000, "text")); // value = undefined
|
||||||
|
|
||||||
// When our script shuts down, we should clean up all of our overlays
|
// When our script shuts down, we should clean up all of our overlays
|
||||||
function scriptEnding() {
|
function scriptEnding() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
Script.include("libraries/globals.js");
|
Script.include("libraries/globals.js");
|
||||||
|
|
||||||
// First, load a sample sound from a URL
|
// First, load a sample sound from a URL
|
||||||
var bird = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw");
|
var bird = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw");
|
||||||
|
|
||||||
function maybePlaySound(deltaTime) {
|
function maybePlaySound(deltaTime) {
|
||||||
if (Math.random() < 0.01) {
|
if (Math.random() < 0.01) {
|
||||||
|
|
|
@ -15,9 +15,9 @@ Script.include("libraries/globals.js");
|
||||||
|
|
||||||
// A few sample files you may want to try:
|
// A few sample files you may want to try:
|
||||||
|
|
||||||
var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw");
|
var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw");
|
||||||
//var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav");
|
//var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav");
|
||||||
//var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Bandcamp.wav");
|
//var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Bandcamp.wav");
|
||||||
|
|
||||||
var soundPlaying = false;
|
var soundPlaying = false;
|
||||||
var options = {
|
var options = {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
Script.include("libraries/globals.js");
|
Script.include("libraries/globals.js");
|
||||||
|
|
||||||
var soundClip = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Voxels/voxel create 3.raw");
|
var soundClip = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Voxels/voxel create 3.raw");
|
||||||
|
|
||||||
var currentTime = 1.570079; // pi/2
|
var currentTime = 1.570079; // pi/2
|
||||||
var deltaTime = 0.05;
|
var deltaTime = 0.05;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
Script.include("libraries/globals.js");
|
Script.include("libraries/globals.js");
|
||||||
|
|
||||||
var soundClip = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail%20Party%20Snippets/Walken1.wav");
|
var soundClip = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail%20Party%20Snippets/Walken1.wav");
|
||||||
|
|
||||||
function playSound() {
|
function playSound() {
|
||||||
Audio.playSound(soundClip, {
|
Audio.playSound(soundClip, {
|
||||||
|
|
|
@ -23,7 +23,7 @@ var audioOptions = {
|
||||||
|
|
||||||
var injector = null;
|
var injector = null;
|
||||||
|
|
||||||
var sound = new Sound(soundURL, audioOptions.isStereo);
|
var sound = SoundCache.getSound(soundURL, audioOptions.isStereo);
|
||||||
|
|
||||||
var entity = null;
|
var entity = null;
|
||||||
var properties = null;
|
var properties = null;
|
||||||
|
|
|
@ -84,13 +84,13 @@ var missileFired = false;
|
||||||
var myMissile;
|
var myMissile;
|
||||||
|
|
||||||
// sounds
|
// sounds
|
||||||
var hitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
var hitSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw");
|
||||||
var shootSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
var shootSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw");
|
||||||
var moveSounds = new Array();
|
var moveSounds = new Array();
|
||||||
moveSounds[0] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo1.raw");
|
moveSounds[0] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo1.raw");
|
||||||
moveSounds[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo2.raw");
|
moveSounds[1] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo2.raw");
|
||||||
moveSounds[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo3.raw");
|
moveSounds[2] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo3.raw");
|
||||||
moveSounds[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo4.raw");
|
moveSounds[3] = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo4.raw");
|
||||||
var currentMoveSound = 0;
|
var currentMoveSound = 0;
|
||||||
var numberOfSounds = 4;
|
var numberOfSounds = 4;
|
||||||
var stepsPerSound = invaderStepsPerCycle / numberOfSounds;
|
var stepsPerSound = invaderStepsPerCycle / numberOfSounds;
|
||||||
|
|
|
@ -39,9 +39,9 @@ var rightBallAlreadyInHand = false;
|
||||||
var leftHandEntity;
|
var leftHandEntity;
|
||||||
var rightHandEntity;
|
var rightHandEntity;
|
||||||
|
|
||||||
var newSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
|
var newSound = SoundCache.getSound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw");
|
||||||
var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
|
var catchSound = SoundCache.getSound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw");
|
||||||
var throwSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw");
|
var throwSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw");
|
||||||
var targetRadius = 1.0;
|
var targetRadius = 1.0;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
#include <SoundCache.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
|
|
||||||
|
@ -3905,7 +3906,9 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
||||||
connect(scriptEngine, SIGNAL(loadScript(const QString&, bool)), this, SLOT(loadScript(const QString&, bool)));
|
connect(scriptEngine, SIGNAL(loadScript(const QString&, bool)), this, SLOT(loadScript(const QString&, bool)));
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
scriptEngine->registerGlobalObject("Overlays", &_overlays);
|
||||||
qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue, RayToOverlayIntersectionResultFromScriptValue);
|
qScriptRegisterMetaType(scriptEngine, OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue,
|
||||||
|
RayToOverlayIntersectionResultFromScriptValue);
|
||||||
|
|
||||||
QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", WindowScriptingInterface::getInstance());
|
QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", WindowScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter,
|
||||||
|
@ -3920,6 +3923,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
||||||
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("AnimationCache", &_animationCache);
|
scriptEngine->registerGlobalObject("AnimationCache", &_animationCache);
|
||||||
|
scriptEngine->registerGlobalObject("SoundCache", &SoundCache::getInstance());
|
||||||
scriptEngine->registerGlobalObject("AudioReflector", &_audioReflector);
|
scriptEngine->registerGlobalObject("AudioReflector", &_audioReflector);
|
||||||
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Metavoxels", &_metavoxels);
|
scriptEngine->registerGlobalObject("Metavoxels", &_metavoxels);
|
||||||
|
|
|
@ -70,8 +70,8 @@ Leapmotion::Leapmotion() :
|
||||||
|
|
||||||
std::vector< Semantic > rootBones;
|
std::vector< Semantic > rootBones;
|
||||||
rootBones.push_back("elbow");
|
rootBones.push_back("elbow");
|
||||||
rootBones.push_back("hand");
|
|
||||||
rootBones.push_back("wrist");
|
rootBones.push_back("wrist");
|
||||||
|
rootBones.push_back("hand");
|
||||||
|
|
||||||
std::vector< Semantic > fingers;
|
std::vector< Semantic > fingers;
|
||||||
fingers.push_back("thumb");
|
fingers.push_back("thumb");
|
||||||
|
|
|
@ -537,7 +537,7 @@ void Model::renderSetup(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_meshGroupsKnown) {
|
if (!_meshGroupsKnown && isLoadedWithTextures()) {
|
||||||
segregateMeshGroups();
|
segregateMeshGroups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,7 +628,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args);
|
||||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args);
|
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args);
|
||||||
|
|
||||||
// render translucent meshes afterwards
|
// render translucent meshes afterwards
|
||||||
//Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
//Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
||||||
|
@ -649,7 +649,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args);
|
||||||
|
|
||||||
GLBATCH(glDisable)(GL_ALPHA_TEST);
|
GLBATCH(glDisable)(GL_ALPHA_TEST);
|
||||||
GLBATCH(glEnable)(GL_BLEND);
|
GLBATCH(glEnable)(GL_BLEND);
|
||||||
|
@ -673,7 +673,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args);
|
||||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args);
|
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBATCH(glDepthMask)(true);
|
GLBATCH(glDepthMask)(true);
|
||||||
|
|
|
@ -118,6 +118,32 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Base3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "position" || property == "start" || property == "p1" || property == "point") {
|
||||||
|
return vec3toScriptValue(_scriptEngine, _position);
|
||||||
|
}
|
||||||
|
if (property == "lineWidth") {
|
||||||
|
return _lineWidth;
|
||||||
|
}
|
||||||
|
if (property == "rotation") {
|
||||||
|
return quatToScriptValue(_scriptEngine, _rotation);
|
||||||
|
}
|
||||||
|
if (property == "isSolid" || property == "isFilled" || property == "solid" || property == "filed") {
|
||||||
|
return _isSolid;
|
||||||
|
}
|
||||||
|
if (property == "isWire" || property == "wire") {
|
||||||
|
return !_isSolid;
|
||||||
|
}
|
||||||
|
if (property == "isDashedLine" || property == "dashed") {
|
||||||
|
return _isDashedLine;
|
||||||
|
}
|
||||||
|
if (property == "ignoreRayIntersection") {
|
||||||
|
return _ignoreRayIntersection;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Overlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face) const {
|
float& distance, BoxFace& face) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,23 @@ void BillboardOverlay::setProperties(const QScriptValue &properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue BillboardOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "url") {
|
||||||
|
return _url;
|
||||||
|
}
|
||||||
|
if (property == "subImage") {
|
||||||
|
return qRectToScriptValue(_scriptEngine, _fromImage);
|
||||||
|
}
|
||||||
|
if (property == "scale") {
|
||||||
|
return _scale;
|
||||||
|
}
|
||||||
|
if (property == "isFacingAvatar") {
|
||||||
|
return _isFacingAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
void BillboardOverlay::setURL(const QString& url) {
|
void BillboardOverlay::setURL(const QString& url) {
|
||||||
setBillboardURL(url);
|
setBillboardURL(url);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; }
|
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; }
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,45 @@ void Circle3DOverlay::setProperties(const QScriptValue &properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Circle3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "startAt") {
|
||||||
|
return _startAt;
|
||||||
|
}
|
||||||
|
if (property == "endAt") {
|
||||||
|
return _endAt;
|
||||||
|
}
|
||||||
|
if (property == "outerRadius") {
|
||||||
|
return _outerRadius;
|
||||||
|
}
|
||||||
|
if (property == "innerRadius") {
|
||||||
|
return _innerRadius;
|
||||||
|
}
|
||||||
|
if (property == "hasTickMarks") {
|
||||||
|
return _hasTickMarks;
|
||||||
|
}
|
||||||
|
if (property == "majorTickMarksAngle") {
|
||||||
|
return _majorTickMarksAngle;
|
||||||
|
}
|
||||||
|
if (property == "minorTickMarksAngle") {
|
||||||
|
return _minorTickMarksAngle;
|
||||||
|
}
|
||||||
|
if (property == "majorTickMarksLength") {
|
||||||
|
return _majorTickMarksLength;
|
||||||
|
}
|
||||||
|
if (property == "minorTickMarksLength") {
|
||||||
|
return _minorTickMarksLength;
|
||||||
|
}
|
||||||
|
if (property == "majorTickMarksColor") {
|
||||||
|
return xColorToScriptValue(_scriptEngine, _majorTickMarksColor);
|
||||||
|
}
|
||||||
|
if (property == "minorTickMarksColor") {
|
||||||
|
return xColorToScriptValue(_scriptEngine, _minorTickMarksColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Planar3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin,
|
bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin,
|
||||||
const glm::vec3& direction, float& distance, BoxFace& face) const {
|
const glm::vec3& direction, float& distance, BoxFace& face) const {
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
~Circle3DOverlay();
|
~Circle3DOverlay();
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
float getStartAt() const { return _startAt; }
|
float getStartAt() const { return _startAt; }
|
||||||
float getEndAt() const { return _endAt; }
|
float getEndAt() const { return _endAt; }
|
||||||
|
|
|
@ -116,3 +116,14 @@ void Grid3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
_majorGridEvery = properties.property("majorGridEvery").toVariant().toInt();
|
_majorGridEvery = properties.property("majorGridEvery").toVariant().toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Grid3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "minorGridWidth") {
|
||||||
|
return _minorGridWidth;
|
||||||
|
}
|
||||||
|
if (property == "majorGridEvery") {
|
||||||
|
return _majorGridEvery;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
|
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _minorGridWidth;
|
float _minorGridWidth;
|
||||||
|
|
|
@ -151,4 +151,13 @@ void ImageOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue ImageOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "subImage") {
|
||||||
|
return qRectToScriptValue(_scriptEngine, _fromImage);
|
||||||
|
}
|
||||||
|
if (property == "imageURL") {
|
||||||
|
return _imageURL.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Overlay2D::getProperty(property);
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; _wantClipFromImage = true; }
|
void setClipFromSource(const QRect& bounds) { _fromImage = bounds; _wantClipFromImage = true; }
|
||||||
void setImageURL(const QUrl& url);
|
void setImageURL(const QUrl& url);
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void replyFinished(); // we actually want to hide this...
|
void replyFinished(); // we actually want to hide this...
|
||||||
|
|
|
@ -79,3 +79,11 @@ void Line3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Line3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "end" || property == "endPoint" || property == "p2") {
|
||||||
|
return vec3toScriptValue(_scriptEngine, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
void setEnd(const glm::vec3& end) { _end = end; }
|
void setEnd(const glm::vec3& end) { _end = end; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _end;
|
glm::vec3 _end;
|
||||||
|
|
|
@ -103,3 +103,14 @@ void LocalVoxelsOverlay::setProperties(const QScriptValue &properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue LocalVoxelsOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "scale") {
|
||||||
|
return vec3toScriptValue(_scriptEngine, getDimensions());
|
||||||
|
}
|
||||||
|
if (property == "name") {
|
||||||
|
return _treeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Volume3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ public:
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QMap<QString, WeakVoxelSystemPointer> _voxelSystemMap; // treeName/voxelSystem
|
static QMap<QString, WeakVoxelSystemPointer> _voxelSystemMap; // treeName/voxelSystem
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
ModelOverlay::ModelOverlay()
|
ModelOverlay::ModelOverlay()
|
||||||
: _model(),
|
: _model(),
|
||||||
|
_modelTextures(QVariantMap()),
|
||||||
_scale(1.0f),
|
_scale(1.0f),
|
||||||
_updateModel(false)
|
_updateModel(false)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +115,8 @@ void ModelOverlay::setProperties(const QScriptValue &properties) {
|
||||||
QMetaObject::invokeMethod(&_model, "setTextureWithNameToURL", Qt::AutoConnection,
|
QMetaObject::invokeMethod(&_model, "setTextureWithNameToURL", Qt::AutoConnection,
|
||||||
Q_ARG(const QString&, key),
|
Q_ARG(const QString&, key),
|
||||||
Q_ARG(const QUrl&, newTextureURL));
|
Q_ARG(const QUrl&, newTextureURL));
|
||||||
|
|
||||||
|
_modelTextures[key] = newTextureURL; // Keep local track of textures for getProperty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +125,34 @@ void ModelOverlay::setProperties(const QScriptValue &properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue ModelOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "url") {
|
||||||
|
return _url.toString();
|
||||||
|
}
|
||||||
|
if (property == "scale") {
|
||||||
|
return _scale;
|
||||||
|
}
|
||||||
|
if (property == "rotation") {
|
||||||
|
return quatToScriptValue(_scriptEngine, _rotation);
|
||||||
|
}
|
||||||
|
if (property == "dimensions") {
|
||||||
|
return vec3toScriptValue(_scriptEngine, _model.getScaleToFitDimensions());
|
||||||
|
}
|
||||||
|
if (property == "textures") {
|
||||||
|
if (_modelTextures.size() > 0) {
|
||||||
|
QScriptValue textures = _scriptEngine->newObject();
|
||||||
|
foreach(const QString& key, _modelTextures.keys()) {
|
||||||
|
textures.setProperty(key, _modelTextures[key].toString());
|
||||||
|
}
|
||||||
|
return textures;
|
||||||
|
} else {
|
||||||
|
return QScriptValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
bool ModelOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool ModelOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face) const {
|
float& distance, BoxFace& face) const {
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
virtual void update(float deltatime);
|
virtual void update(float deltatime);
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||||
virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findRayIntersectionExtraInfo(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face, QString& extraInfo) const;
|
float& distance, BoxFace& face, QString& extraInfo) const;
|
||||||
|
@ -31,6 +32,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Model _model;
|
Model _model;
|
||||||
|
QVariantMap _modelTextures;
|
||||||
|
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
glm::quat _rotation;
|
glm::quat _rotation;
|
||||||
|
|
|
@ -39,8 +39,9 @@ Overlay::Overlay() :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::init(QGLWidget* parent) {
|
void Overlay::init(QGLWidget* parent, QScriptEngine* scriptEngine) {
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
_scriptEngine = scriptEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,6 +105,44 @@ void Overlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Overlay::getProperty(const QString& property) {
|
||||||
|
if (property == "color") {
|
||||||
|
return xColorToScriptValue(_scriptEngine, _color);
|
||||||
|
}
|
||||||
|
if (property == "alpha") {
|
||||||
|
return _alpha;
|
||||||
|
}
|
||||||
|
if (property == "glowLevel") {
|
||||||
|
return _glowLevel;
|
||||||
|
}
|
||||||
|
if (property == "pulseMax") {
|
||||||
|
return _pulseMax;
|
||||||
|
}
|
||||||
|
if (property == "pulseMin") {
|
||||||
|
return _pulseMin;
|
||||||
|
}
|
||||||
|
if (property == "pulsePeriod") {
|
||||||
|
return _pulsePeriod;
|
||||||
|
}
|
||||||
|
if (property == "glowLevelPulse") {
|
||||||
|
return _glowLevelPulse;
|
||||||
|
}
|
||||||
|
if (property == "alphaPulse") {
|
||||||
|
return _alphaPulse;
|
||||||
|
}
|
||||||
|
if (property == "colorPulse") {
|
||||||
|
return _colorPulse;
|
||||||
|
}
|
||||||
|
if (property == "visible") {
|
||||||
|
return _visible;
|
||||||
|
}
|
||||||
|
if (property == "anchor") {
|
||||||
|
return _anchor == MY_AVATAR ? "MyAvatar" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return QScriptValue();
|
||||||
|
}
|
||||||
|
|
||||||
xColor Overlay::getColor() {
|
xColor Overlay::getColor() {
|
||||||
if (_colorPulse == 0.0f) {
|
if (_colorPulse == 0.0f) {
|
||||||
return _color;
|
return _color;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QScriptValue>
|
#include <QScriptValue>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <RegisteredMetaTypes.h>
|
||||||
#include <SharedUtil.h> // for xColor
|
#include <SharedUtil.h> // for xColor
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ public:
|
||||||
|
|
||||||
Overlay();
|
Overlay();
|
||||||
~Overlay();
|
~Overlay();
|
||||||
void init(QGLWidget* parent);
|
void init(QGLWidget* parent, QScriptEngine* scriptEngine);
|
||||||
virtual void update(float deltatime) {}
|
virtual void update(float deltatime) {}
|
||||||
virtual void render(RenderArgs* args) = 0;
|
virtual void render(RenderArgs* args) = 0;
|
||||||
|
|
||||||
|
@ -77,6 +78,7 @@ public:
|
||||||
void setAlphaPulse(float value) { _alphaPulse = value; }
|
void setAlphaPulse(float value) { _alphaPulse = value; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float updatePulse();
|
float updatePulse();
|
||||||
|
@ -100,6 +102,8 @@ protected:
|
||||||
xColor _color;
|
xColor _color;
|
||||||
bool _visible; // should the overlay be drawn at all
|
bool _visible; // should the overlay be drawn at all
|
||||||
Anchor _anchor;
|
Anchor _anchor;
|
||||||
|
|
||||||
|
QScriptEngine* _scriptEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,3 +64,23 @@ void Overlay2D::setProperties(const QScriptValue& properties) {
|
||||||
//qDebug() << "set bounds to " << getBounds();
|
//qDebug() << "set bounds to " << getBounds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Overlay2D::getProperty(const QString& property) {
|
||||||
|
if (property == "bounds") {
|
||||||
|
return qRectToScriptValue(_scriptEngine, _bounds);
|
||||||
|
}
|
||||||
|
if (property == "x") {
|
||||||
|
return _bounds.x();
|
||||||
|
}
|
||||||
|
if (property == "y") {
|
||||||
|
return _bounds.y();
|
||||||
|
}
|
||||||
|
if (property == "width") {
|
||||||
|
return _bounds.width();
|
||||||
|
}
|
||||||
|
if (property == "height") {
|
||||||
|
return _bounds.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Overlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void setBounds(const QRect& bounds) { _bounds = bounds; }
|
void setBounds(const QRect& bounds) { _bounds = bounds; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QRect _bounds; // where on the screen to draw
|
QRect _bounds; // where on the screen to draw
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Menu.h>
|
#include <Menu.h>
|
||||||
|
#include <QScriptValueIterator>
|
||||||
|
|
||||||
#include "BillboardOverlay.h"
|
#include "BillboardOverlay.h"
|
||||||
#include "Circle3DOverlay.h"
|
#include "Circle3DOverlay.h"
|
||||||
|
@ -56,6 +57,7 @@ Overlays::~Overlays() {
|
||||||
|
|
||||||
void Overlays::init(QGLWidget* parent) {
|
void Overlays::init(QGLWidget* parent) {
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
_scriptEngine = new QScriptEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::update(float deltatime) {
|
void Overlays::update(float deltatime) {
|
||||||
|
@ -180,7 +182,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Overlays::addOverlay(Overlay* overlay) {
|
unsigned int Overlays::addOverlay(Overlay* overlay) {
|
||||||
overlay->init(_parent);
|
overlay->init(_parent, _scriptEngine);
|
||||||
|
|
||||||
QWriteLocker lock(&_lock);
|
QWriteLocker lock(&_lock);
|
||||||
unsigned int thisID = _nextOverlayID;
|
unsigned int thisID = _nextOverlayID;
|
||||||
|
@ -242,6 +244,51 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||||
return 0; // not found
|
return 0; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& property) {
|
||||||
|
OverlayPropertyResult result;
|
||||||
|
Overlay* thisOverlay = NULL;
|
||||||
|
QReadLocker lock(&_lock);
|
||||||
|
if (_overlays2D.contains(id)) {
|
||||||
|
thisOverlay = _overlays2D[id];
|
||||||
|
} else if (_overlays3D.contains(id)) {
|
||||||
|
thisOverlay = _overlays3D[id];
|
||||||
|
}
|
||||||
|
if (thisOverlay) {
|
||||||
|
result.value = thisOverlay->getProperty(property);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayPropertyResult::OverlayPropertyResult() :
|
||||||
|
value(QScriptValue())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue OverlayPropertyResultToScriptValue(QScriptEngine* engine, const OverlayPropertyResult& result)
|
||||||
|
{
|
||||||
|
if (!result.value.isValid()) {
|
||||||
|
return QScriptValue::UndefinedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue object = engine->newObject();
|
||||||
|
if (result.value.isObject()) {
|
||||||
|
QScriptValueIterator it(result.value);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
object.setProperty(it.name(), QScriptValue(it.value().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
object = result.value;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayPropertyResultFromScriptValue(const QScriptValue& value, OverlayPropertyResult& result)
|
||||||
|
{
|
||||||
|
result.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) {
|
RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) {
|
||||||
float bestDistance = std::numeric_limits<float>::max();
|
float bestDistance = std::numeric_limits<float>::max();
|
||||||
RayToOverlayIntersectionResult result;
|
RayToOverlayIntersectionResult result;
|
||||||
|
|
|
@ -16,6 +16,17 @@
|
||||||
|
|
||||||
#include "Overlay.h"
|
#include "Overlay.h"
|
||||||
|
|
||||||
|
class OverlayPropertyResult {
|
||||||
|
public:
|
||||||
|
OverlayPropertyResult();
|
||||||
|
QScriptValue value;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(OverlayPropertyResult);
|
||||||
|
|
||||||
|
QScriptValue OverlayPropertyResultToScriptValue(QScriptEngine* engine, const OverlayPropertyResult& value);
|
||||||
|
void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPropertyResult& value);
|
||||||
|
|
||||||
class RayToOverlayIntersectionResult {
|
class RayToOverlayIntersectionResult {
|
||||||
public:
|
public:
|
||||||
RayToOverlayIntersectionResult();
|
RayToOverlayIntersectionResult();
|
||||||
|
@ -27,6 +38,7 @@ public:
|
||||||
QString extraInfo;
|
QString extraInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(RayToOverlayIntersectionResult);
|
Q_DECLARE_METATYPE(RayToOverlayIntersectionResult);
|
||||||
|
|
||||||
QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, const RayToOverlayIntersectionResult& value);
|
QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, const RayToOverlayIntersectionResult& value);
|
||||||
|
@ -59,6 +71,9 @@ public slots:
|
||||||
/// returns the top most 2D overlay at the screen point, or 0 if not overlay at that point
|
/// returns the top most 2D overlay at the screen point, or 0 if not overlay at that point
|
||||||
unsigned int getOverlayAtPoint(const glm::vec2& point);
|
unsigned int getOverlayAtPoint(const glm::vec2& point);
|
||||||
|
|
||||||
|
/// returns the value of specified property, or null if there is no such property
|
||||||
|
OverlayPropertyResult getProperty(unsigned int id, const QString& property);
|
||||||
|
|
||||||
/// returns details about the closest 3D Overlay hit by the pick ray
|
/// returns details about the closest 3D Overlay hit by the pick ray
|
||||||
RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray);
|
RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray);
|
||||||
|
|
||||||
|
@ -77,6 +92,7 @@ private:
|
||||||
QGLWidget* _parent;
|
QGLWidget* _parent;
|
||||||
QReadWriteLock _lock;
|
QReadWriteLock _lock;
|
||||||
QReadWriteLock _deleteLock;
|
QReadWriteLock _deleteLock;
|
||||||
|
QScriptEngine* _scriptEngine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,14 @@ void Planar3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Planar3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "dimensions" || property == "scale" || property == "size") {
|
||||||
|
return vec2toScriptValue(_scriptEngine, _dimensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face) const {
|
float& distance, BoxFace& face) const {
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
void setDimensions(const glm::vec2& value) { _dimensions = value; }
|
void setDimensions(const glm::vec2& value) { _dimensions = value; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||||
|
|
||||||
|
|
|
@ -180,9 +180,38 @@ void Text3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Text3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "text") {
|
||||||
|
return _text;
|
||||||
|
}
|
||||||
|
if (property == "backgroundColor") {
|
||||||
|
return xColorToScriptValue(_scriptEngine, _backgroundColor);
|
||||||
|
}
|
||||||
|
if (property == "lineHeight") {
|
||||||
|
return _lineHeight;
|
||||||
|
}
|
||||||
|
if (property == "leftMargin") {
|
||||||
|
return _leftMargin;
|
||||||
|
}
|
||||||
|
if (property == "topMargin") {
|
||||||
|
return _topMargin;
|
||||||
|
}
|
||||||
|
if (property == "rightMargin") {
|
||||||
|
return _rightMargin;
|
||||||
|
}
|
||||||
|
if (property == "bottomMargin") {
|
||||||
|
return _bottomMargin;
|
||||||
|
}
|
||||||
|
if (property == "isFacingAvatar") {
|
||||||
|
return _isFacingAvatar;
|
||||||
|
}
|
||||||
|
return Planar3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
float Text3DOverlay::textWidth(const QString& text) const {
|
float Text3DOverlay::textWidth(const QString& text) const {
|
||||||
QFont font(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); // Same font properties as render()
|
QFont font(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); // Same font properties as render()
|
||||||
QFontMetrics fontMetrics(font);
|
QFontMetrics fontMetrics(font);
|
||||||
float scaleFactor = _lineHeight * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE;
|
float scaleFactor = _lineHeight * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE;
|
||||||
return scaleFactor * (float)fontMetrics.width(qPrintable(text));
|
return scaleFactor * (float)fontMetrics.width(qPrintable(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
|
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
float textWidth(const QString& text) const; // Meters
|
float textWidth(const QString& text) const; // Meters
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,28 @@ void TextOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue TextOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "font") {
|
||||||
|
QScriptValue font = _scriptEngine->newObject();
|
||||||
|
font.setProperty("size", _fontSize);
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
if (property == "text") {
|
||||||
|
return _text;
|
||||||
|
}
|
||||||
|
if (property == "backgroundColor") {
|
||||||
|
return xColorToScriptValue(_scriptEngine, _backgroundColor);
|
||||||
|
}
|
||||||
|
if (property == "leftMargin") {
|
||||||
|
return _leftMargin;
|
||||||
|
}
|
||||||
|
if (property == "topMargin") {
|
||||||
|
return _topMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Overlay2D::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float TextOverlay::textWidth(const QString& text) const {
|
float TextOverlay::textWidth(const QString& text) const {
|
||||||
QFont font(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); // Same font properties as render()
|
QFont font(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); // Same font properties as render()
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
void setFontSize(int fontSize) { _fontSize = fontSize; }
|
void setFontSize(int fontSize) { _fontSize = fontSize; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
float textWidth(const QString& text) const; // Pixels
|
float textWidth(const QString& text) const; // Pixels
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,14 @@ void Volume3DOverlay::setProperties(const QScriptValue& properties) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue Volume3DOverlay::getProperty(const QString& property) {
|
||||||
|
if (property == "dimensions" || property == "scale" || property == "size") {
|
||||||
|
return vec3toScriptValue(_scriptEngine, _dimensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Base3DOverlay::getProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
float& distance, BoxFace& face) const {
|
float& distance, BoxFace& face) const {
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
void setDimensions(const glm::vec3& value) { _dimensions = value; }
|
void setDimensions(const glm::vec3& value) { _dimensions = value; }
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
|
virtual QScriptValue getProperty(const QString& property);
|
||||||
|
|
||||||
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ void injectorFromScriptValue(const QScriptValue& object, AudioInjector*& out) {
|
||||||
|
|
||||||
AudioInjector::AudioInjector(QObject* parent) :
|
AudioInjector::AudioInjector(QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
_sound(NULL),
|
|
||||||
_options(),
|
_options(),
|
||||||
_shouldStop(false),
|
_shouldStop(false),
|
||||||
_loudness(0.0f),
|
_loudness(0.0f),
|
||||||
|
@ -42,7 +41,7 @@ AudioInjector::AudioInjector(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions) :
|
AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions) :
|
||||||
_sound(sound),
|
_audioData(sound->getByteArray()),
|
||||||
_options(injectorOptions),
|
_options(injectorOptions),
|
||||||
_shouldStop(false),
|
_shouldStop(false),
|
||||||
_loudness(0.0f),
|
_loudness(0.0f),
|
||||||
|
@ -52,6 +51,18 @@ AudioInjector::AudioInjector(Sound* sound, const AudioInjectorOptions& injectorO
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioInjector::AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions) :
|
||||||
|
_audioData(audioData),
|
||||||
|
_options(injectorOptions),
|
||||||
|
_shouldStop(false),
|
||||||
|
_loudness(0.0f),
|
||||||
|
_isFinished(false),
|
||||||
|
_currentSendPosition(0),
|
||||||
|
_localBuffer(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
AudioInjector::~AudioInjector() {
|
AudioInjector::~AudioInjector() {
|
||||||
if (_localBuffer) {
|
if (_localBuffer) {
|
||||||
_localBuffer->stop();
|
_localBuffer->stop();
|
||||||
|
@ -76,11 +87,9 @@ void AudioInjector::injectAudio() {
|
||||||
|
|
||||||
void AudioInjector::injectLocally() {
|
void AudioInjector::injectLocally() {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (_localAudioInterface) {
|
if (_localAudioInterface) {
|
||||||
const QByteArray& soundByteArray = _sound->getByteArray();
|
if (_audioData.size() > 0) {
|
||||||
|
_localBuffer = new AudioInjectorLocalBuffer(_audioData, this);
|
||||||
if (soundByteArray.size() > 0) {
|
|
||||||
_localBuffer = new AudioInjectorLocalBuffer(_sound->getByteArray(), this);
|
|
||||||
_localBuffer->open(QIODevice::ReadOnly);
|
_localBuffer->open(QIODevice::ReadOnly);
|
||||||
_localBuffer->setShouldLoop(_options.loop);
|
_localBuffer->setShouldLoop(_options.loop);
|
||||||
|
|
||||||
|
@ -114,15 +123,13 @@ void AudioInjector::injectLocally() {
|
||||||
const uchar MAX_INJECTOR_VOLUME = 0xFF;
|
const uchar MAX_INJECTOR_VOLUME = 0xFF;
|
||||||
|
|
||||||
void AudioInjector::injectToMixer() {
|
void AudioInjector::injectToMixer() {
|
||||||
QByteArray soundByteArray = _sound->getByteArray();
|
|
||||||
|
|
||||||
if (_currentSendPosition < 0 ||
|
if (_currentSendPosition < 0 ||
|
||||||
_currentSendPosition >= soundByteArray.size()) {
|
_currentSendPosition >= _audioData.size()) {
|
||||||
_currentSendPosition = 0;
|
_currentSendPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we actually have samples downloaded to inject
|
// make sure we actually have samples downloaded to inject
|
||||||
if (soundByteArray.size()) {
|
if (_audioData.size()) {
|
||||||
|
|
||||||
// setup the packet for injected audio
|
// setup the packet for injected audio
|
||||||
QByteArray injectAudioPacket = byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
|
QByteArray injectAudioPacket = byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
|
||||||
|
@ -172,15 +179,15 @@ void AudioInjector::injectToMixer() {
|
||||||
|
|
||||||
// loop to send off our audio in NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL byte chunks
|
// loop to send off our audio in NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL byte chunks
|
||||||
quint16 outgoingInjectedAudioSequenceNumber = 0;
|
quint16 outgoingInjectedAudioSequenceNumber = 0;
|
||||||
while (_currentSendPosition < soundByteArray.size() && !_shouldStop) {
|
while (_currentSendPosition < _audioData.size() && !_shouldStop) {
|
||||||
|
|
||||||
int bytesToCopy = std::min(((_options.stereo) ? 2 : 1) * NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
|
int bytesToCopy = std::min(((_options.stereo) ? 2 : 1) * NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL,
|
||||||
soundByteArray.size() - _currentSendPosition);
|
_audioData.size() - _currentSendPosition);
|
||||||
|
|
||||||
// Measure the loudness of this frame
|
// Measure the loudness of this frame
|
||||||
_loudness = 0.0f;
|
_loudness = 0.0f;
|
||||||
for (int i = 0; i < bytesToCopy; i += sizeof(int16_t)) {
|
for (int i = 0; i < bytesToCopy; i += sizeof(int16_t)) {
|
||||||
_loudness += abs(*reinterpret_cast<int16_t*>(soundByteArray.data() + _currentSendPosition + i)) /
|
_loudness += abs(*reinterpret_cast<int16_t*>(_audioData.data() + _currentSendPosition + i)) /
|
||||||
(MAX_SAMPLE_VALUE / 2.0f);
|
(MAX_SAMPLE_VALUE / 2.0f);
|
||||||
}
|
}
|
||||||
_loudness /= (float)(bytesToCopy / sizeof(int16_t));
|
_loudness /= (float)(bytesToCopy / sizeof(int16_t));
|
||||||
|
@ -203,7 +210,7 @@ void AudioInjector::injectToMixer() {
|
||||||
|
|
||||||
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
|
// copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
|
||||||
memcpy(injectAudioPacket.data() + numPreAudioDataBytes,
|
memcpy(injectAudioPacket.data() + numPreAudioDataBytes,
|
||||||
soundByteArray.data() + _currentSendPosition, bytesToCopy);
|
_audioData.data() + _currentSendPosition, bytesToCopy);
|
||||||
|
|
||||||
// grab our audio mixer from the NodeList, if it exists
|
// grab our audio mixer from the NodeList, if it exists
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
@ -217,7 +224,7 @@ void AudioInjector::injectToMixer() {
|
||||||
|
|
||||||
// send two packets before the first sleep so the mixer can start playback right away
|
// send two packets before the first sleep so the mixer can start playback right away
|
||||||
|
|
||||||
if (_currentSendPosition != bytesToCopy && _currentSendPosition < soundByteArray.size()) {
|
if (_currentSendPosition != bytesToCopy && _currentSendPosition < _audioData.size()) {
|
||||||
// not the first packet and not done
|
// not the first packet and not done
|
||||||
// sleep for the appropriate time
|
// sleep for the appropriate time
|
||||||
int usecToSleep = (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - timer.nsecsElapsed() / 1000;
|
int usecToSleep = (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - timer.nsecsElapsed() / 1000;
|
||||||
|
@ -227,7 +234,7 @@ void AudioInjector::injectToMixer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldLoop && _currentSendPosition >= soundByteArray.size()) {
|
if (shouldLoop && _currentSendPosition >= _audioData.size()) {
|
||||||
_currentSendPosition = 0;
|
_currentSendPosition = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AudioInjector : public QObject {
|
||||||
public:
|
public:
|
||||||
AudioInjector(QObject* parent);
|
AudioInjector(QObject* parent);
|
||||||
AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions);
|
AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions);
|
||||||
|
AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions);
|
||||||
~AudioInjector();
|
~AudioInjector();
|
||||||
|
|
||||||
bool isFinished() const { return _isFinished; }
|
bool isFinished() const { return _isFinished; }
|
||||||
|
@ -51,7 +52,7 @@ private:
|
||||||
void injectToMixer();
|
void injectToMixer();
|
||||||
void injectLocally();
|
void injectLocally();
|
||||||
|
|
||||||
Sound* _sound;
|
QByteArray _audioData;
|
||||||
AudioInjectorOptions _options;
|
AudioInjectorOptions _options;
|
||||||
bool _shouldStop;
|
bool _shouldStop;
|
||||||
float _loudness;
|
float _loudness;
|
||||||
|
|
|
@ -43,28 +43,32 @@ void AudioScriptingInterface::stopAllInjectors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) {
|
AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) {
|
||||||
|
if (sound) {
|
||||||
AudioInjector* injector = new AudioInjector(sound, injectorOptions);
|
AudioInjector* injector = new AudioInjector(sound, injectorOptions);
|
||||||
injector->setLocalAudioInterface(_localAudioInterface);
|
injector->setLocalAudioInterface(_localAudioInterface);
|
||||||
|
|
||||||
QThread* injectorThread = new QThread();
|
QThread* injectorThread = new QThread();
|
||||||
|
|
||||||
injector->moveToThread(injectorThread);
|
injector->moveToThread(injectorThread);
|
||||||
|
|
||||||
// start injecting when the injector thread starts
|
// start injecting when the injector thread starts
|
||||||
connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio);
|
connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio);
|
||||||
|
|
||||||
// connect the right slots and signals so that the AudioInjector is killed once the injection is complete
|
// connect the right slots and signals so that the AudioInjector is killed once the injection is complete
|
||||||
connect(injector, &AudioInjector::finished, injector, &AudioInjector::deleteLater);
|
connect(injector, &AudioInjector::finished, injector, &AudioInjector::deleteLater);
|
||||||
connect(injector, &AudioInjector::finished, injectorThread, &QThread::quit);
|
connect(injector, &AudioInjector::finished, injectorThread, &QThread::quit);
|
||||||
connect(injector, &AudioInjector::finished, this, &AudioScriptingInterface::injectorStopped);
|
connect(injector, &AudioInjector::finished, this, &AudioScriptingInterface::injectorStopped);
|
||||||
connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater);
|
connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater);
|
||||||
|
|
||||||
injectorThread->start();
|
injectorThread->start();
|
||||||
|
|
||||||
_activeInjectors.append(QPointer<AudioInjector>(injector));
|
_activeInjectors.append(QPointer<AudioInjector>(injector));
|
||||||
|
|
||||||
return injector;
|
return injector;
|
||||||
|
} else {
|
||||||
|
qDebug() << "AudioScriptingInterface::playSound called with null Sound object.";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioScriptingInterface::stopInjector(AudioInjector* injector) {
|
void AudioScriptingInterface::stopInjector(AudioInjector* injector) {
|
||||||
|
|
|
@ -29,96 +29,27 @@
|
||||||
#include "AudioEditBuffer.h"
|
#include "AudioEditBuffer.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
|
||||||
|
QScriptValue soundToScriptValue(QScriptEngine* engine, SharedSoundPointer const& in) {
|
||||||
QScriptValue soundToScriptValue(QScriptEngine* engine, Sound* const& in) {
|
return engine->newQObject(in.data());
|
||||||
return engine->newQObject(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundFromScriptValue(const QScriptValue& object, Sound*& out) {
|
void soundFromScriptValue(const QScriptValue &object, SharedSoundPointer &out) {
|
||||||
out = qobject_cast<Sound*>(object.toQObject());
|
out = SharedSoundPointer(qobject_cast<Sound*>(object.toQObject()));
|
||||||
|
qDebug() << "Sound from script value" << out.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
// procedural audio version of Sound
|
Sound::Sound(const QUrl& url, bool isStereo) :
|
||||||
Sound::Sound(float volume, float frequency, float duration, float decay, QObject* parent) :
|
Resource(url),
|
||||||
QObject(parent),
|
|
||||||
_isStereo(false)
|
|
||||||
{
|
|
||||||
static char monoAudioData[MAX_PACKET_SIZE];
|
|
||||||
static int16_t* monoAudioSamples = (int16_t*)(monoAudioData);
|
|
||||||
|
|
||||||
float t;
|
|
||||||
const float AUDIO_CALLBACK_MSECS = (float) NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL / (float)SAMPLE_RATE * 1000.0;
|
|
||||||
const float MAX_VOLUME = 32000.f;
|
|
||||||
const float MAX_DURATION = 2.f;
|
|
||||||
const float MIN_AUDIBLE_VOLUME = 0.001f;
|
|
||||||
const float NOISE_MAGNITUDE = 0.02f;
|
|
||||||
const int MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
|
||||||
const int MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
|
||||||
int numSamples = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; // we add sounds in chunks of this many samples
|
|
||||||
|
|
||||||
int chunkStartingSample = 0;
|
|
||||||
float waveFrequency = (frequency / SAMPLE_RATE) * TWO_PI;
|
|
||||||
while (volume > 0.f) {
|
|
||||||
for (int i = 0; i < numSamples; i++) {
|
|
||||||
t = (float)chunkStartingSample + (float)i;
|
|
||||||
float sample = sinf(t * waveFrequency);
|
|
||||||
sample += ((randFloat() - 0.5f) * NOISE_MAGNITUDE);
|
|
||||||
sample *= volume * MAX_VOLUME;
|
|
||||||
|
|
||||||
monoAudioSamples[i] = glm::clamp((int)sample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE);
|
|
||||||
volume *= (1.f - decay);
|
|
||||||
}
|
|
||||||
// add the monoAudioSamples to our actual output Byte Array
|
|
||||||
_byteArray.append(monoAudioData, numSamples * sizeof(int16_t));
|
|
||||||
chunkStartingSample += numSamples;
|
|
||||||
duration = glm::clamp(duration - (AUDIO_CALLBACK_MSECS / 1000.f), 0.f, MAX_DURATION);
|
|
||||||
//qDebug() << "decaying... _duration=" << _duration;
|
|
||||||
if (duration == 0.f || (volume < MIN_AUDIBLE_VOLUME)) {
|
|
||||||
volume = 0.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sound::Sound(const QUrl& sampleURL, bool isStereo, QObject* parent) :
|
|
||||||
QObject(parent),
|
|
||||||
_isStereo(isStereo),
|
_isStereo(isStereo),
|
||||||
_hasDownloaded(false)
|
_isReady(false)
|
||||||
{
|
{
|
||||||
// assume we have a QApplication or QCoreApplication instance and use the
|
|
||||||
// QNetworkAccess manager to grab the raw audio file at the given URL
|
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
|
||||||
|
|
||||||
qDebug() << "Requesting audio file" << sampleURL.toDisplayString();
|
|
||||||
|
|
||||||
QNetworkReply* soundDownload = networkAccessManager.get(QNetworkRequest(sampleURL));
|
|
||||||
connect(soundDownload, &QNetworkReply::finished, this, &Sound::replyFinished);
|
|
||||||
connect(soundDownload, SIGNAL(error(QNetworkReply::NetworkError)),
|
|
||||||
this, SLOT(replyError(QNetworkReply::NetworkError)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound::Sound(const QByteArray byteArray, QObject* parent) :
|
void Sound::downloadFinished(QNetworkReply* reply) {
|
||||||
QObject(parent),
|
|
||||||
_byteArray(byteArray),
|
|
||||||
_isStereo(false),
|
|
||||||
_hasDownloaded(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sound::append(const QByteArray byteArray) {
|
|
||||||
_byteArray.append(byteArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sound::replyFinished() {
|
|
||||||
|
|
||||||
QNetworkReply* reply = reinterpret_cast<QNetworkReply*>(sender());
|
|
||||||
|
|
||||||
// replace our byte array with the downloaded data
|
// replace our byte array with the downloaded data
|
||||||
QByteArray rawAudioByteArray = reply->readAll();
|
QByteArray rawAudioByteArray = reply->readAll();
|
||||||
|
|
||||||
// foreach(QByteArray b, reply->rawHeaderList())
|
|
||||||
// qDebug() << b.constData() << ": " << reply->rawHeader(b).constData();
|
|
||||||
|
|
||||||
if (reply->hasRawHeader("Content-Type")) {
|
if (reply->hasRawHeader("Content-Type")) {
|
||||||
|
|
||||||
QByteArray headerContentType = reply->rawHeader("Content-Type");
|
QByteArray headerContentType = reply->rawHeader("Content-Type");
|
||||||
|
@ -141,12 +72,7 @@ void Sound::replyFinished() {
|
||||||
qDebug() << "Network reply without 'Content-Type'.";
|
qDebug() << "Network reply without 'Content-Type'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasDownloaded = true;
|
_isReady = true;
|
||||||
}
|
|
||||||
|
|
||||||
void Sound::replyError(QNetworkReply::NetworkError code) {
|
|
||||||
QNetworkReply* reply = reinterpret_cast<QNetworkReply*>(sender());
|
|
||||||
qDebug() << "Error downloading sound file at" << reply->url().toString() << "-" << reply->errorString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::downSample(const QByteArray& rawAudioByteArray) {
|
void Sound::downSample(const QByteArray& rawAudioByteArray) {
|
||||||
|
|
|
@ -16,38 +16,37 @@
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
#include <QtScript/qscriptengine.h>
|
#include <QtScript/qscriptengine.h>
|
||||||
|
|
||||||
class Sound : public QObject {
|
#include <ResourceCache.h>
|
||||||
|
|
||||||
|
class Sound : public Resource {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(bool downloaded READ hasDownloaded)
|
Q_PROPERTY(bool downloaded READ isReady)
|
||||||
public:
|
public:
|
||||||
Sound(const QUrl& sampleURL, bool isStereo = false, QObject* parent = NULL);
|
Sound(const QUrl& url, bool isStereo = false);
|
||||||
Sound(float volume, float frequency, float duration, float decay, QObject* parent = NULL);
|
|
||||||
Sound(const QByteArray byteArray, QObject* parent = NULL);
|
|
||||||
void append(const QByteArray byteArray);
|
|
||||||
|
|
||||||
bool isStereo() const { return _isStereo; }
|
bool isStereo() const { return _isStereo; }
|
||||||
bool hasDownloaded() const { return _hasDownloaded; }
|
bool isReady() const { return _isReady; }
|
||||||
|
|
||||||
const QByteArray& getByteArray() { return _byteArray; }
|
const QByteArray& getByteArray() { return _byteArray; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray _byteArray;
|
QByteArray _byteArray;
|
||||||
bool _isStereo;
|
bool _isStereo;
|
||||||
bool _hasDownloaded;
|
bool _isReady;
|
||||||
|
|
||||||
void trimFrames();
|
void trimFrames();
|
||||||
void downSample(const QByteArray& rawAudioByteArray);
|
void downSample(const QByteArray& rawAudioByteArray);
|
||||||
void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray);
|
void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray);
|
||||||
|
|
||||||
private slots:
|
virtual void downloadFinished(QNetworkReply* reply);
|
||||||
void replyFinished();
|
|
||||||
void replyError(QNetworkReply::NetworkError code);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Sound*)
|
typedef QSharedPointer<Sound> SharedSoundPointer;
|
||||||
|
|
||||||
QScriptValue soundToScriptValue(QScriptEngine* engine, Sound* const& in);
|
Q_DECLARE_METATYPE(SharedSoundPointer)
|
||||||
void soundFromScriptValue(const QScriptValue& object, Sound*& out);
|
|
||||||
|
QScriptValue soundToScriptValue(QScriptEngine* engine, SharedSoundPointer const& in);
|
||||||
|
void soundFromScriptValue(const QScriptValue& object, SharedSoundPointer& out);
|
||||||
|
|
||||||
#endif // hifi_Sound_h
|
#endif // hifi_Sound_h
|
||||||
|
|
43
libraries/audio/src/SoundCache.cpp
Normal file
43
libraries/audio/src/SoundCache.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// SoundCache.cpp
|
||||||
|
// libraries/audio/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2014-11-13.
|
||||||
|
// Copyright 2014 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <qthread.h>
|
||||||
|
|
||||||
|
#include "SoundCache.h"
|
||||||
|
|
||||||
|
static int soundPointerMetaTypeId = qRegisterMetaType<SharedSoundPointer>();
|
||||||
|
|
||||||
|
SoundCache& SoundCache::getInstance() {
|
||||||
|
static SoundCache staticInstance;
|
||||||
|
return staticInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundCache::SoundCache(QObject* parent) :
|
||||||
|
ResourceCache(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
SharedSoundPointer result;
|
||||||
|
QMetaObject::invokeMethod(this, "getSound", Qt::BlockingQueuedConnection,
|
||||||
|
Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return getResource(url).staticCast<Sound>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<Resource> SoundCache::createResource(const QUrl& url, const QSharedPointer<Resource>& fallback,
|
||||||
|
bool delayLoad, const void* extra) {
|
||||||
|
qDebug() << "Requesting sound at" << url.toString();
|
||||||
|
return QSharedPointer<Resource>(new Sound(url), &Resource::allReferencesCleared);
|
||||||
|
}
|
34
libraries/audio/src/SoundCache.h
Normal file
34
libraries/audio/src/SoundCache.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// SoundCache.h
|
||||||
|
// libraries/audio/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2014-11-13.
|
||||||
|
// Copyright 2014 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_SoundCache_h
|
||||||
|
#define hifi_SoundCache_h
|
||||||
|
|
||||||
|
#include <ResourceCache.h>
|
||||||
|
|
||||||
|
#include "Sound.h"
|
||||||
|
|
||||||
|
/// Scriptable interface for sound loading.
|
||||||
|
class SoundCache : public ResourceCache {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static SoundCache& getInstance();
|
||||||
|
|
||||||
|
Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
||||||
|
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
|
||||||
|
private:
|
||||||
|
SoundCache(QObject* parent = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_SoundCache_h
|
|
@ -168,7 +168,7 @@ void Player::setupAudioThread() {
|
||||||
_audioThread = new QThread();
|
_audioThread = new QThread();
|
||||||
_options.position = _avatar->getPosition();
|
_options.position = _avatar->getPosition();
|
||||||
_options.orientation = _avatar->getOrientation();
|
_options.orientation = _avatar->getOrientation();
|
||||||
_injector.reset(new AudioInjector(_recording->getAudio(), _options), &QObject::deleteLater);
|
_injector.reset(new AudioInjector(_recording->getAudioData(), _options), &QObject::deleteLater);
|
||||||
_injector->moveToThread(_audioThread);
|
_injector->moveToThread(_audioThread);
|
||||||
_audioThread->start();
|
_audioThread->start();
|
||||||
QMetaObject::invokeMethod(_injector.data(), "injectAudio", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(_injector.data(), "injectAudio", Qt::QueuedConnection);
|
||||||
|
|
|
@ -43,13 +43,6 @@ void RecordingFrame::setBlendshapeCoefficients(QVector<float> blendshapeCoeffici
|
||||||
_blendshapeCoefficients = blendshapeCoefficients;
|
_blendshapeCoefficients = blendshapeCoefficients;
|
||||||
}
|
}
|
||||||
|
|
||||||
Recording::Recording() : _audio(NULL) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Recording::~Recording() {
|
|
||||||
delete _audio;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Recording::getLength() const {
|
int Recording::getLength() const {
|
||||||
if (_timestamps.isEmpty()) {
|
if (_timestamps.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -77,19 +70,10 @@ void Recording::addFrame(int timestamp, RecordingFrame &frame) {
|
||||||
_frames << frame;
|
_frames << frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Recording::addAudioPacket(const QByteArray& byteArray) {
|
|
||||||
if (!_audio) {
|
|
||||||
_audio = new Sound(byteArray);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_audio->append(byteArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recording::clear() {
|
void Recording::clear() {
|
||||||
_timestamps.clear();
|
_timestamps.clear();
|
||||||
_frames.clear();
|
_frames.clear();
|
||||||
delete _audio;
|
_audioData.clear();
|
||||||
_audio = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeVec3(QDataStream& stream, const glm::vec3& value) {
|
void writeVec3(QDataStream& stream, const glm::vec3& value) {
|
||||||
|
@ -324,7 +308,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) {
|
||||||
fileStream << buffer;
|
fileStream << buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileStream << recording->_audio->getByteArray();
|
fileStream << recording->getAudioData();
|
||||||
|
|
||||||
qint64 writingTime = timer.restart();
|
qint64 writingTime = timer.restart();
|
||||||
// Write data length and CRC-16
|
// Write data length and CRC-16
|
||||||
|
@ -367,7 +351,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) {
|
||||||
|
|
||||||
qDebug() << "Recording:";
|
qDebug() << "Recording:";
|
||||||
qDebug() << "Total frames:" << recording->getFrameNumber();
|
qDebug() << "Total frames:" << recording->getFrameNumber();
|
||||||
qDebug() << "Audio array:" << recording->getAudio()->getByteArray().size();
|
qDebug() << "Audio array:" << recording->getAudioData().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 checksumTime = timer.elapsed();
|
qint64 checksumTime = timer.elapsed();
|
||||||
|
@ -642,7 +626,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString
|
||||||
|
|
||||||
qDebug() << "Recording:";
|
qDebug() << "Recording:";
|
||||||
qDebug() << "Total frames:" << recording->getFrameNumber();
|
qDebug() << "Total frames:" << recording->getFrameNumber();
|
||||||
qDebug() << "Audio array:" << recording->getAudio()->getByteArray().size();
|
qDebug() << "Audio array:" << recording->getAudioData().size();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,6 @@ public:
|
||||||
/// Stores a recording
|
/// Stores a recording
|
||||||
class Recording {
|
class Recording {
|
||||||
public:
|
public:
|
||||||
Recording();
|
|
||||||
~Recording();
|
|
||||||
|
|
||||||
bool isEmpty() const { return _timestamps.isEmpty(); }
|
bool isEmpty() const { return _timestamps.isEmpty(); }
|
||||||
int getLength() const; // in ms
|
int getLength() const; // in ms
|
||||||
|
|
||||||
|
@ -58,11 +55,11 @@ public:
|
||||||
int getFrameNumber() const { return _frames.size(); }
|
int getFrameNumber() const { return _frames.size(); }
|
||||||
qint32 getFrameTimestamp(int i) const;
|
qint32 getFrameTimestamp(int i) const;
|
||||||
const RecordingFrame& getFrame(int i) const;
|
const RecordingFrame& getFrame(int i) const;
|
||||||
Sound* getAudio() const { return _audio; }
|
const QByteArray& getAudioData() const { return _audioData; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addFrame(int timestamp, RecordingFrame& frame);
|
void addFrame(int timestamp, RecordingFrame& frame);
|
||||||
void addAudioPacket(const QByteArray& byteArray);
|
void addAudioPacket(const QByteArray& byteArray) { _audioData.append(byteArray); }
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -70,7 +67,7 @@ private:
|
||||||
QVector<qint32> _timestamps;
|
QVector<qint32> _timestamps;
|
||||||
QVector<RecordingFrame> _frames;
|
QVector<RecordingFrame> _frames;
|
||||||
|
|
||||||
Sound* _audio;
|
QByteArray _audioData;
|
||||||
|
|
||||||
friend class Recorder;
|
friend class Recorder;
|
||||||
friend class Player;
|
friend class Player;
|
||||||
|
|
|
@ -28,6 +28,7 @@ const float EntityItem::DEFAULT_GLOW_LEVEL = 0.0f;
|
||||||
const float EntityItem::DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
const float EntityItem::DEFAULT_LOCAL_RENDER_ALPHA = 1.0f;
|
||||||
const float EntityItem::DEFAULT_MASS = 1.0f;
|
const float EntityItem::DEFAULT_MASS = 1.0f;
|
||||||
const float EntityItem::DEFAULT_LIFETIME = EntityItem::IMMORTAL;
|
const float EntityItem::DEFAULT_LIFETIME = EntityItem::IMMORTAL;
|
||||||
|
const QString EntityItem::DEFAULT_USER_DATA = QString("");
|
||||||
const float EntityItem::DEFAULT_DAMPING = 0.5f;
|
const float EntityItem::DEFAULT_DAMPING = 0.5f;
|
||||||
const glm::vec3 EntityItem::NO_VELOCITY = glm::vec3(0, 0, 0);
|
const glm::vec3 EntityItem::NO_VELOCITY = glm::vec3(0, 0, 0);
|
||||||
const float EntityItem::EPSILON_VELOCITY_LENGTH = (1.0f / 1000.0f) / (float)TREE_SCALE; // really small: 1mm/second
|
const float EntityItem::EPSILON_VELOCITY_LENGTH = (1.0f / 1000.0f) / (float)TREE_SCALE; // really small: 1mm/second
|
||||||
|
@ -71,6 +72,7 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
|
||||||
_gravity = DEFAULT_GRAVITY;
|
_gravity = DEFAULT_GRAVITY;
|
||||||
_damping = DEFAULT_DAMPING;
|
_damping = DEFAULT_DAMPING;
|
||||||
_lifetime = DEFAULT_LIFETIME;
|
_lifetime = DEFAULT_LIFETIME;
|
||||||
|
_userData = DEFAULT_USER_DATA;
|
||||||
_registrationPoint = DEFAULT_REGISTRATION_POINT;
|
_registrationPoint = DEFAULT_REGISTRATION_POINT;
|
||||||
_angularVelocity = DEFAULT_ANGULAR_VELOCITY;
|
_angularVelocity = DEFAULT_ANGULAR_VELOCITY;
|
||||||
_angularDamping = DEFAULT_ANGULAR_DAMPING;
|
_angularDamping = DEFAULT_ANGULAR_DAMPING;
|
||||||
|
@ -123,6 +125,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
||||||
requestedProperties += PROP_IGNORE_FOR_COLLISIONS;
|
requestedProperties += PROP_IGNORE_FOR_COLLISIONS;
|
||||||
requestedProperties += PROP_COLLISIONS_WILL_MOVE;
|
requestedProperties += PROP_COLLISIONS_WILL_MOVE;
|
||||||
requestedProperties += PROP_LOCKED;
|
requestedProperties += PROP_LOCKED;
|
||||||
|
requestedProperties += PROP_USER_DATA;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
@ -239,6 +242,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, appendValue, getIgnoreForCollisions());
|
APPEND_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, appendValue, getIgnoreForCollisions());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, appendValue, getCollisionsWillMove());
|
APPEND_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, appendValue, getCollisionsWillMove());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, getLocked());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, getUserData());
|
||||||
|
|
||||||
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
||||||
requestedProperties,
|
requestedProperties,
|
||||||
|
@ -502,6 +506,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
READ_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, bool, _ignoreForCollisions);
|
READ_ENTITY_PROPERTY(PROP_IGNORE_FOR_COLLISIONS, bool, _ignoreForCollisions);
|
||||||
READ_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, bool, _collisionsWillMove);
|
READ_ENTITY_PROPERTY(PROP_COLLISIONS_WILL_MOVE, bool, _collisionsWillMove);
|
||||||
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, _locked);
|
READ_ENTITY_PROPERTY(PROP_LOCKED, bool, _locked);
|
||||||
|
READ_ENTITY_PROPERTY_STRING(PROP_USER_DATA,setUserData);
|
||||||
|
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
qDebug() << " readEntityDataFromBuffer() _registrationPoint:" << _registrationPoint;
|
qDebug() << " readEntityDataFromBuffer() _registrationPoint:" << _registrationPoint;
|
||||||
|
@ -758,6 +763,7 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ignoreForCollisions, getIgnoreForCollisions);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ignoreForCollisions, getIgnoreForCollisions);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionsWillMove, getCollisionsWillMove);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionsWillMove, getCollisionsWillMove);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(locked, getLocked);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
|
||||||
|
|
||||||
properties._defaultSettings = false;
|
properties._defaultSettings = false;
|
||||||
|
|
||||||
|
@ -794,6 +800,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ignoreForCollisions, setIgnoreForCollisions);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ignoreForCollisions, setIgnoreForCollisions);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionsWillMove, setCollisionsWillMove);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionsWillMove, setCollisionsWillMove);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(locked, setLocked);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
somethingChangedNotification(); // notify derived classes that something has changed
|
somethingChangedNotification(); // notify derived classes that something has changed
|
||||||
|
|
|
@ -252,6 +252,10 @@ public:
|
||||||
bool getLocked() const { return _locked; }
|
bool getLocked() const { return _locked; }
|
||||||
void setLocked(bool value) { _locked = value; }
|
void setLocked(bool value) { _locked = value; }
|
||||||
|
|
||||||
|
static const QString DEFAULT_USER_DATA;
|
||||||
|
const QString& getUserData() const { return _userData; }
|
||||||
|
void setUserData(const QString& value) { _userData = value; }
|
||||||
|
|
||||||
// TODO: We need to get rid of these users of getRadius()...
|
// TODO: We need to get rid of these users of getRadius()...
|
||||||
float getRadius() const;
|
float getRadius() const;
|
||||||
|
|
||||||
|
@ -292,6 +296,7 @@ protected:
|
||||||
bool _ignoreForCollisions;
|
bool _ignoreForCollisions;
|
||||||
bool _collisionsWillMove;
|
bool _collisionsWillMove;
|
||||||
bool _locked;
|
bool _locked;
|
||||||
|
QString _userData;
|
||||||
|
|
||||||
// NOTE: Radius support is obsolete, but these private helper functions are available for this class to
|
// NOTE: Radius support is obsolete, but these private helper functions are available for this class to
|
||||||
// parse old data streams
|
// parse old data streams
|
||||||
|
|
|
@ -37,6 +37,7 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_gravity(EntityItem::DEFAULT_GRAVITY),
|
_gravity(EntityItem::DEFAULT_GRAVITY),
|
||||||
_damping(EntityItem::DEFAULT_DAMPING),
|
_damping(EntityItem::DEFAULT_DAMPING),
|
||||||
_lifetime(EntityItem::DEFAULT_LIFETIME),
|
_lifetime(EntityItem::DEFAULT_LIFETIME),
|
||||||
|
_userData(EntityItem::DEFAULT_USER_DATA),
|
||||||
_script(EntityItem::DEFAULT_SCRIPT),
|
_script(EntityItem::DEFAULT_SCRIPT),
|
||||||
_registrationPoint(EntityItem::DEFAULT_REGISTRATION_POINT),
|
_registrationPoint(EntityItem::DEFAULT_REGISTRATION_POINT),
|
||||||
_angularVelocity(EntityItem::DEFAULT_ANGULAR_VELOCITY),
|
_angularVelocity(EntityItem::DEFAULT_ANGULAR_VELOCITY),
|
||||||
|
@ -53,6 +54,7 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_gravityChanged(false),
|
_gravityChanged(false),
|
||||||
_dampingChanged(false),
|
_dampingChanged(false),
|
||||||
_lifetimeChanged(false),
|
_lifetimeChanged(false),
|
||||||
|
_userDataChanged(false),
|
||||||
_scriptChanged(false),
|
_scriptChanged(false),
|
||||||
_registrationPointChanged(false),
|
_registrationPointChanged(false),
|
||||||
_angularVelocityChanged(false),
|
_angularVelocityChanged(false),
|
||||||
|
@ -223,6 +225,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_CUTOFF, cutoff);
|
CHECK_PROPERTY_CHANGE(PROP_CUTOFF, cutoff);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked);
|
CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures);
|
CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_USER_DATA, userData);
|
||||||
|
|
||||||
return changedProperties;
|
return changedProperties;
|
||||||
}
|
}
|
||||||
|
@ -276,6 +279,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(cutoff);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(cutoff);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(locked);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(locked);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(textures);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(textures);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(userData);
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
QScriptValue sittingPoints = engine->newObject();
|
QScriptValue sittingPoints = engine->newObject();
|
||||||
|
@ -350,6 +354,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(cutoff, setCutoff);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(cutoff, setCutoff);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(locked, setLocked);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(locked, setLocked);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(textures, setTextures);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(textures, setTextures);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(userData, setUserData);
|
||||||
|
|
||||||
_lastEdited = usecTimestampNow();
|
_lastEdited = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
@ -512,6 +517,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures());
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, properties.getUserData());
|
||||||
}
|
}
|
||||||
if (propertyCount > 0) {
|
if (propertyCount > 0) {
|
||||||
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
||||||
|
@ -722,6 +728,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
||||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures);
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures);
|
||||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings);
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings);
|
||||||
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_USER_DATA, setUserData);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
@ -764,6 +771,7 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_gravityChanged = true;
|
_gravityChanged = true;
|
||||||
_dampingChanged = true;
|
_dampingChanged = true;
|
||||||
_lifetimeChanged = true;
|
_lifetimeChanged = true;
|
||||||
|
_userDataChanged = true;
|
||||||
_scriptChanged = true;
|
_scriptChanged = true;
|
||||||
_registrationPointChanged = true;
|
_registrationPointChanged = true;
|
||||||
_angularVelocityChanged = true;
|
_angularVelocityChanged = true;
|
||||||
|
|
|
@ -81,8 +81,9 @@ enum EntityPropertyList {
|
||||||
// used by Model entities
|
// used by Model entities
|
||||||
PROP_TEXTURES,
|
PROP_TEXTURES,
|
||||||
PROP_ANIMATION_SETTINGS,
|
PROP_ANIMATION_SETTINGS,
|
||||||
|
PROP_USER_DATA,
|
||||||
|
|
||||||
PROP_LAST_ITEM = PROP_ANIMATION_SETTINGS
|
PROP_LAST_ITEM = PROP_USER_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
||||||
|
@ -156,9 +157,13 @@ public:
|
||||||
|
|
||||||
float getDamping() const { return _damping; }
|
float getDamping() const { return _damping; }
|
||||||
void setDamping(float value) { _damping = value; _dampingChanged = true; }
|
void setDamping(float value) { _damping = value; _dampingChanged = true; }
|
||||||
|
|
||||||
float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity
|
float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity
|
||||||
void setLifetime(float value) { _lifetime = value; _lifetimeChanged = true; } /// set the lifetime in seconds for the entity
|
void setLifetime(float value) { _lifetime = value; _lifetimeChanged = true; } /// set the lifetime in seconds for the entity
|
||||||
|
|
||||||
|
const QString& getUserData() const { return _userData; }
|
||||||
|
void setUserData(const QString& value) { _userData = value; _userDataChanged = true; }
|
||||||
|
|
||||||
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
|
||||||
quint64 getCreated() const { return _created; }
|
quint64 getCreated() const { return _created; }
|
||||||
void setCreated(quint64 usecTime) { _created = usecTime; }
|
void setCreated(quint64 usecTime) { _created = usecTime; }
|
||||||
|
@ -216,6 +221,7 @@ public:
|
||||||
bool gravityChanged() const { return _gravityChanged; }
|
bool gravityChanged() const { return _gravityChanged; }
|
||||||
bool dampingChanged() const { return _dampingChanged; }
|
bool dampingChanged() const { return _dampingChanged; }
|
||||||
bool lifetimeChanged() const { return _lifetimeChanged; }
|
bool lifetimeChanged() const { return _lifetimeChanged; }
|
||||||
|
bool userDataChanged() const { return _userDataChanged; }
|
||||||
bool scriptChanged() const { return _scriptChanged; }
|
bool scriptChanged() const { return _scriptChanged; }
|
||||||
bool dimensionsChanged() const { return _dimensionsChanged; }
|
bool dimensionsChanged() const { return _dimensionsChanged; }
|
||||||
bool registrationPointChanged() const { return _registrationPointChanged; }
|
bool registrationPointChanged() const { return _registrationPointChanged; }
|
||||||
|
@ -315,6 +321,7 @@ private:
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
float _damping;
|
float _damping;
|
||||||
float _lifetime;
|
float _lifetime;
|
||||||
|
QString _userData;
|
||||||
QString _script;
|
QString _script;
|
||||||
glm::vec3 _registrationPoint;
|
glm::vec3 _registrationPoint;
|
||||||
glm::vec3 _angularVelocity;
|
glm::vec3 _angularVelocity;
|
||||||
|
@ -331,6 +338,7 @@ private:
|
||||||
bool _gravityChanged;
|
bool _gravityChanged;
|
||||||
bool _dampingChanged;
|
bool _dampingChanged;
|
||||||
bool _lifetimeChanged;
|
bool _lifetimeChanged;
|
||||||
|
bool _userDataChanged;
|
||||||
bool _scriptChanged;
|
bool _scriptChanged;
|
||||||
bool _registrationPointChanged;
|
bool _registrationPointChanged;
|
||||||
bool _angularVelocityChanged;
|
bool _angularVelocityChanged;
|
||||||
|
|
|
@ -115,7 +115,9 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, animationIsPlaying);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, animationIsPlaying);
|
||||||
|
|
||||||
if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) {
|
if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) {
|
||||||
setAnimationIsPlaying(animationIsPlaying);
|
if (animationIsPlaying != getAnimationIsPlaying()) {
|
||||||
|
setAnimationIsPlaying(animationIsPlaying);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) {
|
if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) {
|
||||||
setAnimationFPS(animationFPS);
|
setAnimationFPS(animationFPS);
|
||||||
|
@ -345,7 +347,6 @@ QVector<glm::quat> ModelEntityItem::getAnimationFrame() {
|
||||||
|
|
||||||
if (frameCount > 0) {
|
if (frameCount > 0) {
|
||||||
int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount;
|
int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount;
|
||||||
|
|
||||||
if (animationFrameIndex < 0 || animationFrameIndex > frameCount) {
|
if (animationFrameIndex < 0 || animationFrameIndex > frameCount) {
|
||||||
animationFrameIndex = 0;
|
animationFrameIndex = 0;
|
||||||
}
|
}
|
||||||
|
@ -427,7 +428,9 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
|
||||||
|
|
||||||
if (settingsMap.contains("running")) {
|
if (settingsMap.contains("running")) {
|
||||||
bool running = settingsMap["running"].toBool();
|
bool running = settingsMap["running"].toBool();
|
||||||
setAnimationIsPlaying(running);
|
if (running != getAnimationIsPlaying()) {
|
||||||
|
setAnimationIsPlaying(running);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsMap.contains("firstFrame")) {
|
if (settingsMap.contains("firstFrame")) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeEntityAddOrEdit:
|
case PacketTypeEntityAddOrEdit:
|
||||||
case PacketTypeEntityData:
|
case PacketTypeEntityData:
|
||||||
return VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS;
|
return VERSION_ENTITIES_HAVE_USER_DATA;
|
||||||
case PacketTypeEntityErase:
|
case PacketTypeEntityErase:
|
||||||
return 2;
|
return 2;
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
|
|
|
@ -125,6 +125,7 @@ const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3;
|
||||||
const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
||||||
const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4;
|
const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4;
|
||||||
const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5;
|
const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5;
|
||||||
|
const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6;
|
||||||
const PacketVersion VERSION_VOXELS_HAS_FILE_BREAKS = 1;
|
const PacketVersion VERSION_VOXELS_HAS_FILE_BREAKS = 1;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
|
|
||||||
ResourceCache::ResourceCache(QObject* parent) :
|
ResourceCache::ResourceCache(QObject* parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
_lastLRUKey(0) {
|
_lastLRUKey(0)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceCache::~ResourceCache() {
|
ResourceCache::~ResourceCache() {
|
||||||
|
@ -291,7 +293,7 @@ void Resource::makeRequest() {
|
||||||
connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64)));
|
connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64)));
|
||||||
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError()));
|
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError()));
|
||||||
connect(_reply, SIGNAL(finished()), SLOT(handleReplyFinished()));
|
connect(_reply, SIGNAL(finished()), SLOT(handleReplyFinished()));
|
||||||
|
|
||||||
_replyTimer = new QTimer(this);
|
_replyTimer = new QTimer(this);
|
||||||
connect(_replyTimer, SIGNAL(timeout()), SLOT(handleReplyTimeout()));
|
connect(_replyTimer, SIGNAL(timeout()), SLOT(handleReplyTimeout()));
|
||||||
_replyTimer->setSingleShot(true);
|
_replyTimer->setSingleShot(true);
|
||||||
|
|
|
@ -74,7 +74,7 @@ void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOp
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
static QString repeatedMessage
|
static QString repeatedMessage
|
||||||
= LogHandler::getInstance().addRepeatedMessageRegex(
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
"Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
"Octree::recurseElementWithOperation\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
|
@ -96,7 +96,7 @@ void Octree::recurseElementWithPostOperation(OctreeElement* element, RecurseOctr
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
static QString repeatedMessage
|
static QString repeatedMessage
|
||||||
= LogHandler::getInstance().addRepeatedMessageRegex(
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
"Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
"Octree::recurseElementWithPostOperation\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
|
@ -126,7 +126,7 @@ void Octree::recurseElementWithOperationDistanceSorted(OctreeElement* element, R
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
static QString repeatedMessage
|
static QString repeatedMessage
|
||||||
= LogHandler::getInstance().addRepeatedMessageRegex(
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
"Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
"Octree::recurseElementWithOperationDistanceSorted\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
|
@ -167,7 +167,7 @@ bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOpe
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
static QString repeatedMessage
|
static QString repeatedMessage
|
||||||
= LogHandler::getInstance().addRepeatedMessageRegex(
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
"Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
"Octree::recurseElementWithOperator\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return false;
|
return false;
|
||||||
|
@ -231,8 +231,18 @@ OctreeElement* Octree::nodeForOctalCode(OctreeElement* ancestorElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the element created!
|
// returns the element created!
|
||||||
OctreeElement* Octree::createMissingElement(OctreeElement* lastParentElement, const unsigned char* codeToReach) {
|
OctreeElement* Octree::createMissingElement(OctreeElement* lastParentElement, const unsigned char* codeToReach, int recursionCount) {
|
||||||
|
|
||||||
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"Octree::createMissingElement\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
|
qDebug() << "Octree::createMissingElement() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
|
return lastParentElement;
|
||||||
|
}
|
||||||
int indexOfNewChild = branchIndexWithDescendant(lastParentElement->getOctalCode(), codeToReach);
|
int indexOfNewChild = branchIndexWithDescendant(lastParentElement->getOctalCode(), codeToReach);
|
||||||
|
|
||||||
// If this parent element is a leaf, then you know the child path doesn't exist, so deal with
|
// If this parent element is a leaf, then you know the child path doesn't exist, so deal with
|
||||||
// breaking up the leaf first, which will also create a child path
|
// breaking up the leaf first, which will also create a child path
|
||||||
if (lastParentElement->requiresSplit()) {
|
if (lastParentElement->requiresSplit()) {
|
||||||
|
@ -246,7 +256,7 @@ OctreeElement* Octree::createMissingElement(OctreeElement* lastParentElement, co
|
||||||
if (*lastParentElement->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) {
|
if (*lastParentElement->getChildAtIndex(indexOfNewChild)->getOctalCode() == *codeToReach) {
|
||||||
return lastParentElement->getChildAtIndex(indexOfNewChild);
|
return lastParentElement->getChildAtIndex(indexOfNewChild);
|
||||||
} else {
|
} else {
|
||||||
return createMissingElement(lastParentElement->getChildAtIndex(indexOfNewChild), codeToReach);
|
return createMissingElement(lastParentElement->getChildAtIndex(indexOfNewChild), codeToReach, recursionCount + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,25 +265,20 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch
|
||||||
|
|
||||||
int bytesLeftToRead = bytesAvailable;
|
int bytesLeftToRead = bytesAvailable;
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
bool wantDebug = false;
|
|
||||||
|
|
||||||
// give this destination element the child mask from the packet
|
// give this destination element the child mask from the packet
|
||||||
const unsigned char ALL_CHILDREN_ASSUMED_TO_EXIST = 0xFF;
|
const unsigned char ALL_CHILDREN_ASSUMED_TO_EXIST = 0xFF;
|
||||||
|
|
||||||
if ((size_t)bytesLeftToRead < sizeof(unsigned char)) {
|
if ((size_t)bytesLeftToRead < sizeof(unsigned char)) {
|
||||||
if (wantDebug) {
|
qDebug() << "UNEXPECTED: readElementData() only had " << bytesLeftToRead << " bytes. "
|
||||||
qDebug() << "UNEXPECTED: readElementData() only had " << bytesLeftToRead << " bytes. "
|
"Not enough for meaningful data.";
|
||||||
"Not enough for meaningful data.";
|
|
||||||
}
|
|
||||||
return bytesAvailable; // assume we read the entire buffer...
|
return bytesAvailable; // assume we read the entire buffer...
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destinationElement->getScale() < SCALE_AT_DANGEROUSLY_DEEP_RECURSION) {
|
if (destinationElement->getScale() < SCALE_AT_DANGEROUSLY_DEEP_RECURSION) {
|
||||||
if (wantDebug) {
|
qDebug() << "UNEXPECTED: readElementData() destination element is unreasonably small ["
|
||||||
qDebug() << "UNEXPECTED: readElementData() destination element is unreasonably small ["
|
<< destinationElement->getScale() * (float)TREE_SCALE << " meters] "
|
||||||
<< destinationElement->getScale() * (float)TREE_SCALE << " meters] "
|
<< " Discarding " << bytesAvailable << " remaining bytes.";
|
||||||
<< " Discarding " << bytesAvailable << " remaining bytes.";
|
|
||||||
}
|
|
||||||
return bytesAvailable; // assume we read the entire buffer...
|
return bytesAvailable; // assume we read the entire buffer...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +327,7 @@ int Octree::readElementData(OctreeElement* destinationElement, const unsigned ch
|
||||||
: sizeof(childInBufferMask);
|
: sizeof(childInBufferMask);
|
||||||
|
|
||||||
if (bytesLeftToRead < bytesForMasks) {
|
if (bytesLeftToRead < bytesForMasks) {
|
||||||
if (wantDebug) {
|
if (bytesLeftToRead > 0) {
|
||||||
qDebug() << "UNEXPECTED: readElementDataFromBuffer() only had " << bytesLeftToRead << " bytes before masks. "
|
qDebug() << "UNEXPECTED: readElementDataFromBuffer() only had " << bytesLeftToRead << " bytes before masks. "
|
||||||
"Not enough for meaningful data.";
|
"Not enough for meaningful data.";
|
||||||
}
|
}
|
||||||
|
@ -385,7 +390,6 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, unsigned long
|
||||||
ReadBitstreamToTreeParams& args) {
|
ReadBitstreamToTreeParams& args) {
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
const unsigned char* bitstreamAt = bitstream;
|
const unsigned char* bitstreamAt = bitstream;
|
||||||
bool wantDebug = false;
|
|
||||||
|
|
||||||
// If destination element is not included, set it to root
|
// If destination element is not included, set it to root
|
||||||
if (!args.destinationElement) {
|
if (!args.destinationElement) {
|
||||||
|
@ -398,14 +402,24 @@ void Octree::readBitstreamToTree(const unsigned char * bitstream, unsigned long
|
||||||
|
|
||||||
while (bitstreamAt < bitstream + bufferSizeBytes) {
|
while (bitstreamAt < bitstream + bufferSizeBytes) {
|
||||||
OctreeElement* bitstreamRootElement = nodeForOctalCode(args.destinationElement, (unsigned char *)bitstreamAt, NULL);
|
OctreeElement* bitstreamRootElement = nodeForOctalCode(args.destinationElement, (unsigned char *)bitstreamAt, NULL);
|
||||||
|
|
||||||
int numberOfThreeBitSectionsInStream = numberOfThreeBitSectionsInCode(bitstreamAt, bufferSizeBytes);
|
int numberOfThreeBitSectionsInStream = numberOfThreeBitSectionsInCode(bitstreamAt, bufferSizeBytes);
|
||||||
|
if (numberOfThreeBitSectionsInStream > UNREASONABLY_DEEP_RECURSION) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... "
|
||||||
|
"numberOfThreeBitSectionsInStream: \\d+ This buffer is corrupt. Returning."
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << "UNEXPECTED: parsing of the octal code would make UNREASONABLY_DEEP_RECURSION... "
|
||||||
|
"numberOfThreeBitSectionsInStream:" << numberOfThreeBitSectionsInStream <<
|
||||||
|
"This buffer is corrupt. Returning.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (numberOfThreeBitSectionsInStream == OVERFLOWED_OCTCODE_BUFFER) {
|
if (numberOfThreeBitSectionsInStream == OVERFLOWED_OCTCODE_BUFFER) {
|
||||||
if (wantDebug) {
|
qDebug() << "UNEXPECTED: parsing of the octal code would overflow the buffer. "
|
||||||
qDebug() << "UNEXPECTED: parsing of the octal code would overflow the buffer. "
|
"This buffer is corrupt. Returning.";
|
||||||
"This buffer is corrupt. Returning.";
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ protected:
|
||||||
static bool countOctreeElementsOperation(OctreeElement* element, void* extraData);
|
static bool countOctreeElementsOperation(OctreeElement* element, void* extraData);
|
||||||
|
|
||||||
OctreeElement* nodeForOctalCode(OctreeElement* ancestorElement, const unsigned char* needleCode, OctreeElement** parentOfFoundElement) const;
|
OctreeElement* nodeForOctalCode(OctreeElement* ancestorElement, const unsigned char* needleCode, OctreeElement** parentOfFoundElement) const;
|
||||||
OctreeElement* createMissingElement(OctreeElement* lastParentElement, const unsigned char* codeToReach);
|
OctreeElement* createMissingElement(OctreeElement* lastParentElement, const unsigned char* codeToReach, int recursionCount = 0);
|
||||||
int readElementData(OctreeElement *destinationElement, const unsigned char* nodeData,
|
int readElementData(OctreeElement *destinationElement, const unsigned char* nodeData,
|
||||||
int bufferSizeBytes, ReadBitstreamToTreeParams& args);
|
int bufferSizeBytes, ReadBitstreamToTreeParams& args);
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,11 @@ const int MAX_TREE_SLICE_BYTES = 26;
|
||||||
const float VIEW_FRUSTUM_FOV_OVERSEND = 60.0f;
|
const float VIEW_FRUSTUM_FOV_OVERSEND = 60.0f;
|
||||||
|
|
||||||
// These are guards to prevent our voxel tree recursive routines from spinning out of control
|
// These are guards to prevent our voxel tree recursive routines from spinning out of control
|
||||||
const int UNREASONABLY_DEEP_RECURSION = 20; // use this for something that you want to be shallow, but not spin out
|
const int UNREASONABLY_DEEP_RECURSION = 29; // use this for something that you want to be shallow, but not spin out
|
||||||
const int DANGEROUSLY_DEEP_RECURSION = 200; // use this for something that needs to go deeper
|
const int DANGEROUSLY_DEEP_RECURSION = 200; // use this for something that needs to go deeper
|
||||||
const float SCALE_AT_UNREASONABLY_DEEP_RECURSION = (1.0f / powf(2.0f, UNREASONABLY_DEEP_RECURSION));
|
const float SCALE_AT_UNREASONABLY_DEEP_RECURSION = (1.0f / powf(2.0f, UNREASONABLY_DEEP_RECURSION));
|
||||||
const float SCALE_AT_DANGEROUSLY_DEEP_RECURSION = (1.0f / powf(2.0f, DANGEROUSLY_DEEP_RECURSION));
|
const float SCALE_AT_DANGEROUSLY_DEEP_RECURSION = (1.0f / powf(2.0f, DANGEROUSLY_DEEP_RECURSION));
|
||||||
|
const float SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE = SCALE_AT_UNREASONABLY_DEEP_RECURSION * 2.0f; // 0.00006103515 meter ~1/10,0000th
|
||||||
|
|
||||||
const int DEFAULT_MAX_OCTREE_PPS = 600; // the default maximum PPS we think any octree based server should send to a client
|
const int DEFAULT_MAX_OCTREE_PPS = 600; // the default maximum PPS we think any octree based server should send to a client
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#include <LogHandler.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <AACubeShape.h>
|
#include <AACubeShape.h>
|
||||||
|
@ -1159,6 +1160,10 @@ OctreeElement* OctreeElement::addChildAtIndex(int childIndex) {
|
||||||
bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) {
|
bool OctreeElement::safeDeepDeleteChildAtIndex(int childIndex, int recursionCount) {
|
||||||
bool deleteApproved = false;
|
bool deleteApproved = false;
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"OctreeElement::safeDeepDeleteChildAtIndex\\(\\) reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "OctreeElement::safeDeepDeleteChildAtIndex() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return deleteApproved;
|
return deleteApproved;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,6 @@ class ReadBitstreamToTreeParams;
|
||||||
class Shape;
|
class Shape;
|
||||||
class VoxelSystem;
|
class VoxelSystem;
|
||||||
|
|
||||||
const float SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE = (1.0f / TREE_SCALE) / 10000.0f; // 1/10,000th of a meter
|
|
||||||
|
|
||||||
// Callers who want delete hook callbacks should implement this class
|
// Callers who want delete hook callbacks should implement this class
|
||||||
class OctreeElementDeleteHook {
|
class OctreeElementDeleteHook {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <Sound.h>
|
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <VoxelConstants.h>
|
#include <VoxelConstants.h>
|
||||||
#include <VoxelDetail.h>
|
#include <VoxelDetail.h>
|
||||||
|
@ -47,14 +46,6 @@
|
||||||
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface;
|
||||||
EntityScriptingInterface ScriptEngine::_entityScriptingInterface;
|
EntityScriptingInterface ScriptEngine::_entityScriptingInterface;
|
||||||
|
|
||||||
static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* engine) {
|
|
||||||
QUrl soundURL = QUrl(context->argument(0).toString());
|
|
||||||
bool isStereo = context->argument(1).toBool();
|
|
||||||
QScriptValue soundScriptValue = engine->newQObject(new Sound(soundURL, isStereo), QScriptEngine::ScriptOwnership);
|
|
||||||
|
|
||||||
return soundScriptValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){
|
static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){
|
||||||
qDebug() << "script:print()<<" << context->argument(0).toString();
|
qDebug() << "script:print()<<" << context->argument(0).toString();
|
||||||
QString message = context->argument(0).toString()
|
QString message = context->argument(0).toString()
|
||||||
|
@ -263,10 +254,6 @@ void ScriptEngine::init() {
|
||||||
QScriptValue printConstructorValue = newFunction(debugPrint);
|
QScriptValue printConstructorValue = newFunction(debugPrint);
|
||||||
globalObject().setProperty("print", printConstructorValue);
|
globalObject().setProperty("print", printConstructorValue);
|
||||||
|
|
||||||
QScriptValue soundConstructorValue = newFunction(soundConstructor);
|
|
||||||
QScriptValue soundMetaObject = newQMetaObject(&Sound::staticMetaObject, soundConstructorValue);
|
|
||||||
globalObject().setProperty("Sound", soundMetaObject);
|
|
||||||
|
|
||||||
QScriptValue localVoxelsValue = scriptValueFromQMetaObject<LocalVoxels>();
|
QScriptValue localVoxelsValue = scriptValueFromQMetaObject<LocalVoxels>();
|
||||||
globalObject().setProperty("LocalVoxels", localVoxelsValue);
|
globalObject().setProperty("LocalVoxels", localVoxelsValue);
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,6 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
||||||
char dateString[100];
|
char dateString[100];
|
||||||
strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime);
|
strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime);
|
||||||
|
|
||||||
prefixString.append(QString(" [%1]").arg(dateString));
|
|
||||||
|
|
||||||
if (_shouldOutputPID) {
|
if (_shouldOutputPID) {
|
||||||
prefixString.append(QString(" [%1").arg(getpid()));
|
prefixString.append(QString(" [%1").arg(getpid()));
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <QRect>
|
||||||
|
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ void registerMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
|
qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
|
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue);
|
qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue);
|
||||||
|
@ -96,6 +98,22 @@ void quatFromScriptValue(const QScriptValue &object, glm::quat& quat) {
|
||||||
quat.w = object.property("w").toVariant().toFloat();
|
quat.w = object.property("w").toVariant().toFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
obj.setProperty("x", rect.x());
|
||||||
|
obj.setProperty("y", rect.y());
|
||||||
|
obj.setProperty("width", rect.width());
|
||||||
|
obj.setProperty("height", rect.height());
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qRectFromScriptValue(const QScriptValue &object, QRect& rect) {
|
||||||
|
rect.setX(object.property("x").toVariant().toInt());
|
||||||
|
rect.setY(object.property("y").toVariant().toInt());
|
||||||
|
rect.setWidth(object.property("width").toVariant().toInt());
|
||||||
|
rect.setHeight(object.property("height").toVariant().toInt());
|
||||||
|
}
|
||||||
|
|
||||||
QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color) {
|
QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color) {
|
||||||
QScriptValue obj = engine->newObject();
|
QScriptValue obj = engine->newObject();
|
||||||
obj.setProperty("red", color.red);
|
obj.setProperty("red", color.red);
|
||||||
|
|
|
@ -42,6 +42,9 @@ void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2);
|
||||||
QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat);
|
QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat);
|
||||||
void quatFromScriptValue(const QScriptValue &object, glm::quat& quat);
|
void quatFromScriptValue(const QScriptValue &object, glm::quat& quat);
|
||||||
|
|
||||||
|
QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect);
|
||||||
|
void qRectFromScriptValue(const QScriptValue& object, QRect& rect);
|
||||||
|
|
||||||
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
|
QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color);
|
||||||
void xColorFromScriptValue(const QScriptValue &object, xColor& color);
|
void xColorFromScriptValue(const QScriptValue &object, xColor& color);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue