mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 22:27:13 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into console
This commit is contained in:
commit
8bc063e758
403 changed files with 15112 additions and 9429 deletions
|
@ -31,6 +31,7 @@
|
|||
#include <ShutdownEventListener.h>
|
||||
#include <SoundCache.h>
|
||||
#include <ResourceScriptingInterface.h>
|
||||
#include <ScriptEngines.h>
|
||||
|
||||
#include "AssignmentFactory.h"
|
||||
#include "AssignmentActionFactory.h"
|
||||
|
@ -53,6 +54,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
|
|||
|
||||
auto scriptableAvatar = DependencyManager::set<ScriptableAvatar>();
|
||||
auto addressManager = DependencyManager::set<AddressManager>();
|
||||
auto scriptEngines = DependencyManager::set<ScriptEngines>();
|
||||
|
||||
// create a NodeList as an unassigned client, must be after addressManager
|
||||
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned, listenPort);
|
||||
|
@ -174,6 +176,8 @@ AssignmentClient::~AssignmentClient() {
|
|||
void AssignmentClient::aboutToQuit() {
|
||||
stopAssignmentClient();
|
||||
|
||||
DependencyManager::destroy<ScriptEngines>();
|
||||
|
||||
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||
qInstallMessageHandler(0);
|
||||
}
|
||||
|
|
|
@ -60,11 +60,12 @@ private:
|
|||
|
||||
QDir _logDirectory;
|
||||
|
||||
HTTPManager _httpManager;
|
||||
|
||||
const unsigned int _numAssignmentClientForks;
|
||||
const unsigned int _minAssignmentClientForks;
|
||||
const unsigned int _maxAssignmentClientForks;
|
||||
|
||||
HTTPManager _httpManager;
|
||||
Assignment::Type _requestAssignmentType;
|
||||
QString _assignmentPool;
|
||||
QUuid _walletUUID;
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
|
||||
SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& success) const {
|
||||
SpatiallyNestableWeakPointer parent;
|
||||
|
||||
if (parentID.isNull()) {
|
||||
success = true;
|
||||
return parent;
|
||||
}
|
||||
|
||||
// search entities
|
||||
parent = _tree->findEntityByEntityItemID(parentID);
|
||||
if (parent.expired()) {
|
||||
|
|
|
@ -272,7 +272,7 @@ function loadBirds(howMany) {
|
|||
gravity: { x: 0, y: BIRD_GRAVITY, z: 0 },
|
||||
velocity: { x: 0, y: -0.1, z: 0 },
|
||||
damping: LINEAR_DAMPING,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
lifetime: STARTING_LIFETIME,
|
||||
color: colors[whichBird]
|
||||
}),
|
||||
|
@ -289,4 +289,4 @@ function loadBirds(howMany) {
|
|||
color: {red: 100, green: 100, blue: 100}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ var RainSquall = function (properties) {
|
|||
velocity: { x: 0, y: -dropFallSpeed, z: 0 },
|
||||
damping: 0,
|
||||
angularDamping: 0,
|
||||
ignoreForCollisions: true
|
||||
collisionless: true
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ for (var i = 0; i < NUM_MOONS; i++) {
|
|||
dimensions: { x: radius, y: radius, z: radius },
|
||||
color: color,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false
|
||||
dynamic: false
|
||||
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
modelURL: BAT_MODEL,
|
||||
position: dropPosition,
|
||||
compoundShapeURL: BAT_COLLISION_HULL,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
velocity: { x: 0, y: 0.05, z: 0}, // workaround for gravity not taking effect on add
|
||||
gravity: { x: 0, y: -9.81, z: 0},
|
||||
rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, -90.0),
|
||||
|
|
|
@ -107,7 +107,7 @@ var PITCHING_MACHINE_PROPERTIES = {
|
|||
y: 0.61,
|
||||
z: 0.39
|
||||
},
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
shapeType: "Box"
|
||||
};
|
||||
PITCHING_MACHINE_PROPERTIES.dimensions = Vec3.multiply(2.5, PITCHING_MACHINE_PROPERTIES.dimensions);
|
||||
|
@ -217,7 +217,7 @@ var BASEBALL_PROPERTIES = {
|
|||
y: BASEBALL_RADIUS,
|
||||
z: BASEBALL_RADIUS
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
angularVelocity: {
|
||||
x: 17.0,
|
||||
y: 0,
|
||||
|
|
|
@ -104,7 +104,7 @@ function generateFloor() {
|
|||
green: randFloat(70, 71),
|
||||
blue: randFloat(70, 80)
|
||||
},
|
||||
// collisionsWillMove: true
|
||||
// dynamic: true
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ function dropBlock() {
|
|||
shapeType: 'box',
|
||||
position: dropPos,
|
||||
dimensions: BLOCK_SIZE,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -9,
|
||||
|
@ -198,4 +198,4 @@ function map(value, min1, max1, min2, max2) {
|
|||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
|
|
|
@ -101,7 +101,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
|
|||
ignoreCollisions: false,
|
||||
damping: DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true }));
|
||||
dynamic: true }));
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
|
@ -121,4 +121,4 @@ function scriptEnding() {
|
|||
}
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -409,7 +409,7 @@ function createPuppet(model, location) {
|
|||
registrationPoint: { x: 0.5, y: 0, z: 0.5 },
|
||||
animation: ANIMATION_SETTINGS,
|
||||
position: location,
|
||||
ignoreForCollisions: true,
|
||||
collisionless: true,
|
||||
dimensions: DIMENSIONS,
|
||||
lifetime: TEMPORARY_LIFETIME
|
||||
});
|
||||
|
@ -595,4 +595,4 @@ breakdanceEnd= function() {
|
|||
Overlays.deleteOverlay(rightFrontOverlay);
|
||||
|
||||
Entities.deleteEntity(puppetEntityID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ Script.include("../libraries/utils.js");
|
|||
// add lines where the hand ray picking is happening
|
||||
//
|
||||
var WANT_DEBUG = false;
|
||||
var WANT_DEBUG_STATE = false;
|
||||
|
||||
//
|
||||
// these tune time-averaging and "on" value for analog trigger
|
||||
|
@ -32,6 +33,8 @@ var BUMPER_ON_VALUE = 0.5;
|
|||
|
||||
var HAND_HEAD_MIX_RATIO = 0.0; // 0 = only use hands for search/move. 1 = only use head for search/move.
|
||||
|
||||
var PICK_WITH_HAND_RAY = true;
|
||||
|
||||
//
|
||||
// distant manipulation
|
||||
//
|
||||
|
@ -39,7 +42,7 @@ var HAND_HEAD_MIX_RATIO = 0.0; // 0 = only use hands for search/move. 1 = only
|
|||
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
|
||||
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
|
||||
var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did
|
||||
var MOVE_WITH_HEAD = true; // experimental head-controll of distantly held objects
|
||||
var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects
|
||||
var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2;
|
||||
|
||||
var NO_INTERSECT_COLOR = {
|
||||
|
@ -92,7 +95,7 @@ var ZERO_VEC = {
|
|||
z: 0
|
||||
};
|
||||
|
||||
var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}";
|
||||
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
|
||||
var MSEC_PER_SEC = 1000.0;
|
||||
|
||||
// these control how long an abandoned pointer line or action will hang around
|
||||
|
@ -105,10 +108,13 @@ var GRABBABLE_PROPERTIES = [
|
|||
"position",
|
||||
"rotation",
|
||||
"gravity",
|
||||
"ignoreForCollisions",
|
||||
"collisionMask",
|
||||
"collisionsWillMove",
|
||||
"locked",
|
||||
"name"
|
||||
"name",
|
||||
"shapeType",
|
||||
"parentID",
|
||||
"parentJointIndex"
|
||||
];
|
||||
|
||||
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
|
||||
|
@ -116,10 +122,11 @@ var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
|
|||
|
||||
var DEFAULT_GRABBABLE_DATA = {
|
||||
grabbable: true,
|
||||
invertSolidWhileHeld: false
|
||||
disableReleaseVelocity: false
|
||||
};
|
||||
|
||||
|
||||
|
||||
// sometimes we want to exclude objects from being picked
|
||||
var USE_BLACKLIST = true;
|
||||
var blacklist = [];
|
||||
|
@ -156,7 +163,9 @@ var STATE_CONTINUE_EQUIP = 14;
|
|||
var STATE_WAITING_FOR_BUMPER_RELEASE = 15;
|
||||
var STATE_EQUIP_SPRING = 16;
|
||||
|
||||
|
||||
// collision masks are specified by comma-separated list of group names
|
||||
// the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar
|
||||
var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar";
|
||||
|
||||
function stateToName(state) {
|
||||
switch (state) {
|
||||
|
@ -276,8 +285,6 @@ function MyController(hand) {
|
|||
|
||||
var SPATIAL_CONTROLLERS_PER_PALM = 2;
|
||||
var TIP_CONTROLLER_OFFSET = 1;
|
||||
this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand;
|
||||
this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET;
|
||||
|
||||
this.actionID = null; // action this script created...
|
||||
this.grabbedEntity = null; // on this entity.
|
||||
|
@ -297,8 +304,10 @@ function MyController(hand) {
|
|||
this.searchSphere = null;
|
||||
|
||||
// how far from camera to search intersection?
|
||||
var DEFAULT_SEARCH_SPHERE_DISTANCE = 1000;
|
||||
this.intersectionDistance = 0.0;
|
||||
this.searchSphereDistance = 0.0;
|
||||
this.searchSphereDistance = DEFAULT_SEARCH_SPHERE_DISTANCE;
|
||||
|
||||
|
||||
this.ignoreIK = false;
|
||||
this.offsetPosition = Vec3.ZERO;
|
||||
|
@ -361,7 +370,7 @@ function MyController(hand) {
|
|||
};
|
||||
|
||||
this.setState = function(newState) {
|
||||
if (WANT_DEBUG) {
|
||||
if (WANT_DEBUG || WANT_DEBUG_STATE) {
|
||||
print("STATE: " + stateToName(this.state) + " --> " + stateToName(newState) + ", hand: " + this.hand);
|
||||
}
|
||||
this.state = newState;
|
||||
|
@ -451,7 +460,6 @@ function MyController(hand) {
|
|||
visible: true,
|
||||
alpha: 1
|
||||
};
|
||||
|
||||
this.overlayLine = Overlays.addOverlay("line3d", lineProperties);
|
||||
|
||||
} else {
|
||||
|
@ -694,10 +702,9 @@ function MyController(hand) {
|
|||
|
||||
this.searchSphereOff = function() {
|
||||
if (this.searchSphere !== null) {
|
||||
//Overlays.editOverlay(this.searchSphere, { visible: false });
|
||||
Overlays.deleteOverlay(this.searchSphere);
|
||||
this.searchSphere = null;
|
||||
this.searchSphereDistance = 0.0;
|
||||
this.searchSphereDistance = DEFAULT_SEARCH_SPHERE_DISTANCE;
|
||||
this.intersectionDistance = 0.0;
|
||||
}
|
||||
|
||||
|
@ -723,6 +730,10 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
this.propsArePhysical = function(props) {
|
||||
var isPhysical = (props.shapeType && props.shapeType != 'none');
|
||||
return isPhysical;
|
||||
}
|
||||
|
||||
this.turnOffVisualizations = function() {
|
||||
if (USE_ENTITY_LINES_FOR_SEARCHING === true || USE_ENTITY_LINES_FOR_MOVING === true) {
|
||||
|
@ -797,14 +808,14 @@ function MyController(hand) {
|
|||
|
||||
// the trigger is being pressed, so do a ray test to see what we are hitting
|
||||
var handPosition = this.getHandPosition();
|
||||
|
||||
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
|
||||
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
|
||||
|
||||
var distantPickRay = {
|
||||
origin: Camera.position,
|
||||
direction: Vec3.mix(Quat.getUp(this.getHandRotation()), Quat.getFront(Camera.orientation), HAND_HEAD_MIX_RATIO),
|
||||
origin: PICK_WITH_HAND_RAY ? handPosition : Camera.position,
|
||||
direction: PICK_WITH_HAND_RAY ? Quat.getUp(this.getHandRotation()) :
|
||||
Vec3.mix(Quat.getUp(this.getHandRotation()), Quat.getFront(Camera.orientation), HAND_HEAD_MIX_RATIO),
|
||||
length: PICK_MAX_DISTANCE
|
||||
};
|
||||
|
||||
|
@ -822,6 +833,9 @@ function MyController(hand) {
|
|||
this.lastPickTime = now;
|
||||
}
|
||||
|
||||
rayPickedCandidateEntities = []; // the list of candidates to consider grabbing
|
||||
|
||||
this.intersectionDistance = 0.0;
|
||||
for (var index = 0; index < pickRays.length; ++index) {
|
||||
var pickRay = pickRays[index];
|
||||
var directionNormalized = Vec3.normalize(pickRay.direction);
|
||||
|
@ -831,14 +845,6 @@ function MyController(hand) {
|
|||
direction: pickRay.direction
|
||||
};
|
||||
|
||||
if (WANT_DEBUG) {
|
||||
this.debugLine(pickRayBacked.origin, Vec3.multiply(pickRayBacked.direction, NEAR_PICK_MAX_DISTANCE), {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0
|
||||
})
|
||||
}
|
||||
|
||||
Messages.sendMessage('Hifi-Light-Overlay-Ray-Check', JSON.stringify(pickRayBacked));
|
||||
|
||||
var intersection;
|
||||
|
@ -847,191 +853,91 @@ function MyController(hand) {
|
|||
intersection = Entities.findRayIntersection(pickRayBacked, true, [], blacklist);
|
||||
} else {
|
||||
intersection = Entities.findRayIntersection(pickRayBacked, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (intersection.intersects) {
|
||||
|
||||
// the ray is intersecting something we can move.
|
||||
rayPickedCandidateEntities.push(intersection.entityID);
|
||||
this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
|
||||
|
||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA);
|
||||
var defaultDisableNearGrabData = {
|
||||
disableNearGrab: false
|
||||
};
|
||||
//sometimes we want things to stay right where they are when we let go.
|
||||
var disableNearGrabData = getEntityCustomData('handControllerKey', intersection.entityID, defaultDisableNearGrabData);
|
||||
|
||||
if (intersection.properties.name == "Grab Debug Entity") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof grabbableData.grabbable !== 'undefined' && !grabbableData.grabbable) {
|
||||
continue;
|
||||
}
|
||||
if (this.intersectionDistance > pickRay.length) {
|
||||
// too far away for this ray.
|
||||
continue;
|
||||
}
|
||||
if (this.intersectionDistance <= NEAR_PICK_MAX_DISTANCE) {
|
||||
// the hand is very close to the intersected object. go into close-grabbing mode.
|
||||
if (grabbableData.wantsTrigger) {
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
this.setState(STATE_NEAR_TRIGGER);
|
||||
return;
|
||||
} else if (!intersection.properties.locked) {
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
if (this.state == STATE_SEARCHING) {
|
||||
if (disableNearGrabData.disableNearGrab !== true) {
|
||||
this.setState(STATE_NEAR_GRABBING);
|
||||
} else {
|
||||
//disable near grab on this thing
|
||||
}
|
||||
} else { // equipping
|
||||
if (typeof grabbableData.spatialKey !== 'undefined') {
|
||||
// TODO
|
||||
// if we go to STATE_EQUIP_SPRING the item will be pulled to the hand and will then switch
|
||||
// to STATE_EQUIP. This needs some debugging, so just jump straight to STATE_EQUIP here.
|
||||
// this.setState(STATE_EQUIP_SPRING);
|
||||
this.setState(STATE_EQUIP);
|
||||
} else {
|
||||
this.setState(STATE_EQUIP);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (!entityIsGrabbedByOther(intersection.entityID)) {
|
||||
// don't allow two people to distance grab the same object
|
||||
if (intersection.properties.collisionsWillMove && !intersection.properties.locked) {
|
||||
// the hand is far from the intersected object. go into distance-holding mode
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
if (this.state == STATE_EQUIP_SEARCHING) {
|
||||
// if a distance pick in equip mode hits something with a spatialKey, equip it
|
||||
// TODO use STATE_EQUIP_SPRING here once it works right.
|
||||
// this.setState(STATE_EQUIP_SPRING);
|
||||
if (typeof grabbableData.spatialKey === 'undefined') {
|
||||
// We want to give a temporary position offset to this object so it is pulled close to hand
|
||||
var intersectionPointToCenterDistance = Vec3.length(Vec3.subtract(intersection.intersection, intersection.properties.position));
|
||||
this.temporaryPositionOffset = Vec3.normalize(Vec3.subtract(intersection.properties.position, handPosition));
|
||||
this.temporaryPositionOffset = Vec3.multiply(this.temporaryPositionOffset, intersectionPointToCenterDistance * FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
||||
|
||||
}
|
||||
this.setState(STATE_EQUIP);
|
||||
this.turnOffVisualizations();
|
||||
return;
|
||||
} else if ((this.state == STATE_SEARCHING) && this.triggerSmoothedGrab()) {
|
||||
this.setState(STATE_DISTANCE_HOLDING);
|
||||
return;
|
||||
}
|
||||
} else if (grabbableData.wantsTrigger && this.triggerSmoothedGrab()) {
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
this.setState(STATE_FAR_TRIGGER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nearPickedCandidateEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
||||
candidateEntities = rayPickedCandidateEntities.concat(nearPickedCandidateEntities);
|
||||
|
||||
// forward ray test failed, try sphere test.
|
||||
if (WANT_DEBUG) {
|
||||
Entities.addEntity({
|
||||
type: "Sphere",
|
||||
name: "Grab Debug Entity",
|
||||
dimensions: {
|
||||
x: GRAB_RADIUS,
|
||||
y: GRAB_RADIUS,
|
||||
z: GRAB_RADIUS
|
||||
},
|
||||
visible: true,
|
||||
position: handPosition,
|
||||
color: {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0
|
||||
},
|
||||
lifetime: 0.1,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
var forbiddenNames = ["Grab Debug Entity", "grab pointer"];
|
||||
var forbiddenTyes = ['Unknown', 'Light', 'ParticleEffect', 'PolyLine', 'Zone'];
|
||||
|
||||
var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
||||
var minDistance = PICK_MAX_DISTANCE;
|
||||
var i, props, distance, grabbableData;
|
||||
this.grabbedEntity = null;
|
||||
for (i = 0; i < nearbyEntities.length; i++) {
|
||||
for (i = 0; i < candidateEntities.length; i++) {
|
||||
var grabbableDataForCandidate =
|
||||
getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA);
|
||||
if (typeof grabbableDataForCandidate.grabbable !== 'undefined' && !grabbableDataForCandidate.grabbable) {
|
||||
getEntityCustomData(GRABBABLE_DATA_KEY, candidateEntities[i], DEFAULT_GRABBABLE_DATA);
|
||||
var propsForCandidate = Entities.getEntityProperties(candidateEntities[i], GRABBABLE_PROPERTIES);
|
||||
var grabbable = (typeof grabbableDataForCandidate.grabbable === 'undefined' || grabbableDataForCandidate.grabbable);
|
||||
if (!grabbable && !grabbableDataForCandidate.wantsTrigger) {
|
||||
continue;
|
||||
}
|
||||
var propsForCandidate = Entities.getEntityProperties(nearbyEntities[i], GRABBABLE_PROPERTIES);
|
||||
|
||||
if (propsForCandidate.type == 'Unknown') {
|
||||
if (forbiddenTyes.indexOf(propsForCandidate.type) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.type == 'Light') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.type == 'ParticleEffect') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.type == 'PolyLine') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.type == 'Zone') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.locked && !grabbableDataForCandidate.wantsTrigger) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.name == "Grab Debug Entity") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (propsForCandidate.name == "grab pointer") {
|
||||
if (forbiddenNames.indexOf(propsForCandidate.name) >= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
distance = Vec3.distance(propsForCandidate.position, handPosition);
|
||||
if (distance > PICK_MAX_DISTANCE) {
|
||||
// too far away, don't grab
|
||||
continue;
|
||||
}
|
||||
if (distance < minDistance) {
|
||||
this.grabbedEntity = nearbyEntities[i];
|
||||
this.grabbedEntity = candidateEntities[i];
|
||||
minDistance = distance;
|
||||
props = propsForCandidate;
|
||||
grabbableData = grabbableDataForCandidate;
|
||||
}
|
||||
}
|
||||
if (this.grabbedEntity !== null) {
|
||||
if ((this.grabbedEntity !== null) && (this.triggerSmoothedGrab() || this.bumperSqueezed())) {
|
||||
// We are squeezing enough to grab, and we've found an entity that we'll try to do something with.
|
||||
var near = (nearPickedCandidateEntities.indexOf(this.grabbedEntity) >= 0);
|
||||
var isPhysical = this.propsArePhysical(props);
|
||||
|
||||
// near or far trigger
|
||||
if (grabbableData.wantsTrigger) {
|
||||
this.setState(STATE_NEAR_TRIGGER);
|
||||
return;
|
||||
} else if (!props.locked && props.collisionsWillMove) {
|
||||
var defaultDisableNearGrabData = {
|
||||
disableNearGrab: false
|
||||
};
|
||||
//sometimes we want things to stay right where they are when we let go.
|
||||
var disableNearGrabData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultDisableNearGrabData);
|
||||
if (disableNearGrabData.disableNearGrab === true) {
|
||||
//do nothing because near grab is disabled for this object
|
||||
} else {
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
|
||||
|
||||
}
|
||||
|
||||
this.setState(near ? STATE_NEAR_TRIGGER : STATE_FAR_TRIGGER);
|
||||
return;
|
||||
}
|
||||
// near grab or equip with action
|
||||
if (isPhysical && near) {
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP);
|
||||
return;
|
||||
}
|
||||
// far grab or equip with action
|
||||
if (isPhysical && !near) {
|
||||
if (entityIsGrabbedByOther(intersection.entityID)) {
|
||||
// don't distance grab something that is already grabbed.
|
||||
return;
|
||||
}
|
||||
this.temporaryPositionOffset = null;
|
||||
if (typeof grabbableData.spatialKey === 'undefined') {
|
||||
// We want to give a temporary position offset to this object so it is pulled close to hand
|
||||
var intersectionPointToCenterDistance = Vec3.length(Vec3.subtract(intersection.intersection,
|
||||
intersection.properties.position));
|
||||
this.temporaryPositionOffset = Vec3.normalize(Vec3.subtract(intersection.properties.position, handPosition));
|
||||
this.temporaryPositionOffset = Vec3.multiply(this.temporaryPositionOffset,
|
||||
intersectionPointToCenterDistance *
|
||||
FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
||||
}
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_DISTANCE_HOLDING : STATE_EQUIP);
|
||||
return;
|
||||
}
|
||||
|
||||
// else this thing isn't physical. grab it by reparenting it.
|
||||
this.setState(STATE_NEAR_GRABBING);
|
||||
return;
|
||||
}
|
||||
|
||||
//search line visualizations
|
||||
|
@ -1043,21 +949,18 @@ function MyController(hand) {
|
|||
this.handleParticleBeam(distantPickRay.origin, this.getHandRotation(), NO_INTERSECT_COLOR);
|
||||
}
|
||||
|
||||
if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
||||
this.overlayLineOn(searchVisualizationPickRay.origin, Vec3.sum(searchVisualizationPickRay.origin, Vec3.multiply(searchVisualizationPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR);
|
||||
}
|
||||
var SEARCH_SPHERE_SIZE = 0.011;
|
||||
var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
|
||||
|
||||
if (this.intersectionDistance > 0) {
|
||||
var SPHERE_INTERSECTION_SIZE = 0.011;
|
||||
var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
|
||||
var SEARCH_SPHERE_CHASE_DROP = 0.2;
|
||||
// If we hit something with our pick ray, move the search sphere toward that distance
|
||||
this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE);
|
||||
var searchSphereLocation = Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
|
||||
searchSphereLocation.y -= ((this.intersectionDistance - this.searchSphereDistance) / this.intersectionDistance) * SEARCH_SPHERE_CHASE_DROP;
|
||||
this.searchSphereOn(searchSphereLocation, SPHERE_INTERSECTION_SIZE * this.intersectionDistance, this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||
if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
||||
this.overlayLineOn(handPosition, searchSphereLocation, this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
var searchSphereLocation = Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
|
||||
this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||
if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) {
|
||||
this.overlayLineOn(handPosition, searchSphereLocation, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1082,7 +985,7 @@ function MyController(hand) {
|
|||
this.radiusScalar = 1.0;
|
||||
}
|
||||
|
||||
this.actionID = NULL_ACTION_ID;
|
||||
this.actionID = NULL_UUID;
|
||||
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
||||
targetPosition: this.currentObjectPosition,
|
||||
linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||
|
@ -1091,7 +994,7 @@ function MyController(hand) {
|
|||
tag: getTag(),
|
||||
ttl: ACTION_TTL
|
||||
});
|
||||
if (this.actionID === NULL_ACTION_ID) {
|
||||
if (this.actionID === NULL_UUID) {
|
||||
this.actionID = null;
|
||||
}
|
||||
this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC);
|
||||
|
@ -1244,7 +1147,6 @@ function MyController(hand) {
|
|||
y: this.currentObjectPosition.y,
|
||||
z: this.currentObjectPosition.z
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1280,7 +1182,6 @@ function MyController(hand) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
this.setupHoldAction = function() {
|
||||
this.actionID = Entities.addAction("hold", this.grabbedEntity, {
|
||||
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
||||
|
@ -1292,7 +1193,7 @@ function MyController(hand) {
|
|||
kinematicSetVelocity: true,
|
||||
ignoreIK: this.ignoreIK
|
||||
});
|
||||
if (this.actionID === NULL_ACTION_ID) {
|
||||
if (this.actionID === NULL_UUID) {
|
||||
this.actionID = null;
|
||||
return false;
|
||||
}
|
||||
|
@ -1327,7 +1228,6 @@ function MyController(hand) {
|
|||
var projection = Vec3.sum(axisStart, Vec3.multiply(scalar, Vec3.normalize(bPrime)));
|
||||
|
||||
return projection
|
||||
|
||||
};
|
||||
|
||||
this.nearGrabbing = function() {
|
||||
|
@ -1375,9 +1275,19 @@ function MyController(hand) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!this.setupHoldAction()) {
|
||||
return;
|
||||
var isPhysical = this.propsArePhysical(grabbedProperties);
|
||||
if (isPhysical) {
|
||||
// grab entity via action
|
||||
if (!this.setupHoldAction()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// grab entity via parenting
|
||||
var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
Entities.editEntity(this.grabbedEntity, {
|
||||
parentID: MyAvatar.sessionUUID,
|
||||
parentJointIndex: handJointIndex
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state == STATE_NEAR_GRABBING) {
|
||||
|
@ -1385,8 +1295,6 @@ function MyController(hand) {
|
|||
} else {
|
||||
// equipping
|
||||
Entities.callEntityMethod(this.grabbedEntity, "startEquip", [JSON.stringify(this.hand)]);
|
||||
this.startHandGrasp();
|
||||
|
||||
this.setState(STATE_CONTINUE_EQUIP_BD);
|
||||
}
|
||||
|
||||
|
@ -1446,7 +1354,13 @@ function MyController(hand) {
|
|||
Entities.callEntityMethod(this.grabbedEntity, "continueEquip");
|
||||
}
|
||||
|
||||
if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
|
||||
//// jbp::: SEND UPDATE MESSAGE TO WEARABLES MANAGER
|
||||
Messages.sendMessage('Hifi-Wearables-Manager', JSON.stringify({
|
||||
action: 'update',
|
||||
grabbedEntity: this.grabbedEntity
|
||||
}))
|
||||
|
||||
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
|
||||
// if less than a 5 seconds left, refresh the actions ttl
|
||||
var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
|
||||
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
||||
|
@ -1473,7 +1387,6 @@ function MyController(hand) {
|
|||
this.setState(STATE_RELEASE);
|
||||
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
|
||||
Entities.callEntityMethod(this.grabbedEntity, "unequip");
|
||||
this.endHandGrasp();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1496,7 +1409,7 @@ function MyController(hand) {
|
|||
|
||||
if (typeof this.equipSpringID === 'undefined' ||
|
||||
this.equipSpringID === null ||
|
||||
this.equipSpringID === NULL_ACTION_ID) {
|
||||
this.equipSpringID === NULL_UUID) {
|
||||
this.equipSpringID = Entities.addAction("spring", this.grabbedEntity, {
|
||||
targetPosition: targetPosition,
|
||||
linearTimeScale: EQUIP_SPRING_TIMEFRAME,
|
||||
|
@ -1505,7 +1418,7 @@ function MyController(hand) {
|
|||
ttl: ACTION_TTL,
|
||||
ignoreIK: ignoreIK
|
||||
});
|
||||
if (this.equipSpringID === NULL_ACTION_ID) {
|
||||
if (this.equipSpringID === NULL_UUID) {
|
||||
this.equipSpringID = null;
|
||||
this.setState(STATE_OFF);
|
||||
return;
|
||||
|
@ -1579,7 +1492,7 @@ function MyController(hand) {
|
|||
this.continueFarTrigger = function() {
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
this.setState(STATE_RELEASE);
|
||||
Entities.callEntityMethod(this.grabbedEntity, "stopNearTrigger");
|
||||
Entities.callEntityMethod(this.grabbedEntity, "stopFarTrigger");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1682,12 +1595,10 @@ function MyController(hand) {
|
|||
|
||||
if (this.grabbedEntity !== null) {
|
||||
if (this.actionID !== null) {
|
||||
//add velocity whatnot
|
||||
var defaultReleaseVelocityData = {
|
||||
disableReleaseVelocity: false
|
||||
};
|
||||
//sometimes we want things to stay right where they are when we let go.
|
||||
var releaseVelocityData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultReleaseVelocityData);
|
||||
var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY,
|
||||
this.grabbedEntity,
|
||||
DEFAULT_GRABBABLE_DATA);
|
||||
if (releaseVelocityData.disableReleaseVelocity === true) {
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
|
||||
|
@ -1708,21 +1619,27 @@ function MyController(hand) {
|
|||
} else {
|
||||
//don't make adjustments
|
||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.deactivateEntity(this.grabbedEntity);
|
||||
|
||||
this.grabbedEntity = null;
|
||||
this.actionID = null;
|
||||
this.setState(STATE_OFF);
|
||||
|
||||
//// jbp::: SEND RELEASE MESSAGE TO WEARABLES MANAGER
|
||||
|
||||
Messages.sendMessage('Hifi-Wearables-Manager', JSON.stringify({
|
||||
action: 'checkIfWearable',
|
||||
grabbedEntity: this.grabbedEntity
|
||||
}))
|
||||
|
||||
this.grabbedEntity = null;
|
||||
};
|
||||
|
||||
this.cleanup = function() {
|
||||
this.release();
|
||||
this.endHandGrasp();
|
||||
Entities.deleteEntity(this.particleBeam);
|
||||
Entities.deleteEntity(this.spotLight);
|
||||
Entities.deleteEntity(this.pointLight);
|
||||
|
@ -1730,7 +1647,6 @@ function MyController(hand) {
|
|||
|
||||
this.activateEntity = function(entityID, grabbedProperties) {
|
||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, entityID, DEFAULT_GRABBABLE_DATA);
|
||||
var invertSolidWhileHeld = grabbableData["invertSolidWhileHeld"];
|
||||
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
|
||||
data["activated"] = true;
|
||||
data["avatarId"] = MyAvatar.sessionUUID;
|
||||
|
@ -1738,18 +1654,18 @@ function MyController(hand) {
|
|||
// zero gravity and set ignoreForCollisions in a way that lets us put them back, after all grabs are done
|
||||
if (data["refCount"] == 1) {
|
||||
data["gravity"] = grabbedProperties.gravity;
|
||||
data["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions;
|
||||
data["collisionMask"] = grabbedProperties.collisionMask;
|
||||
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
||||
data["parentID"] = grabbedProperties.parentID;
|
||||
data["parentJointIndex"] = grabbedProperties.parentJointIndex;
|
||||
var whileHeldProperties = {
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
},
|
||||
"collisionMask": COLLISION_MASK_WHILE_GRABBED
|
||||
};
|
||||
if (invertSolidWhileHeld) {
|
||||
whileHeldProperties["ignoreForCollisions"] = !grabbedProperties.ignoreForCollisions;
|
||||
}
|
||||
Entities.editEntity(entityID, whileHeldProperties);
|
||||
}
|
||||
|
||||
|
@ -1764,8 +1680,11 @@ function MyController(hand) {
|
|||
if (data["refCount"] < 1) {
|
||||
Entities.editEntity(entityID, {
|
||||
gravity: data["gravity"],
|
||||
collisionMask: data["collisionMask"],
|
||||
collisionsWillMove: data["collisionsWillMove"],
|
||||
ignoreForCollisions: data["ignoreForCollisions"],
|
||||
collisionsWillMove: data["collisionsWillMove"]
|
||||
parentID: data["parentID"],
|
||||
parentJointIndex: data["parentJointIndex"]
|
||||
});
|
||||
data = null;
|
||||
}
|
||||
|
@ -1774,45 +1693,6 @@ function MyController(hand) {
|
|||
}
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
|
||||
};
|
||||
|
||||
|
||||
//this is our handler, where we do the actual work of changing animation settings
|
||||
this.graspHand = function(animationProperties) {
|
||||
var result = {};
|
||||
//full alpha on overlay for this hand
|
||||
//set grab to true
|
||||
//set idle to false
|
||||
//full alpha on the blend btw open and grab
|
||||
if (_this.hand === RIGHT_HAND) {
|
||||
result['rightHandOverlayAlpha'] = 1.0;
|
||||
result['isRightHandGrab'] = true;
|
||||
result['isRightHandIdle'] = false;
|
||||
result['rightHandGrabBlend'] = 1.0;
|
||||
} else if (_this.hand === LEFT_HAND) {
|
||||
result['leftHandOverlayAlpha'] = 1.0;
|
||||
result['isLeftHandGrab'] = true;
|
||||
result['isLeftHandIdle'] = false;
|
||||
result['leftHandGrabBlend'] = 1.0;
|
||||
}
|
||||
//return an object with our updated settings
|
||||
return result;
|
||||
};
|
||||
|
||||
this.graspHandler = null
|
||||
|
||||
this.startHandGrasp = function() {
|
||||
if (this.hand === RIGHT_HAND) {
|
||||
this.graspHandler = MyAvatar.addAnimationStateHandler(this.graspHand, ['isRightHandGrab']);
|
||||
} else if (this.hand === LEFT_HAND) {
|
||||
this.graspHandler = MyAvatar.addAnimationStateHandler(this.graspHand, ['isLeftHandGrab']);
|
||||
}
|
||||
};
|
||||
|
||||
this.endHandGrasp = function() {
|
||||
// Tell the animation system we don't need any more callbacks.
|
||||
MyAvatar.removeAnimationStateHandler(this.graspHandler);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
var rightController = new MyController(RIGHT_HAND);
|
||||
|
@ -1927,4 +1807,4 @@ function renewParticleBeamLifetimes(deltaTime) {
|
|||
}
|
||||
rightController.renewParticleBeamLifetime();
|
||||
leftController.renewParticleBeamLifetime();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ function shootBullet(position, velocity, grenade) {
|
|||
damping: 0.01,
|
||||
density: 8000,
|
||||
ignoreCollisions: false,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
|
||||
Script.addEventHandler(bulletID, "collisionWithEntity", entityCollisionWithEntity);
|
||||
|
@ -294,7 +294,7 @@ function shootTarget() {
|
|||
rotation: Camera.getOrientation(),
|
||||
damping: 0.1,
|
||||
density: 100.0,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
|
||||
// Record start time
|
||||
|
@ -349,7 +349,7 @@ function makeGrid(type, scale, size) {
|
|||
rotation: Camera.getOrientation(),
|
||||
damping: 0.1,
|
||||
density: 100.0,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ function makePlatform(gravity, scale, size) {
|
|||
lifetime: TARGET_LIFE,
|
||||
damping: 0.1,
|
||||
density: 100.0,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ function createEntities() {
|
|||
gravity: { x: 0, y: GRAVITY, z: 0 },
|
||||
ignoreCollisions: false,
|
||||
damping: 0.50,
|
||||
collisionsWillMove: true });
|
||||
dynamic: true });
|
||||
|
||||
paddle = Entities.addEntity(
|
||||
{ type: "Box",
|
||||
|
@ -71,7 +71,7 @@ function createEntities() {
|
|||
damping: 0.10,
|
||||
visible: false,
|
||||
rotation : leftHanded ? MyAvatar.leftHandPose.rotation : MyAvatar.rightHandPose.rotation,
|
||||
collisionsWillMove: false });
|
||||
dynamic: false });
|
||||
|
||||
modelURL = "http://public.highfidelity.io/models/attachments/pong_paddle.fbx";
|
||||
paddleModel = Entities.addEntity(
|
||||
|
@ -84,7 +84,7 @@ function createEntities() {
|
|||
modelURL: modelURL,
|
||||
damping: 0.10,
|
||||
rotation : leftHanded ? MyAvatar.leftHandPose.rotation : MyAvatar.rightHandPose.rotation,
|
||||
collisionsWillMove: false });
|
||||
dynamic: false });
|
||||
|
||||
line = Overlays.addOverlay("line3d", {
|
||||
start: { x: 0, y: 0, z: 0 },
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
//
|
||||
// squeezeHands.js
|
||||
// examples
|
||||
//
|
||||
// Created by Philip Rosedale on June 4, 2014
|
||||
// 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
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
var rightHandAnimation = HIFI_PUBLIC_BUCKET + "animations/RightHandAnimPhilip.fbx";
|
||||
var leftHandAnimation = HIFI_PUBLIC_BUCKET + "animations/LeftHandAnimPhilip.fbx";
|
||||
|
||||
var LEFT = 0;
|
||||
var RIGHT = 1;
|
||||
|
||||
var lastLeftFrame = 0;
|
||||
var lastRightFrame = 0;
|
||||
|
||||
var leftDirection = true;
|
||||
var rightDirection = true;
|
||||
|
||||
var LAST_FRAME = 15.0; // What is the number of the last frame we want to use in the animation?
|
||||
var SMOOTH_FACTOR = 0.0;
|
||||
var MAX_FRAMES = 30.0;
|
||||
|
||||
Script.update.connect(function(deltaTime) {
|
||||
var leftTriggerValue = Controller.getTriggerValue(LEFT);
|
||||
var rightTriggerValue = Controller.getTriggerValue(RIGHT);
|
||||
|
||||
var leftFrame, rightFrame;
|
||||
|
||||
// Average last few trigger frames together for a bit of smoothing
|
||||
leftFrame = (leftTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastLeftFrame * SMOOTH_FACTOR;
|
||||
rightFrame = (rightTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastRightFrame * SMOOTH_FACTOR;
|
||||
|
||||
if (!leftDirection) {
|
||||
leftFrame = MAX_FRAMES - leftFrame;
|
||||
}
|
||||
if (!rightDirection) {
|
||||
rightFrame = MAX_FRAMES - rightFrame;
|
||||
}
|
||||
|
||||
if ((leftTriggerValue == 1.0) && (leftDirection == true)) {
|
||||
leftDirection = false;
|
||||
lastLeftFrame = MAX_FRAMES - leftFrame;
|
||||
} else if ((leftTriggerValue == 0.0) && (leftDirection == false)) {
|
||||
leftDirection = true;
|
||||
lastLeftFrame = leftFrame;
|
||||
}
|
||||
if ((rightTriggerValue == 1.0) && (rightDirection == true)) {
|
||||
rightDirection = false;
|
||||
lastRightFrame = MAX_FRAMES - rightFrame;
|
||||
} else if ((rightTriggerValue == 0.0) && (rightDirection == false)) {
|
||||
rightDirection = true;
|
||||
lastRightFrame = rightFrame;
|
||||
}
|
||||
|
||||
if ((leftFrame != lastLeftFrame) && leftHandAnimation.length){
|
||||
MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, leftFrame, leftFrame);
|
||||
}
|
||||
if ((rightFrame != lastRightFrame) && rightHandAnimation.length) {
|
||||
MyAvatar.startAnimation(rightHandAnimation, 30.0, 1.0, false, true, rightFrame, rightFrame);
|
||||
}
|
||||
|
||||
lastLeftFrame = leftFrame;
|
||||
lastRightFrame = rightFrame;
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
MyAvatar.stopAnimation(leftHandAnimation);
|
||||
MyAvatar.stopAnimation(rightHandAnimation);
|
||||
});
|
|
@ -154,7 +154,7 @@ function checkControllerSide(whichSide) {
|
|||
dimensions: { x: BALL_RADIUS * 2, y: BALL_RADIUS * 2, z: BALL_RADIUS * 2 },
|
||||
damping: 0.00001,
|
||||
shapeType: "sphere",
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
color: HELD_COLOR,
|
||||
lifetime: LIFETIME_SECONDS
|
||||
};
|
||||
|
@ -200,7 +200,7 @@ function checkControllerSide(whichSide) {
|
|||
velocity: linearVelocity,
|
||||
rotation: palmRotation,
|
||||
angularVelocity: angularVelocity,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
color: THROWN_COLOR,
|
||||
gravity: { x: 0, y: -GRAVITY_STRENGTH, z: 0},
|
||||
};
|
||||
|
|
|
@ -1,86 +1,80 @@
|
|||
//
|
||||
// squeezeHands.js
|
||||
// examples
|
||||
// controllers/squeezeHands.js
|
||||
//
|
||||
// Created by Philip Rosedale on June 4, 2014
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
// Created by Anthony J. Thibault
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Default script to drive the animation of the hands based on hand controllers.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var HIFI_OZAN_BUCKET = "http://hifi-public.s3.amazonaws.com/ozan/";
|
||||
|
||||
var rightHandAnimation = HIFI_OZAN_BUCKET + "anim/squeeze_hands/right_hand_anim.fbx";
|
||||
var leftHandAnimation = HIFI_OZAN_BUCKET + "anim/squeeze_hands/left_hand_anim.fbx";
|
||||
|
||||
var lastLeftTrigger = 0;
|
||||
var lastRightTrigger = 0;
|
||||
|
||||
var leftIsClosing = true;
|
||||
var rightIsClosing = true;
|
||||
|
||||
var LAST_FRAME = 15.0; // What is the number of the last frame we want to use in the animation?
|
||||
var SMOOTH_FACTOR = 0.75;
|
||||
var MAX_FRAMES = 30.0;
|
||||
|
||||
var leftHandOverlayAlpha = 0;
|
||||
var rightHandOverlayAlpha = 0;
|
||||
|
||||
var CONTROLLER_DEAD_SPOT = 0.25;
|
||||
var TRIGGER_SMOOTH_TIMESCALE = 0.1;
|
||||
var OVERLAY_RAMP_RATE = 8.0;
|
||||
|
||||
function clamp(val, min, max) {
|
||||
if (val < min) {
|
||||
return min;
|
||||
} else if (val > max) {
|
||||
return max;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
return Math.min(Math.max(val, min), max);
|
||||
}
|
||||
|
||||
function normalizeControllerValue(val) {
|
||||
return clamp((val - CONTROLLER_DEAD_SPOT) / (1.0 - CONTROLLER_DEAD_SPOT), 0.0, 1.0);
|
||||
return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1);
|
||||
}
|
||||
|
||||
Script.update.connect(function(deltaTime) {
|
||||
function lerp(a, b, alpha) {
|
||||
return a * (1 - alpha) + b * alpha;
|
||||
}
|
||||
|
||||
function init() {
|
||||
Script.update.connect(update);
|
||||
MyAvatar.addAnimationStateHandler(animStateHandler, ["leftHandOverlayAlpha", "rightHandOverlayAlpha",
|
||||
"leftHandGraspAlpha", "rightHandGraspAlpha"]);
|
||||
}
|
||||
|
||||
function animStateHandler(props) {
|
||||
return { leftHandOverlayAlpha: leftHandOverlayAlpha,
|
||||
leftHandGraspAlpha: lastLeftTrigger,
|
||||
rightHandOverlayAlpha: rightHandOverlayAlpha,
|
||||
rightHandGraspAlpha: lastRightTrigger };
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
var leftTrigger = normalizeControllerValue(Controller.getValue(Controller.Standard.LT));
|
||||
var rightTrigger = normalizeControllerValue(Controller.getValue(Controller.Standard.RT));
|
||||
|
||||
// Average last few trigger values together for a bit of smoothing
|
||||
var smoothLeftTrigger = leftTrigger * (1.0 - SMOOTH_FACTOR) + lastLeftTrigger * SMOOTH_FACTOR;
|
||||
var smoothRightTrigger = rightTrigger * (1.0 - SMOOTH_FACTOR) + lastRightTrigger * SMOOTH_FACTOR;
|
||||
var tau = clamp(dt / TRIGGER_SMOOTH_TIMESCALE, 0, 1);
|
||||
lastLeftTrigger = lerp(leftTrigger, lastLeftTrigger, tau);
|
||||
lastRightTrigger = lerp(rightTrigger, lastRightTrigger, tau);
|
||||
|
||||
if (leftTrigger == 0.0) {
|
||||
leftIsClosing = true;
|
||||
} else if (leftTrigger == 1.0) {
|
||||
leftIsClosing = false;
|
||||
// ramp on/off left hand overlay
|
||||
var leftHandPose = Controller.getPoseValue(Controller.Standard.LeftHand);
|
||||
if (leftHandPose.valid) {
|
||||
leftHandOverlayAlpha = clamp(leftHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1);
|
||||
} else {
|
||||
leftHandOverlayAlpha = clamp(leftHandOverlayAlpha - OVERLAY_RAMP_RATE * dt, 0, 1);
|
||||
}
|
||||
|
||||
if (rightTrigger == 0.0) {
|
||||
rightIsClosing = true;
|
||||
} else if (rightTrigger == 1.0) {
|
||||
rightIsClosing = false;
|
||||
// ramp on/off right hand overlay
|
||||
var rightHandPose = Controller.getPoseValue(Controller.Standard.RightHand);
|
||||
if (rightHandPose.valid) {
|
||||
rightHandOverlayAlpha = clamp(rightHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1);
|
||||
} else {
|
||||
rightHandOverlayAlpha = clamp(rightHandOverlayAlpha - OVERLAY_RAMP_RATE * dt, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
lastLeftTrigger = smoothLeftTrigger;
|
||||
lastRightTrigger = smoothRightTrigger;
|
||||
function shutdown() {
|
||||
Script.update.disconnect(update);
|
||||
MyAvatar.removeAnimationStateHandler(animStateHandler);
|
||||
}
|
||||
|
||||
// 0..15
|
||||
var leftFrame = smoothLeftTrigger * LAST_FRAME;
|
||||
var rightFrame = smoothRightTrigger * LAST_FRAME;
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
||||
var adjustedLeftFrame = (leftIsClosing) ? leftFrame : (MAX_FRAMES - leftFrame);
|
||||
if (leftHandAnimation.length) {
|
||||
MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, adjustedLeftFrame, adjustedLeftFrame);
|
||||
}
|
||||
|
||||
var adjustedRightFrame = (rightIsClosing) ? rightFrame : (MAX_FRAMES - rightFrame);
|
||||
if (rightHandAnimation.length) {
|
||||
MyAvatar.startAnimation(rightHandAnimation, 30.0, 1.0, false, true, adjustedRightFrame, adjustedRightFrame);
|
||||
}
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
MyAvatar.stopAnimation(leftHandAnimation);
|
||||
MyAvatar.stopAnimation(rightHandAnimation);
|
||||
});
|
||||
init();
|
||||
|
|
|
@ -175,7 +175,7 @@ function createTable() {
|
|||
damping: 0.1,
|
||||
restitution: 0.01,
|
||||
density: 0.5,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
color: { red: randInt(0, 255), green: randInt(0, 255), blue: randInt(0, 255) },
|
||||
});
|
||||
if (type == "Model") {
|
||||
|
@ -196,4 +196,4 @@ function removeTable() {
|
|||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanUp);
|
||||
Controller.mousePressEvent.connect(onClick);
|
||||
Controller.mousePressEvent.connect(onClick);
|
||||
|
|
|
@ -42,7 +42,7 @@ for (var x = 0; x < SIDE_SIZE; x++) {
|
|||
dimensions: { x: radius, y: radius, z: radius },
|
||||
color: color,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
lifetime: LIFETIME
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ function createEarth() {
|
|||
z: EARTH_SPHERE_RADIUS
|
||||
},
|
||||
rotation: Quat.fromPitchYawRollDegrees(0, 90, 0),
|
||||
// collisionsWillMove: true,
|
||||
// dynamic: true,
|
||||
//if you have a shapetype it blocks the smaller markers
|
||||
// shapeType:'sphere'
|
||||
// userData: JSON.stringify({
|
||||
|
@ -122,7 +122,7 @@ function createQuakeMarker(earthquake) {
|
|||
parentID:earth,
|
||||
dimensions: QUAKE_MARKER_DIMENSIONS,
|
||||
position: getQuakePosition(earthquake),
|
||||
ignoreForCollisions:true,
|
||||
collisionless:true,
|
||||
lifetime: 6000,
|
||||
color: getQuakeMarkerColor(earthquake)
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ Script.setInterval(function() {
|
|||
var grabData = userData["grabKey"]
|
||||
|
||||
// {"grabbableKey":{"invertSolidWhileHeld":true},
|
||||
// "grabKey":{"activated":true,"avatarId":"{6ea8b092-10e0-4058-888b-6facc40d0fe9}","refCount":1,"gravity":{"x":0,"y":0,"z":0},"ignoreForCollisions":0,"collisionsWillMove":1}
|
||||
// "grabKey":{"activated":true,"avatarId":"{6ea8b092-10e0-4058-888b-6facc40d0fe9}","refCount":1,"gravity":{"x":0,"y":0,"z":0},"collisionless":0,"dynamic":1}
|
||||
// }
|
||||
|
||||
if (typeof grabData != 'undefined') {
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
Script.load("away.js");
|
||||
Script.load("progress.js");
|
||||
Script.load("edit.js");
|
||||
Script.load("marketplace.js");
|
||||
Script.load("selectAudioDevice.js");
|
||||
Script.load("inspect.js");
|
||||
Script.load("notifications.js");
|
||||
Script.load("users.js");
|
||||
Script.load("controllers/handControllerGrab.js");
|
||||
Script.load("controllers/squeezeHands.js");
|
||||
Script.load("grab.js");
|
||||
Script.load("directory.js");
|
||||
Script.load("dialTone.js");
|
||||
|
|
|
@ -33,11 +33,11 @@ var BUTTON_SIZE = 32;
|
|||
var PADDING = 3;
|
||||
|
||||
Script.include(["libraries/toolBars.js"]);
|
||||
var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.dice.toolbar", function (screenSize) {
|
||||
return {
|
||||
x: (screenSize.x / 2 - BUTTON_SIZE * 2 + PADDING),
|
||||
y: (screenSize.y - (BUTTON_SIZE + PADDING))
|
||||
};
|
||||
var toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.dice.toolbar", function(screenSize) {
|
||||
return {
|
||||
x: (screenSize.x / 2 - BUTTON_SIZE * 2 + PADDING),
|
||||
y: (screenSize.y - (BUTTON_SIZE + PADDING))
|
||||
};
|
||||
});
|
||||
var offButton = toolBar.addOverlay("image", {
|
||||
width: BUTTON_SIZE,
|
||||
|
@ -65,12 +65,13 @@ var deleteButton = toolBar.addOverlay("image", {
|
|||
alpha: 1
|
||||
});
|
||||
|
||||
var diceIconURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/images/dice.png"
|
||||
var diceButton = toolBar.addOverlay("image", {
|
||||
x: screenSize.x / 2 + PADDING,
|
||||
y: screenSize.y - (BUTTON_SIZE + PADDING),
|
||||
width: BUTTON_SIZE,
|
||||
height: BUTTON_SIZE,
|
||||
imageURL: HIFI_PUBLIC_BUCKET + "images/die.png",
|
||||
imageURL: diceIconURL,
|
||||
color: {
|
||||
red: 255,
|
||||
green: 255,
|
||||
|
@ -79,6 +80,7 @@ var diceButton = toolBar.addOverlay("image", {
|
|||
alpha: 1
|
||||
});
|
||||
|
||||
|
||||
var GRAVITY = -3.5;
|
||||
|
||||
// NOTE: angularVelocity is in radians/sec
|
||||
|
@ -90,28 +92,27 @@ function shootDice(position, velocity) {
|
|||
Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
|
||||
} else {
|
||||
for (var i = 0; i < NUMBER_OF_DICE; i++) {
|
||||
dice.push(Entities.addEntity(
|
||||
{
|
||||
type: "Model",
|
||||
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx",
|
||||
position: position,
|
||||
velocity: velocity,
|
||||
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
|
||||
angularVelocity: {
|
||||
x: Math.random() * MAX_ANGULAR_SPEED,
|
||||
y: Math.random() * MAX_ANGULAR_SPEED,
|
||||
z: Math.random() * MAX_ANGULAR_SPEED
|
||||
},
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: GRAVITY,
|
||||
z: 0
|
||||
},
|
||||
lifetime: LIFETIME,
|
||||
shapeType: "box",
|
||||
collisionsWillMove: true,
|
||||
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav"
|
||||
}));
|
||||
dice.push(Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: HIFI_PUBLIC_BUCKET + "models/props/Dice/goldDie.fbx",
|
||||
position: position,
|
||||
velocity: velocity,
|
||||
rotation: Quat.fromPitchYawRollDegrees(Math.random() * 360, Math.random() * 360, Math.random() * 360),
|
||||
angularVelocity: {
|
||||
x: Math.random() * MAX_ANGULAR_SPEED,
|
||||
y: Math.random() * MAX_ANGULAR_SPEED,
|
||||
z: Math.random() * MAX_ANGULAR_SPEED
|
||||
},
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: GRAVITY,
|
||||
z: 0
|
||||
},
|
||||
lifetime: LIFETIME,
|
||||
shapeType: "box",
|
||||
dynamic: true,
|
||||
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav"
|
||||
}));
|
||||
position = Vec3.sum(position, Vec3.multiply(DIE_SIZE, Vec3.normalize(Quat.getRight(Camera.getOrientation()))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,89 +9,118 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
Script.include("libraries/globals.js");
|
||||
Script.include([
|
||||
"libraries/toolBars.js",
|
||||
]);
|
||||
|
||||
var directory = (function () {
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
||||
var DIRECTORY_URL = "https://metaverse.highfidelity.com/directory",
|
||||
directoryWindow,
|
||||
DIRECTORY_BUTTON_URL = HIFI_PUBLIC_BUCKET + "images/tools/directory.svg",
|
||||
BUTTON_WIDTH = 50,
|
||||
BUTTON_HEIGHT = 50,
|
||||
BUTTON_ALPHA = 0.9,
|
||||
BUTTON_MARGIN = 8,
|
||||
directoryButton,
|
||||
EDIT_TOOLBAR_BUTTONS = 10, // Number of buttons in edit.js toolbar
|
||||
viewport;
|
||||
var DIRECTORY_WINDOW_URL = "https://metaverse.highfidelity.com/directory";
|
||||
var directoryWindow = new OverlayWebWindow({
|
||||
title: 'directory',
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
function updateButtonPosition() {
|
||||
Overlays.editOverlay(directoryButton, {
|
||||
x: viewport.x - BUTTON_WIDTH - BUTTON_MARGIN,
|
||||
y: (viewport.y - (EDIT_TOOLBAR_BUTTONS + 1) * (BUTTON_HEIGHT + BUTTON_MARGIN) - BUTTON_MARGIN) / 2 - 1
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
|
||||
|
||||
function showDirectory() {
|
||||
directoryWindow.setURL(DIRECTORY_WINDOW_URL);
|
||||
directoryWindow.setVisible(true);
|
||||
}
|
||||
|
||||
function hideDirectory() {
|
||||
directoryWindow.setVisible(false);
|
||||
directoryWindow.setURL("about:blank");
|
||||
}
|
||||
|
||||
function toggleDirectory() {
|
||||
if (directoryWindow.visible) {
|
||||
hideDirectory();
|
||||
} else {
|
||||
showDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
var toolBar = (function() {
|
||||
var that = {},
|
||||
toolBar,
|
||||
browseDirectoryButton;
|
||||
|
||||
function initialize() {
|
||||
ToolBar.SPACING = 16;
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.directory.toolbar", function(windowDimensions, toolbar) {
|
||||
return {
|
||||
x: windowDimensions.x - 8 - toolbar.width,
|
||||
y: 50
|
||||
};
|
||||
});
|
||||
browseDirectoryButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "directory.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
toolBar.showTool(browseDirectoryButton, true);
|
||||
}
|
||||
|
||||
function onMousePressEvent(event) {
|
||||
var clickedOverlay;
|
||||
var browseDirectoryButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
file;
|
||||
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
||||
|
||||
if (clickedOverlay === directoryButton) {
|
||||
if (directoryWindow.url !== DIRECTORY_URL) {
|
||||
directoryWindow.setURL(DIRECTORY_URL);
|
||||
}
|
||||
directoryWindow.setVisible(true);
|
||||
directoryWindow.raise();
|
||||
if (!event.isLeftButton) {
|
||||
// if another mouse button than left is pressed ignore it
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function onDomainChanged() {
|
||||
directoryWindow.setVisible(false);
|
||||
}
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
|
||||
function onScriptUpdate() {
|
||||
var oldViewport = viewport;
|
||||
|
||||
viewport = Controller.getViewportDimensions();
|
||||
|
||||
if (viewport.x !== oldViewport.x || viewport.y !== oldViewport.y) {
|
||||
updateButtonPosition();
|
||||
if (browseDirectoryButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleDirectory();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
that.mouseReleaseEvent = function(event) {
|
||||
var handled = false;
|
||||
|
||||
|
||||
if (browseDirectoryButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseDirectoryButtonDown = false;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
viewport = Controller.getViewportDimensions();
|
||||
that.cleanup = function() {
|
||||
toolBar.cleanup();
|
||||
};
|
||||
|
||||
directoryWindow = new OverlayWebWindow({
|
||||
title: 'Directory',
|
||||
source: DIRECTORY_URL,
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
initialize();
|
||||
return that;
|
||||
}());
|
||||
|
||||
directoryButton = Overlays.addOverlay("image", {
|
||||
imageURL: DIRECTORY_BUTTON_URL,
|
||||
width: BUTTON_WIDTH,
|
||||
height: BUTTON_HEIGHT,
|
||||
x: viewport.x - BUTTON_WIDTH - BUTTON_MARGIN,
|
||||
y: BUTTON_MARGIN,
|
||||
alpha: BUTTON_ALPHA,
|
||||
visible: true
|
||||
});
|
||||
|
||||
updateButtonPosition();
|
||||
|
||||
Controller.mousePressEvent.connect(onMousePressEvent);
|
||||
Window.domainChanged.connect(onDomainChanged);
|
||||
|
||||
Script.update.connect(onScriptUpdate);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
Overlays.deleteOverlay(directoryButton);
|
||||
}
|
||||
|
||||
setUp();
|
||||
Script.scriptEnding.connect(tearDown);
|
||||
}());
|
||||
Controller.mousePressEvent.connect(toolBar.mousePressEvent)
|
||||
Script.scriptEnding.connect(toolBar.cleanup);
|
||||
|
|
87
examples/dropStuffNearMe.js
Normal file
87
examples/dropStuffNearMe.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// Created by Philip Rosedale on January 9, 2016
|
||||
// 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
|
||||
//
|
||||
// Puts a bunch of entities in front of you, with various adjustable properties for testing.
|
||||
//
|
||||
// Note that when creating things quickly, the entity server will ignore data if we send updates too quickly.
|
||||
// like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND
|
||||
// variable letting you set this speed. If entities are missing from the grid after a relog, this number
|
||||
// being too high may be the reason.
|
||||
|
||||
var SIZE = 0.5;
|
||||
var TYPE = "Box"; // Right now this can be "Box" or "Model" or "Sphere"
|
||||
var MODEL_URL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx";
|
||||
var MODEL_DIMENSION = { x: 0.3, y: 0.3, z: 0.3 };
|
||||
|
||||
var RATE_PER_SECOND = 1000; // The entity server will drop data if we create things too fast.
|
||||
var SCRIPT_INTERVAL = 100;
|
||||
var LIFETIME = 90;
|
||||
|
||||
var NUMBER_TO_CREATE = 300;
|
||||
|
||||
var GRAVITY = { x: 0, y: -9.8, z: 0 };
|
||||
var VELOCITY = { x: 0.0, y: 0, z: 0 };
|
||||
var ANGULAR_VELOCITY = { x: 1, y: 1, z: 1 };
|
||||
|
||||
var DAMPING = 0.5;
|
||||
var ANGULAR_DAMPING = 0.5;
|
||||
|
||||
var collidable = true;
|
||||
var gravity = true;
|
||||
|
||||
|
||||
var x = 0;
|
||||
var z = 0;
|
||||
var totalCreated = 0;
|
||||
|
||||
var RANGE = 10;
|
||||
var HOW_FAR_IN_FRONT_OF_ME = 3 * RANGE;
|
||||
|
||||
|
||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(HOW_FAR_IN_FRONT_OF_ME, Quat.getFront(Camera.orientation)));
|
||||
|
||||
|
||||
function randomVector(range) {
|
||||
return {
|
||||
x: (Math.random() - 0.5) * range.x,
|
||||
y: (Math.random() - 0.5) * range.y,
|
||||
z: (Math.random() - 0.5) * range.z
|
||||
}
|
||||
}
|
||||
|
||||
Vec3.print("Center: ", center);
|
||||
|
||||
Script.setInterval(function () {
|
||||
if (!Entities.serversExist() || !Entities.canRez() || (totalCreated > NUMBER_TO_CREATE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var numToCreate = RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0);
|
||||
for (var i = 0; (i < numToCreate) && (totalCreated < NUMBER_TO_CREATE); i++) {
|
||||
var position = Vec3.sum(center, randomVector({ x: RANGE, y: RANGE, z: RANGE }));
|
||||
|
||||
Vec3.print("Position: ", position);
|
||||
Entities.addEntity({
|
||||
type: TYPE,
|
||||
modelURL: MODEL_URL,
|
||||
name: "gridTest",
|
||||
position: position,
|
||||
dimensions: (TYPE == "Model") ? MODEL_DIMENSION : { x: SIZE, y: SIZE, z: SIZE },
|
||||
color: { red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255 },
|
||||
velocity: VELOCITY,
|
||||
angularVelocity: Vec3.multiply(Math.random(), ANGULAR_VELOCITY),
|
||||
damping: DAMPING,
|
||||
angularDamping: ANGULAR_DAMPING,
|
||||
gravity: (gravity ? GRAVITY : { x: 0, y: 0, z: 0}),
|
||||
dynamic: collidable,
|
||||
lifetime: LIFETIME
|
||||
});
|
||||
|
||||
totalCreated++;
|
||||
}
|
||||
}, SCRIPT_INTERVAL);
|
||||
|
|
@ -24,8 +24,8 @@ function createAvatarDetector() {
|
|||
y: 2,
|
||||
z: 1
|
||||
},
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
visible: false,
|
||||
color: {
|
||||
red: 255,
|
||||
|
@ -52,4 +52,4 @@ var cleanup = function() {
|
|||
|
||||
createAvatarDetector();
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.update.connect(updateAvatarDetector);
|
||||
Script.update.connect(updateAvatarDetector);
|
||||
|
|
|
@ -56,7 +56,7 @@ function explodeHelicopter(explodePosition) {
|
|||
dimensions: partsURLS[i].dimensions,
|
||||
position: position,
|
||||
shapeType: "box",
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
damping: 0,
|
||||
gravity: {
|
||||
x: 0,
|
||||
|
@ -141,4 +141,4 @@ function cleanup() {
|
|||
})
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
|
|
@ -90,8 +90,8 @@ var modelRatProperties = {
|
|||
damping: 0.8,
|
||||
angularDamping: 0.99,
|
||||
friction: 0.75,
|
||||
collisionsWillMove: true,
|
||||
ignoreForCollisions: false,
|
||||
dynamic: true,
|
||||
collisionless: false,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -9.8,
|
||||
|
@ -194,8 +194,8 @@ function addAvoiderBlock(position) {
|
|||
z: 1
|
||||
},
|
||||
position: position,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
visible: false
|
||||
};
|
||||
|
||||
|
@ -468,4 +468,4 @@ if (USE_CONSTANT_SPAWNER === true) {
|
|||
}
|
||||
|
||||
}, RAT_SPAWN_RATE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,8 +183,7 @@ var toolBar = (function() {
|
|||
newTextButton,
|
||||
newWebButton,
|
||||
newZoneButton,
|
||||
newPolyVoxButton,
|
||||
browseMarketplaceButton;
|
||||
newPolyVoxButton;
|
||||
|
||||
function initialize() {
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) {
|
||||
|
@ -194,13 +193,7 @@ var toolBar = (function() {
|
|||
};
|
||||
});
|
||||
|
||||
browseMarketplaceButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "marketplace.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
|
||||
activeButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "edit-status.svg",
|
||||
|
@ -415,7 +408,6 @@ var toolBar = (function() {
|
|||
}
|
||||
|
||||
var newModelButtonDown = false;
|
||||
var browseMarketplaceButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
|
@ -443,11 +435,7 @@ var toolBar = (function() {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleMarketplace();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (newCubeButton === toolBar.clicked(clickedOverlay)) {
|
||||
createNewEntity({
|
||||
type: "Box",
|
||||
|
@ -652,22 +640,10 @@ var toolBar = (function() {
|
|||
}
|
||||
handled = true;
|
||||
}
|
||||
} else if (browseMarketplaceButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
url = Window.s3Browse(".*(fbx|FBX|obj|OBJ)");
|
||||
if (url !== null && url !== "") {
|
||||
addModel(url);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseMarketplaceButtonDown = false;
|
||||
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@ -1026,9 +1002,8 @@ function setupModelMenus() {
|
|||
// adj our menuitems
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: "Models",
|
||||
menuItemName: "Entities",
|
||||
isSeparator: true,
|
||||
beforeItem: "Physics",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
if (!Menu.menuItemExists("Edit", "Delete")) {
|
||||
|
@ -1039,7 +1014,7 @@ function setupModelMenus() {
|
|||
shortcutKeyEvent: {
|
||||
text: "backspace"
|
||||
},
|
||||
afterItem: "Models",
|
||||
afterItem: "Entities",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
modelMenuAddedDelete = true;
|
||||
|
@ -1051,7 +1026,7 @@ function setupModelMenus() {
|
|||
menuName: "Edit",
|
||||
menuItemName: "Entity List...",
|
||||
shortcutKey: "CTRL+META+L",
|
||||
afterItem: "Models",
|
||||
afterItem: "Entities",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
|
@ -1096,28 +1071,21 @@ function setupModelMenus() {
|
|||
});
|
||||
|
||||
Menu.addMenuItem({
|
||||
menuName: "File",
|
||||
menuItemName: "Models",
|
||||
isSeparator: true,
|
||||
beforeItem: "Settings",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "File",
|
||||
menuName: "Edit",
|
||||
menuItemName: "Export Entities",
|
||||
shortcutKey: "CTRL+META+E",
|
||||
afterItem: "Models",
|
||||
afterItem: "Entities",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "File",
|
||||
menuName: "Edit",
|
||||
menuItemName: "Import Entities",
|
||||
shortcutKey: "CTRL+META+I",
|
||||
afterItem: "Export Entities",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "File",
|
||||
menuName: "Edit",
|
||||
menuItemName: "Import Entities from URL",
|
||||
shortcutKey: "CTRL+META+U",
|
||||
afterItem: "Import Entities",
|
||||
|
@ -1162,7 +1130,7 @@ function setupModelMenus() {
|
|||
setupModelMenus(); // do this when first running our script.
|
||||
|
||||
function cleanupModelMenus() {
|
||||
Menu.removeSeparator("Edit", "Models");
|
||||
Menu.removeSeparator("Edit", "Entities");
|
||||
if (modelMenuAddedDelete) {
|
||||
// delete our menuitems
|
||||
Menu.removeMenuItem("Edit", "Delete");
|
||||
|
@ -1175,10 +1143,9 @@ function cleanupModelMenus() {
|
|||
Menu.removeMenuItem("Edit", "Select All Entities In Box");
|
||||
Menu.removeMenuItem("Edit", "Select All Entities Touching Box");
|
||||
|
||||
Menu.removeSeparator("File", "Models");
|
||||
Menu.removeMenuItem("File", "Export Entities");
|
||||
Menu.removeMenuItem("File", "Import Entities");
|
||||
Menu.removeMenuItem("File", "Import Entities from URL");
|
||||
Menu.removeMenuItem("Edit", "Export Entities");
|
||||
Menu.removeMenuItem("Edit", "Import Entities");
|
||||
Menu.removeMenuItem("Edit", "Import Entities from URL");
|
||||
|
||||
Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT);
|
||||
Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
|
||||
|
@ -1535,7 +1502,11 @@ PropertiesTool = function(opts) {
|
|||
var that = {};
|
||||
|
||||
var url = Script.resolvePath('html/entityProperties.html');
|
||||
var webView = new WebWindow('Entity Properties', url, 200, 280, true);
|
||||
var webView = new OverlayWebWindow({
|
||||
title: 'Entity Properties',
|
||||
source: url,
|
||||
toolWindow: true
|
||||
});
|
||||
|
||||
var visible = false;
|
||||
|
||||
|
|
|
@ -19,5 +19,5 @@ var recordAreaEntity = Entities.addEntity({
|
|||
},
|
||||
visible: true,
|
||||
script: PARAMS_SCRIPT_URL,
|
||||
ignoreForCollision: true,
|
||||
});
|
||||
collisionless: true,
|
||||
});
|
||||
|
|
|
@ -54,10 +54,10 @@
|
|||
preload: function (entityID) {
|
||||
print("RECORDING ENTITY PRELOAD");
|
||||
this.entityID = entityID;
|
||||
|
||||
|
||||
var entityProperties = Entities.getEntityProperties(_this.entityID);
|
||||
if (!entityProperties.ignoreForCollisions) {
|
||||
Entities.editEntity(_this.entityID, { ignoreForCollisions: true });
|
||||
if (!entityProperties.collisionless) {
|
||||
Entities.editEntity(_this.entityID, { collisionless: true });
|
||||
}
|
||||
|
||||
Messages.messageReceived.connect(receivingMessage);
|
||||
|
@ -117,4 +117,4 @@
|
|||
}
|
||||
|
||||
return new recordingEntity();
|
||||
});
|
||||
});
|
||||
|
|
66
examples/entityScripts/tribble.js
Normal file
66
examples/entityScripts/tribble.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
(function () {
|
||||
// See tests/performance/tribbles.js
|
||||
var dimensions, oldColor, entityID,
|
||||
editRate = 60,
|
||||
moveRate = 1,
|
||||
scale = 2,
|
||||
accumulated = 0,
|
||||
increment = {red: 1, green: 1, blue: 1},
|
||||
hasUpdate = false,
|
||||
shutdown = false;
|
||||
function nextWavelength(color) {
|
||||
var old = oldColor[color];
|
||||
if (old === 255) {
|
||||
increment[color] = -1;
|
||||
} else if (old === 0) {
|
||||
increment[color] = 1;
|
||||
}
|
||||
var next = (old + increment[color]) % 256;
|
||||
return next;
|
||||
}
|
||||
function update(delta) { // High frequency stuff is done in update in case we fall behind.
|
||||
accumulated += delta;
|
||||
if (accumulated > (1 / editRate)) {
|
||||
var newColor = {red: nextWavelength('red'), green: nextWavelength('green'), blue: nextWavelength('blue')};
|
||||
oldColor = newColor;
|
||||
Entities.editEntity(entityID, {color: newColor});
|
||||
accumulated = 0;
|
||||
}
|
||||
}
|
||||
function randomCentered() { return Math.random() - 0.5; }
|
||||
function randomVector() { return {x: randomCentered() * dimensions.x, y: randomCentered() * dimensions.y, z: randomCentered() * dimensions.z}; }
|
||||
function move() {
|
||||
var newData = {velocity: Vec3.sum({x: 0, y: 1, z: 0}, randomVector()), angularVelocity: Vec3.multiply(Math.PI, randomVector())};
|
||||
var nextChange = Math.ceil(Math.random() * 2000 / moveRate);
|
||||
Entities.editEntity(entityID, newData);
|
||||
if (!shutdown) { Script.setTimeout(move, nextChange); }
|
||||
}
|
||||
this.preload = function (givenEntityID) {
|
||||
entityID = givenEntityID;
|
||||
var properties = Entities.getEntityProperties(entityID);
|
||||
var userData = properties.userData && JSON.parse(properties.userData);
|
||||
var moveTimeout = userData ? userData.moveTimeout : 0;
|
||||
var editTimeout = userData ? userData.editTimeout : 0;
|
||||
editRate = (userData && userData.editRate) || editRate;
|
||||
moveRate = (moveRate && userData.moveRate) || moveRate;
|
||||
oldColor = properties.color;
|
||||
dimensions = Vec3.multiply(scale, properties.dimensions);
|
||||
if (editTimeout) {
|
||||
hasUpdate = true;
|
||||
Script.update.connect(update);
|
||||
if (editTimeout > 0) {
|
||||
Script.setTimeout(function () { Script.update.disconnect(update); hasUpdate = false; }, editTimeout * 1000);
|
||||
}
|
||||
}
|
||||
if (moveTimeout) {
|
||||
Script.setTimeout(move, 1000);
|
||||
if (moveTimeout > 0) {
|
||||
Script.setTimeout(function () { shutdown = true; }, moveTimeout * 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
this.unload = function () {
|
||||
shutdown = true;
|
||||
if (hasUpdate) { Script.update.disconnect(update); }
|
||||
};
|
||||
})
|
|
@ -165,7 +165,7 @@ function spawnBalls() {
|
|||
blue: randFloat(10, 180)
|
||||
},
|
||||
ignoreCollisions: false,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -9.9,
|
||||
|
@ -244,4 +244,4 @@ Script.scriptEnding.connect(cleanup);
|
|||
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
|
|
|
@ -43,7 +43,7 @@ function draw(deltaTime) {
|
|||
|
||||
var properties = {
|
||||
type: "Sphere",
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
position: startPosition,
|
||||
dimensions: {x: largeRadius, y: largeRadius, z: largeRadius},
|
||||
registrationPoint: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
|
@ -84,7 +84,7 @@ function draw(deltaTime) {
|
|||
if (numberEntitiesAdded <= MAX_ENTITIES) {
|
||||
var properties = {
|
||||
type: "Sphere",
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
position: center,
|
||||
dimensions: {x: entitySize, y: entitySize, z: entitySize},
|
||||
registrationPoint: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
|
|
|
@ -19,7 +19,7 @@ var position = Vec3.sum(MyAvatar.position, Quat.getFront(MyAvatar.orientation));
|
|||
var properties = {
|
||||
type: "Box",
|
||||
position: position,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
color: { red: 200, green: 0, blue: 0 }
|
||||
};
|
||||
var collider = Entities.addEntity(properties);
|
||||
|
|
|
@ -177,7 +177,7 @@ function makeNewProp(which, position) {
|
|||
damping: PUCK_DAMPING,
|
||||
angularDamping: ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
} else if (which == "paddle1") {
|
||||
paddle1Pos = Vec3.sum(center, {
|
||||
|
@ -211,7 +211,7 @@ function makeNewProp(which, position) {
|
|||
damping: PADDLE_DAMPING,
|
||||
angularDamping: PADDLE_ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
} else if (which == "paddle2") {
|
||||
paddle2Pos = Vec3.sum(center, {
|
||||
|
@ -245,7 +245,7 @@ function makeNewProp(which, position) {
|
|||
damping: PADDLE_DAMPING,
|
||||
angularDamping: PADDLE_ANGULAR_DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ function makeBalls(pos) {
|
|||
damping: 0.50,
|
||||
shapeType: "sphere",
|
||||
collisionSoundURL: hitSound,
|
||||
collisionsWillMove: true }));
|
||||
dynamic: true }));
|
||||
ballPosition.z += (BALL_SIZE + BALL_GAP) * SCALE;
|
||||
ballNumber++;
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ function makeBalls(pos) {
|
|||
ignoreCollisions: false,
|
||||
damping: 0.50,
|
||||
shapeType: "sphere",
|
||||
collisionsWillMove: true });
|
||||
dynamic: true });
|
||||
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ function shootCue(velocity) {
|
|||
damping: 0.10,
|
||||
density: 8000,
|
||||
ignoreCollisions: false,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
print("Shot, velocity = " + velocity);
|
||||
}
|
||||
|
|
|
@ -219,8 +219,8 @@
|
|||
type: 'Box',
|
||||
dimensions: COLOR_INDICATOR_DIMENSIONS,
|
||||
position: this.currentProperties.position,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true
|
||||
dynamic: false,
|
||||
collisionless: true
|
||||
}
|
||||
|
||||
this.colorIndicator = Entities.addEntity(properties);
|
||||
|
@ -262,4 +262,4 @@
|
|||
};
|
||||
|
||||
return new ColorBusterWand();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -81,8 +81,8 @@ function createColorBusterCube(row, column, vertical) {
|
|||
name: 'Hifi-ColorBusterCube',
|
||||
type: 'Box',
|
||||
dimensions: CUBE_DIMENSIONS,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: false,
|
||||
dynamic: false,
|
||||
collisionless: false,
|
||||
color: startingColor[1],
|
||||
position: position,
|
||||
userData: JSON.stringify({
|
||||
|
@ -127,4 +127,4 @@ if (DELETE_AT_ENDING === true) {
|
|||
|
||||
}
|
||||
|
||||
createBoard();
|
||||
createBoard();
|
||||
|
|
|
@ -71,7 +71,7 @@ function createColorBusterWand() {
|
|||
dimensions: COLOR_WAND_DIMENSIONS,
|
||||
position: center,
|
||||
script: COLOR_WAND_SCRIPT_URL,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
userData: JSON.stringify({
|
||||
hifiColorBusterWandKey: {
|
||||
owner: MyAvatar.sessionUUID,
|
||||
|
@ -96,4 +96,4 @@ if (DELETE_AT_ENDING === true) {
|
|||
Script.scriptEnding.connect(deleteWand);
|
||||
}
|
||||
|
||||
createColorBusterWand();
|
||||
createColorBusterWand();
|
||||
|
|
|
@ -169,8 +169,8 @@ function fire(side, value) {
|
|||
if (intersection.intersects) {
|
||||
Script.setTimeout(function() {
|
||||
createEntityHitEffect(intersection.intersection);
|
||||
if (shootAnything && intersection.properties.collisionsWillMove === 1) {
|
||||
// Any entity with collisions will move can be shot
|
||||
if (shootAnything && intersection.properties.dynamic === 1) {
|
||||
// Any dynamic entity can be shot
|
||||
Entities.editEntity(intersection.entityID, {
|
||||
velocity: Vec3.multiply(shotDirection, GUN_FORCE)
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ var pistolSpawnerEntity = Entities.addEntity({
|
|||
dimensions: {x: 0.38, y: 1.9, z: 3.02},
|
||||
script: scriptURL,
|
||||
visible: false,
|
||||
ignoreForCollisions: true
|
||||
collisionless: true
|
||||
});
|
||||
|
||||
var pistol = Entities.addEntity({
|
||||
|
@ -17,7 +17,7 @@ var pistol = Entities.addEntity({
|
|||
dimensions: {x: 0.38, y: 1.9, z: 3.02},
|
||||
script: scriptURL,
|
||||
color: {red: 200, green: 0, blue: 20},
|
||||
ignoreForCollisions: true
|
||||
collisionless: true
|
||||
});
|
||||
|
||||
|
||||
|
@ -28,4 +28,4 @@ function cleanup() {
|
|||
}
|
||||
|
||||
// Script.update.connect(update);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
|
|
@ -142,7 +142,7 @@ function mousePressEvent(event) {
|
|||
if (!pickResults.intersects) {
|
||||
return;
|
||||
}
|
||||
if (pickResults.properties.collisionsWillMove) {
|
||||
if (pickResults.properties.dynamic) {
|
||||
grabbedEntity = pickResults.entityID;
|
||||
var props = Entities.getEntityProperties(grabbedEntity)
|
||||
originalGravity = props.gravity;
|
||||
|
|
|
@ -190,7 +190,7 @@ function controller(side) {
|
|||
direction: Vec3.normalize(Vec3.subtract(this.tipPosition, this.palmPosition))
|
||||
};
|
||||
var intersection = getRayIntersection(pickRay, true);
|
||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
||||
if (intersection.intersects && intersection.properties.dynamic) {
|
||||
this.laserWasHovered = true;
|
||||
if (this.triggerHeld && !this.grabbing) {
|
||||
this.grab(intersection.entityID);
|
||||
|
@ -298,4 +298,4 @@ var leftController = new controller(LEFT);
|
|||
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -49,7 +49,7 @@ function mousePressEvent(event) {
|
|||
dimensions: {x: 0.3, y: 0.7, z: 0.3},
|
||||
gravity: {x: 0.0, y: -3.0, z: 0.0},
|
||||
damping: 0.2,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
|
||||
var pointToOffsetFrom = Vec3.sum(position, {x: 0.0, y: 2.0, z: 0.0});
|
||||
|
|
|
@ -51,7 +51,7 @@ SettingsWindow = function() {
|
|||
this.plankyStack = null;
|
||||
this.webWindow = null;
|
||||
this.init = function(plankyStack) {
|
||||
_this.webWindow = new WebWindow('Planky', Script.resolvePath('../../html/plankySettings.html'), 255, 500, true);
|
||||
_this.webWindow = new OverlayWebWindow('Planky', Script.resolvePath('../../html/plankySettings.html'), 255, 500, true);
|
||||
_this.webWindow.setVisible(false);
|
||||
_this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived);
|
||||
_this.plankyStack = plankyStack;
|
||||
|
@ -254,7 +254,7 @@ PlankyStack = function() {
|
|||
density: _this.options.density,
|
||||
velocity: {x: 0, y: 0, z: 0},
|
||||
angularVelocity: Quat.fromPitchYawRollDegrees(0, 0, 0),
|
||||
ignoreForCollisions: true
|
||||
collisionless: true
|
||||
};
|
||||
_this.planks.forEach(function(plank, index, object) {
|
||||
if (plank.layer === layer && plank.row === row) {
|
||||
|
@ -289,7 +289,7 @@ PlankyStack = function() {
|
|||
}
|
||||
if (!editMode) {
|
||||
_this.planks.forEach(function(plank, index, object) {
|
||||
Entities.editEntity(plank.entity, {ignoreForCollisions: false, collisionsWillMove: true});
|
||||
Entities.editEntity(plank.entity, {collisionless: false, dynamic: true});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -67,7 +67,7 @@ SatelliteCreator = function() {
|
|||
damping: 0.0,
|
||||
ignoreCollisions: false,
|
||||
lifetime: 6000,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
visible: true
|
||||
});
|
||||
|
||||
|
@ -90,7 +90,7 @@ SatelliteCreator = function() {
|
|||
damping: 0.0,
|
||||
ignoreCollisions: false,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
visible: true
|
||||
});
|
||||
|
||||
|
@ -174,7 +174,7 @@ SatelliteCreator = function() {
|
|||
damping: 0.0,
|
||||
ignoreCollisions: false,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
});
|
||||
|
||||
this.getProperties = function() {
|
||||
|
|
|
@ -191,7 +191,7 @@ function initializeInvaders() {
|
|||
dimensions: { x: invaderSize * 2, y: invaderSize * 2, z: invaderSize * 2 },
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
modelURL: invaderModels[row].modelURL,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
lifetime: itemLifetimes
|
||||
});
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ function fireMissile() {
|
|||
velocity: { x: 0, y: 5, z: 0},
|
||||
gravity: { x: 0, y: 0, z: 0 },
|
||||
damping: 0,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
dimensions: { x: missileSize, y: missileSize, z: missileSize },
|
||||
color: { red: 0, green: 0, blue: 255 },
|
||||
lifetime: 5
|
||||
|
|
|
@ -286,7 +286,7 @@ function makeSword() {
|
|||
damping: 0.1,
|
||||
collisionSoundURL: swordCollisionSoundURL,
|
||||
restitution: 0.01,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
});
|
||||
|
||||
if (originalAvatarCollisionSound === undefined) {
|
||||
|
|
|
@ -30,7 +30,7 @@ ColorCube.prototype.create = function() {
|
|||
name: that.NAME,
|
||||
color: that.COLOR,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
dimensions: { x: size, y: size, z: size },
|
||||
lifetime: 3600,
|
||||
userData: JSON.stringify(that.USER_DATA)
|
||||
|
|
|
@ -55,7 +55,7 @@ CreateSimulation = function() {
|
|||
damping: DAMPING,
|
||||
ignoreCollisions: false,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: false
|
||||
dynamic: false
|
||||
});
|
||||
|
||||
|
||||
|
@ -187,7 +187,7 @@ CreateSimulation = function() {
|
|||
damping: DAMPING,
|
||||
ignoreCollisions: false,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
});
|
||||
|
||||
this.computeAcceleration = function() {
|
||||
|
|
|
@ -37,7 +37,7 @@ function makeAll() {
|
|||
type: "Model",
|
||||
modelURL: HIFI_PUBLIC_BUCKET + model,
|
||||
collisionSoundURL: sound,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
shapeType: "box",
|
||||
restitution: 0.8,
|
||||
dimensions: currentDimensions,
|
||||
|
|
102
examples/example/ui/energyBar.js
Normal file
102
examples/example/ui/energyBar.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
// energyBar.js
|
||||
// examples/ui
|
||||
//
|
||||
// Created by Eric Levin on 1/4/15
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// This script adds an energy bar overlay which displays the amount of energy a user has left for grabbing and moving objects
|
||||
//
|
||||
// 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 energyColor = {red: 0, green: 200, blue: 0};
|
||||
var lowEnergyColor = {red: 255, green: 0, blue: 0};
|
||||
var totalWidth = 200;
|
||||
var paddingRight = 50;
|
||||
var xPosition = Window.innerWidth - totalWidth - paddingRight;
|
||||
var lowEnergyThreshold = 0.3;
|
||||
var currentEnergy = 1.0;
|
||||
var energyLossRate = 0.003;
|
||||
var energyChargeRate = 0.003;
|
||||
var isGrabbing = false;
|
||||
var refractoryPeriod = 2000;
|
||||
|
||||
var lastAvatarVelocity = MyAvatar.getVelocity();
|
||||
var lastAvatarPosition = MyAvatar.position;
|
||||
|
||||
var background = Overlays.addOverlay("text", {
|
||||
x: xPosition,
|
||||
y: 20,
|
||||
width: totalWidth,
|
||||
height: 10,
|
||||
backgroundColor: {red: 184, green: 181, blue: 178}
|
||||
})
|
||||
|
||||
var bar = Overlays.addOverlay("text", {
|
||||
x: xPosition,
|
||||
y: 20,
|
||||
width: totalWidth,
|
||||
height: 10,
|
||||
backgroundColor: energyColor
|
||||
});
|
||||
|
||||
|
||||
// Takes an energy value between 0 and 1 and sets energy bar width appropriately
|
||||
function setEnergy(energy) {
|
||||
energy = clamp(energy, 0, 1);
|
||||
var barWidth = totalWidth * energy;
|
||||
var color = energy <= lowEnergyThreshold ? lowEnergyColor: energyColor;
|
||||
Overlays.editOverlay(bar, { width: barWidth, backgroundColor: color});
|
||||
}
|
||||
|
||||
function avatarAccelerationEnergy() {
|
||||
var AVATAR_MOVEMENT_ENERGY_CONSTANT = 0.001;
|
||||
var velocity = MyAvatar.getVelocity();
|
||||
var dV = Math.abs(Vec3.length(velocity) - Vec3.length(lastAvatarVelocity));
|
||||
var dE = Vec3.length(lastAvatarVelocity) * dV * AVATAR_MOVEMENT_ENERGY_CONSTANT;
|
||||
lastAvatarVelocity = velocity;
|
||||
return dE;
|
||||
}
|
||||
|
||||
function teleported() {
|
||||
var MAX_AVATAR_MOVEMENT_PER_FRAME = 30.0;
|
||||
var position = MyAvatar.position;
|
||||
var dP = Vec3.length(Vec3.subtract(position, lastAvatarPosition));
|
||||
lastAvatarPosition = position;
|
||||
return (dP > MAX_AVATAR_MOVEMENT_PER_FRAME);
|
||||
}
|
||||
|
||||
function audioEnergy() {
|
||||
var AUDIO_ENERGY_CONSTANT = 0.000001;
|
||||
return MyAvatar.audioLoudness * AUDIO_ENERGY_CONSTANT;
|
||||
}
|
||||
|
||||
function update() {
|
||||
// refill energy
|
||||
currentEnergy += energyChargeRate;
|
||||
|
||||
// Avatar acceleration
|
||||
currentEnergy -= avatarAccelerationEnergy();
|
||||
|
||||
// Teleport cost
|
||||
if (teleported()) {
|
||||
currentEnergy = 0;
|
||||
}
|
||||
|
||||
// Making sounds
|
||||
currentEnergy -= audioEnergy();
|
||||
|
||||
|
||||
currentEnergy = clamp(currentEnergy, 0, 1);
|
||||
setEnergy(currentEnergy);
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
Overlays.deleteOverlay(background);
|
||||
Overlays.deleteOverlay(bar);
|
||||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -44,9 +44,9 @@ ArcBall = function(spawnPosition) {
|
|||
green: 10,
|
||||
blue: 150
|
||||
},
|
||||
ignoreForCollisions: true,
|
||||
collisionless: true,
|
||||
damping: 0.8,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
spatialKey: {
|
||||
|
@ -142,4 +142,4 @@ ArcBall = function(spawnPosition) {
|
|||
}
|
||||
|
||||
this.cleanup = cleanup;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ LightBall = function(spawnPosition) {
|
|||
green: 10,
|
||||
blue: 150
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
// gravity: {
|
||||
// x: 0,
|
||||
// y: -0.5,
|
||||
|
|
|
@ -23,7 +23,7 @@ LightSaber = function(spawnPosition) {
|
|||
modelURL: modelURL,
|
||||
position: spawnPosition,
|
||||
shapeType: 'box',
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
script: scriptURL,
|
||||
dimensions: {
|
||||
x: 0.06,
|
||||
|
|
|
@ -33,7 +33,7 @@ RaveStick = function(spawnPosition) {
|
|||
modelURL: modelURL,
|
||||
position: spawnPosition,
|
||||
shapeType: 'box',
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
script: scriptURL,
|
||||
dimensions: {
|
||||
x: 0.06,
|
||||
|
|
|
@ -320,7 +320,7 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!pickResults.properties.collisionsWillMove) {
|
||||
if (!pickResults.properties.dynamic) {
|
||||
// only grab dynamic objects
|
||||
return;
|
||||
}
|
||||
|
@ -506,14 +506,14 @@ Grabber.prototype.activateEntity = function(entityID, grabbedProperties) {
|
|||
data["activated"] = true;
|
||||
data["avatarId"] = MyAvatar.sessionUUID;
|
||||
data["refCount"] = data["refCount"] ? data["refCount"] + 1 : 1;
|
||||
// zero gravity and set ignoreForCollisions to true, but in a way that lets us put them back, after all grabs are done
|
||||
// zero gravity and set collisionless to true, but in a way that lets us put them back, after all grabs are done
|
||||
if (data["refCount"] == 1) {
|
||||
data["gravity"] = grabbedProperties.gravity;
|
||||
data["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions;
|
||||
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
||||
data["collisionless"] = grabbedProperties.collisionless;
|
||||
data["dynamic"] = grabbedProperties.dynamic;
|
||||
var whileHeldProperties = {gravity: {x:0, y:0, z:0}};
|
||||
if (invertSolidWhileHeld) {
|
||||
whileHeldProperties["ignoreForCollisions"] = ! grabbedProperties.ignoreForCollisions;
|
||||
whileHeldProperties["collisionless"] = ! grabbedProperties.collisionless;
|
||||
}
|
||||
Entities.editEntity(entityID, whileHeldProperties);
|
||||
}
|
||||
|
@ -527,8 +527,8 @@ Grabber.prototype.deactivateEntity = function(entityID) {
|
|||
if (data["refCount"] < 1) {
|
||||
Entities.editEntity(entityID, {
|
||||
gravity: data["gravity"],
|
||||
ignoreForCollisions: data["ignoreForCollisions"],
|
||||
collisionsWillMove: data["collisionsWillMove"]
|
||||
collisionless: data["collisionless"],
|
||||
dynamic: data["dynamic"]
|
||||
});
|
||||
data = null;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ function makeGrenade() {
|
|||
dimensions: { x: 0.09,
|
||||
y: 0.20,
|
||||
z: 0.09 },
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
modelURL: grenadeURL,
|
||||
shapeType: "box"
|
||||
});
|
||||
|
@ -160,7 +160,7 @@ function blowShitUp(position, radius) {
|
|||
var SPIN_RATE = 20.0;
|
||||
for (var i = 0; i < stuff.length; i++) {
|
||||
var properties = Entities.getEntityProperties(stuff[i]);
|
||||
if (properties.collisionsWillMove) {
|
||||
if (properties.dynamic) {
|
||||
var diff = Vec3.subtract(properties.position, position);
|
||||
var distance = Vec3.length(diff);
|
||||
var velocity = Vec3.sum(properties.velocity, Vec3.multiply(STRENGTH * 1.0 / distance, Vec3.normalize(diff)));
|
||||
|
|
|
@ -46,7 +46,7 @@ Script.setInterval(function () {
|
|||
position: position,
|
||||
dimensions: MODEL_DIMENSION,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
lifetime: LIFETIME
|
||||
});
|
||||
} else {
|
||||
|
@ -57,7 +57,7 @@ Script.setInterval(function () {
|
|||
dimensions: { x: SIZE, y: SIZE, z: SIZE },
|
||||
color: { red: x / ROWS_X * 255, green: 50, blue: z / ROWS_Z * 255 },
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
lifetime: LIFETIME
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ ball = Entities.addEntity(
|
|||
position: basePosition,
|
||||
dimensions: { x: 0.1, y: 0.1, z: 0.1 },
|
||||
color: { red: 255, green: 0, blue: 255 },
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true
|
||||
dynamic: false,
|
||||
collisionless: true
|
||||
});
|
||||
|
||||
disc = Entities.addEntity(
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src="list.min.js"></script>
|
||||
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
||||
<script type="text/javascript" src="eventBridgeLoader.js"></script>
|
||||
<script>
|
||||
var entities = {};
|
||||
var selectedEntities = [];
|
||||
|
@ -15,217 +17,219 @@
|
|||
const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities.
|
||||
|
||||
function loaded() {
|
||||
entityList = new List('entity-list', { valueNames: ['name', 'type', 'url'], page: MAX_ITEMS});
|
||||
entityList.clear();
|
||||
elEntityTable = document.getElementById("entity-table");
|
||||
elEntityTableBody = document.getElementById("entity-table-body");
|
||||
elRefresh = document.getElementById("refresh");
|
||||
elDelete = document.getElementById("delete");
|
||||
elTeleport = document.getElementById("teleport");
|
||||
elRadius = document.getElementById("radius");
|
||||
elNoEntitiesMessage = document.getElementById("no-entities");
|
||||
elNoEntitiesRadius = document.getElementById("no-entities-radius");
|
||||
|
||||
document.getElementById("entity-name").onclick = function() {
|
||||
setSortColumn('name');
|
||||
};
|
||||
document.getElementById("entity-type").onclick = function() {
|
||||
setSortColumn('type');
|
||||
};
|
||||
document.getElementById("entity-url").onclick = function() {
|
||||
setSortColumn('url');
|
||||
};
|
||||
|
||||
function onRowClicked(clickEvent) {
|
||||
var id = this.dataset.entityId;
|
||||
var selection = [this.dataset.entityId];
|
||||
if (clickEvent.ctrlKey) {
|
||||
selection = selection.concat(selectedEntities);
|
||||
} else if (clickEvent.shiftKey && selectedEntities.length > 0) {
|
||||
var previousItemFound = -1;
|
||||
var clickedItemFound = -1;
|
||||
for (var entity in entityList.visibleItems) {
|
||||
if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) {
|
||||
clickedItemFound = entity;
|
||||
} else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) {
|
||||
previousItemFound = entity;
|
||||
}
|
||||
}
|
||||
if (previousItemFound !== -1 && clickedItemFound !== -1) {
|
||||
var betweenItems = [];
|
||||
var toItem = Math.max(previousItemFound, clickedItemFound);
|
||||
// skip first and last item in this loop, we add them to selection after the loop
|
||||
for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) {
|
||||
entityList.visibleItems[i].elm.className = 'selected';
|
||||
betweenItems.push(entityList.visibleItems[i].values().id);
|
||||
}
|
||||
if (previousItemFound > clickedItemFound) {
|
||||
// always make sure that we add the items in the right order
|
||||
betweenItems.reverse();
|
||||
}
|
||||
selection = selection.concat(betweenItems, selectedEntities);
|
||||
}
|
||||
}
|
||||
|
||||
selectedEntities = selection;
|
||||
|
||||
this.className = 'selected';
|
||||
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "selectionUpdate",
|
||||
focus: false,
|
||||
entityIds: selection,
|
||||
}));
|
||||
}
|
||||
|
||||
function onRowDoubleClicked() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "selectionUpdate",
|
||||
focus: true,
|
||||
entityIds: [this.dataset.entityId],
|
||||
}));
|
||||
}
|
||||
|
||||
function addEntity(id, name, type, url) {
|
||||
if (entities[id] === undefined) {
|
||||
var urlParts = url.split('/');
|
||||
var filename = urlParts[urlParts.length - 1];
|
||||
|
||||
entityList.add([{ id: id, name: name, type: type, url: filename }], function(items) {
|
||||
var currentElement = items[0].elm;
|
||||
var id = items[0]._values.id;
|
||||
entities[id] = {
|
||||
id: id,
|
||||
name: name,
|
||||
el: currentElement,
|
||||
item: items[0],
|
||||
};
|
||||
currentElement.setAttribute('id', 'entity_' + id);
|
||||
currentElement.setAttribute('title', url);
|
||||
currentElement.dataset.entityId = id;
|
||||
currentElement.onclick = onRowClicked;
|
||||
currentElement.ondblclick = onRowDoubleClicked;
|
||||
});
|
||||
|
||||
if (refreshEntityListTimer) {
|
||||
clearTimeout(refreshEntityListTimer);
|
||||
}
|
||||
refreshEntityListTimer = setTimeout(refreshEntityListObject, 50);
|
||||
} else {
|
||||
var item = entities[id].item;
|
||||
item.values({ name: name, url: url });
|
||||
}
|
||||
}
|
||||
|
||||
function clearEntities() {
|
||||
entities = {};
|
||||
entityList.clear();
|
||||
}
|
||||
|
||||
var elSortOrder = {
|
||||
name: document.querySelector('#entity-name .sort-order'),
|
||||
type: document.querySelector('#entity-type .sort-order'),
|
||||
url: document.querySelector('#entity-url .sort-order'),
|
||||
}
|
||||
function setSortColumn(column) {
|
||||
if (currentSortColumn == column) {
|
||||
currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc";
|
||||
} else {
|
||||
elSortOrder[currentSortColumn].style.display = 'none';
|
||||
elSortOrder[column].style.display = 'inline';
|
||||
currentSortColumn = column;
|
||||
currentSortOrder = "asc";
|
||||
}
|
||||
elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING;
|
||||
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
||||
}
|
||||
|
||||
function refreshEntities() {
|
||||
clearEntities();
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
|
||||
}
|
||||
|
||||
function refreshEntityListObject() {
|
||||
refreshEntityListTimer = null;
|
||||
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
||||
entityList.search(document.getElementById("filter").value);
|
||||
}
|
||||
|
||||
function updateSelectedEntities(selectedEntities) {
|
||||
var notFound = false;
|
||||
for (var id in entities) {
|
||||
entities[id].el.className = '';
|
||||
}
|
||||
for (var i = 0; i < selectedEntities.length; i++) {
|
||||
var id = selectedEntities[i];
|
||||
if (id in entities) {
|
||||
var entity = entities[id];
|
||||
entity.el.className = 'selected';
|
||||
} else {
|
||||
notFound = true;
|
||||
}
|
||||
}
|
||||
return notFound;
|
||||
}
|
||||
|
||||
elRefresh.onclick = function() {
|
||||
refreshEntities();
|
||||
}
|
||||
elTeleport.onclick = function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'teleport' }));
|
||||
}
|
||||
elDelete.onclick = function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
|
||||
refreshEntities();
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", function (keyDownEvent) {
|
||||
if (keyDownEvent.target.nodeName === "INPUT") {
|
||||
return;
|
||||
}
|
||||
var keyCode = keyDownEvent.keyCode;
|
||||
if (keyCode === DELETE) {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
|
||||
refreshEntities();
|
||||
}
|
||||
}, false);
|
||||
|
||||
elRadius.onchange = function () {
|
||||
elRadius.value = Math.max(elRadius.value, 0);
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value }));
|
||||
refreshEntities();
|
||||
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value;
|
||||
}
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
if (data.type === "clearEntityList") {
|
||||
clearEntities();
|
||||
} else if (data.type == "selectionUpdate") {
|
||||
var notFound = updateSelectedEntities(data.selectedIDs);
|
||||
if (notFound) {
|
||||
refreshEntities();
|
||||
}
|
||||
} else if (data.type == "update") {
|
||||
var newEntities = data.entities;
|
||||
if (newEntities.length == 0) {
|
||||
elEntityTable.style.display = "none";
|
||||
elNoEntitiesMessage.style.display = "block";
|
||||
} else {
|
||||
elEntityTable.style.display = "table";
|
||||
elNoEntitiesMessage.style.display = "none";
|
||||
for (var i = 0; i < newEntities.length; i++) {
|
||||
var id = newEntities[i].id;
|
||||
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url);
|
||||
}
|
||||
updateSelectedEntities(data.selectedIDs);
|
||||
}
|
||||
}
|
||||
});
|
||||
setTimeout(refreshEntities, 1000);
|
||||
}
|
||||
openEventBridge(function() {
|
||||
entityList = new List('entity-list', { valueNames: ['name', 'type', 'url'], page: MAX_ITEMS});
|
||||
entityList.clear();
|
||||
elEntityTable = document.getElementById("entity-table");
|
||||
elEntityTableBody = document.getElementById("entity-table-body");
|
||||
elRefresh = document.getElementById("refresh");
|
||||
elDelete = document.getElementById("delete");
|
||||
elTeleport = document.getElementById("teleport");
|
||||
elRadius = document.getElementById("radius");
|
||||
elNoEntitiesMessage = document.getElementById("no-entities");
|
||||
elNoEntitiesRadius = document.getElementById("no-entities-radius");
|
||||
|
||||
document.getElementById("entity-name").onclick = function() {
|
||||
setSortColumn('name');
|
||||
};
|
||||
document.getElementById("entity-type").onclick = function() {
|
||||
setSortColumn('type');
|
||||
};
|
||||
document.getElementById("entity-url").onclick = function() {
|
||||
setSortColumn('url');
|
||||
};
|
||||
|
||||
function onRowClicked(clickEvent) {
|
||||
var id = this.dataset.entityId;
|
||||
var selection = [this.dataset.entityId];
|
||||
if (clickEvent.ctrlKey) {
|
||||
selection = selection.concat(selectedEntities);
|
||||
} else if (clickEvent.shiftKey && selectedEntities.length > 0) {
|
||||
var previousItemFound = -1;
|
||||
var clickedItemFound = -1;
|
||||
for (var entity in entityList.visibleItems) {
|
||||
if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) {
|
||||
clickedItemFound = entity;
|
||||
} else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) {
|
||||
previousItemFound = entity;
|
||||
}
|
||||
}
|
||||
if (previousItemFound !== -1 && clickedItemFound !== -1) {
|
||||
var betweenItems = [];
|
||||
var toItem = Math.max(previousItemFound, clickedItemFound);
|
||||
// skip first and last item in this loop, we add them to selection after the loop
|
||||
for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) {
|
||||
entityList.visibleItems[i].elm.className = 'selected';
|
||||
betweenItems.push(entityList.visibleItems[i].values().id);
|
||||
}
|
||||
if (previousItemFound > clickedItemFound) {
|
||||
// always make sure that we add the items in the right order
|
||||
betweenItems.reverse();
|
||||
}
|
||||
selection = selection.concat(betweenItems, selectedEntities);
|
||||
}
|
||||
}
|
||||
|
||||
selectedEntities = selection;
|
||||
|
||||
this.className = 'selected';
|
||||
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "selectionUpdate",
|
||||
focus: false,
|
||||
entityIds: selection,
|
||||
}));
|
||||
}
|
||||
|
||||
function onRowDoubleClicked() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "selectionUpdate",
|
||||
focus: true,
|
||||
entityIds: [this.dataset.entityId],
|
||||
}));
|
||||
}
|
||||
|
||||
function addEntity(id, name, type, url) {
|
||||
if (entities[id] === undefined) {
|
||||
var urlParts = url.split('/');
|
||||
var filename = urlParts[urlParts.length - 1];
|
||||
|
||||
entityList.add([{ id: id, name: name, type: type, url: filename }], function(items) {
|
||||
var currentElement = items[0].elm;
|
||||
var id = items[0]._values.id;
|
||||
entities[id] = {
|
||||
id: id,
|
||||
name: name,
|
||||
el: currentElement,
|
||||
item: items[0],
|
||||
};
|
||||
currentElement.setAttribute('id', 'entity_' + id);
|
||||
currentElement.setAttribute('title', url);
|
||||
currentElement.dataset.entityId = id;
|
||||
currentElement.onclick = onRowClicked;
|
||||
currentElement.ondblclick = onRowDoubleClicked;
|
||||
});
|
||||
|
||||
if (refreshEntityListTimer) {
|
||||
clearTimeout(refreshEntityListTimer);
|
||||
}
|
||||
refreshEntityListTimer = setTimeout(refreshEntityListObject, 50);
|
||||
} else {
|
||||
var item = entities[id].item;
|
||||
item.values({ name: name, url: url });
|
||||
}
|
||||
}
|
||||
|
||||
function clearEntities() {
|
||||
entities = {};
|
||||
entityList.clear();
|
||||
}
|
||||
|
||||
var elSortOrder = {
|
||||
name: document.querySelector('#entity-name .sort-order'),
|
||||
type: document.querySelector('#entity-type .sort-order'),
|
||||
url: document.querySelector('#entity-url .sort-order'),
|
||||
}
|
||||
function setSortColumn(column) {
|
||||
if (currentSortColumn == column) {
|
||||
currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc";
|
||||
} else {
|
||||
elSortOrder[currentSortColumn].style.display = 'none';
|
||||
elSortOrder[column].style.display = 'inline';
|
||||
currentSortColumn = column;
|
||||
currentSortOrder = "asc";
|
||||
}
|
||||
elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING;
|
||||
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
||||
}
|
||||
|
||||
function refreshEntities() {
|
||||
clearEntities();
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' }));
|
||||
}
|
||||
|
||||
function refreshEntityListObject() {
|
||||
refreshEntityListTimer = null;
|
||||
entityList.sort(currentSortColumn, { order: currentSortOrder });
|
||||
entityList.search(document.getElementById("filter").value);
|
||||
}
|
||||
|
||||
function updateSelectedEntities(selectedEntities) {
|
||||
var notFound = false;
|
||||
for (var id in entities) {
|
||||
entities[id].el.className = '';
|
||||
}
|
||||
for (var i = 0; i < selectedEntities.length; i++) {
|
||||
var id = selectedEntities[i];
|
||||
if (id in entities) {
|
||||
var entity = entities[id];
|
||||
entity.el.className = 'selected';
|
||||
} else {
|
||||
notFound = true;
|
||||
}
|
||||
}
|
||||
return notFound;
|
||||
}
|
||||
|
||||
elRefresh.onclick = function() {
|
||||
refreshEntities();
|
||||
}
|
||||
elTeleport.onclick = function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'teleport' }));
|
||||
}
|
||||
elDelete.onclick = function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
|
||||
refreshEntities();
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", function (keyDownEvent) {
|
||||
if (keyDownEvent.target.nodeName === "INPUT") {
|
||||
return;
|
||||
}
|
||||
var keyCode = keyDownEvent.keyCode;
|
||||
if (keyCode === DELETE) {
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' }));
|
||||
refreshEntities();
|
||||
}
|
||||
}, false);
|
||||
|
||||
elRadius.onchange = function () {
|
||||
elRadius.value = Math.max(elRadius.value, 0);
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'radius', radius: elRadius.value }));
|
||||
refreshEntities();
|
||||
elNoEntitiesRadius.firstChild.nodeValue = elRadius.value;
|
||||
}
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
if (data.type === "clearEntityList") {
|
||||
clearEntities();
|
||||
} else if (data.type == "selectionUpdate") {
|
||||
var notFound = updateSelectedEntities(data.selectedIDs);
|
||||
if (notFound) {
|
||||
refreshEntities();
|
||||
}
|
||||
} else if (data.type == "update") {
|
||||
var newEntities = data.entities;
|
||||
if (newEntities.length == 0) {
|
||||
elEntityTable.style.display = "none";
|
||||
elNoEntitiesMessage.style.display = "block";
|
||||
} else {
|
||||
elEntityTable.style.display = "table";
|
||||
elNoEntitiesMessage.style.display = "none";
|
||||
for (var i = 0; i < newEntities.length; i++) {
|
||||
var id = newEntities[i].id;
|
||||
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url);
|
||||
}
|
||||
updateSelectedEntities(data.selectedIDs);
|
||||
}
|
||||
}
|
||||
});
|
||||
setTimeout(refreshEntities, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,8 @@
|
|||
// void scriptEventReceived(const QString& data);
|
||||
//
|
||||
|
||||
var EventBridge;
|
||||
|
||||
EventBridgeConnectionProxy = function(parent) {
|
||||
this.parent = parent;
|
||||
this.realSignal = this.parent.realBridge.scriptEventReceived
|
||||
|
@ -46,12 +48,10 @@ openEventBridge = function(callback) {
|
|||
socket.onopen = function() {
|
||||
channel = new QWebChannel(socket, function(channel) {
|
||||
console.log("Document url is " + document.URL);
|
||||
for(var key in channel.objects){
|
||||
console.log("registered object: " + key);
|
||||
}
|
||||
var webWindow = channel.objects[document.URL.toLowerCase()];
|
||||
console.log("WebWindow is " + webWindow)
|
||||
eventBridgeProxy = new EventBridgeProxy(webWindow);
|
||||
EventBridge = eventBridgeProxy;
|
||||
if (callback) { callback(eventBridgeProxy); }
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,110 +1,114 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
||||
<script type="text/javascript" src="eventBridgeLoader.js"></script>
|
||||
<script>
|
||||
function loaded() {
|
||||
var gridColor = { red: 0, green: 0, blue: 0 };
|
||||
var gridColors = [
|
||||
{ red: 0, green: 0, blue: 0 },
|
||||
{ red: 255, green: 255, blue: 255 },
|
||||
{ red: 255, green: 0, blue: 0 },
|
||||
{ red: 0, green: 255, blue: 0},
|
||||
{ red: 0, green: 0, blue: 255 },
|
||||
];
|
||||
var gridColorIndex = 0;
|
||||
|
||||
elPosY = document.getElementById("horiz-y");
|
||||
elMinorSpacing = document.getElementById("minor-spacing");
|
||||
elMajorSpacing = document.getElementById("major-spacing");
|
||||
elSnapToGrid = document.getElementById("snap-to-grid");
|
||||
elHorizontalGridVisible = document.getElementById("horiz-grid-visible");
|
||||
elMoveToSelection = document.getElementById("move-to-selection");
|
||||
elMoveToAvatar = document.getElementById("move-to-avatar");
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
if (data.origin) {
|
||||
var origin = data.origin;
|
||||
elPosY.value = origin.y.toFixed(2);
|
||||
openEventBridge(function() {
|
||||
var gridColor = { red: 0, green: 0, blue: 0 };
|
||||
var gridColors = [
|
||||
{ red: 0, green: 0, blue: 0 },
|
||||
{ red: 255, green: 255, blue: 255 },
|
||||
{ red: 255, green: 0, blue: 0 },
|
||||
{ red: 0, green: 255, blue: 0},
|
||||
{ red: 0, green: 0, blue: 255 },
|
||||
];
|
||||
var gridColorIndex = 0;
|
||||
|
||||
elPosY = document.getElementById("horiz-y");
|
||||
elMinorSpacing = document.getElementById("minor-spacing");
|
||||
elMajorSpacing = document.getElementById("major-spacing");
|
||||
elSnapToGrid = document.getElementById("snap-to-grid");
|
||||
elHorizontalGridVisible = document.getElementById("horiz-grid-visible");
|
||||
elMoveToSelection = document.getElementById("move-to-selection");
|
||||
elMoveToAvatar = document.getElementById("move-to-avatar");
|
||||
|
||||
if (window.EventBridge !== undefined) {
|
||||
EventBridge.scriptEventReceived.connect(function(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
if (data.origin) {
|
||||
var origin = data.origin;
|
||||
elPosY.value = origin.y.toFixed(2);
|
||||
}
|
||||
|
||||
if (data.minorGridWidth !== undefined) {
|
||||
elMinorSpacing.value = data.minorGridWidth;
|
||||
}
|
||||
|
||||
if (data.majorGridEvery !== undefined) {
|
||||
elMajorSpacing.value = data.majorGridEvery;
|
||||
}
|
||||
|
||||
if (data.gridColor) {
|
||||
gridColor = data.gridColor;
|
||||
}
|
||||
|
||||
if (data.snapToGrid !== undefined) {
|
||||
elSnapToGrid.checked = data.snapToGrid == true;
|
||||
}
|
||||
|
||||
if (data.visible !== undefined) {
|
||||
elHorizontalGridVisible.checked = data.visible == true;
|
||||
}
|
||||
});
|
||||
|
||||
function emitUpdate() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "update",
|
||||
origin: {
|
||||
y: elPosY.value,
|
||||
},
|
||||
minorGridWidth: elMinorSpacing.value,
|
||||
majorGridEvery: elMajorSpacing.value,
|
||||
gridColor: gridColor,
|
||||
colorIndex: gridColorIndex,
|
||||
snapToGrid: elSnapToGrid.checked,
|
||||
visible: elHorizontalGridVisible.checked,
|
||||
}));
|
||||
}
|
||||
|
||||
if (data.minorGridWidth !== undefined) {
|
||||
elMinorSpacing.value = data.minorGridWidth;
|
||||
}
|
||||
|
||||
if (data.majorGridEvery !== undefined) {
|
||||
elMajorSpacing.value = data.majorGridEvery;
|
||||
}
|
||||
|
||||
if (data.gridColor) {
|
||||
gridColor = data.gridColor;
|
||||
}
|
||||
|
||||
if (data.snapToGrid !== undefined) {
|
||||
elSnapToGrid.checked = data.snapToGrid == true;
|
||||
}
|
||||
|
||||
if (data.visible !== undefined) {
|
||||
elHorizontalGridVisible.checked = data.visible == true;
|
||||
}
|
||||
});
|
||||
|
||||
function emitUpdate() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "update",
|
||||
origin: {
|
||||
y: elPosY.value,
|
||||
},
|
||||
minorGridWidth: elMinorSpacing.value,
|
||||
majorGridEvery: elMajorSpacing.value,
|
||||
gridColor: gridColor,
|
||||
colorIndex: gridColorIndex,
|
||||
snapToGrid: elSnapToGrid.checked,
|
||||
visible: elHorizontalGridVisible.checked,
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elPosY.addEventListener("change", emitUpdate);
|
||||
elMinorSpacing.addEventListener("change", emitUpdate);
|
||||
elMajorSpacing.addEventListener("change", emitUpdate);
|
||||
elSnapToGrid.addEventListener("change", emitUpdate);
|
||||
elHorizontalGridVisible.addEventListener("change", emitUpdate);
|
||||
|
||||
elMoveToAvatar.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToAvatar",
|
||||
}));
|
||||
|
||||
elPosY.addEventListener("change", emitUpdate);
|
||||
elMinorSpacing.addEventListener("change", emitUpdate);
|
||||
elMajorSpacing.addEventListener("change", emitUpdate);
|
||||
elSnapToGrid.addEventListener("change", emitUpdate);
|
||||
elHorizontalGridVisible.addEventListener("change", emitUpdate);
|
||||
|
||||
elMoveToAvatar.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToAvatar",
|
||||
}));
|
||||
});
|
||||
elMoveToSelection.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToSelection",
|
||||
}));
|
||||
});
|
||||
|
||||
var gridColorBox = document.getElementById('grid-color');
|
||||
|
||||
for (var i = 0; i < gridColors.length; i++) {
|
||||
var colors = gridColors[i];
|
||||
var box = document.createElement('div');
|
||||
box.setAttribute('class', 'color-box');
|
||||
box.style.background = 'rgb(' + colors.red + ', ' + colors.green + ', ' + colors.blue + ')';
|
||||
document.getElementById("grid-colors").appendChild(box);
|
||||
box.addEventListener("click", function(color, index) {
|
||||
return function() {
|
||||
gridColor = color;
|
||||
gridColorIndex = index;
|
||||
emitUpdate();
|
||||
}
|
||||
}({ red: colors.red, green: colors.green, blue: colors.blue }, i));
|
||||
}
|
||||
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'init' }));
|
||||
});
|
||||
elMoveToSelection.addEventListener("click", function() {
|
||||
EventBridge.emitWebEvent(JSON.stringify({
|
||||
type: "action",
|
||||
action: "moveToSelection",
|
||||
}));
|
||||
});
|
||||
|
||||
var gridColorBox = document.getElementById('grid-color');
|
||||
|
||||
for (var i = 0; i < gridColors.length; i++) {
|
||||
var colors = gridColors[i];
|
||||
var box = document.createElement('div');
|
||||
box.setAttribute('class', 'color-box');
|
||||
box.style.background = 'rgb(' + colors.red + ', ' + colors.green + ', ' + colors.blue + ')';
|
||||
document.getElementById("grid-colors").appendChild(box);
|
||||
box.addEventListener("click", function(color, index) {
|
||||
return function() {
|
||||
gridColor = color;
|
||||
gridColorIndex = index;
|
||||
emitUpdate();
|
||||
}
|
||||
}({ red: colors.red, green: colors.green, blue: colors.blue }, i));
|
||||
}
|
||||
|
||||
EventBridge.emitWebEvent(JSON.stringify({ type: 'init' }));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
|
|
@ -117,7 +117,7 @@ var leafSquall = function (properties) {
|
|||
},
|
||||
damping: 0,
|
||||
angularDamping: 0,
|
||||
ignoreForCollisions: true
|
||||
collisionless: true
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ var playerSphere = Entities.addEntity({
|
|||
y: -9.8,
|
||||
z: 0
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
damping: 0.2
|
||||
});
|
||||
|
||||
|
@ -267,4 +267,4 @@ function cleanup() {
|
|||
}
|
||||
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
|
|
@ -4,7 +4,9 @@ EntityListTool = function(opts) {
|
|||
var that = {};
|
||||
|
||||
var url = ENTITY_LIST_HTML_URL;
|
||||
var webView = new WebWindow('Entities', url, 200, 280, true);
|
||||
var webView = new OverlayWebWindow({
|
||||
title: 'Entities', source: url, toolWindow: true
|
||||
});
|
||||
|
||||
var searchRadius = 100;
|
||||
|
||||
|
|
|
@ -199,9 +199,9 @@ EntityPropertyDialogBox = (function () {
|
|||
index++;
|
||||
array.push({ label: "Density:", value: properties.density.toFixed(decimals) });
|
||||
index++;
|
||||
array.push({ label: "Ignore for Collisions:", type: "checkbox", value: properties.ignoreForCollisions });
|
||||
array.push({ label: "Collisionless:", type: "checkbox", value: properties.collisionless });
|
||||
index++;
|
||||
array.push({ label: "Collisions Will Move:", type: "checkbox", value: properties.collisionsWillMove });
|
||||
array.push({ label: "Dynamic:", type: "checkbox", value: properties.dynamic });
|
||||
index++;
|
||||
array.push({ label: "Collision Sound URL:", value: properties.collisionSoundURL });
|
||||
index++;
|
||||
|
@ -412,8 +412,8 @@ EntityPropertyDialogBox = (function () {
|
|||
|
||||
index++; // skip header
|
||||
properties.density = array[index++].value;
|
||||
properties.ignoreForCollisions = array[index++].value;
|
||||
properties.collisionsWillMove = array[index++].value;
|
||||
properties.collisionless = array[index++].value;
|
||||
properties.dynamic = array[index++].value;
|
||||
|
||||
properties.lifetime = array[index++].value;
|
||||
properties.visible = array[index++].value;
|
||||
|
|
|
@ -231,7 +231,9 @@ GridTool = function(opts) {
|
|||
var listeners = [];
|
||||
|
||||
var url = GRID_CONTROLS_HTML_URL;
|
||||
var webView = new WebWindow('Grid', url, 200, 280, true);
|
||||
var webView = new OverlayWebWindow({
|
||||
title: 'Grid', source: url, toolWindow: true
|
||||
});
|
||||
|
||||
horizontalGrid.addListener(function(data) {
|
||||
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
||||
|
|
|
@ -383,6 +383,9 @@
|
|||
searchList[object._id] = object;
|
||||
});
|
||||
return searchList;
|
||||
},
|
||||
findRayIntersection: function(pickRay) {
|
||||
return Overlays.findRayIntersection(pickRay);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -297,3 +297,8 @@ calculateHandSizeRatio = function() {
|
|||
var handSizeRatio = centerHandPoint/standardCenterHandPoint;
|
||||
return handSizeRatio;
|
||||
}
|
||||
|
||||
clamp = function(val, min, max){
|
||||
return Math.max(min, Math.min(max, val))
|
||||
}
|
||||
|
||||
|
|
|
@ -227,8 +227,8 @@ entitySlider.prototype = {
|
|||
type: 'Line',
|
||||
name: 'Hifi-Slider-Axis::' + this.sliderType,
|
||||
color: this.color,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
dimensions: {
|
||||
x: 3,
|
||||
y: 3,
|
||||
|
@ -250,8 +250,8 @@ entitySlider.prototype = {
|
|||
var properties = {
|
||||
name: 'Hifi-End-Of-Axis',
|
||||
type: 'Box',
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
dimensions: {
|
||||
x: 0.01,
|
||||
y: 0.01,
|
||||
|
@ -360,11 +360,11 @@ entitySlider.prototype = {
|
|||
type: 'Sphere',
|
||||
name: 'Hifi-Slider-' + this.sliderType,
|
||||
dimensions: SLIDER_DIMENSIONS,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
color: this.color,
|
||||
position: sliderPosition,
|
||||
script: SLIDER_SCRIPT_URL,
|
||||
ignoreForCollisions: true,
|
||||
collisionless: true,
|
||||
userData: JSON.stringify({
|
||||
lightModifierKey: {
|
||||
lightID: this.lightID,
|
||||
|
@ -558,8 +558,8 @@ function createPanelEntity(position) {
|
|||
z: 0.1
|
||||
},
|
||||
visible: false,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true
|
||||
dynamic: false,
|
||||
collisionless: true
|
||||
}
|
||||
|
||||
var panel = Entities.addEntity(panelProperties);
|
||||
|
@ -582,8 +582,8 @@ function createVisiblePanel() {
|
|||
z: SLIDER_DIMENSIONS.z / 4
|
||||
},
|
||||
visible: true,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
position: moveDown,
|
||||
rotation: avatarRot,
|
||||
script: VISIBLE_PANEL_SCRIPT_URL
|
||||
|
@ -602,7 +602,7 @@ function createLightModel(position, rotation) {
|
|||
shapeType: 'box',
|
||||
modelURL: LIGHT_MODEL_URL,
|
||||
dimensions: LIGHT_MODEL_DIMENSIONS,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
position: position,
|
||||
rotation: rotation,
|
||||
script: PARENT_SCRIPT_URL,
|
||||
|
@ -639,8 +639,8 @@ function createCloseButton(axisStart) {
|
|||
position: Vec3.sum(position, VERTICAL_OFFFSET),
|
||||
rotation: Quat.multiply(avatarRot, Quat.fromPitchYawRollDegrees(90, 0, 45)),
|
||||
//rotation: Quat.fromPitchYawRollDegrees(0, 0, 90),
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
script: CLOSE_BUTTON_SCRIPT_URL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
|
@ -873,4 +873,4 @@ subscribeToCleanupMessages();
|
|||
// linearAttenuation: 0,
|
||||
// quadraticAttenuation: 0,
|
||||
// exponent: 0,
|
||||
// cutoff: 180, // in degrees
|
||||
// cutoff: 180, // in degrees
|
||||
|
|
|
@ -42,7 +42,7 @@ for (var i = 0; i < NUM_BLOCKS; i++) {
|
|||
z: basePosition.z + randFloat(-SPAWN_RANGE, SPAWN_RANGE)
|
||||
},
|
||||
color: {red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
gravity: {x: 0, y: 0, z: 0}
|
||||
}));
|
||||
}
|
||||
|
@ -60,4 +60,4 @@ Script.scriptEnding.connect(cleanup);
|
|||
|
||||
function randFloat(low, high) {
|
||||
return low + Math.random() * ( high - low );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ BALL_PROTOTYPE = {
|
|||
dimensions: BALL_DIMENSIONS,
|
||||
color: BALL_COLOR,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false
|
||||
dynamic: false
|
||||
};
|
||||
|
||||
// 2 millimeters
|
||||
|
@ -62,7 +62,7 @@ LINE_PROTOTYPE = {
|
|||
lineWidth: 5,
|
||||
visible: true,
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
dynamic: false,
|
||||
}
|
||||
|
||||
EDGE_PROTOTYPE = LINE_PROTOTYPE;
|
||||
|
@ -76,7 +76,7 @@ EDGE_PROTOTYPE = LINE_PROTOTYPE;
|
|||
// rotation: rotation,
|
||||
// visible: true,
|
||||
// ignoreCollisions: true,
|
||||
// collisionsWillMove: false
|
||||
// dynamic: false
|
||||
// }
|
||||
|
||||
|
||||
|
|
131
examples/marketplace.js
Normal file
131
examples/marketplace.js
Normal file
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// marketplace.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 8 Jan 2016
|
||||
// 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
|
||||
//
|
||||
|
||||
Script.include([
|
||||
"libraries/toolBars.js",
|
||||
]);
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
||||
var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace";
|
||||
var marketplaceWindow = new OverlayWebWindow({
|
||||
title: 'Marketplace',
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
visible: false
|
||||
});
|
||||
|
||||
var toolHeight = 50;
|
||||
var toolWidth = 50;
|
||||
|
||||
|
||||
function showMarketplace(marketplaceID) {
|
||||
var url = MARKETPLACE_URL;
|
||||
if (marketplaceID) {
|
||||
url = url + "/items/" + marketplaceID;
|
||||
}
|
||||
print("setting marketplace URL to " + url);
|
||||
marketplaceWindow.setURL(url);
|
||||
marketplaceWindow.setVisible(true);
|
||||
}
|
||||
|
||||
function hideMarketplace() {
|
||||
marketplaceWindow.setVisible(false);
|
||||
marketplaceWindow.setURL("about:blank");
|
||||
}
|
||||
|
||||
function toggleMarketplace() {
|
||||
if (marketplaceWindow.visible) {
|
||||
hideMarketplace();
|
||||
} else {
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
var toolBar = (function() {
|
||||
var that = {},
|
||||
toolBar,
|
||||
browseMarketplaceButton;
|
||||
|
||||
function initialize() {
|
||||
ToolBar.SPACING = 16;
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.marketplace.toolbar", function(windowDimensions, toolbar) {
|
||||
return {
|
||||
x: windowDimensions.x - 8 - toolbar.width,
|
||||
y: 135
|
||||
};
|
||||
});
|
||||
browseMarketplaceButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "marketplace.svg",
|
||||
width: toolWidth,
|
||||
height: toolHeight,
|
||||
alpha: 0.9,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
toolBar.showTool(browseMarketplaceButton, true);
|
||||
}
|
||||
|
||||
var browseMarketplaceButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
file;
|
||||
|
||||
if (!event.isLeftButton) {
|
||||
// if another mouse button than left is pressed ignore it
|
||||
return false;
|
||||
}
|
||||
|
||||
clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleMarketplace();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
that.mouseReleaseEvent = function(event) {
|
||||
var handled = false;
|
||||
|
||||
|
||||
if (browseMarketplaceButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
});
|
||||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseMarketplaceButtonDown = false;
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
that.cleanup = function() {
|
||||
toolBar.cleanup();
|
||||
};
|
||||
|
||||
initialize();
|
||||
return that;
|
||||
}());
|
||||
|
||||
Controller.mousePressEvent.connect(toolBar.mousePressEvent)
|
||||
Script.scriptEnding.connect(toolBar.cleanup);
|
|
@ -28,8 +28,7 @@
|
|||
var PAINT_TRIGGER_THRESHOLD = 0.6;
|
||||
var MIN_STROKE_WIDTH = 0.0005;
|
||||
var MAX_STROKE_WIDTH = 0.03;
|
||||
|
||||
var textureURL = "https://s3.amazonaws.com/hifi-public/eric/textures/paintStrokes/paintStroke.png";
|
||||
var textureURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/paintStroke.png";
|
||||
|
||||
var TRIGGER_CONTROLS = [
|
||||
Controller.Standard.LT,
|
||||
|
@ -170,7 +169,7 @@
|
|||
type: "PolyLine",
|
||||
name: "paintStroke",
|
||||
color: this.strokeColor,
|
||||
textures: "https://s3.amazonaws.com/hifi-public/eric/textures/paintStrokes/paintStroke.png",
|
||||
textures: textureURL,
|
||||
dimensions: {
|
||||
x: 50,
|
||||
y: 50,
|
||||
|
|
|
@ -41,6 +41,7 @@ var whiteboard = Entities.addEntity({
|
|||
type: "Model",
|
||||
shapeType: "box",
|
||||
modelURL: modelURL,
|
||||
dimensions: {x: 2, y: 2.67, z: 0.76},
|
||||
name: "whiteboard base",
|
||||
position: center,
|
||||
rotation: rotation,
|
||||
|
@ -53,8 +54,11 @@ var colorIndicatorPosition = {
|
|||
};
|
||||
colorIndicatorPosition.y += 1.55;
|
||||
colorIndicatorPosition = Vec3.sum(colorIndicatorPosition, Vec3.multiply(-0.1, Quat.getFront(rotation)));
|
||||
var colorIndicatorBorderDimensions = {x: 1.84, y: 0.46, z: 0.04};
|
||||
var colorIndicatorBorder = Entities.addEntity({
|
||||
type: "Model",
|
||||
name: "Whiteboard Color Indicator Border",
|
||||
dimensions: colorIndicatorBorderDimensions,
|
||||
position: colorIndicatorPosition,
|
||||
modelURL: colorIndicatorBorderModelURL,
|
||||
rotation: rotation,
|
||||
|
@ -63,10 +67,12 @@ var colorIndicatorBorder = Entities.addEntity({
|
|||
|
||||
var surfaceCenter = Vec3.sum(center, Vec3.multiply(-0.1, Quat.getFront(rotation)));
|
||||
surfaceCenter.y += 0.6;
|
||||
var whiteboardDimensions = {x: 1.8, y: 1.3, z: 0.01};
|
||||
var drawingSurface = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: surfaceModelURL,
|
||||
shapeType: "box",
|
||||
dimensions: whiteboardDimensions,
|
||||
name: "whiteboard surface",
|
||||
position: surfaceCenter,
|
||||
script: scriptURL,
|
||||
|
@ -111,6 +117,7 @@ var eraser = Entities.addEntity({
|
|||
type: "Model",
|
||||
modelURL: eraserModelURL,
|
||||
position: eraserPosition,
|
||||
dimensions: {x: 1.73, y: 0.47, z: 0.11},
|
||||
name: "Eraser",
|
||||
script: scriptURL,
|
||||
rotation: rotation,
|
||||
|
@ -122,11 +129,7 @@ var eraser = Entities.addEntity({
|
|||
})
|
||||
});
|
||||
|
||||
Script.setTimeout(function() {
|
||||
whiteboardDimensions = Entities.getEntityProperties(whiteboard, "naturalDimensions").naturalDimensions;
|
||||
colorIndicatorBorderDimensions = Entities.getEntityProperties(colorIndicatorBorder, "naturalDimensions").naturalDimensions;
|
||||
setUp();
|
||||
}, 2000)
|
||||
setUp();
|
||||
|
||||
|
||||
function setUp() {
|
||||
|
@ -138,6 +141,7 @@ function setUp() {
|
|||
blockerPosition = Vec3.sum(blockerPosition, Vec3.multiply(-1, Quat.getFront(rotation)));
|
||||
blocker = Entities.addEntity({
|
||||
type: "Box",
|
||||
name: "Whiteboard Blocker",
|
||||
rotation: rotation,
|
||||
position: blockerPosition,
|
||||
dimensions: {
|
||||
|
@ -148,26 +152,17 @@ function setUp() {
|
|||
shapeType: "box",
|
||||
visible: false
|
||||
});
|
||||
|
||||
var eraseModelDimensions = Entities.getEntityProperties(eraser, "naturalDimensions").naturalDimensions;
|
||||
Entities.editEntity(eraser, {
|
||||
dimensions: eraseModelDimensions
|
||||
});
|
||||
Entities.editEntity(colorIndicatorBorder, {
|
||||
dimensions: colorIndicatorBorderDimensions
|
||||
});
|
||||
|
||||
scriptURL = Script.resolvePath("colorIndicatorEntityScript.js");
|
||||
var colorIndicatorPosition = Vec3.sum(center, {
|
||||
x: 0,
|
||||
y: whiteboardDimensions.y / 2 + colorIndicatorBorderDimensions.y / 2,
|
||||
y: whiteboardDimensions.y / 2 + colorIndicatorBorderDimensions.y * 2,
|
||||
z: 0
|
||||
});
|
||||
colorIndicatorPosition = Vec3.sum(colorIndicatorPosition, Vec3.multiply(-.1, Quat.getFront(rotation)));
|
||||
colorIndicatorPosition = Vec3.sum(colorIndicatorPosition, Vec3.multiply(-0.1, Quat.getFront(rotation)));
|
||||
var colorIndicatorBoxDimensions = Vec3.multiply(colorIndicatorBorderDimensions, 0.9);
|
||||
colorIndicatorBox = Entities.addEntity({
|
||||
type: "Box",
|
||||
name: "Color Indicator",
|
||||
name: "Whiteboard Color Indicator",
|
||||
color: colors[0],
|
||||
rotation: rotation,
|
||||
position: colorIndicatorPosition,
|
||||
|
@ -205,13 +200,13 @@ function setUp() {
|
|||
colorBoxPosition = Vec3.sum(colorBoxPosition, Vec3.multiply(palleteDepthOffset, Quat.getFront(rotation)));
|
||||
colorBoxPosition.y += palleteHeightOffset;
|
||||
var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 1.76);
|
||||
var palleteXOffset = Vec3.multiply(direction, 0.43);
|
||||
var palleteXOffset = Vec3.multiply(direction, 0.33);
|
||||
colorBoxPosition = Vec3.sum(colorBoxPosition, palleteXOffset);
|
||||
var scriptURL = Script.resolvePath("colorSelectorEntityScript.js");
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
var colorBox = Entities.addEntity({
|
||||
type: "Box",
|
||||
name: "Color Selector",
|
||||
name: "Whiteboard Color Selector",
|
||||
position: colorBoxPosition,
|
||||
dimensions: colorSquareDimensions,
|
||||
rotation: rotation,
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
/*global window, alert, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/
|
||||
/*global window, alert, EventBridge, dat, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/
|
||||
|
||||
var Settings = function() {
|
||||
this.exportSettings = function() {
|
||||
|
@ -65,8 +65,8 @@ var keysToIgnore = [
|
|||
'registrationPoint',
|
||||
'angularVelocity',
|
||||
'angularDamping',
|
||||
'ignoreForCollisions',
|
||||
'collisionsWillMove',
|
||||
'collisionless',
|
||||
'dynamic',
|
||||
'href',
|
||||
'actionData',
|
||||
'marketplaceID',
|
||||
|
@ -502,11 +502,3 @@ function registerDOMElementsForListenerBlocking() {
|
|||
});
|
||||
}
|
||||
|
||||
///utility method for converting weird collisionWillMove type propertyies from binary to new Boolean()
|
||||
//
|
||||
// function convertBinaryToBoolean(value) {
|
||||
// if (value === 0) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
|
@ -58,7 +58,7 @@ for (var i = 0; i < planetTypes.length; i++) {
|
|||
angularDamping: 0.0,
|
||||
ignoreCollisions: false,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: false }));
|
||||
dynamic: false }));
|
||||
}
|
||||
|
||||
Script.setTimeout(createParticles, 1000);
|
||||
|
@ -82,7 +82,7 @@ function createParticles() {
|
|||
ignoreCollisions: false,
|
||||
damping: DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true }));
|
||||
dynamic: true }));
|
||||
}
|
||||
Script.update.connect(update);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ function spawnBoxes() {
|
|||
collisionSoundURL: collisionSoundURL,
|
||||
shapeType: "box",
|
||||
position: position,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
dimensions: {x: 1, y: 2, z: 3},
|
||||
velocity: {x: 0, y: -.01, z: 0},
|
||||
gravity: {x: 0, y: -2.5 - Math.random() * 6, z: 0}
|
||||
|
|
|
@ -102,7 +102,7 @@ function createOrUpdateLine(event) {
|
|||
sphereEntityID = Entities.addEntity({
|
||||
type: "Sphere",
|
||||
position: intersection.intersection,
|
||||
ignoreForCollisions: 1,
|
||||
collisionless: 1,
|
||||
dimensions: { x: 0.6, y: 0.6, z: 0.6 },
|
||||
color: { red: 0, green: 255, blue: 0 },
|
||||
lifetime: 15 // if someone crashes while pointing, don't leave the line there forever.
|
||||
|
|
|
@ -148,7 +148,7 @@ for (var i = 0; i < NUM_BALLS; i++) {
|
|||
ignoreCollisions: false,
|
||||
damping: DAMPING,
|
||||
lifetime: LIFETIME,
|
||||
collisionsWillMove: true }));
|
||||
dynamic: true }));
|
||||
}
|
||||
|
||||
var VEL_MAG = 2.0;
|
||||
|
|
|
@ -48,8 +48,8 @@ var selectedInputMenu = "";
|
|||
var selectedOutputMenu = "";
|
||||
|
||||
function setupAudioMenus() {
|
||||
Menu.addMenu("Tools > Audio");
|
||||
Menu.addSeparator("Tools > Audio","Output Audio Device");
|
||||
Menu.addMenu("Audio > Devices", "Advanced");
|
||||
Menu.addSeparator("Audio > Devices","Output Audio Device");
|
||||
|
||||
var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING);
|
||||
var outputDevices = AudioDevice.getOutputDevices();
|
||||
|
@ -63,7 +63,7 @@ function setupAudioMenus() {
|
|||
var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice);
|
||||
var menuItem = "Use " + outputDevices[i] + " for Output";
|
||||
Menu.addMenuItem({
|
||||
menuName: "Tools > Audio",
|
||||
menuName: "Audio > Devices",
|
||||
menuItemName: menuItem,
|
||||
isCheckable: true,
|
||||
isChecked: thisDeviceSelected
|
||||
|
@ -73,7 +73,7 @@ function setupAudioMenus() {
|
|||
}
|
||||
}
|
||||
|
||||
Menu.addSeparator("Tools > Audio","Input Audio Device");
|
||||
Menu.addSeparator("Audio > Devices","Input Audio Device");
|
||||
|
||||
var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING);
|
||||
var inputDevices = AudioDevice.getInputDevices();
|
||||
|
@ -87,7 +87,7 @@ function setupAudioMenus() {
|
|||
var thisDeviceSelected = (inputDevices[i] == selectedInputDevice);
|
||||
var menuItem = "Use " + inputDevices[i] + " for Input";
|
||||
Menu.addMenuItem({
|
||||
menuName: "Tools > Audio",
|
||||
menuName: "Audio > Devices",
|
||||
menuItemName: menuItem,
|
||||
isCheckable: true,
|
||||
isChecked: thisDeviceSelected
|
||||
|
@ -99,7 +99,7 @@ function setupAudioMenus() {
|
|||
}
|
||||
|
||||
function onDevicechanged() {
|
||||
Menu.removeMenu("Tools > Audio");
|
||||
Menu.removeMenu("Audio > Devices");
|
||||
setupAudioMenus();
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ Script.setTimeout(function () {
|
|||
}, 5000);
|
||||
|
||||
function scriptEnding() {
|
||||
Menu.removeMenu("Tools > Audio");
|
||||
Menu.removeMenu("Audio > Devices");
|
||||
}
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ function makeNewStick() {
|
|||
damping: .1,
|
||||
collisionSoundURL: "http://public.highfidelity.io/sounds/Collisions-hitsandslaps/67LCollision07.wav",
|
||||
restitution: 0.01,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
actionID = Entities.addAction("hold", stickID,
|
||||
{relativePosition: {x: 0.0, y: 0.0, z: -0.5},
|
||||
|
|
|
@ -37,7 +37,7 @@ function makeNewStick() {
|
|||
damping: .1,
|
||||
collisionSoundURL: "http://public.highfidelity.io/sounds/Collisions-hitsandslaps/67LCollision07.wav",
|
||||
restitution: 0.01,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
actionID = Entities.addAction("hold", stickID, {relativePosition: {x: 0.0, y: 0.0, z: -0.9},
|
||||
hand: hand,
|
||||
|
|
148
examples/tests/avatarAttachmentTest.js
Normal file
148
examples/tests/avatarAttachmentTest.js
Normal file
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// avatarAttachmentTest.js
|
||||
// examples/tests
|
||||
//
|
||||
// Created by Anthony Thibault on January 7, 2016
|
||||
// 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
|
||||
//
|
||||
|
||||
// Test for MyAvatar attachment API
|
||||
// MyAvatar.setAttachmentData();
|
||||
// MyAvatar.getAttachmentData();
|
||||
|
||||
// Toggle button helper
|
||||
function ToggleButtonBuddy(x, y, width, height, urls) {
|
||||
this.up = Overlays.addOverlay("image", {
|
||||
x: x, y: y, width: width, height: height,
|
||||
subImage: { x: 0, y: height, width: width, height: height},
|
||||
imageURL: urls.up,
|
||||
visible: true,
|
||||
alpha: 1.0
|
||||
});
|
||||
this.down = Overlays.addOverlay("image", {
|
||||
x: x, y: y, width: width, height: height,
|
||||
subImage: { x: 0, y: height, width: width, height: height},
|
||||
imageURL: urls.down,
|
||||
visible: false,
|
||||
alpha: 1.0
|
||||
});
|
||||
this.callbacks = [];
|
||||
|
||||
var self = this;
|
||||
Controller.mousePressEvent.connect(function (event) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
||||
if (clickedOverlay === self.up) {
|
||||
// flip visiblity
|
||||
Overlays.editOverlay(self.up, {visible: false});
|
||||
Overlays.editOverlay(self.down, {visible: true});
|
||||
self.onToggle(true);
|
||||
} else if (clickedOverlay === self.down) {
|
||||
// flip visiblity
|
||||
Overlays.editOverlay(self.up, {visible: true});
|
||||
Overlays.editOverlay(self.down, {visible: false});
|
||||
self.onToggle(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
ToggleButtonBuddy.prototype.destroy = function () {
|
||||
Overlays.deleteOverlay(this.up);
|
||||
Overlays.deleteOverlay(this.down);
|
||||
};
|
||||
ToggleButtonBuddy.prototype.addToggleHandler = function (callback) {
|
||||
this.callbacks.push(callback);
|
||||
return callback;
|
||||
};
|
||||
ToggleButtonBuddy.prototype.removeToggleHandler = function (callback) {
|
||||
var index = this.callbacks.indexOf(callback);
|
||||
if (index != -1) {
|
||||
this.callbacks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
ToggleButtonBuddy.prototype.onToggle = function (isDown) {
|
||||
var i, l = this.callbacks.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
this.callbacks[i](isDown);
|
||||
}
|
||||
};
|
||||
|
||||
var windowDimensions = Controller.getViewportDimensions();
|
||||
var BUTTON_WIDTH = 64;
|
||||
var BUTTON_HEIGHT = 64;
|
||||
var BUTTON_PADDING = 10;
|
||||
var buttonPositionX = windowDimensions.x - BUTTON_PADDING - BUTTON_WIDTH;
|
||||
var buttonPositionY = (windowDimensions.y - BUTTON_HEIGHT) / 2 - (BUTTON_HEIGHT + BUTTON_PADDING);
|
||||
|
||||
var hatButton = new ToggleButtonBuddy(buttonPositionX, buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, {
|
||||
up: "https://s3.amazonaws.com/hifi-public/tony/icons/hat-up.svg",
|
||||
down: "https://s3.amazonaws.com/hifi-public/tony/icons/hat-down.svg"
|
||||
});
|
||||
|
||||
buttonPositionY += BUTTON_HEIGHT + BUTTON_PADDING;
|
||||
var coatButton = new ToggleButtonBuddy(buttonPositionX, buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, {
|
||||
up: "https://s3.amazonaws.com/hifi-public/tony/icons/coat-up.svg",
|
||||
down: "https://s3.amazonaws.com/hifi-public/tony/icons/coat-down.svg"
|
||||
});
|
||||
|
||||
var HAT_ATTACHMENT = {
|
||||
modelURL: "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx",
|
||||
jointName: "Head",
|
||||
translation: {"x": 0, "y": 0.2, "z": 0},
|
||||
rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
|
||||
scale: 1,
|
||||
isSoft: false
|
||||
};
|
||||
|
||||
var COAT_ATTACHMENT = {
|
||||
modelURL: "https://hifi-content.s3.amazonaws.com/ozan/dev/clothes/coat/coat_rig.fbx",
|
||||
jointName: "Hips",
|
||||
translation: {"x": 0, "y": 0, "z": 0},
|
||||
rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
|
||||
scale: 1,
|
||||
isSoft: true
|
||||
};
|
||||
|
||||
hatButton.addToggleHandler(function (isDown) {
|
||||
if (isDown) {
|
||||
wearAttachment(HAT_ATTACHMENT);
|
||||
} else {
|
||||
removeAttachment(HAT_ATTACHMENT);
|
||||
}
|
||||
});
|
||||
|
||||
coatButton.addToggleHandler(function (isDown) {
|
||||
if (isDown) {
|
||||
wearAttachment(COAT_ATTACHMENT);
|
||||
} else {
|
||||
removeAttachment(COAT_ATTACHMENT);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function wearAttachment(attachment) {
|
||||
MyAvatar.attach(attachment.modelURL,
|
||||
attachment.jointName,
|
||||
attachment.translation,
|
||||
attachment.rotation,
|
||||
attachment.scale,
|
||||
attachment.isSoft);
|
||||
}
|
||||
|
||||
function removeAttachment(attachment) {
|
||||
var attachments = MyAvatar.attachmentData;
|
||||
var i, l = attachments.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
if (attachments[i].modelURL === attachment.modelURL) {
|
||||
attachments.splice(i, 1);
|
||||
MyAvatar.attachmentData = attachments;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
hatButton.destroy();
|
||||
coatbutton.destroy();
|
||||
});
|
124
examples/tests/performance/renderableMatrix.js
Normal file
124
examples/tests/performance/renderableMatrix.js
Normal file
|
@ -0,0 +1,124 @@
|
|||
"use strict";
|
||||
/*jslint nomen: true, plusplus: true, vars: true*/
|
||||
var Entities, Script, print, Vec3, MyAvatar, Camera, Quat;
|
||||
//
|
||||
// Created by Howard Stearns
|
||||
// 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
|
||||
//
|
||||
// Creates a rectangular matrix of objects with no physical or entity changes after creation.
|
||||
// Useful for testing the rendering, LOD, and octree storage aspects of the system.
|
||||
//
|
||||
|
||||
var LIFETIME = 60;
|
||||
// Matrix will be axis-aligned, approximately all in this field of view.
|
||||
// As special case, if zero, grid is centered above your head.
|
||||
var MINIMUM_VIEW_ANGLE_IN_RADIANS = 30 * Math.PI / 180; // 30 degrees
|
||||
var ROWS_X = 10;
|
||||
var ROWS_Y = 10;
|
||||
var ROWS_Z = 10;
|
||||
var SEPARATION = 10;
|
||||
var SIZE = 1;
|
||||
var TYPES_TO_USE = [ // Entities will be populated from this list set by the script writer for different tests.
|
||||
'Box',
|
||||
'Sphere',
|
||||
//'Light',
|
||||
//'ParticleEffect',
|
||||
//'Web',
|
||||
//"https://hifi-content.s3.amazonaws.com/ozan/dev/sets/lowpoly_island/CypressTreeGroup.fbx",
|
||||
//"http://s3.amazonaws.com/hifi-public/marketplace/hificontent/Games/blocks/block.fbx",
|
||||
];
|
||||
var MODEL_SCALE = { x: 1, y: 2, z: 3 }; // how to stretch out models proportionally to SIZE
|
||||
// Note that when creating things quickly, the entity server will ignore data if we send updates too quickly.
|
||||
// like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND
|
||||
// variable letting you set this speed. If entities are missing from the grid after a relog, this number
|
||||
// being too high may be the reason.
|
||||
var RATE_PER_SECOND = 1000; // The entity server will drop data if we create things too fast.
|
||||
var SCRIPT_INTERVAL = 100;
|
||||
|
||||
var ALLOWED_TYPES = ['Box', 'Sphere', 'Light', 'ParticleEffect', 'Web']; // otherwise assumed to be a model url
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var z = 0;
|
||||
var xDim = ROWS_X * SEPARATION;
|
||||
var yDim = ROWS_Y * SEPARATION;
|
||||
var zDim = ROWS_Z * SEPARATION;
|
||||
var centered = !MINIMUM_VIEW_ANGLE_IN_RADIANS;
|
||||
var approximateNearDistance = !centered &&
|
||||
Math.max(xDim, 2 * yDim, zDim) / (2 * Math.tan(MINIMUM_VIEW_ANGLE_IN_RADIANS / 2)); // matrix is up, not vertically centered
|
||||
var o = Vec3.sum(MyAvatar.position,
|
||||
Vec3.sum({x: xDim / -2, y: 0, z: zDim / -2},
|
||||
centered ? {x: 0, y: SEPARATION, z: 0} : Vec3.multiply(approximateNearDistance, Quat.getFront(Camera.orientation))));
|
||||
var totalCreated = 0;
|
||||
var startTime = new Date();
|
||||
var totalToCreate = ROWS_X * ROWS_Y * ROWS_Z;
|
||||
print("Creating " + totalToCreate + " entities starting at " + startTime);
|
||||
|
||||
Script.setInterval(function () {
|
||||
if (!Entities.serversExist() || !Entities.canRez()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var numToCreate = Math.min(RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0), totalToCreate - totalCreated);
|
||||
var chooseTypeRandomly = TYPES_TO_USE.length !== 2;
|
||||
var i, typeIndex, type, isModel, properties;
|
||||
for (i = 0; i < numToCreate; i++) {
|
||||
typeIndex = chooseTypeRandomly ? Math.floor(Math.random() * TYPES_TO_USE.length) : i % TYPES_TO_USE.length;
|
||||
type = TYPES_TO_USE[typeIndex];
|
||||
isModel = ALLOWED_TYPES.indexOf(type) === -1;
|
||||
properties = {
|
||||
position: { x: o.x + SIZE + (x * SEPARATION), y: o.y + SIZE + (y * SEPARATION), z: o.z + SIZE + (z * SEPARATION) },
|
||||
name: "renderable-" + x + "-" + y + "-" + z,
|
||||
type: isModel ? 'Model' : type,
|
||||
dimensions: isModel ? Vec3.multiply(SIZE, MODEL_SCALE) : { x: SIZE, y: SIZE, z: SIZE },
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
lifetime: LIFETIME
|
||||
};
|
||||
if (isModel) {
|
||||
properties.modelURL = type;
|
||||
} else if (type === 'Web') {
|
||||
properties.sourceUrl = 'https://highfidelity.com';
|
||||
} else {
|
||||
properties.color = { red: x / ROWS_X * 255, green: y / ROWS_Y * 255, blue: z / ROWS_Z * 255 };
|
||||
if (type === 'ParticleEffect') {
|
||||
properties.emitOrientation = Quat.fromPitchYawRollDegrees(-90.0, 0.0, 0.0);
|
||||
properties.particleRadius = 0.04;
|
||||
properties.radiusSpread = 0.0;
|
||||
properties.emitRate = 100;
|
||||
properties.emitSpeed = 1;
|
||||
properties.speedSpread = 0.0;
|
||||
properties.emitAcceleration = { x: 0.0, y: -0.3, z: 0.0 };
|
||||
properties.accelerationSpread = { x: 0.0, y: 0.0, z: 0.0 };
|
||||
properties.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png";
|
||||
properties.lifespan = 5.0;
|
||||
properties.colorStart = properties.color;
|
||||
properties.colorFinish = properties.color;
|
||||
properties.alphaFinish = 0.0;
|
||||
properties.polarFinish = 2.0 * Math.PI / 180;
|
||||
} else if (type === 'Light') {
|
||||
properties.dimensions = Vec3.multiply(SEPARATION, properties.position);
|
||||
}
|
||||
}
|
||||
Entities.addEntity(properties);
|
||||
totalCreated++;
|
||||
|
||||
x++;
|
||||
if (x === ROWS_X) {
|
||||
x = 0;
|
||||
y++;
|
||||
if (y === ROWS_Y) {
|
||||
y = 0;
|
||||
z++;
|
||||
print("Created: " + totalCreated);
|
||||
}
|
||||
}
|
||||
if (z === ROWS_Z) {
|
||||
print("Total: " + totalCreated + " entities in " + ((new Date() - startTime) / 1000.0) + " seconds.");
|
||||
Script.stop();
|
||||
}
|
||||
}
|
||||
}, SCRIPT_INTERVAL);
|
97
examples/tests/performance/staticEdits.js
Normal file
97
examples/tests/performance/staticEdits.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
"use strict";
|
||||
/*jslint nomen: true, plusplus: true, vars: true*/
|
||||
var Entities, Script, print, Vec3, MyAvatar;
|
||||
//
|
||||
// Created by Howard Stearns
|
||||
// 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
|
||||
//
|
||||
// Creates a rectangular matrix of objects overhed, and edits them at EDIT_FREQUENCY_TARGET.
|
||||
// Reports ms since last edit, ms to edit all the created entities, and average ms to edit one entity,
|
||||
// so that you can measure how many edits can be made.
|
||||
//
|
||||
var LIFETIME = 15;
|
||||
var EDIT_FREQUENCY_TARGET = 60; // hertz
|
||||
var ROWS_X = 10;
|
||||
var ROWS_Y = 1;
|
||||
var ROWS_Z = 10;
|
||||
var SEPARATION = 10.0;
|
||||
var SIZE = 1.0;
|
||||
// Note that when creating things quickly, the entity server will ignore data if we send updates too quickly.
|
||||
// like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND
|
||||
// variable letting you set this speed. If entities are missing from the grid after a relog, this number
|
||||
// being too high may be the reason.
|
||||
var RATE_PER_SECOND = 600; // The entity server will drop data if we create things too fast.
|
||||
var SCRIPT_INTERVAL = 100;
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var z = 0;
|
||||
var o = Vec3.sum(MyAvatar.position, {x: ROWS_X * SEPARATION / -2, y: SEPARATION, z: ROWS_Z * SEPARATION / -2});
|
||||
var totalCreated = 0;
|
||||
var startTime = new Date();
|
||||
var totalToCreate = ROWS_X * ROWS_Y * ROWS_Z;
|
||||
print("Creating " + totalToCreate + " entities starting at " + startTime);
|
||||
|
||||
var ids = [], colors = [], flasher, lastService = Date.now();
|
||||
function doFlash() { // One could call this in an interval timer, an update, or even a separate entity script.
|
||||
var i, oldColor, newColor;
|
||||
var start = Date.now();
|
||||
for (i = 0; i < ids.length; i++) {
|
||||
oldColor = colors[i];
|
||||
newColor = {red: oldColor.green, green: oldColor.blue, blue: oldColor.red};
|
||||
colors[i] = newColor;
|
||||
Entities.editEntity(ids[i], {color: newColor});
|
||||
}
|
||||
var elapsed = Date.now() - start, serviceTime = start - lastService;
|
||||
lastService = start;
|
||||
print(serviceTime, elapsed, elapsed / totalCreated); // ms since last flash, ms to edit all entities, average ms to edit one entity
|
||||
}
|
||||
function stopFlash() {
|
||||
Script.clearTimeout(flasher);
|
||||
Script.stop();
|
||||
}
|
||||
var creator = Script.setInterval(function () {
|
||||
if (!Entities.serversExist() || !Entities.canRez()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var numToCreate = Math.min(RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0), totalToCreate - totalCreated);
|
||||
var i, properties;
|
||||
for (i = 0; i < numToCreate; i++) {
|
||||
properties = {
|
||||
position: { x: o.x + SIZE + (x * SEPARATION), y: o.y + SIZE + (y * SEPARATION), z: o.z + SIZE + (z * SEPARATION) },
|
||||
name: "gridTest",
|
||||
type: 'Box',
|
||||
dimensions: {x: SIZE, y: SIZE, z: SIZE},
|
||||
ignoreCollisions: true,
|
||||
collisionsWillMove: false,
|
||||
lifetime: LIFETIME,
|
||||
color: {red: x / ROWS_X * 255, green: y / ROWS_Y * 255, blue: z / ROWS_Z * 255}
|
||||
};
|
||||
colors.push(properties.color);
|
||||
ids.push(Entities.addEntity(properties));
|
||||
totalCreated++;
|
||||
|
||||
x++;
|
||||
if (x === ROWS_X) {
|
||||
x = 0;
|
||||
y++;
|
||||
if (y === ROWS_Y) {
|
||||
y = 0;
|
||||
z++;
|
||||
print("Created: " + totalCreated);
|
||||
}
|
||||
}
|
||||
if (z === ROWS_Z) {
|
||||
print("Total: " + totalCreated + " entities in " + ((new Date() - startTime) / 1000.0) + " seconds.");
|
||||
Script.clearTimeout(creator);
|
||||
flasher = Script.setInterval(doFlash, Math.ceil((1 / EDIT_FREQUENCY_TARGET) * 1000));
|
||||
Script.setTimeout(stopFlash, LIFETIME * 1000);
|
||||
}
|
||||
}
|
||||
}, SCRIPT_INTERVAL);
|
||||
Script.scriptEnding.connect(function () { Script.clearTimeout(flasher); });
|
||||
|
96
examples/tests/performance/tribbles.js
Normal file
96
examples/tests/performance/tribbles.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
"use strict";
|
||||
/*jslint nomen: true, plusplus: true, vars: true*/
|
||||
var Vec3, Quat, MyAvatar, Entities, Camera, Script, print;
|
||||
//
|
||||
// Created by Howard Stearns
|
||||
// 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
|
||||
//
|
||||
// Drops a bunch of physical spheres in front of you, each running a script that will:
|
||||
// * Edit color at EDIT_RATE for EDIT_TIMEOUT.
|
||||
// * Randomly move at an average of MOVE_RATE for MOVE_TIMEOUT.
|
||||
// The _TIMEOUT parameters can be 0 for no activity, and -1 to be active indefinitely.
|
||||
//
|
||||
|
||||
var NUMBER_TO_CREATE = 120;
|
||||
var LIFETIME = 60; // seconds
|
||||
var EDIT_RATE = 60; // hz
|
||||
var EDIT_TIMEOUT = -1;
|
||||
var MOVE_RATE = 1; // hz
|
||||
var MOVE_TIMEOUT = LIFETIME / 2;
|
||||
|
||||
var SIZE = 0.5;
|
||||
var TYPE = "Sphere";
|
||||
// Note that when creating things quickly, the entity server will ignore data if we send updates too quickly.
|
||||
// like Internet MTU, these rates are set by th domain operator, so in this script there is a RATE_PER_SECOND
|
||||
// variable letting you set this speed. If entities are missing from the grid after a relog, this number
|
||||
// being too high may be the reason.
|
||||
var RATE_PER_SECOND = 600; // The entity server will drop data if we create things too fast.
|
||||
var SCRIPT_INTERVAL = 100;
|
||||
|
||||
var GRAVITY = { x: 0, y: -9.8, z: 0 };
|
||||
var VELOCITY = { x: 0.0, y: 0, z: 0 };
|
||||
var ANGULAR_VELOCITY = { x: 1, y: 1, z: 1 };
|
||||
|
||||
var DAMPING = 0.5;
|
||||
var ANGULAR_DAMPING = 0.5;
|
||||
|
||||
var RANGE = 3;
|
||||
var HOW_FAR_IN_FRONT_OF_ME = RANGE * 3;
|
||||
var HOW_FAR_UP = RANGE / 1.5; // higher (for uneven ground) above range/2 (for distribution)
|
||||
|
||||
var x = 0;
|
||||
var z = 0;
|
||||
var totalCreated = 0;
|
||||
var offset = Vec3.sum(Vec3.multiply(HOW_FAR_UP, Vec3.UNIT_Y),
|
||||
Vec3.multiply(HOW_FAR_IN_FRONT_OF_ME, Quat.getFront(Camera.orientation)));
|
||||
var center = Vec3.sum(MyAvatar.position, offset);
|
||||
|
||||
function randomVector(range) {
|
||||
return {
|
||||
x: (Math.random() - 0.5) * range.x,
|
||||
y: (Math.random() - 0.5) * range.y,
|
||||
z: (Math.random() - 0.5) * range.z
|
||||
};
|
||||
}
|
||||
|
||||
Script.setInterval(function () {
|
||||
if (!Entities.serversExist() || !Entities.canRez()) {
|
||||
return;
|
||||
}
|
||||
if (totalCreated >= NUMBER_TO_CREATE) {
|
||||
print("Created " + totalCreated + " tribbles.");
|
||||
Script.stop();
|
||||
}
|
||||
|
||||
var i, numToCreate = RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0);
|
||||
var parameters = JSON.stringify({
|
||||
moveTimeout: MOVE_TIMEOUT,
|
||||
moveRate: MOVE_RATE,
|
||||
editTimeout: EDIT_TIMEOUT,
|
||||
editRate: EDIT_RATE
|
||||
});
|
||||
for (i = 0; (i < numToCreate) && (totalCreated < NUMBER_TO_CREATE); i++) {
|
||||
Entities.addEntity({
|
||||
userData: parameters,
|
||||
type: TYPE,
|
||||
name: "tribble-" + totalCreated,
|
||||
position: Vec3.sum(center, randomVector({ x: RANGE, y: RANGE, z: RANGE })),
|
||||
dimensions: {x: SIZE, y: SIZE, z: SIZE},
|
||||
color: {red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255},
|
||||
velocity: VELOCITY,
|
||||
angularVelocity: Vec3.multiply(Math.random(), ANGULAR_VELOCITY),
|
||||
damping: DAMPING,
|
||||
angularDamping: ANGULAR_DAMPING,
|
||||
gravity: GRAVITY,
|
||||
collisionsWillMove: true,
|
||||
lifetime: LIFETIME,
|
||||
script: "https://s3.amazonaws.com/hifi-public/scripts/entityScripts/tribble.js"
|
||||
});
|
||||
|
||||
totalCreated++;
|
||||
}
|
||||
}, SCRIPT_INTERVAL);
|
||||
|
|
@ -47,8 +47,8 @@ var rack = Entities.addEntity({
|
|||
y: 1.37,
|
||||
z: 1.73
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
ignoreForCollisions: false,
|
||||
dynamic: true,
|
||||
collisionless: false,
|
||||
collisionSoundURL: collisionSoundURL,
|
||||
compoundShapeURL: rackCollisionHullURL,
|
||||
userData: JSON.stringify({
|
||||
|
@ -89,8 +89,8 @@ function createBalls() {
|
|||
y: -9.8,
|
||||
z: 0
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
ignoreForCollisions: false,
|
||||
dynamic: true,
|
||||
collisionless: false,
|
||||
modelURL: basketballURL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
|
@ -150,4 +150,4 @@ function atEnd() {
|
|||
Script.clearInterval(distanceCheckInterval);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(atEnd);
|
||||
Script.scriptEnding.connect(atEnd);
|
||||
|
|
|
@ -42,7 +42,7 @@ function makeBasketball() {
|
|||
y: DIAMETER,
|
||||
z: DIAMETER
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
collisionSoundURL: collisionSoundURL,
|
||||
modelURL: basketballURL,
|
||||
restitution: 1.0,
|
||||
|
@ -94,4 +94,4 @@ function deleteStuff() {
|
|||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -90,7 +90,7 @@ var topBlock = Entities.addEntity({
|
|||
rotation: topBlock_rotation,
|
||||
damping: LINEAR_DAMPING,
|
||||
gravity: BLOCK_GRAVITY,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.01,
|
||||
|
@ -108,7 +108,7 @@ var sideBlock1 = Entities.addEntity({
|
|||
rotation: sideBlock1_rotation,
|
||||
damping: LINEAR_DAMPING,
|
||||
gravity: BLOCK_GRAVITY,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
|
||||
var sideBlock2 = Entities.addEntity({
|
||||
|
@ -119,10 +119,10 @@ var sideBlock2 = Entities.addEntity({
|
|||
dimensions: blockDimensions,
|
||||
position: sideBlock2_position,
|
||||
rotation: sideBlock2_rotation,
|
||||
collsionsWillMove: true,
|
||||
dynamic: true,
|
||||
damping: LINEAR_DAMPING,
|
||||
gravity: BLOCK_GRAVITY,
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
|
||||
var ground = Entities.addEntity({
|
||||
|
|
|
@ -234,8 +234,8 @@
|
|||
compoundShapeURL: ARROW_COLLISION_HULL_URL,
|
||||
dimensions: ARROW_DIMENSIONS,
|
||||
position: this.bowProperties.position,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
collisionSoundURL: ARROW_HIT_SOUND_URL,
|
||||
damping: 0.01,
|
||||
userData: JSON.stringify({
|
||||
|
@ -264,7 +264,7 @@
|
|||
z: 0
|
||||
},
|
||||
position: collision.contactPoint,
|
||||
collisionsWillMove: false
|
||||
dynamic: false
|
||||
})
|
||||
// print('ARROW COLLIDED WITH::' + entityB);
|
||||
Script.removeEventHandler(arrow, "collisionWithEntity", makeArrowStick)
|
||||
|
@ -286,8 +286,8 @@
|
|||
type: 'Line',
|
||||
position: Vec3.sum(this.bowProperties.position, TOP_NOTCH_OFFSET),
|
||||
dimensions: LINE_DIMENSIONS,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
|
@ -304,8 +304,8 @@
|
|||
type: 'Line',
|
||||
position: Vec3.sum(this.bowProperties.position, BOTTOM_NOTCH_OFFSET),
|
||||
dimensions: LINE_DIMENSIONS,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
|
@ -389,8 +389,8 @@
|
|||
position: Vec3.sum(this.bowProperties.position, TOP_NOTCH_OFFSET),
|
||||
dimensions: LINE_DIMENSIONS,
|
||||
visible: true,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
|
@ -538,8 +538,9 @@
|
|||
|
||||
//make the arrow physical, give it gravity, a lifetime, and set our velocity
|
||||
var arrowProperties = {
|
||||
collisionsWillMove: true,
|
||||
ignoreForCollisions: false,
|
||||
dynamic: true,
|
||||
collisionless: false,
|
||||
collisionMask: "static,dynamic,otherAvatar", // workaround: not with kinematic --> no collision with bow
|
||||
velocity: releaseVelocity,
|
||||
gravity: ARROW_GRAVITY,
|
||||
lifetime: 10,
|
||||
|
@ -612,4 +613,4 @@
|
|||
};
|
||||
|
||||
return new Bow();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ var bow = Entities.addEntity({
|
|||
modelURL: MODEL_URL,
|
||||
position: center,
|
||||
dimensions: BOW_DIMENSIONS,
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
gravity: BOW_GRAVITY,
|
||||
shapeType: 'compound',
|
||||
compoundShapeURL: COLLISION_HULL_URL,
|
||||
|
@ -68,4 +68,4 @@ function cleanup() {
|
|||
Entities.deleteEntity(bow);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
|
|
|
@ -41,7 +41,7 @@ var wand = Entities.addEntity({
|
|||
z: 0.05
|
||||
},
|
||||
//must be enabled to be grabbable in the physics engine
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
compoundShapeURL: WAND_COLLISION_SHAPE,
|
||||
script: WAND_SCRIPT_URL,
|
||||
userData: JSON.stringify({
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
addCollisionsToBubbleAfterCreation: function(bubble) {
|
||||
//if the bubble collide immediately, we get weird effects. so we add collisions after release
|
||||
Entities.editEntity(bubble, {
|
||||
collisionsWillMove: true
|
||||
dynamic: true
|
||||
});
|
||||
},
|
||||
randomizeBubbleGravity: function() {
|
||||
|
@ -161,8 +161,8 @@
|
|||
modelURL: BUBBLE_MODEL,
|
||||
position: this.getWandTipPosition(properties),
|
||||
dimensions: BUBBLE_INITIAL_DIMENSIONS,
|
||||
collisionsWillMove: false,
|
||||
ignoreForCollisions: true,
|
||||
dynamic: false,
|
||||
collisionless: true,
|
||||
damping: BUBBLE_LINEAR_DAMPING,
|
||||
shapeType: "sphere"
|
||||
});
|
||||
|
@ -198,4 +198,4 @@
|
|||
|
||||
return new BubbleWand();
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -47,7 +47,7 @@ function createDoll() {
|
|||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
|
@ -57,4 +57,4 @@ function createDoll() {
|
|||
return doll;
|
||||
}
|
||||
|
||||
createDoll();
|
||||
createDoll();
|
||||
|
|
|
@ -33,7 +33,7 @@ var flashlight = Entities.addEntity({
|
|||
y: 0.30,
|
||||
z: 0.08
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
shapeType: 'box',
|
||||
script: scriptURL,
|
||||
userData: JSON.stringify({
|
||||
|
@ -41,4 +41,4 @@ var flashlight = Entities.addEntity({
|
|||
invertSolidWhileHeld: true
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,7 +34,7 @@ var pingPongGun = Entities.addEntity({
|
|||
y: 0.21,
|
||||
z: 0.47
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
dynamic: true,
|
||||
collisionSoundURL: COLLISION_SOUND_URL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
|
@ -54,4 +54,4 @@ var pingPongGun = Entities.addEntity({
|
|||
function cleanUp() {
|
||||
Entities.deleteEntity(pingPongGun);
|
||||
}
|
||||
Script.scriptEnding.connect(cleanUp);
|
||||
Script.scriptEnding.connect(cleanUp);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue