Merge pull request #6003 from imgntn/basketball_rack

[Scripts] Basketball rack
This commit is contained in:
Eric Levin 2015-10-07 10:59:20 -07:00
commit f01d4dde42
4 changed files with 332 additions and 29 deletions

View file

@ -1,12 +1,10 @@
// //
// createHoop.js // createHoop.js
// examples/entityScripts
// //
// Created by James B. Pollack on 9/29/2015 // Created by James B. Pollack on 9/29/2015
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
// //
// This is a script that creates a persistent basketball hoop with a working collision hull. Feel free to move it. // This is a script that creates a persistent basketball hoop with a working collision hull. Feel free to move it.
// Run basketball.js to make a basketball.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html

View file

@ -0,0 +1,152 @@
//
// createRack.js
//
// Created by James B. Pollack @imgntn on 10/5/2015
// Copyright 2015 High Fidelity, Inc.
//
// This is a script that creates a persistent basketball rack.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
Script.include("../../libraries/utils.js");
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx";
var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav";
var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx";
var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj";
var NUMBER_OF_BALLS = 4;
var DIAMETER = 0.30;
var RESET_DISTANCE = 1;
var MINIMUM_MOVE_LENGTH = 0.05;
var GRABBABLE_DATA_KEY = "grabbableKey";
var rackStartPosition =
Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, {
x: 0,
y: 0.0,
z: -2
}));
var rack = Entities.addEntity({
name: 'Basketball Rack',
type: "Model",
modelURL: rackURL,
position: rackStartPosition,
shapeType: 'compound',
gravity: {
x: 0,
y: -9.8,
z: 0
},
linearDamping: 1,
dimensions: {
x: 0.4,
y: 1.37,
z: 1.73
},
collisionsWillMove: true,
ignoreForCollisions: false,
collisionSoundURL: collisionSoundURL,
compoundShapeURL: rackCollisionHullURL,
// scriptURL: rackScriptURL
});
setEntityCustomData(GRABBABLE_DATA_KEY, rack, {
grabbable: false
});
var nonCollidingBalls = [];
var collidingBalls = [];
var originalBallPositions = [];
function createCollidingBalls() {
var position = rackStartPosition;
var i;
for (i = 0; i < NUMBER_OF_BALLS; i++) {
var ballPosition = {
x: position.x,
y: position.y + DIAMETER * 2,
z: position.z + (DIAMETER) - (DIAMETER * i)
};
var collidingBall = Entities.addEntity({
type: "Model",
name: 'Colliding Basketball',
shapeType: 'Sphere',
position: ballPosition,
dimensions: {
x: DIAMETER,
y: DIAMETER,
z: DIAMETER
},
restitution: 1.0,
linearDamping: 0.00001,
gravity: {
x: 0,
y: -9.8,
z: 0
},
collisionsWillMove: true,
ignoreForCollisions: false,
modelURL: basketballURL,
});
collidingBalls.push(collidingBall);
originalBallPositions.push(position);
}
}
function testBallDistanceFromStart() {
var resetCount = 0;
collidingBalls.forEach(function(ball, index) {
var currentPosition = Entities.getEntityProperties(ball, "position").position;
var originalPosition = originalBallPositions[index];
var distance = Vec3.subtract(originalPosition, currentPosition);
var length = Vec3.length(distance);
if (length > RESET_DISTANCE) {
Script.setTimeout(function() {
var newPosition = Entities.getEntityProperties(ball, "position").position;
var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition));
if (moving < MINIMUM_MOVE_LENGTH) {
resetCount++;
if (resetCount === NUMBER_OF_BALLS) {
deleteCollidingBalls();
createCollidingBalls();
}
}
}, 200)
}
});
}
function deleteEntity(entityID) {
if (entityID === rack) {
deleteCollidingBalls();
Script.clearInterval(distanceCheckInterval);
Entities.deletingEntity.disconnect(deleteEntity);
}
}
function deleteCollidingBalls() {
while (collidingBalls.length > 0) {
Entities.deleteEntity(collidingBalls.pop());
}
}
createCollidingBalls();
Entities.deletingEntity.connect(deleteEntity);
var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000);
function atEnd() {
Script.clearInterval(distanceCheckInterval);
}
Script.scriptEnding.connect(atEnd);

View file

