mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-06 08:03:11 +02:00
272 lines
8 KiB
JavaScript
272 lines
8 KiB
JavaScript
//
|
|
// controller.js
|
|
// examples
|
|
//
|
|
// Created by Ryan Huffman on 10/9/14.
|
|
// 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
|
|
//
|
|
|
|
var gamepads = {};
|
|
|
|
// Function -> button/axis mappings
|
|
var AXIS_STRAFE = Joysticks.AXIS_LEFT_X;
|
|
var AXIS_FORWARD = Joysticks.AXIS_LEFT_Y;
|
|
var AXIS_ROTATE = Joysticks.AXIS_RIGHT_X;
|
|
|
|
var BUTTON_SPRINT = Joysticks.BUTTON_LEFT_STICK;
|
|
|
|
var BUTTON_TOGGLE_MIRROR = Joysticks.BUTTON_FACE_LEFT;
|
|
|
|
var BUTTON_TURN_AROUND = Joysticks.BUTTON_RIGHT_STICK;
|
|
|
|
var BUTTON_FLY_UP = Joysticks.BUTTON_RIGHT_SHOULDER;
|
|
var BUTTON_FLY_DOWN = Joysticks.BUTTON_LEFT_SHOULDER;
|
|
var BUTTON_WARP = null; // Disable for now
|
|
|
|
var BUTTON_WARP_FORWARD = Joysticks.BUTTON_DPAD_UP;
|
|
var BUTTON_WARP_BACKWARD = Joysticks.BUTTON_DPAD_DOWN;
|
|
var BUTTON_WARP_LEFT = Joysticks.BUTTON_DPAD_LEFT;
|
|
var BUTTON_WARP_RIGHT = Joysticks.BUTTON_DPAD_RIGHT;
|
|
|
|
// Distance in meters to warp via BUTTON_WARP_*
|
|
var WARP_DISTANCE = 1;
|
|
|
|
// Walk speed in m/s
|
|
var MOVE_SPEED = 0.5;
|
|
var MOVE_SPRINT_SPEED = 2;
|
|
|
|
// Amount to rotate in radians
|
|
var ROTATE_INCREMENT = Math.PI / 8;
|
|
|
|
// Pick from above where we want to warp
|
|
var WARP_PICK_OFFSET = { x: 0, y: 10, z: 0 };
|
|
|
|
// When warping, the warp position will snap to a target below the current warp position.
|
|
// This is the max distance it will snap to.
|
|
var WARP_PICK_MAX_DISTANCE = 100;
|
|
|
|
var flyDownButtonState = false;
|
|
var flyUpButtonState = false;
|
|
|
|
// When toggling to mirror mode, this stores the mode the user was previously in
|
|
// so it can be toggled back to.
|
|
var toggledFromCameraMode = 'first person';
|
|
|
|
// Current move direction, axis aligned - that is, looking down and moving forward
|
|
// will not move you into the ground, but instead will keep you on the horizontal plane.
|
|
var moveDirection = { x: 0, y: 0, z: 0 };
|
|
var sprintButtonState = false;
|
|
|
|
var warpActive = false;
|
|
var warpPosition = { x: 0, y: 0, z: 0 };
|
|
|
|
var WARP_SPHERE_SIZE = 1;
|
|
var warpSphere = Overlays.addOverlay("sphere", {
|
|
position: { x: 0, y: 0, z: 0 },
|
|
size: WARP_SPHERE_SIZE,
|
|
color: { red: 0, green: 255, blue: 0 },
|
|
alpha: 1.0,
|
|
solid: true,
|
|
visible: false,
|
|
});
|
|
|
|
var WARP_LINE_HEIGHT = 10;
|
|
var warpLine = Overlays.addOverlay("line3d", {
|
|
start: { x: 0, y: 0, z:0 },
|
|
end: { x: 0, y: 0, z: 0 },
|
|
color: { red: 0, green: 255, blue: 255},
|
|
alpha: 1,
|
|
lineWidth: 5,
|
|
visible: false,
|
|
});
|
|
|
|
function copyVec3(vec) {
|
|
return { x: vec.x, y: vec.y, z: vec.z };
|
|
}
|
|
|
|
function activateWarp() {
|
|
if (warpActive) return;
|
|
warpActive = true;
|
|
|
|
updateWarp();
|
|
}
|
|
|
|
function updateWarp() {
|
|
if (!warpActive) return;
|
|
|
|
var look = Quat.getFront(Camera.getOrientation());
|
|
var pitch = Math.asin(look.y);
|
|
|
|
// Get relative to looking straight down
|
|
pitch += Math.PI / 2;
|
|
|
|
// Scale up
|
|
pitch *= 2;
|
|
var distance = pitch * pitch * pitch;
|
|
|
|
var warpDirection = Vec3.normalize({ x: look.x, y: 0, z: look.z });
|
|
warpPosition = Vec3.multiply(warpDirection, distance);
|
|
warpPosition = Vec3.sum(MyAvatar.position, warpPosition);
|
|
|
|
var pickRay = {
|
|
origin: Vec3.sum(warpPosition, WARP_PICK_OFFSET),
|
|
direction: { x: 0, y: -1, z: 0 }
|
|
};
|
|
|
|
var intersection = Entities.findRayIntersection(pickRay);
|
|
|
|
if (intersection.intersects && intersection.distance < WARP_PICK_MAX_DISTANCE) {
|
|
// Warp 1 meter above the object - this is an approximation
|
|
// TODO Get the actual offset to the Avatar's feet and plant them to
|
|
// the object.
|
|
warpPosition = Vec3.sum(intersection.intersection, { x: 0, y: 1, z:0 });
|
|
}
|
|
|
|
// Adjust overlays to match warp position
|
|
Overlays.editOverlay(warpSphere, {
|
|
position: warpPosition,
|
|
visible: true,
|
|
});
|
|
Overlays.editOverlay(warpLine, {
|
|
start: warpPosition,
|
|
end: Vec3.sum(warpPosition, { x: 0, y: WARP_LINE_HEIGHT, z: 0 }),
|
|
visible: true,
|
|
});
|
|
}
|
|
|
|
function finishWarp() {
|
|
if (!warpActive) return;
|
|
warpActive = false;
|
|
Overlays.editOverlay(warpSphere, {
|
|
visible: false,
|
|
});
|
|
Overlays.editOverlay(warpLine, {
|
|
visible: false,
|
|
});
|
|
MyAvatar.position = warpPosition;
|
|
}
|
|
|
|
function reportAxisValue(axis, newValue, oldValue) {
|
|
if (Math.abs(oldValue) < 0.2) oldValue = 0;
|
|
if (Math.abs(newValue) < 0.2) newValue = 0;
|
|
|
|
if (axis == AXIS_FORWARD) {
|
|
moveDirection.z = newValue;
|
|
} else if (axis == AXIS_STRAFE) {
|
|
moveDirection.x = newValue;
|
|
} else if (axis == AXIS_ROTATE) {
|
|
if (oldValue == 0 && newValue != 0) {
|
|
var rotateRadians = newValue > 0 ? -ROTATE_INCREMENT : ROTATE_INCREMENT;
|
|
var orientation = MyAvatar.orientation;
|
|
orientation = Quat.multiply(Quat.fromPitchYawRollRadians(0, rotateRadians, 0), orientation) ;
|
|
MyAvatar.orientation = orientation;
|
|
}
|
|
}
|
|
}
|
|
|
|
function reportButtonValue(button, newValue, oldValue) {
|
|
if (button == BUTTON_FLY_DOWN) {
|
|
flyDownButtonState = newValue;
|
|
} else if (button == BUTTON_FLY_UP) {
|
|
flyUpButtonState = newValue;
|
|
} else if (button == BUTTON_WARP) {
|
|
if (newValue) {
|
|
activateWarp();
|
|
} else {
|
|
finishWarp();
|
|
}
|
|
} else if (button == BUTTON_TURN_AROUND) {
|
|
if (newValue) {
|
|
MyAvatar.orientation = Quat.multiply(
|
|
Quat.fromPitchYawRollRadians(0, Math.PI, 0), MyAvatar.orientation);
|
|
}
|
|
} else if (button == BUTTON_SPRINT) {
|
|
sprintButtonState = newValue;
|
|
} else if (button == BUTTON_TOGGLE_MIRROR) {
|
|
if (newValue) {
|
|
var currentMode = Camera.mode;
|
|
if (currentMode != "mirror") {
|
|
toggledFromCameraMode = currentMode;
|
|
}
|
|
Camera.mode = "mirror";
|
|
} else {
|
|
Camera.mode = toggledFromCameraMode;
|
|
}
|
|
} else if (newValue) {
|
|
var direction = null;
|
|
|
|
if (button == BUTTON_WARP_FORWARD) {
|
|
direction = Quat.getFront(Camera.getOrientation());
|
|
} else if (button == BUTTON_WARP_BACKWARD) {
|
|
direction = Quat.getFront(Camera.getOrientation());
|
|
direction = Vec3.multiply(-1, direction);
|
|
} else if (button == BUTTON_WARP_LEFT) {
|
|
direction = Quat.getRight(Camera.getOrientation());
|
|
direction = Vec3.multiply(-1, direction);
|
|
} else if (button == BUTTON_WARP_RIGHT) {
|
|
direction = Quat.getRight(Camera.getOrientation());
|
|
}
|
|
|
|
if (direction) {
|
|
direction.y = 0;
|
|
direction = Vec3.multiply(Vec3.normalize(direction), WARP_DISTANCE);
|
|
MyAvatar.position = Vec3.sum(MyAvatar.position, direction);
|
|
}
|
|
}
|
|
|
|
if (flyUpButtonState && !flyDownButtonState) {
|
|
moveDirection.y = 1;
|
|
} else if (!flyUpButtonState && flyDownButtonState) {
|
|
moveDirection.y = -1;
|
|
} else {
|
|
moveDirection.y = 0;
|
|
}
|
|
}
|
|
|
|
function update(dt) {
|
|
var velocity = { x: 0, y: 0, z: 0 };
|
|
var move = copyVec3(moveDirection);
|
|
move.y = 0;
|
|
if (Vec3.length(move) > 0) {
|
|
speed = sprintButtonState ? MOVE_SPRINT_SPEED : MOVE_SPEED;
|
|
velocity = Vec3.multiplyQbyV(Camera.getOrientation(), move);
|
|
velocity.y = 0;
|
|
velocity = Vec3.multiply(Vec3.normalize(velocity), speed);
|
|
}
|
|
|
|
if (moveDirection.y != 0) {
|
|
velocity.y = moveDirection.y * MOVE_SPEED;
|
|
}
|
|
|
|
MyAvatar.setVelocity(velocity);
|
|
|
|
updateWarp();
|
|
}
|
|
|
|
function addJoystick(gamepad) {
|
|
gamepad.axisValueChanged.connect(reportAxisValue);
|
|
gamepad.buttonStateChanged.connect(reportButtonValue);
|
|
|
|
gamepads[gamepad.instanceId] = gamepad;
|
|
|
|
print("Added gamepad: " + gamepad.name + " (" + gamepad.instanceId + ")");
|
|
}
|
|
|
|
function removeJoystick(gamepad) {
|
|
delete gamepads[gamepad.instanceId]
|
|
|
|
print("Removed gamepad: " + gamepad.name + " (" + gamepad.instanceId + ")");
|
|
}
|
|
|
|
var allJoysticks = Joysticks.getAllJoysticks();
|
|
for (var i = 0; i < allJoysticks.length; i++) {
|
|
addJoystick(allJoysticks[i]);
|
|
}
|
|
|
|
Joysticks.joystickAdded.connect(addJoystick);
|
|
Joysticks.joystickRemoved.connect(removeJoystick);
|
|
|
|
Script.update.connect(update);
|