Merge pull request #2402 from Atlante45/inspect_js

Inspect js
This commit is contained in:
Philip Rosedale 2014-03-20 17:21:21 -07:00
commit b49058ea77
7 changed files with 249 additions and 254 deletions

View file

@ -20,8 +20,6 @@ var windowDimensions = Controller.getViewportDimensions();
var NEW_VOXEL_SIZE = 1.0;
var NEW_VOXEL_DISTANCE_FROM_CAMERA = 3.0;
var ORBIT_RATE_ALTITUDE = 200.0;
var ORBIT_RATE_AZIMUTH = 90.0;
var PIXELS_PER_EXTRUDE_VOXEL = 16;
var WHEEL_PIXELS_PER_SCALE_CHANGE = 100;
var MAX_VOXEL_SCALE = 1.0;
@ -37,19 +35,7 @@ var previewLineWidth = 1.5;
var oldMode = Camera.getMode();
var isAdding = false;
var isExtruding = false;
var isOrbiting = false;
var isOrbitingFromTouch = false;
var isPanning = false;
var isPanningFromTouch = false;
var touchPointsToOrbit = 2; // you can change these, but be mindful that on some track pads 2 touch points = right click+drag
var touchPointsToPan = 3;
var orbitAzimuth = 0.0;
var orbitAltitude = 0.0;
var orbitCenter = { x: 0, y: 0, z: 0 };
var orbitPosition = { x: 0, y: 0, z: 0 };
var torsoToEyeVector = { x: 0, y: 0, z: 0 };
var orbitRadius = 0.0;
var isExtruding = false;
var extrudeDirection = { x: 0, y: 0, z: 0 };
var extrudeScale = 0.0;
var lastVoxelPosition = { x: 0, y: 0, z: 0 };
@ -444,24 +430,11 @@ function getNewVoxelPosition() {
return newPosition;
}
function fixEulerAngles(eulers) {
var rVal = { x: 0, y: 0, z: eulers.z };
if (eulers.x >= 90.0) {
rVal.x = 180.0 - eulers.x;
rVal.y = eulers.y - 180.0;
} else if (eulers.x <= -90.0) {
rVal.x = 180.0 - eulers.x;
rVal.y = eulers.y - 180.0;
}
return rVal;
}
var trackLastMouseX = 0;
var trackLastMouseY = 0;
var trackAsDelete = false;
var trackAsRecolor = false;
var trackAsEyedropper = false;
var trackAsOrbitOrPan = false;
var voxelToolSelected = true;
var recolorToolSelected = false;
@ -761,10 +734,6 @@ function trackKeyPressEvent(event) {
trackAsEyedropper = true;
moveTools();
}
if (event.text == "ALT") {
trackAsOrbitOrPan = true;
moveTools();
}
showPreviewGuides();
}
@ -802,10 +771,6 @@ function trackKeyReleaseEvent(event) {
trackAsEyedropper = false;
moveTools();
}
if (event.text == "ALT") {
trackAsOrbitOrPan = false;
moveTools();
}
// on F1 toggle the preview mode between cubes and lines
if (event.text == "F1") {
@ -816,74 +781,6 @@ function trackKeyReleaseEvent(event) {
}
}
function startOrbitMode(event) {
mouseX = event.x;
mouseY = event.y;
var pickRay = Camera.computePickRay(event.x, event.y);
var intersection = Voxels.findRayIntersection(pickRay);
// start orbit camera!
var cameraPosition = Camera.getPosition();
torsoToEyeVector = Vec3.subtract(cameraPosition, MyAvatar.position);
torsoToEyeVector.x = 0.0;
torsoToEyeVector.z = 0.0;
oldMode = Camera.getMode();
Camera.setMode("independent");
Camera.keepLookingAt(intersection.intersection);
// get position for initial azimuth, elevation
orbitCenter = intersection.intersection;
var orbitVector = Vec3.subtract(cameraPosition, orbitCenter);
orbitRadius = Vec3.length(orbitVector);
orbitAzimuth = Math.atan2(orbitVector.z, orbitVector.x);
orbitAltitude = Math.asin(orbitVector.y / Vec3.length(orbitVector));
//print("startOrbitMode...");
}
function handleOrbitingMove(event) {
var cameraOrientation = Camera.getOrientation();
var origEulers = Quat.safeEulerAngles(cameraOrientation);
var newEulers = fixEulerAngles(Quat.safeEulerAngles(cameraOrientation));
var dx = event.x - mouseX;
var dy = event.y - mouseY;
orbitAzimuth += dx / ORBIT_RATE_AZIMUTH;
orbitAltitude += dy / ORBIT_RATE_ALTITUDE;
var orbitVector = { x:(Math.cos(orbitAltitude) * Math.cos(orbitAzimuth)) * orbitRadius,
y:Math.sin(orbitAltitude) * orbitRadius,
z:(Math.cos(orbitAltitude) * Math.sin(orbitAzimuth)) * orbitRadius };
orbitPosition = Vec3.sum(orbitCenter, orbitVector);
Camera.setPosition(orbitPosition);
mouseX = event.x;
mouseY = event.y;
//print("handleOrbitingMove...");
}
function endOrbitMode(event) {
var cameraOrientation = Camera.getOrientation();
MyAvatar.position = Vec3.subtract(Camera.getPosition(), torsoToEyeVector);
MyAvatar.headOrientation = cameraOrientation;
Camera.stopLooking();
Camera.setMode(oldMode);
Camera.setOrientation(cameraOrientation);
//print("endOrbitMode...");
}
function startPanMode(event, intersection) {
// start pan camera!
print("handle PAN mode!!!");
}
function handlePanMove(event) {
print("PANNING mode!!! ");
//print("isPanning="+isPanning + " inPanningFromTouch="+isPanningFromTouch + " trackAsOrbitOrPan="+trackAsOrbitOrPan);
}
function endPanMode(event) {
print("ending PAN mode!!!");
}
function mousePressEvent(event) {
// if our tools are off, then don't do anything
@ -891,31 +788,6 @@ function mousePressEvent(event) {
return;
}
// Normally, if we're panning or orbiting from touch, ignore these... because our touch takes precedence.
// but In the case of a button="RIGHT" click, we may get some touch messages first, and we actually want to
// cancel any touch mode, and then let the right-click through
if (isOrbitingFromTouch || isPanningFromTouch) {
// if the user is holding the ALT key AND they are clicking the RIGHT button (or on multi-touch doing a two
// finger touch, then we want to let the new panning behavior take over.
// if it's any other case we still want to bail
if (event.button == "RIGHT" && trackAsOrbitOrPan) {
// cancel our current multitouch operation...
if (isOrbitingFromTouch) {
endOrbitMode(event);
isOrbitingFromTouch = false;
}
if (isPanningFromTouch) {
//print("mousePressEvent... calling endPanMode()");
endPanMode(event);
isPanningFromTouch = false;
}
// let things fall through
} else {
return;
}
}
// no clicking on overlays while in panning mode
if (!trackAsOrbitOrPan) {
var clickedOnSomething = false;
@ -1008,17 +880,7 @@ function mousePressEvent(event) {
calcThumbFromScale(intersection.voxel.s);
}
// Note: touch and mouse events can cross paths, so we want to ignore any mouse events that would
// start a pan or orbit if we're already doing a pan or orbit via touch...
if ((event.isAlt || trackAsOrbitOrPan) && !(isOrbitingFromTouch || isPanningFromTouch)) {
if (event.isLeftButton && !event.isRightButton) {
startOrbitMode(event);
isOrbiting = true;
} else if (event.isRightButton && !event.isLeftButton) {
startPanMode(event);
isPanning = true;
}
} else if (trackAsDelete || event.isRightButton && !trackAsEyedropper) {
if (trackAsDelete || event.isRightButton && !trackAsEyedropper) {
// Delete voxel
voxelDetails = calculateVoxelFromIntersection(intersection,"delete");
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
@ -1209,23 +1071,7 @@ function mouseMoveEvent(event) {
return;
}
// if we're panning or orbiting from touch, ignore these... because our touch takes precedence.
if (isOrbitingFromTouch || isPanningFromTouch) {
return;
}
// double check that we didn't accidentally miss a pan or orbit click request
if (trackAsOrbitOrPan && !isPanning && !isOrbiting) {
if (event.isLeftButton && !event.isRightButton) {
startOrbitMode(event);
isOrbiting = true;
}
if (!event.isLeftButton && event.isRightButton) {
startPanMode(event);
isPanning = true;
}
}
if (!trackAsOrbitOrPan && isMovingSlider) {
thumbX = (event.x - thumbClickOffsetX) - sliderX;
if (thumbX < minThumbX) {
@ -1236,10 +1082,6 @@ function mouseMoveEvent(event) {
}
calcScaleFromThumb(thumbX);
} else if (isOrbiting) {
handleOrbitingMove(event);
} else if (isPanning) {
handlePanMove(event);
} else if (!trackAsOrbitOrPan && isAdding) {
// Watch the drag direction to tell which way to 'extrude' this voxel
if (!isExtruding) {
@ -1293,16 +1135,6 @@ function mouseReleaseEvent(event) {
if (isMovingSlider) {
isMovingSlider = false;
}
if (isOrbiting) {
endOrbitMode(event);
isOrbiting = false;
}
if (isPanning) {
print("mouseReleaseEvent... calling endPanMode()");
endPanMode(event);
isPanning = false;
}
isAdding = false;
isExtruding = false;
}
@ -1396,96 +1228,18 @@ function touchBeginEvent(event) {
if (!editToolsOn) {
return;
}
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) {
return;
}
if (event.isAlt || trackAsOrbitOrPan) {
if (event.touchPoints == touchPointsToOrbit) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches...
if (isPanningFromTouch) {
print("touchBeginEvent... calling endPanMode()");
endPanMode(event);
isPanningFromTouch = false;
}
startOrbitMode(event);
isOrbitingFromTouch = true;
} else if (event.touchPoints == touchPointsToPan) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches...
if (isOrbitingFromTouch) {
endOrbitMode(event);
isOrbitingFromTouch = false;
}
startPanMode(event);
isPanningFromTouch = true;
}
}
}
function touchUpdateEvent(event) {
if (!editToolsOn) {
return;
}
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) {
return;
}
if (isOrbitingFromTouch) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches...
if (event.touchPoints == touchPointsToPan) {
//print("we now have touchPointsToPan touches... switch to pan...");
endOrbitMode(event);
isOrbitingFromTouch = false;
startPanMode(event);
isPanningFromTouch = true;
} else {
handleOrbitingMove(event);
}
}
if (isPanningFromTouch) {
//print("touchUpdateEvent... isPanningFromTouch... event.touchPoints=" + event.touchPoints);
// we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches...
if (event.touchPoints == touchPointsToOrbit) {
//print("we now have touchPointsToOrbit touches... switch to orbit...");
//print("touchUpdateEvent... calling endPanMode()");
endPanMode(event);
isPanningFromTouch = false;
startOrbitMode(event);
isOrbitingFromTouch = true;
handleOrbitingMove(event);
} else {
handlePanMove(event);
}
}
}
function touchEndEvent(event) {
if (!editToolsOn) {
return;
}
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) {
return;
}
if (isOrbitingFromTouch) {
endOrbitMode(event);
isOrbitingFromTouch = false;
}
if (isPanningFromTouch) {
print("touchEndEvent... calling endPanMode()");
endPanMode(event);
isPanningFromTouch = false;
}
}
var lastFingerAddVoxel = { x: -1, y: -1, z: -1}; // off of the build-able area

240
examples/inspect.js Normal file
View file

@ -0,0 +1,240 @@
//
// inspect.js
// hifi
//
// Created by Clément Brisset on March 20, 2014
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// Allows you to inspect non moving objects (Voxels or Avatars) using Atl, Control (Command on Mac) and Shift
//
// radial mode = hold ALT
// orbit mode = hold ALT + CONTROL
// pan mode = hold ALT + CONTROL + SHIFT
// Once you are in a mode left click on the object to inspect and hold the click
// Dragging the mouse will move your camera according to the mode you are in.
//
var AZIMUTH_RATE = 90.0;
var ALTITUDE_RATE = 200.0;
var RADIUS_RATE = 20.0;
var PAN_RATE = 50.0;
var alt = false;
var shift = false;
var control = false;
var isActive = false;
var noMode = 0;
var orbitMode = 1;
var radialMode = 2;
var panningMode = 3;
var mode = noMode;
var mouseLastX = 0;
var mouseLastY = 0;
var center = { x: 0, y: 0, z: 0 };
var position = { x: 0, y: 0, z: 0 };
var vector = { x: 0, y: 0, z: 0 };
var radius = 0.0;
var azimuth = 0.0;
var altitude = 0.0;
function handleRadialMode(dx, dy) {
azimuth += dx / AZIMUTH_RATE;
radius += radius * dy / RADIUS_RATE;
if (radius < 1) {
radius = 1;
}
vector = { x: (Math.cos(altitude) * Math.cos(azimuth)) * radius,
y: Math.sin(altitude) * radius,
z: (Math.cos(altitude) * Math.sin(azimuth)) * radius };
position = Vec3.sum(center, vector);
Camera.setPosition(position);
}
function handleOrbitMode(dx, dy) {
azimuth += dx / AZIMUTH_RATE;
altitude += dy / ALTITUDE_RATE;
vector = { x:(Math.cos(altitude) * Math.cos(azimuth)) * radius,
y:Math.sin(altitude) * radius,
z:(Math.cos(altitude) * Math.sin(azimuth)) * radius };
position = Vec3.sum(center, vector);
Camera.setPosition(position);
}
function handlePanMode(dx, dy) {
var up = Quat.getUp(Camera.getOrientation());
var right = Quat.getRight(Camera.getOrientation());
var distance = Vec3.length(vector);
var dv = Vec3.sum(Vec3.multiply(up, - distance * dy / PAN_RATE), Vec3.multiply(right, distance * dx / PAN_RATE));
center = Vec3.sum(center, dv);
position = Vec3.sum(position, dv);
Camera.setPosition(position);
Camera.keepLookingAt(center);
}
function saveCameraState() {
oldMode = Camera.getMode();
var oldPosition = Camera.getPosition();
Camera.setMode("independent");
Camera.setPosition(oldPosition);
}
function restoreCameraState() {
Camera.stopLooking();
Camera.setMode(oldMode);
}
function handleModes() {
var newMode = noMode;
if (alt) {
if (control) {
if (shift) {
newMode = panningMode;
} else {
newMode = orbitMode;
}
} else {
newMode = radialMode;
}
}
// if leaving noMode
if (mode == noMode && newMode != noMode) {
saveCameraState();
}
// if entering noMode
if (newMode == noMode && mode != noMode) {
restoreCameraState();
}
mode = newMode;
}
function keyPressEvent(event) {
var changed = false;
if (event.text == "ALT") {
alt = true;
changed = true;
}
if (event.text == "CONTROL") {
control = true;
changed = true;
}
if (event.text == "SHIFT") {
shift = true;
changed = true;
}
if (changed) {
handleModes();
}
}
function keyReleaseEvent(event) {
var changed = false;
if (event.text == "ALT") {
alt = false;
changed = true;
}
if (event.text == "CONTROL") {
control = false;
changed = true;
}
if (event.text == "SHIFT") {
shift = false;
changed = true;
}
if (changed) {
handleModes();
}
}
function mousePressEvent(event) {
if (alt) {
isActive = true;
mouseLastX = event.x;
mouseLastY = event.y;
// Compute trajectories related values
var pickRay = Camera.computePickRay(mouseLastX, mouseLastY);
var intersection = Voxels.findRayIntersection(pickRay);
position = Camera.getPosition();
avatarTarget = MyAvatar.getTargetAvatarPosition();
voxelTarget = intersection.intersection;
if (Vec3.length(Vec3.subtract(avatarTarget, position)) < Vec3.length(Vec3.subtract(voxelTarget, position))) {
if (avatarTarget.x != 0 || avatarTarget.y != 0 || avatarTarget.z != 0) {
center = avatarTarget;
} else {
center = voxelTarget;
}
} else {
if (voxelTarget.x != 0 || voxelTarget.y != 0 || voxelTarget.z != 0) {
center = voxelTarget;
} else {
center = avatarTarget;
}
}
vector = Vec3.subtract(position, center);
radius = Vec3.length(vector);
azimuth = Math.atan2(vector.z, vector.x);
altitude = Math.asin(vector.y / Vec3.length(vector));
Camera.keepLookingAt(center);
}
}
function mouseReleaseEvent(event) {
if (isActive) {
isActive = false;
}
}
function mouseMoveEvent(event) {
if (isActive && mode != noMode) {
if (mode == radialMode) {
handleRadialMode(event.x - mouseLastX, event.y - mouseLastY);
}
if (mode == orbitMode) {
handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY);
}
if (mode == panningMode) {
handlePanMode(event.x - mouseLastX, event.y - mouseLastY);
}
mouseLastX = event.x;
mouseLastY = event.y;
}
}
function scriptEnding() {
if (mode != noMode) {
restoreCameraState();
}
}
Controller.keyPressEvent.connect(keyPressEvent);
Controller.keyReleaseEvent.connect(keyReleaseEvent);
Controller.mousePressEvent.connect(mousePressEvent);
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Script.scriptEnding.connect(scriptEnding);