@ -1,5 +1,5 @@
// //
// basketball.js // createSingleBasketball.js
// examples // examples
// //
// Created by Philip Rosedale on August 20, 2015 // Created by Philip Rosedale on August 20, 2015
@ -17,34 +17,39 @@ var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav";
var basketball = null; var basketball = null;
var originalPosition = null; var originalPosition = null;
var hasMoved = false; var hasMoved = false;
var GRAVITY = -9.8; var GRAVITY = -9.8;
var DISTANCE_IN_FRONT_OF_ME = 1.0; var DISTANCE_IN_FRONT_OF_ME = 1.0;
var START_MOVE = 0.01; var START_MOVE = 0.01;
var DIAMETER = 0.30; var DIAMETER = 0.30;
function makeBasketball() { function makeBasketball() {
var position = Vec3.sum(MyAvatar.position, var position = Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, Vec3.multiplyQbyV(MyAvatar.orientation, {
{ x: 0, y: 0.0, z: -DISTANCE_IN_FRONT_OF_ME })); x: 0,
y: 0.0,
z: -DISTANCE_IN_FRONT_OF_ME
}));
var rotation = Quat.multiply(MyAvatar.orientation, var rotation = Quat.multiply(MyAvatar.orientation,
Quat.fromPitchYawRollDegrees(0, -90, 0)); Quat.fromPitchYawRollDegrees(0, -90, 0));
basketball = Entities.addEntity({ basketball = Entities.addEntity({
type: "Model", type: "Model",
position: position, position: position,
rotation: rotation, rotation: rotation,
dimensions: { x: DIAMETER, dimensions: {
y: DIAMETER, x: DIAMETER,
z: DIAMETER }, y: DIAMETER,
collisionsWillMove: true, z: DIAMETER
collisionSoundURL: collisionSoundURL, },
modelURL: basketballURL, collisionsWillMove: true,
restitution: 1.0, collisionSoundURL: collisionSoundURL,
linearDamping: 0.00001, modelURL: basketballURL,
shapeType: "sphere" restitution: 1.0,
}); linearDamping: 0.00001,
originalPosition = position; shapeType: "sphere"
});
originalPosition = position;
} }
function update() { function update() {
@ -55,28 +60,33 @@ function update() {
var moved = Vec3.length(Vec3.subtract(originalPosition, newProperties.position)); var moved = Vec3.length(Vec3.subtract(originalPosition, newProperties.position));
if (!hasMoved && (moved > START_MOVE)) { if (!hasMoved && (moved > START_MOVE)) {
hasMoved = true; hasMoved = true;
Entities.editEntity(basketball, { gravity: {x: 0, y: GRAVITY, z: 0 }}); Entities.editEntity(basketball, {
gravity: {
x: 0,
y: GRAVITY,
z: 0
}
});
} }
var MAX_DISTANCE = 10.0; var MAX_DISTANCE = 10.0;
var distance = Vec3.length(Vec3.subtract(MyAvatar.position, newProperties.position)); var distance = Vec3.length(Vec3.subtract(MyAvatar.position, newProperties.position));
if (distance > MAX_DISTANCE) { if (distance > MAX_DISTANCE) {
deleteStuff(); deleteStuff();
} }
} }
} }
function scriptEnding() { function scriptEnding() {
deleteStuff(); deleteStuff();
} }
function deleteStuff() { function deleteStuff() {
if (basketball != null) { if (basketball != null) {
Entities.deleteEntity(basketball); Entities.deleteEntity(basketball);
basketball = null; basketball = null;
hasMoved = false; hasMoved = false;
} }
} }
Script.update.connect(update); Script.update.connect(update);
Script.scriptEnding.connect(scriptEnding); Script.scriptEnding.connect(scriptEnding);

View file

@ -86,6 +86,8 @@ function createAllToys() {
createBasketballHoop(); createBasketballHoop();
createBasketballRack();
createGates(); createGates();
createFire(); createFire();
@ -673,6 +675,147 @@ function createBasketballHoop() {
}); });
} }
function createBasketballRack() {
var NUMBER_OF_BALLS = 4;
var DIAMETER = 0.30;
var RESET_DISTANCE = 1;
var MINIMUM_MOVE_LENGTH = 0.05;
var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx";
var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav";
var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx";
var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj";
var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0);
var rackStartPosition = {
x: 542.86,
y: 494.84,
z: 475.06
};
var rack = Entities.addEntity({
name: 'Basketball Rack',
type: "Model",
modelURL: rackURL,
position: rackStartPosition,
rotation: rackRotation,
shapeType: 'compound',
gravity: {
x: 0,
y: -9.8,
z: 0
},
linearDamping: 1,
dimensions: {
x: 0.4,
y: 1.37,
z: 1.73
},
collisionsWillMove: true,
ignoreForCollisions: false,
compoundShapeURL: rackCollisionHullURL
});
setEntityCustomData(resetKey, rack, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, rack, {
grabbable: false
});
var collidingBalls = [];
var originalBallPositions = [];
function createCollidingBalls() {
var position = rackStartPosition;
var i;
for (i = 0; i < NUMBER_OF_BALLS; i++) {
var ballPosition = {
x: position.x,
y: position.y + DIAMETER * 2,
z: position.z + (DIAMETER) - (DIAMETER * i)
};
var collidingBall = Entities.addEntity({
type: "Model",
name: 'Colliding Basketball',
shapeType: 'Sphere',
position: {
x: position.x + (DIAMETER * 2) - (DIAMETER * i),
y: position.y + DIAMETER * 2,
z: position.z
},
dimensions: {
x: DIAMETER,
y: DIAMETER,
z: DIAMETER
},
restitution: 1.0,
linearDamping: 0.00001,
gravity: {
x: 0,
y: -9.8,
z: 0
},
collisionsWillMove: true,
ignoreForCollisions: false,
modelURL: basketballURL,
});
collidingBalls.push(collidingBall);
originalBallPositions.push(position);
}
}
function testBallDistanceFromStart() {
var resetCount = 0;
collidingBalls.forEach(function(ball, index) {
var currentPosition = Entities.getEntityProperties(ball, "position").position;
var originalPosition = originalBallPositions[index];
var distance = Vec3.subtract(originalPosition, currentPosition);
var length = Vec3.length(distance);
if (length > RESET_DISTANCE) {
Script.setTimeout(function() {
var newPosition = Entities.getEntityProperties(ball, "position").position;
var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition));
if (moving < MINIMUM_MOVE_LENGTH) {
resetCount++;
if (resetCount === NUMBER_OF_BALLS) {
deleteCollidingBalls();
createCollidingBalls();
}
}
}, 200);
}
});
}
function deleteEntity(entityID) {
if (entityID === rack) {
deleteCollidingBalls();
Script.clearInterval(distanceCheckInterval);
Entities.deletingEntity.disconnect(deleteEntity);
}
}
function deleteCollidingBalls() {
while (collidingBalls.length > 0) {
Entities.deleteEntity(collidingBalls.pop());
}
}
createCollidingBalls();
Entities.deletingEntity.connect(deleteEntity);
var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000);
}
function createWand(position) { function createWand(position) {
var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx';
var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj';