Merge pull request #6309 from thoys/20724

CR for Job #20724 - Camera entity mode
This commit is contained in:
Brad Hefta-Gaub 2015-11-17 20:05:22 -08:00
commit a1e10a9f04
9 changed files with 130 additions and 5 deletions

View file

@ -1617,6 +1617,11 @@ PropertiesTool = function(opts) {
pushCommandForSelections();
selectionManager._update();
}
} else if (data.action == "previewCamera") {
if (selectionManager.hasSelection()) {
Camera.mode = "entity";
Camera.cameraEntity = selectionManager.selections[0];
}
} else if (data.action == "rescaleDimensions") {
var multiplier = data.percentage / 100;
if (selectionManager.hasSelection()) {

View file

@ -0,0 +1,57 @@
//
// securityCamera.js
// examples/example
//
// Created by Thijs Wenker on November 4, 2015
// Copyright 2015 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
//
const CAMERA_OFFSET = {x: 0, y: 4, z: -14};
const LOOKAT_START_OFFSET = {x: -10, y: 0, z: 14};
const LOOKAT_END_OFFSET = {x: 10, y: 0, z: 14};
const TINY_VALUE = 0.001;
var lookatTargets = [Vec3.sum(MyAvatar.position, LOOKAT_START_OFFSET), Vec3.sum(MyAvatar.position, LOOKAT_END_OFFSET)];
var currentTarget = 0;
var forward = true;
var oldCameraMode = Camera.mode;
var cameraLookAt = function(cameraPos, lookAtPos) {
var lookAtRaw = Quat.lookAt(cameraPos, lookAtPos, Vec3.UP);
lookAtRaw.w = -lookAtRaw.w;
return lookAtRaw;
};
cameraEntity = Entities.addEntity({
type: "Box",
visible: false,
position: Vec3.sum(MyAvatar.position, CAMERA_OFFSET)
});
Camera.mode = "entity";
Camera.cameraEntity = cameraEntity;
Script.update.connect(function(deltaTime) {
var cameraProperties = Entities.getEntityProperties(cameraEntity, ["position", "rotation"]);
var targetOrientation = cameraLookAt(cameraProperties.position, lookatTargets[currentTarget]);
if (Math.abs(targetOrientation.x - cameraProperties.rotation.x) < TINY_VALUE &&
Math.abs(targetOrientation.y - cameraProperties.rotation.y) < TINY_VALUE &&
Math.abs(targetOrientation.z - cameraProperties.rotation.z) < TINY_VALUE &&
Math.abs(targetOrientation.w - cameraProperties.rotation.w) < TINY_VALUE) {
currentTarget = (currentTarget + 1) % lookatTargets.length;
return;
}
Entities.editEntity(cameraEntity, {rotation: Quat.mix(cameraProperties.rotation, targetOrientation, deltaTime / 3)});
});
Script.scriptEnding.connect(function() {
Entities.deleteEntity(cameraEntity);
Camera.mode = oldCameraMode;
Camera.cameraEntity = null;
});

View file

@ -382,7 +382,7 @@
var elHyperlinkHref = document.getElementById("property-hyperlink-href");
var elHyperlinkDescription = document.getElementById("property-hyperlink-description");
var elPreviewCameraButton = document.getElementById("preview-camera-button");
if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) {
@ -931,6 +931,12 @@
action: "centerAtmosphereToZone",
}));
});
elPreviewCameraButton.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "previewCamera"
}));
});
window.onblur = function() {
// Fake a change event
@ -1032,7 +1038,7 @@
<div class="section-header">
<label>Spacial Properites</label>
<label>Spacial Properties</label>
</div>
<div class="property">
@ -1044,6 +1050,7 @@
<div>
<input type="button" id="move-selection-to-grid" value="Selection to Grid">
<input type="button" id="move-all-to-grid" value="All to Grid">
<input type="button" id="preview-camera-button" value="Preview Camera">
</div>
</div>
</div>

View file

@ -204,7 +204,7 @@ EntityPropertyDialogBox = (function () {
array.push({ label: "Collisions Will Move:", type: "checkbox", value: properties.collisionsWillMove });
index++;
array.push({ label: "Collision Sound URL:", value: properties.collisionSoundURL });
index++;
index++;
array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) });
index++;
@ -260,6 +260,10 @@ EntityPropertyDialogBox = (function () {
array.push({ label: "Cutoff (in degrees):", value: properties.cutoff });
index++;
}
array.push({ label: "", type: "inlineButton", buttonLabel: "Preview Camera", name: "previewCamera" });
index++;
array.push({ button: "Cancel" });
index++;
@ -268,6 +272,11 @@ EntityPropertyDialogBox = (function () {
};
Window.inlineButtonClicked.connect(function (name) {
if (name == "previewCamera") {
Camera.mode = "entity";
Camera.cameraEntity = propertiesForEditedEntity.id;
}
if (name == "resetDimensions") {
Window.reloadNonBlockingForm([
{ value: propertiesForEditedEntity.naturalDimensions.x.toFixed(decimals), oldIndex: dimensionX },

View file

@ -1226,6 +1226,19 @@ void Application::paintGL() {
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
}
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
} else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
if (cameraEntity != nullptr) {
if (isHMDMode()) {
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
_myCamera.setRotation(cameraEntity->getRotation() * hmdRotation);
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
_myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset));
} else {
_myCamera.setRotation(cameraEntity->getRotation());
_myCamera.setPosition(cameraEntity->getPosition());
}
}
}
// Update camera position
if (!isHMDMode()) {
@ -2676,8 +2689,8 @@ void Application::cycleCamera() {
menu->setIsOptionChecked(MenuOption::ThirdPerson, false);
menu->setIsOptionChecked(MenuOption::FullscreenMirror, true);
} else if (menu->isOptionChecked(MenuOption::IndependentMode)) {
// do nothing if in independe mode
} else if (menu->isOptionChecked(MenuOption::IndependentMode) || menu->isOptionChecked(MenuOption::CameraEntityMode)) {
// do nothing if in independent or camera entity modes
return;
}
cameraMenuChanged(); // handle the menu change
@ -2704,6 +2717,10 @@ void Application::cameraMenuChanged() {
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
_myCamera.setMode(CAMERA_MODE_INDEPENDENT);
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::CameraEntityMode)) {
if (_myCamera.getMode() != CAMERA_MODE_ENTITY) {
_myCamera.setMode(CAMERA_MODE_ENTITY);
}
}
}

View file

@ -28,6 +28,8 @@ CameraMode stringToMode(const QString& mode) {
return CAMERA_MODE_MIRROR;
} else if (mode == "independent") {
return CAMERA_MODE_INDEPENDENT;
} else if (mode == "entity") {
return CAMERA_MODE_ENTITY;
}
return CAMERA_MODE_NULL;
}
@ -41,6 +43,8 @@ QString modeToString(CameraMode mode) {
return "mirror";
} else if (mode == CAMERA_MODE_INDEPENDENT) {
return "independent";
} else if (mode == CAMERA_MODE_ENTITY) {
return "entity";
}
return "unknown";
}
@ -94,6 +98,17 @@ void Camera::setMode(CameraMode mode) {
emit modeUpdated(modeToString(mode));
}
QUuid Camera::getCameraEntity() const {
if (_cameraEntity != nullptr) {
return _cameraEntity->getID();
}
return QUuid();
};
void Camera::setCameraEntity(QUuid entityID) {
_cameraEntity = qApp->getEntities()->getTree()->findEntityByID(entityID);
}
void Camera::setProjection(const glm::mat4& projection) {
_projection = projection;
}
@ -118,6 +133,9 @@ void Camera::setModeString(const QString& mode) {
case CAMERA_MODE_INDEPENDENT:
Menu::getInstance()->setIsOptionChecked(MenuOption::IndependentMode, true);
break;
case CAMERA_MODE_ENTITY:
Menu::getInstance()->setIsOptionChecked(MenuOption::CameraEntityMode, true);
break;
default:
break;
}