View file

@ -1690,7 +1690,7 @@ void Application::updateMyAvatarLookAtPosition() {
} else {
// look in direction of the mouse ray, but use distance from intersection, if any
float distance = TREE_SCALE;
if (_myAvatar->getLookAtTargetAvatar()) {
if (_myAvatar->getLookAtTargetAvatar() && _myAvatar != _myAvatar->getLookAtTargetAvatar()) {
distance = glm::distance(_mouseRayOrigin,
static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition());
}

View file

@ -31,7 +31,7 @@ public:
~ModelBrowser();
signals:
void selected(QString);
void selected(QString filename);
public slots:
void browse();

View file

@ -582,16 +582,15 @@ void MyAvatar::updateLookAtTargetAvatar() {
foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) {
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
if (avatar == static_cast<Avatar*>(this)) {
continue;
}
float distance;
if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) {
_lookAtTargetAvatar = avatarPointer;
_targetAvatarPosition = avatarPointer->getPosition();
return;
}
}
_lookAtTargetAvatar.clear();
_targetAvatarPosition = glm::vec3(0, 0, 0);
}
}

View file

@ -76,6 +76,7 @@ public:
void orbit(const glm::vec3& position, int deltaX, int deltaY);
Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; }
AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); }
void updateLookAtTargetAvatar();
void clearLookAtTargetAvatar();
@ -116,6 +117,7 @@ private:
glm::vec3 _moveTarget;
int _moveTargetStepCounter;
QWeakPointer<AvatarData> _lookAtTargetAvatar;
glm::vec3 _targetAvatarPosition;
bool _shouldRender;
bool _billboardValid;

View file

@ -28,7 +28,7 @@ public:
static QByteArray download(const QUrl dataURL, int timeout = 0);
signals:
void done(QNetworkReply::NetworkError);
void done(QNetworkReply::NetworkError error);
private slots:
void processReply(QNetworkReply* reply);