From ea2e96ac6fc09ca15a19e6e1e4a622de44fb9b77 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 28 Apr 2014 13:02:54 -0700 Subject: [PATCH] toggle collision and gravity with timers --- examples/swissArmyJetpack.js | 158 ++++++++++++++++++++++++----------- 1 file changed, 107 insertions(+), 51 deletions(-) diff --git a/examples/swissArmyJetpack.js b/examples/swissArmyJetpack.js index 719a6f620c..4963ecba09 100644 --- a/examples/swissArmyJetpack.js +++ b/examples/swissArmyJetpack.js @@ -12,44 +12,44 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var numberOfButtons = 3; +// misc global constants +var NUMBER_OF_BUTTONS = 3; var DOWN = { x: 0.0, y: -1.0, z: 0.0 }; var MAX_VOXEL_SCAN_DISTANCE = 20.0; + +// behavior transition thresholds var MIN_FLYING_SPEED = 1.0; +var MIN_COLLISIONLESS_SPEED = 5.0; +var MAX_WALKING_SPEED = 10.0; +var MAX_COLLIDABLE_SPEED = 25.0; -var enabledColors = new Array(); -enabledColors[0] = { red: 255, green: 0, blue: 0}; -enabledColors[1] = { red: 0, green: 255, blue: 0}; -enabledColors[2] = { red: 0, green: 0, blue: 255}; - -var disabledColors = new Array(); -disabledColors[0] = { red: 90, green: 75, blue: 75}; -disabledColors[1] = { red: 75, green: 90, blue: 75}; -disabledColors[2] = { red: 75, green: 90, blue: 90}; - -var buttons = new Array(); -var labels = new Array(); - -var labelContents = new Array(); -labelContents[0] = "Collide with Avatars"; -labelContents[1] = "Collide with Voxels"; -labelContents[2] = "Collide with Particles"; -var groupBits = 0; - -var buttonStates = new Array(); - -var disabledOffsetT = 12; -var enabledOffsetT = 55 + 12; - +// button URL and geometry/UI tuning +var BUTTON_IMAGE_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg"; +var DISABLED_OFFSET_Y = 12; +var ENABLED_OFFSET_Y = 55 + 12; var UI_BUFFER = 1; var OFFSET_X = UI_BUFFER; var OFFSET_Y = 200; var BUTTON_WIDTH = 30; var BUTTON_HEIGHT = 30; -var textX = OFFSET_X + BUTTON_WIDTH + UI_BUFFER; +var TEXT_OFFSET_X = OFFSET_X + BUTTON_WIDTH + UI_BUFFER; var TEXT_HEIGHT = BUTTON_HEIGHT; var TEXT_WIDTH = 210; +var MSEC_PER_SECOND = 1000; +var EXPIRY_PERIOD = 2 * MSEC_PER_SECOND; + +var dater = new Date(); +var collisionOnExpiry = dater.getTime() + EXPIRY_PERIOD; +var gravityOnExpiry = dater.getTime() + EXPIRY_PERIOD; + +// avatar state +var velocity = { x: 0.0, y: 0.0, z: 0.0 }; +var standing = false; + +// speedometer globals +var speed = 0.0; +var lastPosition = MyAvatar.position; var speedometer = Overlays.addOverlay("text", { x: OFFSET_X, y: OFFSET_Y - BUTTON_HEIGHT, @@ -61,12 +61,32 @@ var speedometer = Overlays.addOverlay("text", { leftMargin: 4, text: "Speed: 0.0" }); -var speed = 0.0; -var lastPosition = MyAvatar.position; -for (i = 0; i < numberOfButtons; i++) { +// collision group buttons +var buttons = new Array(); +var labels = new Array(); + +var labelContents = new Array(); +labelContents[0] = "Collide with Avatars"; +labelContents[1] = "Collide with Voxels"; +labelContents[2] = "Collide with Particles"; +var groupBits = 0; + +var enabledColors = new Array(); +enabledColors[0] = { red: 255, green: 0, blue: 0}; +enabledColors[1] = { red: 0, green: 255, blue: 0}; +enabledColors[2] = { red: 0, green: 0, blue: 255}; + +var disabledColors = new Array(); +disabledColors[0] = { red: 90, green: 75, blue: 75}; +disabledColors[1] = { red: 75, green: 90, blue: 75}; +disabledColors[2] = { red: 75, green: 90, blue: 90}; + +var buttonStates = new Array(); + +for (i = 0; i < NUMBER_OF_BUTTONS; i++) { var offsetS = 12 - var offsetT = disabledOffsetT; + var offsetT = DISABLED_OFFSET_Y; buttons[i] = Overlays.addOverlay("image", { x: OFFSET_X, @@ -74,13 +94,13 @@ for (i = 0; i < numberOfButtons; i++) { width: BUTTON_WIDTH, height: BUTTON_HEIGHT, subImage: { x: offsetS, y: offsetT, width: BUTTON_WIDTH, height: BUTTON_HEIGHT }, - imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg", + imageURL: BUTTON_IMAGE_URL, color: disabledColors[i], alpha: 1, }); labels[i] = Overlays.addOverlay("text", { - x: textX, + x: TEXT_OFFSET_X, y: OFFSET_Y + (BUTTON_HEIGHT * i), width: TEXT_WIDTH, height: TEXT_HEIGHT, @@ -94,16 +114,14 @@ for (i = 0; i < numberOfButtons; i++) { buttonStates[i] = false; } -// avatar state -var velocity = { x: 0.0, y: 0.0, z: 0.0 }; -var standing = false; + +// functions function updateButton(i, enabled) { - var offsetY = disabledOffsetT; + var offsetY = DISABLED_OFFSET_Y; var buttonColor = disabledColors[i]; - groupBits if (enabled) { - offsetY = enabledOffsetT; + offsetY = ENABLED_OFFSET_Y; buttonColor = enabledColors[i]; if (i == 0) { groupBits |= COLLISION_GROUP_AVATARS; @@ -121,16 +139,19 @@ function updateButton(i, enabled) { groupBits &= ~COLLISION_GROUP_PARTICLES; } } - MyAvatar.collisionGroups = groupBits; + if (groupBits != MyAvatar.collisionGroups) { + MyAvatar.collisionGroups = groupBits; + } Overlays.editOverlay(buttons[i], { subImage: { y: offsetY } } ); Overlays.editOverlay(buttons[i], { color: buttonColor } ); buttonStates[i] = enabled; } + // When our script shuts down, we should clean up all of our overlays function scriptEnding() { - for (i = 0; i < numberOfButtons; i++) { + for (i = 0; i < NUMBER_OF_BUTTONS; i++) { Overlays.deleteOverlay(buttons[i]); Overlays.deleteOverlay(labels[i]); } @@ -138,11 +159,12 @@ function scriptEnding() { } Script.scriptEnding.connect(scriptEnding); + function updateSpeedometerDisplay() { Overlays.editOverlay(speedometer, { text: "Speed: " + speed.toFixed(2) }); } +Script.setInterval(updateSpeedometerDisplay, 100); -var multiple_timer = Script.setInterval(updateSpeedometerDisplay, 100); // Our update() function is called at approximately 60fps, and we will use it to animate our various overlays function update(deltaTime) { @@ -155,21 +177,55 @@ function update(deltaTime) { // measure speed var distance = Vec3.distance(MyAvatar.position, lastPosition); - speed = 0.9 * speed + 0.1 * distance / deltaTime; + speed = 0.8 * speed + 0.2 * distance / deltaTime; lastPosition = MyAvatar.position; - // scan for landing platform - if (speed < MIN_FLYING_SPEED && !(MyAvatar.motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY)) { + dater = new Date(); + var now = dater.getTime(); + + if (speed < MIN_FLYING_SPEED) { + // scan for landing platform ray = { origin: MyAvatar.position, direction: DOWN }; var intersection = Voxels.findRayIntersection(ray); if (intersection.intersects) { - var v = intersection.voxel; - var maxCorner = Vec3.sum({ x: v.x, y: v.y, z: v.z }, {x: v.s, y: v.s, z: v.s }); - var distance = lastPosition.y - maxCorner.y; - if (distance < MAX_VOXEL_SCAN_DISTANCE) { - MyAvatar.motionBehaviors = AVATAR_MOTION_OBEY_GRAVITY; + if (!(MyAvatar.motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY)) { + var v = intersection.voxel; + var maxCorner = Vec3.sum({ x: v.x, y: v.y, z: v.z }, {x: v.s, y: v.s, z: v.s }); + var distance = lastPosition.y - maxCorner.y; + if ((gravityOnExpiry < now) && (distance < MAX_VOXEL_SCAN_DISTANCE)) { + MyAvatar.motionBehaviors = MyAvatar.motionBehaviors | AVATAR_MOTION_OBEY_GRAVITY; + } } - //print("voxel corner = <" + v.x + ", " + v.y + ", " + v.z + "> " + " scale = " + v.s + " dt = " + deltaTime); + } else { + if (MyAvatar.motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY) { + MyAvatar.motionBehaviors = MyAvatar.motionBehaviors & ~AVATAR_MOTION_OBEY_GRAVITY; + } + gravityOnExpiry = now + EXPIRY_PERIOD; + } + } else { + gravityOnExpiry = now + EXPIRY_PERIOD; + } + if (speed < MIN_COLLISIONLESS_SPEED) { + if (collisionOnExpiry < now && !(MyAvatar.collisionGroups & COLLISION_GROUP_VOXELS)) { + // TODO: check to make sure not already colliding + // enable collision with voxels + groupBits |= COLLISION_GROUP_VOXELS; + updateButton(1, groupBits & COLLISION_GROUP_VOXELS); + } + } else { + collisionOnExpiry = now + EXPIRY_PERIOD; + } + if (speed > MAX_WALKING_SPEED) { + if (MyAvatar.motionBehaviors & AVATAR_MOTION_OBEY_GRAVITY) { + // turn off gravity + MyAvatar.motionBehaviors = MyAvatar.motionBehaviors & ~AVATAR_MOTION_OBEY_GRAVITY; + } + } + if (speed > MAX_COLLIDABLE_SPEED) { + if (MyAvatar.collisionGroups & COLLISION_GROUP_VOXELS) { + // disable collisions with voxels + groupBits &= ~COLLISION_GROUP_VOXELS; + updateButton(1, groupBits & COLLISION_GROUP_VOXELS); } } } @@ -179,7 +235,7 @@ Script.update.connect(update); // we also handle click detection in our mousePressEvent() function mousePressEvent(event) { var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - for (i = 0; i < numberOfButtons; i++) { + for (i = 0; i < NUMBER_OF_BUTTONS; i++) { if (clickedOverlay == buttons[i]) { var enabled = !(buttonStates[i]); updateButton(i, enabled);