mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #6309 from thoys/20724
CR for Job #20724 - Camera entity mode
This commit is contained in:
commit
a1e10a9f04
9 changed files with 130 additions and 5 deletions
|
@ -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()) {
|
||||
|
|
57
examples/example/securityCamera.js
Normal file
57
examples/example/securityCamera.js
Normal 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;
|
||||
});
|
|
@ -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>
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())));
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in a new issue