Merge branch 'master' of https://github.com/highfidelity/hifi into edit-button-to-select-in-pal

This commit is contained in:
howard-stearns 2017-01-06 10:21:22 -08:00
commit b149fa3d79
3 changed files with 239 additions and 11 deletions

Binary file not shown.

View file

@ -11,6 +11,18 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// hardcoding these as it appears we cannot traverse the originalTextures in overlays??? Maybe I've missed
// something, will revisit as this is sorta horrible.
const UNSELECTED_TEXTURES = {"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
};
const SELECTED_TEXTURES = { "idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"),
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png")
};
const UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6};
const SELECTED_COLOR = {red: 0xf3, green: 0x91, blue: 0x29};
(function() { // BEGIN LOCAL_SCOPE
Script.include("/~/system/libraries/controllers.js");
@ -19,8 +31,19 @@ Script.include("/~/system/libraries/controllers.js");
// Overlays.
//
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
function ExtendedOverlay(key, type, properties, selected) { // A wrapper around overlays to store the key it is associated with.
function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapper around overlays to store the key it is associated with.
overlays[key] = this;
if (hasModel) {
var modelKey = key + "-m";
this.model = new ExtendedOverlay(modelKey, "model", {
url: Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx"),
textures: textures(selected),
ignoreRayIntersection: true
}, false, false);
} else {
this.model = undefined;
}
this.key = key;
this.selected = selected || false; // not undefined
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
@ -34,14 +57,24 @@ ExtendedOverlay.prototype.deleteOverlay = function () { // remove display and da
ExtendedOverlay.prototype.editOverlay = function (properties) { // change display of this overlay
Overlays.editOverlay(this.activeOverlay, properties);
};
const UNSELECTED_COLOR = {red: 20, green: 250, blue: 20};
const SELECTED_COLOR = {red: 250, green: 20, blue: 20};
function color(selected) { return selected ? SELECTED_COLOR : UNSELECTED_COLOR; }
function color(selected) {
return selected ? SELECTED_COLOR : UNSELECTED_COLOR;
}
function textures(selected) {
return selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES;
}
ExtendedOverlay.prototype.select = function (selected) {
if (this.selected === selected) {
return;
}
this.editOverlay({color: color(selected)});
if (this.model) {
this.model.editOverlay({textures: textures(selected)});
}
this.selected = selected;
};
// Class methods:
@ -167,12 +200,12 @@ pal.fromQml.connect(function (message) { // messages are {method, params}, like
//
function addAvatarNode(id) {
var selected = ExtendedOverlay.isSelected(id);
return new ExtendedOverlay(id, "sphere", { // 3d so we don't go cross-eyed looking at it, but on top of everything
solid: true,
alpha: 0.8,
color: color(selected),
drawInFront: true
}, selected);
return new ExtendedOverlay(id, "sphere", {
drawInFront: true,
solid: true,
alpha: 0.8,
color: color(selected),
ignoreRayIntersection: false}, selected, true);
}
function populateUserList() {
var data = [];
@ -227,6 +260,7 @@ function updateOverlays() {
if (!id) {
return; // don't update ourself
}
var overlay = ExtendedOverlay.get(id);
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
print('Adding non-PAL avatar node', id);
@ -235,11 +269,36 @@ function updateOverlays() {
var avatar = AvatarList.getAvatar(id);
var target = avatar.position;
var distance = Vec3.distance(target, eye);
var offset = 0.2;
// base offset on 1/2 distance from hips to head if we can
var headIndex = avatar.getJointIndex("Head");
if (headIndex > 0) {
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
}
// get diff between target and eye (a vector pointing to the eye from avatar position)
var diff = Vec3.subtract(target, eye);
// move a bit in front, towards the camera
target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset));
// now bump it up a bit
target.y = target.y + offset;
overlay.ping = pingPong;
overlay.editOverlay({
position: target,
dimensions: 0.05 * distance // constant apparent size
dimensions: 0.032 * distance
});
if (overlay.model) {
overlay.model.ping = pingPong;
overlay.model.editOverlay({
position: target,
scale: 0.2 * distance, // constant apparent size
rotation: Camera.orientation
});
}
});
pingPong = !pingPong;
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)

View file

@ -0,0 +1,169 @@
// chair.js
//
// Restrictions right now:
// Chair objects need to be set as not colliding with avatars, so that they pull avatar
// avatar into collision with them. Also they need to be at or above standing height
// (like a stool).
//
// Copyright 2016 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
//
(function(){
var CHECK_INTERVAL_MSECS = 250; // When sitting, check for need to stand up
var SETTINGS_INTERVAL_MSECS = 1000; // Periodically check user data for updates
var DEFAULT_SIT_DISTANCE = 1.0; // How far away from the chair can you sit?
var HYSTERESIS = 1.1;
var sitTarget = { x: 0, y: 0, z: 0 }; // Offset where your butt should go relative
// to the object's center.
var SITTING = 0;
var STANDING = 1;
var state = STANDING;
var sitDistance = DEFAULT_SIT_DISTANCE;
var entity;
var props;
var checkTimer = false;
var settingsTimer = false;
var sitting = false;
var _this;
var WANT_DEBUG = false;
function debugPrint(string) {
if (WANT_DEBUG) {
print(string);
}
}
function howFarAway(position) {
return Vec3.distance(MyAvatar.position, position);
}
function isSeatOpen(position, distance) {
closest = true;
AvatarList.getAvatarIdentifiers().forEach(function(avatarSessionUUID) {
var avatar = AvatarList.getAvatar(avatarSessionUUID);
if (avatarSessionUUID && Vec3.distance(avatar.position, position) < distance) {
debugPrint("Seat Occupied!");
closest = false;
}
});
return closest;
}
function enterSitPose() {
var rot;
var UPPER_LEG_ANGLE = 240;
var LOWER_LEG_ANGLE = -80;
rot = Quat.safeEulerAngles(MyAvatar.getJointRotation("RightUpLeg"));
MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees(UPPER_LEG_ANGLE, rot.y, rot.z), MyAvatar.getJointTranslation("RightUpLeg"));
rot = Quat.safeEulerAngles(MyAvatar.getJointRotation("RightLeg"));
MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees(LOWER_LEG_ANGLE, rot.y, rot.z), MyAvatar.getJointTranslation("RightLeg"));
rot = Quat.safeEulerAngles(MyAvatar.getJointRotation("LeftUpLeg"));
MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees(UPPER_LEG_ANGLE, rot.y, rot.z), MyAvatar.getJointTranslation("LeftUpLeg"));
rot = Quat.safeEulerAngles(MyAvatar.getJointRotation("LeftLeg"));
MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees(LOWER_LEG_ANGLE, rot.y, rot.z), MyAvatar.getJointTranslation("LeftLeg"));
}
function leaveSitPose() {
MyAvatar.clearJointData("RightUpLeg");
MyAvatar.clearJointData("LeftUpLeg");
MyAvatar.clearJointData("RightLeg");
MyAvatar.clearJointData("LeftLeg");
}
function sitDown(position, rotation) {
var eulers = Quat.safeEulerAngles(MyAvatar.orientation);
eulers.y = Quat.safeEulerAngles(rotation).y;
MyAvatar.position = Vec3.sum(position, Vec3.multiplyQbyV(props.rotation, sitTarget));
MyAvatar.orientation = Quat.fromPitchYawRollDegrees(eulers.x, eulers.y, eulers.z);
enterSitPose();
state = SITTING;
}
this.preload = function(entityID) {
// Load the sound and range from the entity userData fields, and note the position of the entity.
debugPrint("chair preload");
entity = entityID;
_this = this;
settingsTimer = Script.setInterval(this.checkSettings, SETTINGS_INTERVAL_MSECS);
};
this.maybeStand = function() {
props = Entities.getEntityProperties(entity, [ "position", "rotation" ]);
// First, check if the entity is far enough away to not need to do anything with it
var howFar = howFarAway(props.position);
if ((state === SITTING) && (howFar > sitDistance * HYSTERESIS)) {
leaveSitPose();
Script.clearInterval(checkTimer);
checkTimer = null;
state = STANDING;
debugPrint("Standing");
}
}
this.clickDownOnEntity = function(entityID, mouseEvent) {
// If entity is clicked, sit
props = Entities.getEntityProperties(entity, [ "position", "rotation" ]);
if ((state === STANDING) && isSeatOpen(props.position, sitDistance)) {
sitDown(props.position, props.rotation);
checkTimer = Script.setInterval(this.maybeStand, CHECK_INTERVAL_MSECS);
debugPrint("Sitting from mouse click");
}
}
this.startFarTrigger = function() {
// If entity is far clicked, sit
props = Entities.getEntityProperties(entity, [ "position", "rotation" ]);
if ((state === STANDING) && isSeatOpen(props.position, sitDistance)) {
sitDown(props.position, props.rotation);
checkTimer = Script.setInterval(this.maybeStand, CHECK_INTERVAL_MSECS);
debugPrint("Sitting from far trigger");
}
}
this.checkSettings = function() {
var dataProps = Entities.getEntityProperties(entity, [ "userData" ]);
if (dataProps.userData) {
var data = JSON.parse(dataProps.userData);
if (data.sitDistance) {
if (!(sitDistance === data.sitDistance)) {
debugPrint("Read new sit distance: " + data.sitDistance);
}
sitDistance = data.sitDistance;
}
if (data.sitTarget) {
if (data.sitTarget.y && (data.sitTarget.y != sitTarget.y)) {
debugPrint("Read new sitTarget.y: " + data.sitTarget.y);
sitTarget.y = data.sitTarget.y;
}
if (data.sitTarget.x && (data.sitTarget.x != sitTarget.x)) {
debugPrint("Read new sitTarget.x: " + data.sitTarget.x);
sitTarget.x = data.sitTarget.x;
}
if (data.sitTarget.z && (data.sitTarget.z != sitTarget.z)) {
debugPrint("Read new sitTarget.z: " + data.sitTarget.z);
sitTarget.z = data.sitTarget.z;
}
}
}
}
this.unload = function(entityID) {
debugPrint("chair unload");
if (checkTimer) {
Script.clearInterval(checkTimer);
}
if (settingsTimer) {
Script.clearInterval(settingsTimer);
}
};
})