mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
merge from upstream
This commit is contained in:
commit
e12b7807ad
22 changed files with 484 additions and 309 deletions
|
@ -295,7 +295,8 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
avatarPacketList.startSegment();
|
||||
|
||||
numAvatarDataBytes += avatarPacketList.write(otherNode->getUUID().toRfc4122());
|
||||
numAvatarDataBytes += avatarPacketList.write(otherAvatar.toByteArray(false));
|
||||
numAvatarDataBytes +=
|
||||
avatarPacketList.write(otherAvatar.toByteArray(false, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO));
|
||||
|
||||
avatarPacketList.endSegment();
|
||||
|
||||
|
@ -364,6 +365,31 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
}
|
||||
);
|
||||
|
||||
// We're done encoding this version of the otherAvatars. Update their "lastSent" joint-states so
|
||||
// that we can notice differences, next time around.
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& otherNode)->bool {
|
||||
if (!otherNode->getLinkedData()) {
|
||||
return false;
|
||||
}
|
||||
if (otherNode->getType() != NodeType::Agent) {
|
||||
return false;
|
||||
}
|
||||
if (!otherNode->getActiveSocket()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[&](const SharedNodePointer& otherNode) {
|
||||
AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
|
||||
MutexTryLocker lock(otherNodeData->getMutex());
|
||||
if (!lock.isLocked()) {
|
||||
return;
|
||||
}
|
||||
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
||||
otherAvatar.doneEncoding(false);
|
||||
});
|
||||
|
||||
_lastFrameTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,13 @@
|
|||
//
|
||||
|
||||
|
||||
Script.include("../../libraries/utils.js");
|
||||
|
||||
var RIGHT_HAND_CLICK = Controller.findAction("RIGHT_HAND_CLICK");
|
||||
var rightTriggerAction = RIGHT_HAND_CLICK;
|
||||
|
||||
var GRAB_USER_DATA_KEY = "grabKey";
|
||||
|
||||
var LEFT_HAND_CLICK = Controller.findAction("LEFT_HAND_CLICK");
|
||||
var leftTriggerAction = LEFT_HAND_CLICK;
|
||||
|
||||
|
@ -37,7 +41,7 @@ var INTERSECT_COLOR = {
|
|||
blue: 10
|
||||
};
|
||||
|
||||
var GRAB_RADIUS = 2;
|
||||
var GRAB_RADIUS = 0.5;
|
||||
|
||||
var GRAB_COLOR = {
|
||||
red: 250,
|
||||
|
@ -154,7 +158,6 @@ controller.prototype.attemptMove = function() {
|
|||
|
||||
var newPosition = Vec3.sum(handPosition, Vec3.multiply(direction, this.distanceToEntity))
|
||||
this.distanceHolding = true;
|
||||
//TO DO : USE SPRING ACTION UPDATE FOR MOVING
|
||||
if (this.actionID === null) {
|
||||
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
||||
targetPosition: newPosition,
|
||||
|
@ -184,7 +187,10 @@ controller.prototype.hidePointer = function() {
|
|||
|
||||
|
||||
controller.prototype.letGo = function() {
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
if (this.grabbedEntity && this.actionID) {
|
||||
this.deactivateEntity(this.grabbedEntity);
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
}
|
||||
this.grabbedEntity = null;
|
||||
this.actionID = null;
|
||||
this.distanceHolding = false;
|
||||
|
@ -264,11 +270,29 @@ controller.prototype.checkForInRangeObject = function() {
|
|||
if (grabbedEntity === null) {
|
||||
return false;
|
||||
} else {
|
||||
//We are grabbing an entity, so let it know we've grabbed it
|
||||
this.grabbedEntity = grabbedEntity;
|
||||
this.activateEntity(this.grabbedEntity);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
controller.prototype.activateEntity = function(entity) {
|
||||
var data = {
|
||||
activated: true,
|
||||
avatarId: MyAvatar.sessionUUID
|
||||
};
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||
}
|
||||
|
||||
controller.prototype.deactivateEntity = function(entity) {
|
||||
var data = {
|
||||
activated: false,
|
||||
avatarId: null
|
||||
};
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
|
||||
}
|
||||
|
||||
controller.prototype.onActionEvent = function(action, state) {
|
||||
if (this.pullAction === action && state === 1) {
|
||||
|
@ -293,7 +317,9 @@ controller.prototype.onActionEvent = function(action, state) {
|
|||
|
||||
controller.prototype.cleanup = function() {
|
||||
Entities.deleteEntity(this.pointer);
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
if (this.grabbedEntity) {
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
@ -314,6 +340,7 @@ function cleanup() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.update.connect(update)
|
||||
Controller.actionEvent.connect(onActionEvent);
|
|
@ -65,6 +65,10 @@ OmniTool = function(side) {
|
|||
});
|
||||
}
|
||||
|
||||
OmniTool.prototype.onCleanup = function(action) {
|
||||
this.unloadModule();
|
||||
}
|
||||
|
||||
OmniTool.prototype.onActionEvent = function(action, state) {
|
||||
// FIXME figure out the issues when only one spatial controller is active
|
||||
// logDebug("Action: " + action + " " + state);
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// breakdanceOmniToolModule.js
|
||||
// examples/libraries/omniTool/modules
|
||||
//
|
||||
// This is an omniTool module version of the breakdance game
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on Sept 3, 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Script.include("../toys/breakdanceCore.js");
|
||||
|
||||
OmniToolModules.Breakdance = function() {
|
||||
print("OmniToolModules.Breakdance...");
|
||||
}
|
||||
|
||||
OmniToolModules.Breakdance.prototype.onLoad = function(deltaTime) {
|
||||
print("OmniToolModules.Breakdance.prototype.onLoad()...");
|
||||
breakdanceStart();
|
||||
}
|
||||
|
||||
OmniToolModules.Breakdance.prototype.onUpdate = function(deltaTime) {
|
||||
print("OmniToolModules.Breakdance.prototype.onUpdate()...");
|
||||
breakdanceUpdate();
|
||||
}
|
||||
|
||||
OmniToolModules.Breakdance.prototype.onUnload = function() {
|
||||
print("OmniToolModules.Breakdance.prototype.onUnload()...");
|
||||
breakdanceEnd();
|
||||
}
|
||||
|
||||
OmniToolModuleType = "Breakdance";
|
|
@ -101,4 +101,29 @@ logInfo = function(str) {
|
|||
|
||||
logDebug = function(str) {
|
||||
print(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Computes the penetration between a point and a sphere (centered at the origin)
|
||||
// if point is inside sphere: returns true and stores the result in 'penetration'
|
||||
// (the vector that would move the point outside the sphere)
|
||||
// otherwise returns false
|
||||
findSphereHit = function(point, sphereRadius) {
|
||||
var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations
|
||||
var vectorLength = Vec3.length(point);
|
||||
if (vectorLength < EPSILON) {
|
||||
return true;
|
||||
}
|
||||
var distance = vectorLength - sphereRadius;
|
||||
if (distance < 0.0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
findSpherePointHit = function(sphereCenter, sphereRadius, point) {
|
||||
return findSphereHit(Vec3.subtract(point,sphereCenter), sphereRadius);
|
||||
}
|
||||
|
||||
findSphereSphereHit = function(firstCenter, firstRadius, secondCenter, secondRadius) {
|
||||
return findSpherePointHit(firstCenter, firstRadius + secondRadius, secondCenter);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//
|
||||
// breakdanceToy.js
|
||||
// examples
|
||||
// breakdanceCore.js
|
||||
// examples/toys
|
||||
//
|
||||
// This is the core breakdance game library, it can be used as part of an entity script, or an omniTool module, or bootstapped on it's own
|
||||
// Created by Brad Hefta-Gaub on August 24, 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
|
@ -9,34 +10,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
// helpers
|
||||
// Computes the penetration between a point and a sphere (centered at the origin)
|
||||
// if point is inside sphere: returns true and stores the result in 'penetration'
|
||||
// (the vector that would move the point outside the sphere)
|
||||
// otherwise returns false
|
||||
function findSphereHit(point, sphereRadius) {
|
||||
var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations
|
||||
var vectorLength = Vec3.length(point);
|
||||
if (vectorLength < EPSILON) {
|
||||
return true;
|
||||
}
|
||||
var distance = vectorLength - sphereRadius;
|
||||
if (distance < 0.0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function findSpherePointHit(sphereCenter, sphereRadius, point) {
|
||||
return findSphereHit(Vec3.subtract(point,sphereCenter), sphereRadius);
|
||||
}
|
||||
|
||||
function findSphereSphereHit(firstCenter, firstRadius, secondCenter, secondRadius) {
|
||||
return findSpherePointHit(firstCenter, firstRadius + secondRadius, secondCenter);
|
||||
}
|
||||
|
||||
Script.include("../libraries/utils.js");
|
||||
|
||||
function getPositionPuppet() {
|
||||
var DISTANCE_IN_FRONT = 2;
|
||||
|
@ -245,13 +220,18 @@ function getPositionRightOnBase() {
|
|||
}
|
||||
|
||||
|
||||
// We will also demonstrate some 3D overlays. We will create a couple of cubes, spheres, and lines
|
||||
// our 3D cube that moves around...
|
||||
var handSize = 0.25;
|
||||
var leftCubePosition = MyAvatar.getLeftPalmPosition();
|
||||
var rightCubePosition = MyAvatar.getRightPalmPosition();
|
||||
// some globals we will need access to
|
||||
var HAND_SIZE = 0.25;
|
||||
var TARGET_SIZE = 0.3;
|
||||
var TARGET_COLOR = { red: 128, green: 128, blue: 128};
|
||||
var TARGET_COLOR_HIT = { red: 0, green: 255, blue: 0};
|
||||
|
||||
var text = Overlays.addOverlay("text", {
|
||||
var textOverlay, leftHandOverlay, rightHandOverlay,
|
||||
leftOnBaseOverlay, leftLoweredOverlay, leftOverheadOverlay, leftSideOverlay, leftFrontOverlay,
|
||||
rightOnBaseOverlay, rightLoweredOverlay, rightOverheadOverlay, rightSideOverlay, rightFrontOverlay;
|
||||
|
||||
function createOverlays() {
|
||||
textOverlay = Overlays.addOverlay("text", {
|
||||
x: 100,
|
||||
y: 300,
|
||||
width: 900,
|
||||
|
@ -265,31 +245,110 @@ var text = Overlays.addOverlay("text", {
|
|||
backgroundAlpha: 0.5
|
||||
});
|
||||
|
||||
var leftHand= Overlays.addOverlay("cube", {
|
||||
position: leftCubePosition,
|
||||
size: handSize,
|
||||
leftHandOverlay = Overlays.addOverlay("cube", {
|
||||
position: MyAvatar.getLeftPalmPosition(),
|
||||
size: HAND_SIZE,
|
||||
color: { red: 0, green: 0, blue: 255},
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var rightHand= Overlays.addOverlay("cube", {
|
||||
position: rightCubePosition,
|
||||
size: handSize,
|
||||
rightHandOverlay = Overlays.addOverlay("cube", {
|
||||
position: MyAvatar.getRightPalmPosition(),
|
||||
size: HAND_SIZE,
|
||||
color: { red: 255, green: 0, blue: 0},
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
leftOnBaseOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftOnBase(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var targetSize = 0.3;
|
||||
var targetColor = { red: 128, green: 128, blue: 128};
|
||||
var targetColorHit = { red: 0, green: 255, blue: 0};
|
||||
var moveCycleColor = { red: 255, green: 255, blue: 0};
|
||||
|
||||
leftLoweredOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftLowered(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
leftOverheadOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftOverhead(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
leftSideOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftSide(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
leftFrontOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftFront(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
rightOnBaseOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightOnBase(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
rightLoweredOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightLowered(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
rightOverheadOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightOverhead(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
rightSideOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightSide(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
rightFrontOverlay = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightFront(),
|
||||
size: TARGET_SIZE,
|
||||
color: TARGET_COLOR,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
}
|
||||
|
||||
var TEMPORARY_LIFETIME = 60;
|
||||
|
||||
var animationSettings = JSON.stringify({
|
||||
var ANIMATION_SETTINGS = JSON.stringify({
|
||||
fps: 30,
|
||||
running: true,
|
||||
loop: true,
|
||||
|
@ -297,107 +356,22 @@ var animationSettings = JSON.stringify({
|
|||
lastFrame: 10000
|
||||
});
|
||||
|
||||
var naturalDimensions = { x: 1.63, y: 1.67, z: 0.31 };
|
||||
var dimensions = Vec3.multiply(naturalDimensions, 0.3);
|
||||
var NATURAL_DIMENSIONS = { x: 1.63, y: 1.67, z: 0.31 };
|
||||
var DIMENSIONS = Vec3.multiply(NATURAL_DIMENSIONS, 0.3);
|
||||
var puppetEntityID;
|
||||
|
||||
var puppetEntityID = Entities.addEntity({
|
||||
function createPuppet() {
|
||||
puppetEntityID = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/bboy1/bboy1.fbx",
|
||||
animationURL: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx",
|
||||
animationSettings: animationSettings,
|
||||
animationSettings: ANIMATION_SETTINGS,
|
||||
position: getPositionPuppet(),
|
||||
ignoreForCollisions: true,
|
||||
dimensions: dimensions,
|
||||
dimensions: DIMENSIONS,
|
||||
lifetime: TEMPORARY_LIFETIME
|
||||
});
|
||||
|
||||
var leftOnBase = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftOnBase(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
var leftLowered = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftLowered(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
var leftOverhead = Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftOverhead(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var leftSide= Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftSide(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
var leftFront= Overlays.addOverlay("cube", {
|
||||
position: getPositionLeftFront(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var rightOnBase = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightOnBase(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var rightLowered = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightLowered(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
var rightOverhead = Overlays.addOverlay("cube", {
|
||||
position: getPositionRightOverhead(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var rightSide= Overlays.addOverlay("cube", {
|
||||
position: getPositionRightSide(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
|
||||
var rightFront= Overlays.addOverlay("cube", {
|
||||
position: getPositionRightFront(),
|
||||
size: targetSize,
|
||||
color: targetColor,
|
||||
alpha: 1,
|
||||
solid: false
|
||||
});
|
||||
|
||||
var startDate = new Date();
|
||||
var lastTime = startDate.getTime();
|
||||
}
|
||||
|
||||
var NO_POSE = 0;
|
||||
var LEFT_ON_BASE = 1;
|
||||
|
@ -411,8 +385,6 @@ var RIGHT_LOWERED = 128;
|
|||
var RIGHT_SIDE = 256;
|
||||
var RIGHT_FRONT = 512;
|
||||
|
||||
var lastPoseValue = NO_POSE;
|
||||
|
||||
//http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx
|
||||
//http://s3.amazonaws.com/hifi-public/animations/Breakdancing/bboy_pose_to_idle.fbx
|
||||
//http://s3.amazonaws.com/hifi-public/animations/Breakdancing/bboy_uprock.fbx
|
||||
|
@ -461,8 +433,6 @@ poses[LEFT_ON_BASE + RIGHT_LOWERED ] = { name: "Left On Base + Right Lowered"
|
|||
poses[LEFT_ON_BASE + RIGHT_SIDE ] = { name: "Left On Base + Right Side", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx" };
|
||||
poses[LEFT_ON_BASE + RIGHT_FRONT ] = { name: "Left On Base + Right Front", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx" };
|
||||
|
||||
|
||||
|
||||
poses[LEFT_OVERHEAD + RIGHT_OVERHEAD ] = { name: "Left Overhead + Right Overhead", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/bboy_uprock.fbx" };
|
||||
poses[LEFT_LOWERED + RIGHT_OVERHEAD ] = { name: "Left Lowered + Right Overhead", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_footwork_1.fbx" };
|
||||
poses[LEFT_SIDE + RIGHT_OVERHEAD ] = { name: "Left Side + Right Overhead", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_footwork_2.fbx" };
|
||||
|
@ -484,43 +454,46 @@ poses[LEFT_SIDE + RIGHT_FRONT ] = { name: "Left Side + Right Front",
|
|||
poses[LEFT_FRONT + RIGHT_FRONT ] = { name: "Left Front + Right Front", animation: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_uprock_var_1_end.fbx" };
|
||||
|
||||
|
||||
Script.update.connect(function(deltaTime) {
|
||||
var date= new Date();
|
||||
var now= date.getTime();
|
||||
var elapsed = now - lastTime;
|
||||
var inMoveCycle = false;
|
||||
breakdanceStart = function() {
|
||||
print("breakdanceStart...");
|
||||
createOverlays();
|
||||
createPuppet();
|
||||
}
|
||||
|
||||
breakdanceUpdate = function(deltaTime) {
|
||||
//print("breakdanceUpdate...");
|
||||
|
||||
var leftHandPos = MyAvatar.getLeftPalmPosition();
|
||||
var rightHandPos = MyAvatar.getRightPalmPosition();
|
||||
|
||||
Overlays.editOverlay(leftHand, { position: leftHandPos } );
|
||||
Overlays.editOverlay(rightHand, { position: rightHandPos } );
|
||||
Overlays.editOverlay(leftHandOverlay, { position: leftHandPos } );
|
||||
Overlays.editOverlay(rightHandOverlay, { position: rightHandPos } );
|
||||
|
||||
var hitTargetLeftOnBase = findSphereSphereHit(leftHandPos, handSize/2, getPositionLeftOnBase(), targetSize/2);
|
||||
var hitTargetLeftOverhead = findSphereSphereHit(leftHandPos, handSize/2, getPositionLeftOverhead(), targetSize/2);
|
||||
var hitTargetLeftLowered = findSphereSphereHit(leftHandPos, handSize/2, getPositionLeftLowered(), targetSize/2);
|
||||
var hitTargetLeftSide = findSphereSphereHit(leftHandPos, handSize/2, getPositionLeftSide(), targetSize/2);
|
||||
var hitTargetLeftFront = findSphereSphereHit(leftHandPos, handSize/2, getPositionLeftFront(), targetSize/2);
|
||||
var hitTargetLeftOnBase = findSphereSphereHit(leftHandPos, HAND_SIZE/2, getPositionLeftOnBase(), TARGET_SIZE/2);
|
||||
var hitTargetLeftOverhead = findSphereSphereHit(leftHandPos, HAND_SIZE/2, getPositionLeftOverhead(), TARGET_SIZE/2);
|
||||
var hitTargetLeftLowered = findSphereSphereHit(leftHandPos, HAND_SIZE/2, getPositionLeftLowered(), TARGET_SIZE/2);
|
||||
var hitTargetLeftSide = findSphereSphereHit(leftHandPos, HAND_SIZE/2, getPositionLeftSide(), TARGET_SIZE/2);
|
||||
var hitTargetLeftFront = findSphereSphereHit(leftHandPos, HAND_SIZE/2, getPositionLeftFront(), TARGET_SIZE/2);
|
||||
|
||||
var hitTargetRightOnBase = findSphereSphereHit(rightHandPos, handSize/2, getPositionRightOnBase(), targetSize/2);
|
||||
var hitTargetRightOverhead = findSphereSphereHit(rightHandPos, handSize/2, getPositionRightOverhead(), targetSize/2);
|
||||
var hitTargetRightLowered = findSphereSphereHit(rightHandPos, handSize/2, getPositionRightLowered(), targetSize/2);
|
||||
var hitTargetRightSide = findSphereSphereHit(rightHandPos, handSize/2, getPositionRightSide(), targetSize/2);
|
||||
var hitTargetRightFront = findSphereSphereHit(rightHandPos, handSize/2, getPositionRightFront(), targetSize/2);
|
||||
var hitTargetRightOnBase = findSphereSphereHit(rightHandPos, HAND_SIZE/2, getPositionRightOnBase(), TARGET_SIZE/2);
|
||||
var hitTargetRightOverhead = findSphereSphereHit(rightHandPos, HAND_SIZE/2, getPositionRightOverhead(), TARGET_SIZE/2);
|
||||
var hitTargetRightLowered = findSphereSphereHit(rightHandPos, HAND_SIZE/2, getPositionRightLowered(), TARGET_SIZE/2);
|
||||
var hitTargetRightSide = findSphereSphereHit(rightHandPos, HAND_SIZE/2, getPositionRightSide(), TARGET_SIZE/2);
|
||||
var hitTargetRightFront = findSphereSphereHit(rightHandPos, HAND_SIZE/2, getPositionRightFront(), TARGET_SIZE/2);
|
||||
|
||||
|
||||
// determine target colors
|
||||
var targetColorLeftOnBase = hitTargetLeftOnBase ? targetColorHit : targetColor;
|
||||
var targetColorLeftOverhead = hitTargetLeftOverhead ? targetColorHit : targetColor;
|
||||
var targetColorLeftLowered = hitTargetLeftLowered ? targetColorHit : targetColor;
|
||||
var targetColorLeftSide = hitTargetLeftSide ? targetColorHit : targetColor;
|
||||
var targetColorLeftFront = hitTargetLeftFront ? targetColorHit : targetColor;
|
||||
var targetColorLeftOnBase = hitTargetLeftOnBase ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorLeftOverhead = hitTargetLeftOverhead ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorLeftLowered = hitTargetLeftLowered ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorLeftSide = hitTargetLeftSide ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorLeftFront = hitTargetLeftFront ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
|
||||
var targetColorRightOnBase = hitTargetRightOnBase ? targetColorHit : targetColor;
|
||||
var targetColorRightOverhead = hitTargetRightOverhead ? targetColorHit : targetColor;
|
||||
var targetColorRightLowered = hitTargetRightLowered ? targetColorHit : targetColor;
|
||||
var targetColorRightSide = hitTargetRightSide ? targetColorHit : targetColor;
|
||||
var targetColorRightFront = hitTargetRightFront ? targetColorHit : targetColor;
|
||||
var targetColorRightOnBase = hitTargetRightOnBase ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorRightOverhead = hitTargetRightOverhead ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorRightLowered = hitTargetRightLowered ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorRightSide = hitTargetRightSide ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
var targetColorRightFront = hitTargetRightFront ? TARGET_COLOR_HIT : TARGET_COLOR;
|
||||
|
||||
// calculate a combined arm pose based on left and right hits
|
||||
var poseValue = NO_POSE;
|
||||
|
@ -536,47 +509,48 @@ Script.update.connect(function(deltaTime) {
|
|||
poseValue += hitTargetRightFront ? RIGHT_FRONT : 0;
|
||||
|
||||
if (poses[poseValue] == undefined) {
|
||||
Overlays.editOverlay(text, { text: "no pose -- value:" + poseValue });
|
||||
Overlays.editOverlay(textOverlay, { text: "no pose -- value:" + poseValue });
|
||||
} else {
|
||||
Overlays.editOverlay(text, { text: "pose:" + poses[poseValue].name + "\n" + "animation:" + poses[poseValue].animation });
|
||||
Overlays.editOverlay(textOverlay, { text: "pose:" + poses[poseValue].name + "\n" + "animation:" + poses[poseValue].animation });
|
||||
var props = Entities.getEntityProperties(puppetEntityID);
|
||||
print("puppetEntityID:" + puppetEntityID + "age:"+props.age);
|
||||
Entities.editEntity(puppetEntityID, {
|
||||
animationURL: poses[poseValue].animation,
|
||||
lifetime: TEMPORARY_LIFETIME + props.age // renew lifetime
|
||||
});
|
||||
}
|
||||
|
||||
lastPoseValue = poseValue;
|
||||
|
||||
Overlays.editOverlay(leftOnBase, { position: getPositionLeftOnBase(), color: targetColorLeftOnBase } );
|
||||
Overlays.editOverlay(leftOverhead, { position: getPositionLeftOverhead(), color: targetColorLeftOverhead } );
|
||||
Overlays.editOverlay(leftLowered, { position: getPositionLeftLowered(), color: targetColorLeftLowered } );
|
||||
Overlays.editOverlay(leftSide, { position: getPositionLeftSide() , color: targetColorLeftSide } );
|
||||
Overlays.editOverlay(leftFront, { position: getPositionLeftFront() , color: targetColorLeftFront } );
|
||||
Overlays.editOverlay(leftOnBaseOverlay, { position: getPositionLeftOnBase(), color: targetColorLeftOnBase } );
|
||||
Overlays.editOverlay(leftOverheadOverlay, { position: getPositionLeftOverhead(), color: targetColorLeftOverhead } );
|
||||
Overlays.editOverlay(leftLoweredOverlay, { position: getPositionLeftLowered(), color: targetColorLeftLowered } );
|
||||
Overlays.editOverlay(leftSideOverlay, { position: getPositionLeftSide() , color: targetColorLeftSide } );
|
||||
Overlays.editOverlay(leftFrontOverlay, { position: getPositionLeftFront() , color: targetColorLeftFront } );
|
||||
|
||||
Overlays.editOverlay(rightOnBase, { position: getPositionRightOnBase(), color: targetColorRightOnBase } );
|
||||
Overlays.editOverlay(rightOverhead, { position: getPositionRightOverhead(), color: targetColorRightOverhead } );
|
||||
Overlays.editOverlay(rightLowered, { position: getPositionRightLowered(), color: targetColorRightLowered } );
|
||||
Overlays.editOverlay(rightSide, { position: getPositionRightSide() , color: targetColorRightSide } );
|
||||
Overlays.editOverlay(rightFront, { position: getPositionRightFront() , color: targetColorRightFront } );
|
||||
});
|
||||
Overlays.editOverlay(rightOnBaseOverlay, { position: getPositionRightOnBase(), color: targetColorRightOnBase } );
|
||||
Overlays.editOverlay(rightOverheadOverlay, { position: getPositionRightOverhead(), color: targetColorRightOverhead } );
|
||||
Overlays.editOverlay(rightLoweredOverlay, { position: getPositionRightLowered(), color: targetColorRightLowered } );
|
||||
Overlays.editOverlay(rightSideOverlay, { position: getPositionRightSide() , color: targetColorRightSide } );
|
||||
Overlays.editOverlay(rightFrontOverlay, { position: getPositionRightFront() , color: targetColorRightFront } );
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
Overlays.deleteOverlay(leftHand);
|
||||
Overlays.deleteOverlay(rightHand);
|
||||
|
||||
Overlays.deleteOverlay(text);
|
||||
Overlays.deleteOverlay(leftOnBase);
|
||||
Overlays.deleteOverlay(leftOverhead);
|
||||
Overlays.deleteOverlay(leftLowered);
|
||||
Overlays.deleteOverlay(leftSide);
|
||||
Overlays.deleteOverlay(leftFront);
|
||||
Overlays.deleteOverlay(rightOnBase);
|
||||
Overlays.deleteOverlay(rightOverhead);
|
||||
Overlays.deleteOverlay(rightLowered);
|
||||
Overlays.deleteOverlay(rightSide);
|
||||
Overlays.deleteOverlay(rightFront);
|
||||
breakdanceEnd= function() {
|
||||
print("breakdanceEnd...");
|
||||
|
||||
Overlays.deleteOverlay(leftHandOverlay);
|
||||
Overlays.deleteOverlay(rightHandOverlay);
|
||||
|
||||
Overlays.deleteOverlay(textOverlay);
|
||||
Overlays.deleteOverlay(leftOnBaseOverlay);
|
||||
Overlays.deleteOverlay(leftOverheadOverlay);
|
||||
Overlays.deleteOverlay(leftLoweredOverlay);
|
||||
Overlays.deleteOverlay(leftSideOverlay);
|
||||
Overlays.deleteOverlay(leftFrontOverlay);
|
||||
Overlays.deleteOverlay(rightOnBaseOverlay);
|
||||
Overlays.deleteOverlay(rightOverheadOverlay);
|
||||
Overlays.deleteOverlay(rightLoweredOverlay);
|
||||
Overlays.deleteOverlay(rightSideOverlay);
|
||||
Overlays.deleteOverlay(rightFrontOverlay);
|
||||
|
||||
print("puppetEntityID:"+puppetEntityID);
|
||||
Entities.deleteEntity(puppetEntityID);
|
||||
});
|
||||
}
|
17
examples/toys/breakdanceToy.js
Normal file
17
examples/toys/breakdanceToy.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// breakdanceToy.js
|
||||
// examples/toys
|
||||
//
|
||||
// This is an local script version of the breakdance game
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on Sept 3, 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Script.include("breakdanceCore.js");
|
||||
breakdanceStart();
|
||||
Script.update.connect(breakdanceUpdate);
|
||||
Script.scriptEnding.connect(breakdanceEnd);
|
|
@ -10,16 +10,39 @@
|
|||
//
|
||||
|
||||
#include "FileLogger.h"
|
||||
#include "HifiSockAddr.h"
|
||||
#include <FileUtils.h>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QDesktopServices>
|
||||
|
||||
const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt";
|
||||
const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
|
||||
const QString LOGS_DIRECTORY = "Logs";
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
#include <FileUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
|
||||
static const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt";
|
||||
static const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss";
|
||||
static const QString LOGS_DIRECTORY = "Logs";
|
||||
// Max log size is 1 MB
|
||||
static const uint64_t MAX_LOG_SIZE = 1024 * 1024;
|
||||
// Max log age is 1 hour
|
||||
static const uint64_t MAX_LOG_AGE_USECS = USECS_PER_SECOND * 3600;
|
||||
|
||||
QString getLogRollerFilename() {
|
||||
QString result = FileUtils::standardPath(LOGS_DIRECTORY);
|
||||
QHostAddress clientAddress = getLocalAddress();
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
result.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT)));
|
||||
return result;
|
||||
}
|
||||
|
||||
const QString& getLogFilename() {
|
||||
static QString fileName = FileUtils::standardPath(LOGS_DIRECTORY) + "hifi-log.txt";
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
class FilePersistThread : public GenericQueueThread < QString > {
|
||||
public:
|
||||
|
@ -28,8 +51,22 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void rollFileIfNecessary(QFile& file) {
|
||||
uint64_t now = usecTimestampNow();
|
||||
if ((file.size() > MAX_LOG_SIZE) || (now - _lastRollTime) > MAX_LOG_AGE_USECS) {
|
||||
QString newFileName = getLogRollerFilename();
|
||||
if (file.copy(newFileName)) {
|
||||
_lastRollTime = now;
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
file.close();
|
||||
qDebug() << "Rolled log file: " << newFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool processQueueItems(const Queue& messages) {
|
||||
QFile file(_logger._fileName);
|
||||
rollFileIfNecessary(file);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
|
||||
QTextStream out(&file);
|
||||
foreach(const QString& message, messages) {
|
||||
|
@ -40,20 +77,17 @@ protected:
|
|||
}
|
||||
private:
|
||||
const FileLogger& _logger;
|
||||
uint64_t _lastRollTime = 0;
|
||||
};
|
||||
|
||||
static FilePersistThread* _persistThreadInstance;
|
||||
|
||||
FileLogger::FileLogger(QObject* parent) :
|
||||
AbstractLoggerInterface(parent)
|
||||
AbstractLoggerInterface(parent), _fileName(getLogFilename())
|
||||
{
|
||||
_persistThreadInstance = new FilePersistThread(*this);
|
||||
_persistThreadInstance->initialize(true, QThread::LowestPriority);
|
||||
|
||||
_fileName = FileUtils::standardPath(LOGS_DIRECTORY);
|
||||
QHostAddress clientAddress = getLocalAddress();
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
_fileName.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT)));
|
||||
}
|
||||
|
||||
FileLogger::~FileLogger() {
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
virtual void locateLog() override;
|
||||
|
||||
private:
|
||||
QString _fileName;
|
||||
const QString _fileName;
|
||||
friend class FilePersistThread;
|
||||
};
|
||||
|
||||
|
|
|
@ -123,18 +123,18 @@ MyAvatar::~MyAvatar() {
|
|||
_lookAtTargetAvatar.reset();
|
||||
}
|
||||
|
||||
QByteArray MyAvatar::toByteArray(bool cullSmallChanges) {
|
||||
QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||
CameraMode mode = Application::getInstance()->getCamera()->getMode();
|
||||
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
|
||||
// fake the avatar position that is sent up to the AvatarMixer
|
||||
glm::vec3 oldPosition = _position;
|
||||
_position = getSkeletonPosition();
|
||||
QByteArray array = AvatarData::toByteArray(cullSmallChanges);
|
||||
QByteArray array = AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
// copy the correct position back
|
||||
_position = oldPosition;
|
||||
return array;
|
||||
}
|
||||
return AvatarData::toByteArray(cullSmallChanges);
|
||||
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
}
|
||||
|
||||
void MyAvatar::reset() {
|
||||
|
|
|
@ -200,7 +200,7 @@ private:
|
|||
|
||||
glm::vec3 getWorldBodyPosition() const;
|
||||
glm::quat getWorldBodyOrientation() const;
|
||||
QByteArray toByteArray(bool cullSmallChanges);
|
||||
QByteArray toByteArray(bool cullSmallChanges, bool sendAll);
|
||||
void simulate(float deltaTime);
|
||||
void updateFromTrackers(float deltaTime);
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
||||
|
|
|
@ -313,7 +313,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol
|
|||
|
||||
QByteArray samples = sound->getByteArray();
|
||||
if (stretchFactor == 1.0f) {
|
||||
return playSound(samples, options, NULL);
|
||||
return playSoundAndDelete(samples, options, NULL);
|
||||
}
|
||||
|
||||
soxr_io_spec_t spec = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I);
|
||||
|
@ -333,9 +333,16 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol
|
|||
qCDebug(audio) << "Unable to resample" << soundUrl << "from" << nInputSamples << "@" << standardRate << "to" << nOutputSamples << "@" << resampledRate;
|
||||
resampled = samples;
|
||||
}
|
||||
return playSound(resampled, options, NULL);
|
||||
return playSoundAndDelete(resampled, options, NULL);
|
||||
}
|
||||
|
||||
AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface) {
|
||||
AudioInjector* sound = playSound(buffer, options, localInterface);
|
||||
sound->triggerDeleteAfterFinish();
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
||||
AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface) {
|
||||
QThread* injectorThread = new QThread();
|
||||
injectorThread->setObjectName("Audio Injector Thread");
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
void setLocalAudioInterface(AbstractAudioInterface* localAudioInterface) { _localAudioInterface = localAudioInterface; }
|
||||
|
||||
static AudioInjector* playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||
static AudioInjector* playSound(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface);
|
||||
static AudioInjector* playSound(const QString& soundUrl, const float volume, const float stretchFactor, const glm::vec3 position);
|
||||
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
|
||||
quint64 DEFAULT_FILTERED_LOG_EXPIRY = 2 * USECS_PER_SECOND;
|
||||
|
||||
// this controls how large a change in joint-rotation must be before the interface sends it to the avatar mixer
|
||||
const float MIN_ROTATION_DOT = 0.9999999f;
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f);
|
||||
|
@ -145,7 +141,7 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
|
|||
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
|
||||
}
|
||||
|
||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||
// TODO: DRY this up to a shared method
|
||||
// that can pack any type given the number of bytes
|
||||
// and return the number of bytes to push the pointer
|
||||
|
@ -244,11 +240,12 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
|
||||
_lastSentJointData.resize(_jointData.size());
|
||||
|
||||
// foreach (const JointData& data, _jointData) {
|
||||
for (int i=0; i < _jointData.size(); i++) {
|
||||
const JointData& data = _jointData.at(i);
|
||||
if (_lastSentJointData[i].rotation != data.rotation) {
|
||||
if (!cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= MIN_ROTATION_DOT) {
|
||||
if (sendAll || _lastSentJointData[i].rotation != data.rotation) {
|
||||
if (sendAll ||
|
||||
!cullSmallChanges ||
|
||||
fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) {
|
||||
validity |= (1 << validityBit);
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +264,6 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
const JointData& data = _jointData[ i ];
|
||||
if (validity & (1 << validityBit)) {
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation);
|
||||
_lastSentJointData[i].rotation = data.rotation;
|
||||
}
|
||||
if (++validityBit == BITS_IN_BYTE) {
|
||||
validityBit = 0;
|
||||
|
@ -278,6 +274,20 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||
}
|
||||
|
||||
void AvatarData::doneEncoding(bool cullSmallChanges) {
|
||||
// The server has finished sending this version of the joint-data to other nodes. Update _lastSentJointData.
|
||||
_lastSentJointData.resize(_jointData.size());
|
||||
for (int i = 0; i < _jointData.size(); i ++) {
|
||||
const JointData& data = _jointData[ i ];
|
||||
if (_lastSentJointData[i].rotation != data.rotation) {
|
||||
if (!cullSmallChanges ||
|
||||
fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) {
|
||||
_lastSentJointData[i].rotation = data.rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AvatarData::shouldLogError(const quint64& now) {
|
||||
if (now > _errorLogExpiry) {
|
||||
_errorLogExpiry = now + DEFAULT_FILTERED_LOG_EXPIRY;
|
||||
|
@ -1083,7 +1093,11 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
|||
void AvatarData::sendAvatarDataPacket() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
QByteArray avatarByteArray = toByteArray(true);
|
||||
// about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed.
|
||||
// this is to guard against a joint moving once, the packet getting lost, and the joint never moving again.
|
||||
bool sendFullUpdate = randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO;
|
||||
QByteArray avatarByteArray = toByteArray(true, sendFullUpdate);
|
||||
doneEncoding(true);
|
||||
|
||||
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
|
||||
avatarPacket->write(avatarByteArray);
|
||||
|
|
|
@ -111,6 +111,11 @@ const int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000;
|
|||
// See also static AvatarData::defaultFullAvatarModelUrl().
|
||||
const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default");
|
||||
|
||||
// how often should we send a full report about joint rotations, even if they haven't changed?
|
||||
const float AVATAR_SEND_FULL_UPDATE_RATIO = 0.02;
|
||||
// this controls how large a change in joint-rotation must be before the interface sends it to the avatar mixer
|
||||
const float AVATAR_MIN_ROTATION_DOT = 0.9999999f;
|
||||
|
||||
|
||||
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found).
|
||||
// This is the start location in the Sandbox (xyz: 6270, 211, 6000).
|
||||
|
@ -171,7 +176,8 @@ public:
|
|||
glm::vec3 getHandPosition() const;
|
||||
void setHandPosition(const glm::vec3& handPosition);
|
||||
|
||||
virtual QByteArray toByteArray(bool cullSmallChanges);
|
||||
virtual QByteArray toByteArray(bool cullSmallChanges, bool sendAll);
|
||||
virtual void doneEncoding(bool cullSmallChanges);
|
||||
|
||||
/// \return true if an error should be logged
|
||||
bool shouldLogError(const quint64& now);
|
||||
|
|
|
@ -18,6 +18,26 @@
|
|||
#include "ScriptEngineLogging.h"
|
||||
#include "Quat.h"
|
||||
|
||||
quat Quat::normalize(const glm::quat& q) {
|
||||
return glm::normalize(q);
|
||||
}
|
||||
|
||||
glm::quat Quat::rotationBetween(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return ::rotationBetween(v1, v2);
|
||||
}
|
||||
|
||||
glm::quat Quat::lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up) {
|
||||
return glm::quat_cast(glm::lookAt(eye, center, up));
|
||||
}
|
||||
|
||||
glm::quat Quat::lookAtSimple(const glm::vec3& eye, const glm::vec3& center) {
|
||||
auto dir = glm::normalize(center - eye);
|
||||
// if the direction is nearly aligned with the Y axis, then use the X axis for 'up'
|
||||
if (dir.x < 0.001f && dir.z < 0.001f) {
|
||||
return lookAt(eye, center, Vectors::UNIT_X);
|
||||
}
|
||||
return lookAt(eye, center, Vectors::UNIT_Y);
|
||||
}
|
||||
|
||||
glm::quat Quat::multiply(const glm::quat& q1, const glm::quat& q2) {
|
||||
return q1 * q2;
|
||||
|
|
|
@ -25,6 +25,10 @@ class Quat : public QObject {
|
|||
|
||||
public slots:
|
||||
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
|
||||
glm::quat normalize(const glm::quat& q);
|
||||
glm::quat lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3& up);
|
||||
glm::quat lookAtSimple(const glm::vec3& eye, const glm::vec3& center);
|
||||
glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::quat fromVec3Degrees(const glm::vec3& vec3); // degrees
|
||||
glm::quat fromVec3Radians(const glm::vec3& vec3); // radians
|
||||
glm::quat fromPitchYawRollDegrees(float pitch, float yaw, float roll); // degrees
|
||||
|
|
|
@ -599,7 +599,8 @@ void ScriptEngine::run() {
|
|||
/ (1000 * 1000)) + 0.5);
|
||||
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
||||
|
||||
QByteArray avatarByteArray = _avatarData->toByteArray(true);
|
||||
QByteArray avatarByteArray = _avatarData->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
_avatarData->doneEncoding(true);
|
||||
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
|
||||
|
||||
avatarPacket->write(avatarByteArray);
|
||||
|
|
|
@ -13,66 +13,26 @@
|
|||
|
||||
#include <QDebug>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include "ScriptEngineLogging.h"
|
||||
#include "NumericalConstants.h"
|
||||
#include "Vec3.h"
|
||||
|
||||
glm::vec3 Vec3::reflect(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return glm::reflect(v1, v2);
|
||||
}
|
||||
glm::vec3 Vec3::cross(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return glm::cross(v1,v2);
|
||||
}
|
||||
|
||||
float Vec3::dot(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return glm::dot(v1,v2);
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::multiply(const glm::vec3& v1, float f) {
|
||||
return v1 * f;
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::multiply(float f, const glm::vec3& v1) {
|
||||
return v1 * f;
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::multiplyQbyV(const glm::quat& q, const glm::vec3& v) {
|
||||
return q * v;
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::sum(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return v1 + v2;
|
||||
}
|
||||
glm::vec3 Vec3::subtract(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return v1 - v2;
|
||||
}
|
||||
|
||||
float Vec3::length(const glm::vec3& v) {
|
||||
return glm::length(v);
|
||||
}
|
||||
|
||||
float Vec3::distance(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return glm::distance(v1, v2);
|
||||
}
|
||||
|
||||
float Vec3::orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3) {
|
||||
return glm::degrees(glm::orientedAngle(glm::normalize(v1), glm::normalize(v2), glm::normalize(v3)));
|
||||
float radians = glm::orientedAngle(glm::normalize(v1), glm::normalize(v2), glm::normalize(v3));
|
||||
return glm::degrees(radians);
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::normalize(const glm::vec3& v) {
|
||||
return glm::normalize(v);
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::mix(const glm::vec3& v1, const glm::vec3& v2, float m) {
|
||||
return glm::mix(v1, v2, m);
|
||||
}
|
||||
|
||||
void Vec3::print(const QString& lable, const glm::vec3& v) {
|
||||
qCDebug(scriptengine) << qPrintable(lable) << v.x << "," << v.y << "," << v.z;
|
||||
}
|
||||
|
||||
bool Vec3::equal(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
return v1 == v2;
|
||||
bool Vec3::withinEpsilon(const glm::vec3& v1, const glm::vec3& v2, float epsilon) {
|
||||
float distanceSquared = glm::length2(v1 - v2);
|
||||
return (epsilon*epsilon) >= distanceSquared;
|
||||
}
|
||||
|
||||
glm::vec3 Vec3::toPolar(const glm::vec3& v) {
|
||||
|
|
|
@ -11,40 +11,59 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_Vec3_h
|
||||
#define hifi_Vec3_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include "GLMHelpers.h"
|
||||
|
||||
/// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API
|
||||
class Vec3 : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
glm::vec3 reflect(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::vec3 cross(const glm::vec3& v1, const glm::vec3& v2);
|
||||
float dot(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::vec3 multiply(const glm::vec3& v1, float f);
|
||||
glm::vec3 multiply(float, const glm::vec3& v1);
|
||||
glm::vec3 multiplyQbyV(const glm::quat& q, const glm::vec3& v);
|
||||
glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2);
|
||||
float length(const glm::vec3& v);
|
||||
float distance(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::vec3 reflect(const glm::vec3& v1, const glm::vec3& v2) { return glm::reflect(v1, v2); }
|
||||
glm::vec3 cross(const glm::vec3& v1, const glm::vec3& v2) { return glm::cross(v1, v2); }
|
||||
float dot(const glm::vec3& v1, const glm::vec3& v2) { return glm::dot(v1, v2); }
|
||||
glm::vec3 multiply(const glm::vec3& v1, float f) { return v1 * f; }
|
||||
glm::vec3 multiply(float f, const glm::vec3& v1) { return v1 * f; }
|
||||
glm::vec3 multiplyQbyV(const glm::quat& q, const glm::vec3& v) { return q * v; }
|
||||
glm::vec3 sum(const glm::vec3& v1, const glm::vec3& v2) { return v1 + v2; }
|
||||
glm::vec3 subtract(const glm::vec3& v1, const glm::vec3& v2) { return v1 - v2; }
|
||||
float length(const glm::vec3& v) { return glm::length(v); }
|
||||
float distance(const glm::vec3& v1, const glm::vec3& v2) { return glm::distance(v1, v2); }
|
||||
float orientedAngle(const glm::vec3& v1, const glm::vec3& v2, const glm::vec3& v3);
|
||||
glm::vec3 normalize(const glm::vec3& v);
|
||||
glm::vec3 mix(const glm::vec3& v1, const glm::vec3& v2, float m);
|
||||
void print(const QString& lable, const glm::vec3& v);
|
||||
bool equal(const glm::vec3& v1, const glm::vec3& v2);
|
||||
glm::vec3 normalize(const glm::vec3& v) { return glm::normalize(v); };
|
||||
glm::vec3 mix(const glm::vec3& v1, const glm::vec3& v2, float m) { return glm::mix(v1, v2, m); }
|
||||
void print(const QString& label, const glm::vec3& v);
|
||||
bool equal(const glm::vec3& v1, const glm::vec3& v2) { return v1 == v2; }
|
||||
bool withinEpsilon(const glm::vec3& v1, const glm::vec3& v2, float epsilon);
|
||||
// FIXME misnamed, should be 'spherical' or 'euler' depending on the implementation
|
||||
glm::vec3 toPolar(const glm::vec3& v);
|
||||
glm::vec3 fromPolar(const glm::vec3& polar);
|
||||
glm::vec3 fromPolar(float elevation, float azimuth);
|
||||
const glm::vec3& UNIT_X() { return Vectors::UNIT_X; }
|
||||
const glm::vec3& UNIT_Y() { return Vectors::UNIT_Y; }
|
||||
const glm::vec3& UNIT_Z() { return Vectors::UNIT_Z; }
|
||||
const glm::vec3& UNIT_NEG_X() { return Vectors::UNIT_NEG_X; }
|
||||
const glm::vec3& UNIT_NEG_Y() { return Vectors::UNIT_NEG_Y; }
|
||||
const glm::vec3& UNIT_NEG_Z() { return Vectors::UNIT_NEG_Z; }
|
||||
const glm::vec3& UNIT_XY() { return Vectors::UNIT_XY; }
|
||||
const glm::vec3& UNIT_XZ() { return Vectors::UNIT_XZ; }
|
||||
const glm::vec3& UNIT_YZ() { return Vectors::UNIT_YZ; }
|
||||
const glm::vec3& UNIT_XYZ() { return Vectors::UNIT_XYZ; }
|
||||
const glm::vec3& FLOAT_MAX() { return Vectors::MAX; }
|
||||
const glm::vec3& FLOAT_MIN() { return Vectors::MIN; }
|
||||
const glm::vec3& ZERO() { return Vectors::ZERO; }
|
||||
const glm::vec3& ONE() { return Vectors::ONE; }
|
||||
const glm::vec3& TWO() { return Vectors::TWO; }
|
||||
const glm::vec3& HALF() { return Vectors::HALF; }
|
||||
const glm::vec3& RIGHT() { return Vectors::RIGHT; }
|
||||
const glm::vec3& UP() { return Vectors::UNIT_X; }
|
||||
const glm::vec3& FRONT() { return Vectors::FRONT; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // hifi_Vec3_h
|
||||
|
|
|
@ -27,6 +27,7 @@ const vec3 Vectors::MAX{ FLT_MAX };
|
|||
const vec3 Vectors::MIN{ -FLT_MAX };
|
||||
const vec3 Vectors::ZERO{ 0.0f };
|
||||
const vec3 Vectors::ONE{ 1.0f };
|
||||
const vec3 Vectors::TWO{ 2.0f };
|
||||
const vec3 Vectors::HALF{ 0.5f };
|
||||
const vec3& Vectors::RIGHT = Vectors::UNIT_X;
|
||||
const vec3& Vectors::UP = Vectors::UNIT_Y;
|
||||
|
|
|
@ -64,12 +64,12 @@ public:
|
|||
static const vec3 UNIT_XY;
|
||||
static const vec3 UNIT_XZ;
|
||||
static const vec3 UNIT_YZ;
|
||||
static const vec3 UNIT_ZX;
|
||||
static const vec3 UNIT_XYZ;
|
||||
static const vec3 MAX;
|
||||
static const vec3 MIN;
|
||||
static const vec3 ZERO;
|
||||
static const vec3 ONE;
|
||||
static const vec3 TWO;
|
||||
static const vec3 HALF;
|
||||
static const vec3& RIGHT;
|
||||
static const vec3& UP;
|
||||
|
|
Loading…
Reference in a new issue