View file

@ -24,6 +24,7 @@ enum CameraMode
CAMERA_MODE_FIRST_PERSON,
CAMERA_MODE_MIRROR,
CAMERA_MODE_INDEPENDENT,
CAMERA_MODE_ENTITY,
NUM_CAMERA_MODES
};
@ -36,6 +37,7 @@ class Camera : public QObject {
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity)
public:
Camera();
@ -49,6 +51,8 @@ public:
void loadViewFrustum(ViewFrustum& frustum) const;
ViewFrustum toViewFrustum() const;
EntityItemPointer getCameraEntityPointer() const { return _cameraEntity; }
public slots:
QString getModeString() const;
void setModeString(const QString& mode);
@ -68,6 +72,9 @@ public slots:
const glm::mat4& getProjection() const { return _projection; }
void setProjection(const glm::mat4& projection);
QUuid getCameraEntity() const;
void setCameraEntity(QUuid entityID);
PickRay computePickRay(float x, float y);
// These only work on independent cameras
@ -97,6 +104,7 @@ private:
glm::quat _rotation;
bool _isKeepLookingAt{ false };
glm::vec3 _lookingAt;
EntityItemPointer _cameraEntity;
};
#endif // hifi_Camera_h

View file

@ -268,6 +268,9 @@ Menu::Menu() {
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(cameraModeMenu,
MenuOption::IndependentMode, 0,
false, qApp, SLOT(cameraMenuChanged())));
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(cameraModeMenu,
MenuOption::CameraEntityMode, 0,
false, qApp, SLOT(cameraMenuChanged())));
cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(cameraModeMenu,
MenuOption::FullscreenMirror, 0, // QML Qt::Key_H,
false, qApp, SLOT(cameraMenuChanged())));

View file

@ -155,6 +155,7 @@ namespace MenuOption {
const QString Bookmarks = "Bookmarks";
const QString CachesSize = "RAM Caches Size";
const QString CalibrateCamera = "Calibrate Camera";
const QString CameraEntityMode = "Entity Mode";
const QString CenterPlayerInView = "Center Player In View";
const QString Chat = "Chat...";
const QString Collisions = "Collisions";