This commit is contained in:
Andrzej Kapolka 2014-11-04 11:45:23 -08:00
commit f00c54c23c
5 changed files with 212 additions and 134 deletions

View file

@ -1109,6 +1109,14 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
domainObject[AUTOMATIC_NETWORKING_KEY] = _automaticNetworkingSetting;
// add a flag to indicate if this domain uses restricted access - for now that will exclude it from listings
const QString RESTRICTED_ACCESS_FLAG = "restricted";
const QVariant* allowedUsersVariant = valueForKeyPath(_settingsManager.getSettingsMap(),
ALLOWED_USERS_SETTINGS_KEYPATH);
QStringList allowedUsers = allowedUsersVariant ? allowedUsersVariant->toStringList() : QStringList();
domainObject[RESTRICTED_ACCESS_FLAG] = (allowedUsers.size() > 0);
// add the number of currently connected agent users
int numConnectedAuthedUsers = 0;
foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {

View file

@ -50,14 +50,14 @@ var SPAWN_DISTANCE = 1;
var DEFAULT_DIMENSION = 0.20;
var modelURLs = [
HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX",
HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx",
HIFI_PUBLIC_BUCKET + "meshes/pug.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush6.fbx",
HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo",
HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx",
HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX",
HIFI_PUBLIC_BUCKET + "meshes/orc.fbx",
HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx"
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed2.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed4.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed7.fbx"
];
var jointList = MyAvatar.getJointNames();

View file

@ -34,6 +34,13 @@ var EASING_MULTIPLIER = 8;
var INITIAL_ZOOM_DISTANCE = 2;
var INITIAL_ZOOM_DISTANCE_FIRST_PERSON = 3;
var easeOutCubic = function(t) {
t--;
return t * t * t + 1;
};
EASE_TIME = 0.5;
CameraManager = function() {
var that = {};
@ -51,6 +58,10 @@ CameraManager = function() {
that.focalPoint = { x: 0, y: 0, z: 0 };
that.targetFocalPoint = { x: 0, y: 0, z: 0 };
easing = false;
easingTime = 0;
startOrientation = Quat.fromPitchYawRollDegrees(0, 0, 0);
that.previousCameraMode = null;
that.lastMousePosition = { x: 0, y: 0 };
@ -66,10 +77,6 @@ CameraManager = function() {
var focalPoint = Vec3.sum(Camera.getPosition(),
Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation())));
if (Camera.getMode() == 'first person') {
that.targetZoomDistance = INITIAL_ZOOM_DISTANCE_FIRST_PERSON;
}
// Determine the correct yaw and pitch to keep the camera in the same location
var dPos = Vec3.subtract(focalPoint, Camera.getPosition());
var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z);
@ -100,13 +107,35 @@ CameraManager = function() {
cameraTool.setVisible(false);
}
that.focus = function() {
var dim = SelectionManager.worldDimensions;
var size = Math.max(dim.x, Math.max(dim.y, dim.z));
that.focus = function(position, dimensions, easeOrientation) {
if (dimensions) {
var size = Math.max(dimensions.x, Math.max(dimensions.y, dimensions.z));
that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM);
} else {
that.targetZoomDistance = Vec3.length(Vec3.subtract(Camera.getPosition(), position));
}
that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM);
if (easeOrientation) {
// Do eased turning towards target
that.focalPoint = that.targetFocalPoint = position;
that.setFocalPoint(SelectionManager.worldPosition);
that.zoomDistance = that.targetZoomDistance = Vec3.length(Vec3.subtract(Camera.getPosition(), position));
var dPos = Vec3.subtract(that.focalPoint, Camera.getPosition());
var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z);
that.targetPitch = -Math.atan2(dPos.y, xzDist) * 180 / Math.PI;
that.targetYaw = Math.atan2(dPos.x, dPos.z) * 180 / Math.PI;
that.pitch = that.targetPitch;
that.yaw = that.targetYaw;
startOrientation = Camera.getOrientation();
easing = true;
easingTime = 0;
} else {
that.setFocalPoint(position);
}
that.updateCamera();
}
@ -255,6 +284,11 @@ CameraManager = function() {
xRot = Quat.angleAxis(-that.pitch, { x: 1, y: 0, z: 0 });
q = Quat.multiply(yRot, xRot);
if (easing) {
var t = easeOutCubic(easingTime / EASE_TIME);
q = Quat.slerp(startOrientation, q, t);
}
Camera.setOrientation(q);
}
@ -270,6 +304,10 @@ CameraManager = function() {
return;
}
if (easing) {
easingTime = Math.min(EASE_TIME, easingTime + dt);
}
var scale = Math.min(dt * EASING_MULTIPLIER, 1.0);
var dYaw = that.targetYaw - that.yaw;
@ -292,12 +330,15 @@ CameraManager = function() {
that.zoomDistance += scale * dZoom;
that.updateCamera();
if (easingTime >= 1) {
easing = false;
}
}
// Last mode that was first or third person
var lastAvatarCameraMode = "first person";
Camera.modeUpdated.connect(function(newMode) {
print("Camera mode has been updated: " + newMode);
if (newMode == "first person" || newMode == "third person") {
lastAvatarCameraMode = newMode;
that.disable(true);

View file

@ -51,15 +51,21 @@ var wantEntityGlow = false;
var SPAWN_DISTANCE = 1;
var DEFAULT_DIMENSION = 0.20;
var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool";
var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
var modelURLs = [
HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX",
HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx",
HIFI_PUBLIC_BUCKET + "meshes/pug.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush6.fbx",
HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo",
HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx",
HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX",
HIFI_PUBLIC_BUCKET + "meshes/orc.fbx",
HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx"
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed2.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed4.fbx",
HIFI_PUBLIC_BUCKET + "models/entities/3-Buildings-1-Rustic-Shed7.fbx"
];
var mode = 0;
@ -387,7 +393,6 @@ function isLocked(properties) {
var selectedEntityID;
var mouseLastPosition;
var orientation;
var intersection;
@ -401,142 +406,158 @@ function rayPlaneIntersection(pickRay, point, normal) {
return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t));
}
function findClickedEntity(event) {
var pickRay = Camera.computePickRay(event.x, event.y);
var foundIntersection = Entities.findRayIntersection(pickRay);
if (!foundIntersection.accurate) {
return null;
}
var foundEntity = foundIntersection.entityID;
if (!foundEntity.isKnownID) {
var identify = Entities.identifyEntity(foundEntity);
if (!identify.isKnownID) {
print("Unknown ID " + identify.id + " (update loop " + foundEntity.id + ")");
selectionManager.clearSelections();
return null;
}
foundEntity = identify;
}
return { pickRay: pickRay, entityID: foundEntity };
}
function mousePressEvent(event) {
mouseLastPosition = { x: event.x, y: event.y };
var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
var entitySelected = false;
if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)
|| cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) {
// Event handled; do nothing.
if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)) {
return;
} else {
// If we aren't active and didn't click on an overlay: quit
if (!isActive) {
}
if (isActive) {
var entitySelected = false;
if (cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) {
// Event handled; do nothing.
return;
}
var pickRay = Camera.computePickRay(event.x, event.y);
Vec3.print("[Mouse] Looking at: ", pickRay.origin);
var foundIntersection = Entities.findRayIntersection(pickRay);
if(!foundIntersection.accurate) {
selectionManager.clearSelections();
return;
}
var foundEntity = foundIntersection.entityID;
if (!foundEntity.isKnownID) {
var identify = Entities.identifyEntity(foundEntity);
if (!identify.isKnownID) {
print("Unknown ID " + identify.id + " (update loop " + foundEntity.id + ")");
} else {
var result = findClickedEntity(event);
if (result === null) {
selectionManager.clearSelections();
return;
}
foundEntity = identify;
}
var pickRay = result.pickRay;
var foundEntity = result.entityID;
var properties = Entities.getEntityProperties(foundEntity);
if (isLocked(properties)) {
print("Model locked " + properties.id);
} else {
var halfDiagonal = Vec3.length(properties.dimensions) / 2.0;
var properties = Entities.getEntityProperties(foundEntity);
if (isLocked(properties)) {
print("Model locked " + properties.id);
} else {
var halfDiagonal = Vec3.length(properties.dimensions) / 2.0;
print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal);
// P P - Model
// /| A - Palm
// / | d B - unit vector toward tip
// / | X - base of the perpendicular line
// A---X----->B d - distance fom axis
// x x - distance from A
//
// |X-A| = (P-A).B
// X == A + ((P-A).B)B
// d = |P-X|
print("Checking properties: " + properties.id + " " + properties.isKnownID + " - Half Diagonal:" + halfDiagonal);
// P P - Model
// /| A - Palm
// / | d B - unit vector toward tip
// / | X - base of the perpendicular line
// A---X----->B d - distance fom axis
// x x - distance from A
//
// |X-A| = (P-A).B
// X == A + ((P-A).B)B
// d = |P-X|
var A = pickRay.origin;
var B = Vec3.normalize(pickRay.direction);
var P = properties.position;
var A = pickRay.origin;
var B = Vec3.normalize(pickRay.direction);
var P = properties.position;
var x = Vec3.dot(Vec3.subtract(P, A), B);
var X = Vec3.sum(A, Vec3.multiply(B, x));
var d = Vec3.length(Vec3.subtract(P, X));
var halfDiagonal = Vec3.length(properties.dimensions) / 2.0;
var x = Vec3.dot(Vec3.subtract(P, A), B);
var X = Vec3.sum(A, Vec3.multiply(B, x));
var d = Vec3.length(Vec3.subtract(P, X));
var halfDiagonal = Vec3.length(properties.dimensions) / 2.0;
var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14;
var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14;
var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE)
&& (allowSmallModels || angularSize > MIN_ANGULAR_SIZE);
var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE)
&& (allowSmallModels || angularSize > MIN_ANGULAR_SIZE);
if (0 < x && sizeOK) {
entitySelected = true;
selectedEntityID = foundEntity;
orientation = MyAvatar.orientation;
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
if (0 < x && sizeOK) {
entitySelected = true;
selectedEntityID = foundEntity;
orientation = MyAvatar.orientation;
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
if (!event.isShifted) {
selectionManager.clearSelections();
if (!event.isShifted) {
selectionManager.clearSelections();
}
selectionManager.addEntity(foundEntity);
print("Model selected: " + foundEntity.id);
}
selectionManager.addEntity(foundEntity);
print("Model selected: " + foundEntity.id);
}
}
}
if (entitySelected) {
selectionDisplay.select(selectedEntityID, event);
if (entitySelected) {
selectionDisplay.select(selectedEntityID, event);
}
} else if (Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)) {
var result = findClickedEntity(event);
if (event.isRightButton) {
if (result !== null) {
var currentProperties = Entities.getEntityProperties(result.entityID);
cameraManager.enable();
cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
cameraManager.mousePressEvent(event);
}
} else {
cameraManager.mousePressEvent(event);
}
}
}
var highlightedEntityID = { isKnownID: false };
function mouseMoveEvent(event) {
if (!isActive) {
return;
}
// allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing
if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) {
return;
}
var pickRay = Camera.computePickRay(event.x, event.y);
var entityIntersection = Entities.findRayIntersection(pickRay);
if (entityIntersection.accurate) {
if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) {
selectionDisplay.unhighlightSelectable(highlightedEntityID);
highlightedEntityID = { id: -1, isKnownID: false };
if (isActive) {
// allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing
if (selectionDisplay.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) {
return;
}
var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0;
var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(),
entityIntersection.properties.position)) * 180 / 3.14;
var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE)
&& (allowSmallModels || angularSize > MIN_ANGULAR_SIZE);
if (entityIntersection.entityID.isKnownID && sizeOK) {
if (wantEntityGlow) {
Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 });
var pickRay = Camera.computePickRay(event.x, event.y);
var entityIntersection = Entities.findRayIntersection(pickRay);
if (entityIntersection.accurate) {
if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) {
selectionDisplay.unhighlightSelectable(highlightedEntityID);
highlightedEntityID = { id: -1, isKnownID: false };
}
highlightedEntityID = entityIntersection.entityID;
selectionDisplay.highlightSelectable(entityIntersection.entityID);
}
var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0;
var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(),
entityIntersection.properties.position)) * 180 / 3.14;
var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE)
&& (allowSmallModels || angularSize > MIN_ANGULAR_SIZE);
if (entityIntersection.entityID.isKnownID && sizeOK) {
if (wantEntityGlow) {
Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 });
}
highlightedEntityID = entityIntersection.entityID;
selectionDisplay.highlightSelectable(entityIntersection.entityID);
}
}
} else {
cameraManager.mouseMoveEvent(event);
}
}
function mouseReleaseEvent(event) {
if (!isActive) {
return;
}
if (selectionManager.hasSelection()) {
if (isActive && selectionManager.hasSelection()) {
tooltip.show(false);
}
cameraManager.mouseReleaseEvent(event);
}
@ -575,6 +596,11 @@ function setupModelMenus() {
Menu.addMenuItem({ menuName: "File", menuItemName: "Export Models", shortcutKey: "CTRL+META+E", afterItem: "Models" });
Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" });
Menu.addMenuItem({ menuName: "Developer", menuItemName: "Debug Ryans Rotation Problems", isCheckable: true });
Menu.addMenuItem({ menuName: "View", menuItemName: MENU_INSPECT_TOOL_ENABLED, afterItem: "Edit Entities Help...",
isCheckable: true, isChecked: Settings.getValue(SETTING_INSPECT_TOOL_ENABLED) == "true" });
Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED,
isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" });
}
setupModelMenus(); // do this when first running our script.
@ -596,9 +622,15 @@ function cleanupModelMenus() {
Menu.removeMenuItem("File", "Export Models");
Menu.removeMenuItem("File", "Import Models");
Menu.removeMenuItem("Developer", "Debug Ryans Rotation Problems");
Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED);
Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS);
}
Script.scriptEnding.connect(function() {
Settings.setValue(SETTING_INSPECT_TOOL_ENABLED, Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED));
Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
progressDialog.cleanup();
toolBar.cleanup();
cleanupModelMenus();
@ -718,7 +750,11 @@ Controller.keyReleaseEvent.connect(function (event) {
} else if (event.text == "TAB") {
selectionDisplay.toggleSpaceMode();
} else if (event.text == "f") {
cameraManager.focus();
if (isActive) {
cameraManager.focus(selectionManager.worldPosition,
selectionManager.worldDimensions,
Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
}
} else if (event.text == '[') {
if (isActive) {
cameraManager.enable();
@ -796,7 +832,6 @@ function applyEntityProperties(data) {
var properties = data.createEntities[i].properties;
var newEntityID = Entities.addEntity(properties);
DELETED_ENTITY_MAP[entityID.id] = newEntityID;
print(newEntityID.isKnownID);
if (data.selectCreated) {
selectedEntityIDs.push(newEntityID);
}

View file

@ -64,12 +64,6 @@ public:
/// clears the tree
virtual void clear();
//Q_INVOKABLE Model* getModel(const ModelEntityItem* modelEntityItem);
// renderers for various types of entities
void renderEntityTypeBox(EntityItem* entity, RenderArgs* args);
void renderEntityTypeModel(EntityItem* entity, RenderArgs* args);
static QThread* getMainThread();
/// if a renderable entity item needs a model, we will allocate it for them