mirror of
https://github.com/overte-org/overte.git
synced 2025-06-20 20:00:09 +02:00
* mirrors wip * fix view + projection, texture flipping, billboarding * wip portals * wip * fix cpu frustum culling (hacky?) * fix mirrors in deferred * mirrors on models + text * portals use exit as ignoreItem * cleanup * entity tags * wild guess to handle view correction, hide portalExitID in create when mirrorMode != portal * let's try this?? * plz * promising * fix paramsOffset and view flipping * portals shouldn't flip * break when tag found * fix portal view calculation * Revert "Mirrors + Portals" * Revert "Revert "Mirrors + Portals"" * web entity wantsKeyboardFocus property * fix typo * move audio zones to zone entity properties * fix audio zones in create * set dynamic factory * new procecural particle entity type * fix particle intersection * shorten create labels * fix 0 update props case * Ability to smooth model animations * sound entities * fix layered simulate items * fix stereo sound speed * support non-localOnly sound avatar entities * add sound url prompt * support registration point, improve locking * remove keyboardRasied * locking attempt #2 * fix keyboardRasied typo * add default particle props * add unlit property for shapes * Merge branch master into protocol_changes * add ambient light color * fix create issue * fix create issue * add tonemapping props to zones, wip ambient occlusion * wip ambient occlusion * it's working! * remove attachments * fix non-localOnly positional sounds not updating * change AO default to HBAO, remove from create * more graphics options * fix AO setting + effects in mirrors * fix AA in mirrors * alezia's fixes * fix haze in mirrors * add comment for SKYBOX_DISTANCE * new line * model loading priority updates over time, takes into account out of bounds, avatar entities have higher priority, and fsts can specify to wait for wearables to load before rendering * add loadPriority to model entities, working on other avatars waitForWearables * fix build error * try to fix isServer assert * fix stats + waitForWearables * Listen for click instead of release. * Reverted initial commit. Implemented hack to listen for menu click events. * Missed some reverts. * Missed another one. * Prevent duplicate actions. * Added extra needed checks. * Fix without formatting? (#91) * Hopefully fixed formatting. * Things can't be too easy. * Remove google poly * automated entity property serialization * cleanup + automate EntityPropertyFlags * text vertical alignment, use uint8_t for entity property enums, fix text recalculating too often * fix text size * Update interface/resources/controllers/keyboardMouse.json Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> * fix component mode serialization * Fixed mouse look in selfie mode. * fix text debug assert on invalid or unloaded font * missed some enums * fix ADD_GROUP_PROPERTY_TO_MAP * fix PROP_GRAB_EQUIPPABLE_INDICATOR_URL missing urlPermission * fix KeyLightPropertyGroup legacy properties * fix PolyLineEntityItem::getEntityProperties * comment cmake script * fix copyright * Replaced key value with key text. Added additional comment about the specific delete key used. * weekly promoted place Highlight the first place in the list as the weekly promoted place * Fixed lingering references to `avatarIcon`. Signed-off-by: armored-dragon <publicmail@armoreddragon.com> * Adding icon for "Grab And Equip" section Adding icon for "Grab And Equip" section * Add "Grab And Equip" section Add "Grab And Equip" section for the grabbale and Equipable groups of properties. * Add files via upload * Add tooltips for the "Grab and Equip" properties Add the tooltips for the "Grab and Equip" properties * Text adjustments for grab.equippable Text adjustments for grab.equippable * Make Maturity Filter persisted Make Maturity Filter persisted and with a default value (Teen & Everyone) * Adjust the default value for maturity Adjust the default value for maturity * move "triggerable" under GRAB & EQUIP move "triggerable" under GRAB & EQUIP * Remove hifi-screenshare Cherry picked and updated from Tivoli dd5b6ea6ee5597a06603e16509640e7ed18106bb Co-authored-by: Julian Groß <julian.g@posteo.de> * Insert placeholder to not break protocol yet. * Fix incorrectly resolved merge conflict, left too much code. * Fixes based on review comments on previous PR * Remove code accidentally re-added during a conflict fix * bump protocol * rebuild fonts with full charset (NOT -allglyphs) * Attempt at fixing Windows master branch builds * Change minimum angular velocity to a lower one * Fix Uuid.NULL behavior --------- Signed-off-by: armored-dragon <publicmail@armoreddragon.com> Co-authored-by: HifiExperiments <thingsandstuffblog@gmail.com> Co-authored-by: ksuprynowicz <ksuprynowicz@post.pl> Co-authored-by: Dale Glass <51060919+daleglass@users.noreply.github.com> Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Co-authored-by: Julian Groß <julian.g@posteo.de> Co-authored-by: armored-dragon <publicmail@armoreddragon.com> Co-authored-by: Armored-Dragon <github56254@armoreddragon.com> Co-authored-by: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Co-authored-by: Maki <mxmcube@gmail.com> Co-authored-by: Dale Glass <dale@daleglass.net>
285 lines
No EOL
11 KiB
JavaScript
285 lines
No EOL
11 KiB
JavaScript
//
|
|
// attachedEntitiesManager.js
|
|
//
|
|
// Created by Seth Alves on 2016-1-20
|
|
// Copyright 2016 High Fidelity, Inc.
|
|
//
|
|
// This script handles messages from the grab script related to wearables, and interacts with a doppelganger.
|
|
//
|
|
// 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("libraries/utils.js");
|
|
|
|
var DEFAULT_WEARABLE_DATA = {
|
|
joints: {}
|
|
};
|
|
|
|
|
|
var MINIMUM_DROP_DISTANCE_FROM_JOINT = 0.8;
|
|
var ATTACHED_ENTITY_SEARCH_DISTANCE = 10.0;
|
|
var ATTACHED_ENTITIES_SETTINGS_KEY = "ATTACHED_ENTITIES";
|
|
var DRESSING_ROOM_DISTANCE = 2.0;
|
|
var SHOW_TOOL_BAR = false;
|
|
|
|
// tool bar
|
|
|
|
if (SHOW_TOOL_BAR) {
|
|
var BUTTON_SIZE = 64;
|
|
var PADDING = 6;
|
|
Script.include(["libraries/toolBars.js"]);
|
|
|
|
var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.attachedEntities.toolbar");
|
|
var lockButton = toolBar.addTool({
|
|
width: BUTTON_SIZE,
|
|
height: BUTTON_SIZE,
|
|
imageURL: Script.resolvePath("assets/images/lock.svg"),
|
|
color: {
|
|
red: 255,
|
|
green: 255,
|
|
blue: 255
|
|
},
|
|
alpha: 1,
|
|
visible: true
|
|
}, false);
|
|
}
|
|
|
|
|
|
function mousePressEvent(event) {
|
|
var clickedOverlay = Overlays.getOverlayAtPoint({
|
|
x: event.x,
|
|
y: event.y
|
|
});
|
|
|
|
if (lockButton === toolBar.clicked(clickedOverlay)) {
|
|
manager.toggleLocked();
|
|
}
|
|
}
|
|
|
|
function scriptEnding() {
|
|
if (SHOW_TOOL_BAR) {
|
|
toolBar.cleanup();
|
|
}
|
|
}
|
|
|
|
if (SHOW_TOOL_BAR) {
|
|
Controller.mousePressEvent.connect(mousePressEvent);
|
|
}
|
|
Script.scriptEnding.connect(scriptEnding);
|
|
|
|
|
|
|
|
// attached entites
|
|
|
|
|
|
function AttachedEntitiesManager() {
|
|
var clothingLocked = false;
|
|
|
|
this.subscribeToMessages = function() {
|
|
Messages.subscribe('Hifi-Object-Manipulation');
|
|
Messages.messageReceived.connect(this.handleWearableMessages);
|
|
}
|
|
|
|
this.handleWearableMessages = function(channel, message, sender) {
|
|
if (channel !== 'Hifi-Object-Manipulation') {
|
|
return;
|
|
}
|
|
|
|
var parsedMessage = null;
|
|
|
|
try {
|
|
parsedMessage = JSON.parse(message);
|
|
} catch (e) {
|
|
print('error parsing wearable message');
|
|
return;
|
|
}
|
|
|
|
if (parsedMessage.action === 'update' ||
|
|
parsedMessage.action === 'loaded') {
|
|
// ignore
|
|
} else if (parsedMessage.action === 'release') {
|
|
manager.handleEntityRelease(parsedMessage.grabbedEntity, parsedMessage.joint)
|
|
// manager.saveAttachedEntities();
|
|
} else if (parsedMessage.action === 'equip') {
|
|
// manager.saveAttachedEntities();
|
|
} else {
|
|
print('attachedEntitiesManager -- unknown actions: ' + parsedMessage.action);
|
|
}
|
|
}
|
|
|
|
this.handleEntityRelease = function(grabbedEntity, releasedFromJoint) {
|
|
// if this is still equipped, just rewrite the position information.
|
|
var grabData = getEntityCustomData('grabKey', grabbedEntity, {});
|
|
|
|
var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints;
|
|
|
|
var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID", "parentJointIndex"]);
|
|
if (props.parentID === Uuid.NONE || props.parentID === MyAvatar.sessionUUID) {
|
|
var bestJointName = "";
|
|
var bestJointIndex = -1;
|
|
var bestJointDistance = 0;
|
|
var bestJointOffset = null;
|
|
for (var jointName in allowedJoints) {
|
|
if ((releasedFromJoint == "LeftHand" || releasedFromJoint == "RightHand") &&
|
|
(jointName == "LeftHand" || jointName == "RightHand")) {
|
|
// don't auto-attach to a hand if a hand just dropped something
|
|
continue;
|
|
}
|
|
var jointIndex = MyAvatar.getJointIndex(jointName);
|
|
if (jointIndex >= 0) {
|
|
var jointPosition = MyAvatar.getJointPosition(jointIndex);
|
|
var distanceFromJoint = Vec3.distance(jointPosition, props.position);
|
|
if (distanceFromJoint <= MINIMUM_DROP_DISTANCE_FROM_JOINT) {
|
|
if (bestJointIndex == -1 || distanceFromJoint < bestJointDistance) {
|
|
bestJointName = jointName;
|
|
bestJointIndex = jointIndex;
|
|
bestJointDistance = distanceFromJoint;
|
|
bestJointOffset = allowedJoints[jointName];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bestJointIndex != -1) {
|
|
var wearProps = Entities.getEntityProperties(grabbedEntity);
|
|
wearProps.parentID = MyAvatar.sessionUUID;
|
|
wearProps.parentJointIndex = bestJointIndex;
|
|
delete wearProps.localPosition;
|
|
delete wearProps.localRotation;
|
|
var updatePresets = false;
|
|
if (bestJointOffset && bestJointOffset.constructor === Array) {
|
|
if (!clothingLocked || bestJointOffset.length < 2) {
|
|
// we're unlocked or this thing didn't have a preset position, so update it
|
|
updatePresets = true;
|
|
} else {
|
|
// don't snap the entity to the preferred position if unlocked
|
|
wearProps.localPosition = bestJointOffset[0];
|
|
wearProps.localRotation = bestJointOffset[1];
|
|
}
|
|
}
|
|
|
|
Entities.deleteEntity(grabbedEntity);
|
|
//the true boolean here after add entity adds it as an 'avatar entity', which can travel with you from server to server.
|
|
|
|
var newEntity = Entities.addEntity(wearProps, true);
|
|
|
|
if (updatePresets) {
|
|
this.updateRelativeOffsets(newEntity);
|
|
}
|
|
} else if (props.parentID != Uuid.NONE) {
|
|
// drop the entity and set it to have no parent (not on the avatar), unless it's being equipped in a hand.
|
|
if (props.parentID === MyAvatar.sessionUUID &&
|
|
(props.parentJointIndex == MyAvatar.getJointIndex("RightHand") ||
|
|
props.parentJointIndex == MyAvatar.getJointIndex("LeftHand"))) {
|
|
// this is equipped on a hand -- don't clear the parent.
|
|
} else {
|
|
var wearProps = Entities.getEntityProperties(grabbedEntity);
|
|
wearProps.parentID = Uuid.NONE;
|
|
wearProps.parentJointIndex = -1;
|
|
delete wearProps.id;
|
|
delete wearProps.created;
|
|
delete wearProps.age;
|
|
delete wearProps.ageAsText;
|
|
delete wearProps.naturalDimensions;
|
|
delete wearProps.naturalPosition;
|
|
delete wearProps.actionData;
|
|
delete wearProps.sittingPoints;
|
|
delete wearProps.boundingBox;
|
|
delete wearProps.avatarEntity;
|
|
delete wearProps.owningAvatarID;
|
|
delete wearProps.localPosition;
|
|
delete wearProps.localRotation;
|
|
Entities.deleteEntity(grabbedEntity);
|
|
Entities.addEntity(wearProps);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.updateRelativeOffsets = function(entityID) {
|
|
// save the preferred (current) relative position and rotation into the user-data of the entity
|
|
var props = Entities.getEntityProperties(entityID);
|
|
if (props.parentID == MyAvatar.sessionUUID) {
|
|
grabData = getEntityCustomData('grabKey', entityID, {});
|
|
var wearableData = getEntityCustomData('wearable', entityID, DEFAULT_WEARABLE_DATA);
|
|
var currentJointName = MyAvatar.getJointNames()[props.parentJointIndex];
|
|
wearableData.joints[currentJointName] = [props.localPosition, props.localRotation];
|
|
setEntityCustomData('wearable', entityID, wearableData);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// this.saveAttachedEntities = function() {
|
|
// print("--- saving attached entities ---");
|
|
// saveData = [];
|
|
// var nearbyEntities = Entities.findEntities(MyAvatar.position, ATTACHED_ENTITY_SEARCH_DISTANCE);
|
|
// for (i = 0; i < nearbyEntities.length; i++) {
|
|
// var entityID = nearbyEntities[i];
|
|
// if (this.updateRelativeOffsets(entityID)) {
|
|
// var props = Entities.getEntityProperties(entityID); // refresh, because updateRelativeOffsets changed them
|
|
// this.scrubProperties(props);
|
|
// saveData.push(props);
|
|
// }
|
|
// }
|
|
// Settings.setValue(ATTACHED_ENTITIES_SETTINGS_KEY, JSON.stringify(saveData));
|
|
// }
|
|
|
|
// this.scrubProperties = function(props) {
|
|
// var toScrub = ["queryAACube", "position", "rotation",
|
|
// "created", "ageAsText", "naturalDimensions",
|
|
// "naturalPosition", "velocity", "acceleration",
|
|
// "angularVelocity", "boundingBox"];
|
|
// toScrub.forEach(function(propertyName) {
|
|
// delete props[propertyName];
|
|
// });
|
|
// // if the userData has a grabKey, clear old state
|
|
// if ("userData" in props) {
|
|
// try {
|
|
// parsedUserData = JSON.parse(props.userData);
|
|
// if ("grabKey" in parsedUserData) {
|
|
// parsedUserData.grabKey.refCount = 0;
|
|
// delete parsedUserData.grabKey["avatarId"];
|
|
// props["userData"] = JSON.stringify(parsedUserData);
|
|
// }
|
|
// } catch (e) {
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// this.loadAttachedEntities = function(grabbedEntity) {
|
|
// print("--- loading attached entities ---");
|
|
// jsonAttachmentData = Settings.getValue(ATTACHED_ENTITIES_SETTINGS_KEY);
|
|
// var loadData = [];
|
|
// try {
|
|
// loadData = JSON.parse(jsonAttachmentData);
|
|
// } catch (e) {
|
|
// print('error parsing saved attachment data');
|
|
// return;
|
|
// }
|
|
|
|
// for (i = 0; i < loadData.length; i ++) {
|
|
// var savedProps = loadData[ i ];
|
|
// var currentProps = Entities.getEntityProperties(savedProps.id);
|
|
// if (currentProps.id == savedProps.id &&
|
|
// // TODO -- also check that parentJointIndex matches?
|
|
// currentProps.parentID == MyAvatar.sessionUUID) {
|
|
// // entity is already in-world. TODO -- patch it up?
|
|
// continue;
|
|
// }
|
|
// this.scrubProperties(savedProps);
|
|
// delete savedProps["id"];
|
|
// savedProps.parentID = MyAvatar.sessionUUID; // this will change between sessions
|
|
// var loadedEntityID = Entities.addEntity(savedProps, true);
|
|
|
|
// Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
|
|
// action: 'loaded',
|
|
// grabbedEntity: loadedEntityID
|
|
// }));
|
|
// }
|
|
// }
|
|
}
|
|
|
|
var manager = new AttachedEntitiesManager();
|
|
manager.subscribeToMessages(); |