mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 13:28:16 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into depthReticleWork
This commit is contained in:
commit
bd80ecd4dc
39 changed files with 837 additions and 714 deletions
|
@ -277,14 +277,17 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
|
||||||
// set of stats to have, but we'd probably want a different data structure if we keep it very long.
|
// set of stats to have, but we'd probably want a different data structure if we keep it very long.
|
||||||
// Since this version uses a single shared QMap for all senders, there could be some lock contention
|
// Since this version uses a single shared QMap for all senders, there could be some lock contention
|
||||||
// on this QWriteLocker
|
// on this QWriteLocker
|
||||||
void EntityServer::trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& viewerNode) {
|
void EntityServer::trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& sessionID) {
|
||||||
QWriteLocker locker(&_viewerSendingStatsLock);
|
QWriteLocker locker(&_viewerSendingStatsLock);
|
||||||
_viewerSendingStats[viewerNode][dataID] = { usecTimestampNow(), dataLastEdited };
|
_viewerSendingStats[sessionID][dataID] = { usecTimestampNow(), dataLastEdited };
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityServer::trackViewerGone(const QUuid& viewerNode) {
|
void EntityServer::trackViewerGone(const QUuid& sessionID) {
|
||||||
QWriteLocker locker(&_viewerSendingStatsLock);
|
QWriteLocker locker(&_viewerSendingStatsLock);
|
||||||
_viewerSendingStats.remove(viewerNode);
|
_viewerSendingStats.remove(sessionID);
|
||||||
|
if (_entitySimulation) {
|
||||||
|
_entitySimulation->clearOwnership(sessionID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EntityServer::serverSubclassStats() {
|
QString EntityServer::serverSubclassStats() {
|
||||||
|
|
|
@ -27,6 +27,8 @@ struct ViewerSendingStats {
|
||||||
quint64 lastEdited;
|
quint64 lastEdited;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SimpleEntitySimulation;
|
||||||
|
|
||||||
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
|
class EntityServer : public OctreeServer, public NewlyCreatedEntityHook {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -52,8 +54,8 @@ public:
|
||||||
virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject) override;
|
virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject) override;
|
||||||
virtual QString serverSubclassStats() override;
|
virtual QString serverSubclassStats() override;
|
||||||
|
|
||||||
virtual void trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& viewerNode) override;
|
virtual void trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& sessionID) override;
|
||||||
virtual void trackViewerGone(const QUuid& viewerNode) override;
|
virtual void trackViewerGone(const QUuid& sessionID) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void pruneDeletedEntities();
|
void pruneDeletedEntities();
|
||||||
|
@ -65,7 +67,7 @@ private slots:
|
||||||
void handleEntityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
void handleEntityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntitySimulation* _entitySimulation;
|
SimpleEntitySimulation* _entitySimulation;
|
||||||
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
||||||
|
|
||||||
QReadWriteLock _viewerSendingStatsLock;
|
QReadWriteLock _viewerSendingStatsLock;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
"use strict";
|
||||||
// handControllerGrab.js
|
// handControllerGrab.js
|
||||||
//
|
//
|
||||||
// Created by Eric Levin on 9/2/15
|
// Created by Eric Levin on 9/2/15
|
||||||
|
@ -801,6 +802,8 @@ function MyController(hand) {
|
||||||
this.isInitialGrab = false;
|
this.isInitialGrab = false;
|
||||||
this.doubleParentGrab = false;
|
this.doubleParentGrab = false;
|
||||||
|
|
||||||
|
this.checkForStrayChildren();
|
||||||
|
|
||||||
if (this.state == STATE_SEARCHING ? this.triggerSmoothedReleased() : this.bumperReleased()) {
|
if (this.state == STATE_SEARCHING ? this.triggerSmoothedReleased() : this.bumperReleased()) {
|
||||||
this.setState(STATE_RELEASE);
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
|
@ -1444,6 +1447,13 @@ function MyController(hand) {
|
||||||
this.heartBeat(this.grabbedEntity);
|
this.heartBeat(this.grabbedEntity);
|
||||||
|
|
||||||
var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "parentID", "position"]);
|
var props = Entities.getEntityProperties(this.grabbedEntity, ["localPosition", "parentID", "position"]);
|
||||||
|
if (!props.position) {
|
||||||
|
// server may have reset, taking our equipped entity with it. move back to "off" stte
|
||||||
|
this.setState(STATE_RELEASE);
|
||||||
|
this.callEntityMethodOnGrabbed("releaseGrab");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (props.parentID == MyAvatar.sessionUUID &&
|
if (props.parentID == MyAvatar.sessionUUID &&
|
||||||
Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) {
|
Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) {
|
||||||
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
|
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
|
||||||
|
@ -1751,6 +1761,17 @@ function MyController(hand) {
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.checkForStrayChildren = function() {
|
||||||
|
// sometimes things can get parented to a hand and this script is unaware. Search for such entities and
|
||||||
|
// unhook them.
|
||||||
|
var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||||
|
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex);
|
||||||
|
children.forEach(function(childID) {
|
||||||
|
print("disconnecting stray child of hand: (" + _this.hand + ") " + childID);
|
||||||
|
Entities.editEntity(childID, {parentID: NULL_UUID});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.deactivateEntity = function(entityID, noVelocity) {
|
this.deactivateEntity = function(entityID, noVelocity) {
|
||||||
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
|
var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {});
|
||||||
if (data && data["refCount"]) {
|
if (data && data["refCount"]) {
|
||||||
|
|
|
@ -17,8 +17,8 @@ var SIZE = 10.0;
|
||||||
var SEPARATION = 20.0;
|
var SEPARATION = 20.0;
|
||||||
var ROWS_X = 30;
|
var ROWS_X = 30;
|
||||||
var ROWS_Z = 30;
|
var ROWS_Z = 30;
|
||||||
var TYPE = "Sphere"; // Right now this can be "Box" or "Model" or "Sphere"
|
var TYPE = "Model"; // Right now this can be "Box" or "Model" or "Sphere"
|
||||||
var MODEL_URL = "https://hifi-public.s3.amazonaws.com/models/props/LowPolyIsland/CypressTreeGroup.fbx";
|
var MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/CellScience/Instances/vesicle.fbx";
|
||||||
var MODEL_DIMENSION = { x: 33, y: 16, z: 49 };
|
var MODEL_DIMENSION = { x: 33, y: 16, z: 49 };
|
||||||
var RATE_PER_SECOND = 1000; // The entity server will drop data if we create things too fast.
|
var RATE_PER_SECOND = 1000; // The entity server will drop data if we create things too fast.
|
||||||
var SCRIPT_INTERVAL = 100;
|
var SCRIPT_INTERVAL = 100;
|
||||||
|
@ -38,6 +38,7 @@ Script.setInterval(function () {
|
||||||
var numToCreate = RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0);
|
var numToCreate = RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0);
|
||||||
for (var i = 0; i < numToCreate; i++) {
|
for (var i = 0; i < numToCreate; i++) {
|
||||||
var position = { x: SIZE + (x * SEPARATION), y: SIZE, z: SIZE + (z * SEPARATION) };
|
var position = { x: SIZE + (x * SEPARATION), y: SIZE, z: SIZE + (z * SEPARATION) };
|
||||||
|
print('position:'+JSON.stringify(position))
|
||||||
if (TYPE == "Model") {
|
if (TYPE == "Model") {
|
||||||
Entities.addEntity({
|
Entities.addEntity({
|
||||||
type: TYPE,
|
type: TYPE,
|
||||||
|
|
|
@ -815,6 +815,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
} else if (action == controller::toInt(controller::Action::RETICLE_Y)) {
|
} else if (action == controller::toInt(controller::Action::RETICLE_Y)) {
|
||||||
auto oldPos = _compositor.getReticlePosition();
|
auto oldPos = _compositor.getReticlePosition();
|
||||||
_compositor.setReticlePosition({ oldPos.x, oldPos.y + state });
|
_compositor.setReticlePosition({ oldPos.x, oldPos.y + state });
|
||||||
|
} else if (action == controller::toInt(controller::Action::TOGGLE_OVERLAY)) {
|
||||||
|
toggleOverlays();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1197,7 +1199,6 @@ void Application::initializeUi() {
|
||||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||||
// support the window management and scripting proxies for VR use
|
// support the window management and scripting proxies for VR use
|
||||||
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
||||||
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
|
||||||
|
|
||||||
// FIXME either expose so that dialogs can set this themselves or
|
// FIXME either expose so that dialogs can set this themselves or
|
||||||
// do better detection in the offscreen UI of what has focus
|
// do better detection in the offscreen UI of what has focus
|
||||||
|
@ -2025,9 +2026,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson));
|
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson));
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
break;
|
break;
|
||||||
case Qt::Key_O:
|
|
||||||
_overlayConductor.setEnabled(!_overlayConductor.getEnabled());
|
|
||||||
break;
|
|
||||||
case Qt::Key_Slash:
|
case Qt::Key_Slash:
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Stats);
|
Menu::getInstance()->triggerOption(MenuOption::Stats);
|
||||||
break;
|
break;
|
||||||
|
@ -2432,6 +2431,19 @@ void Application::idle(uint64_t now) {
|
||||||
return; // bail early, nothing to do here.
|
return; // bail early, nothing to do here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stats::getInstance()->updateStats();
|
||||||
|
AvatarInputs::getInstance()->update();
|
||||||
|
|
||||||
|
// These tasks need to be done on our first idle, because we don't want the showing of
|
||||||
|
// overlay subwindows to do a showDesktop() until after the first time through
|
||||||
|
static bool firstIdle = true;
|
||||||
|
if (firstIdle) {
|
||||||
|
firstIdle = false;
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
||||||
|
_overlayConductor.setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Overlays));
|
||||||
|
}
|
||||||
|
|
||||||
auto displayPlugin = getActiveDisplayPlugin();
|
auto displayPlugin = getActiveDisplayPlugin();
|
||||||
// depending on whether we're throttling or not.
|
// depending on whether we're throttling or not.
|
||||||
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
||||||
|
@ -2975,6 +2987,16 @@ void Application::updateThreads(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::toggleOverlays() {
|
||||||
|
auto newOverlaysVisible = !_overlayConductor.getEnabled();
|
||||||
|
Menu::getInstance()->setIsOptionChecked(MenuOption::Overlays, newOverlaysVisible);
|
||||||
|
_overlayConductor.setEnabled(newOverlaysVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setOverlaysVisible(bool visible) {
|
||||||
|
_overlayConductor.setEnabled(visible);
|
||||||
|
}
|
||||||
|
|
||||||
void Application::cycleCamera() {
|
void Application::cycleCamera() {
|
||||||
auto menu = Menu::getInstance();
|
auto menu = Menu::getInstance();
|
||||||
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
|
|
|
@ -149,6 +149,7 @@ public:
|
||||||
const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; }
|
const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; }
|
||||||
ApplicationCompositor& getApplicationCompositor() { return _compositor; }
|
ApplicationCompositor& getApplicationCompositor() { return _compositor; }
|
||||||
const ApplicationCompositor& getApplicationCompositor() const { return _compositor; }
|
const ApplicationCompositor& getApplicationCompositor() const { return _compositor; }
|
||||||
|
|
||||||
Overlays& getOverlays() { return _overlays; }
|
Overlays& getOverlays() { return _overlays; }
|
||||||
|
|
||||||
bool isForeground() const { return _isForeground; }
|
bool isForeground() const { return _isForeground; }
|
||||||
|
@ -270,6 +271,8 @@ public slots:
|
||||||
|
|
||||||
void cycleCamera();
|
void cycleCamera();
|
||||||
void cameraMenuChanged();
|
void cameraMenuChanged();
|
||||||
|
void toggleOverlays();
|
||||||
|
void setOverlaysVisible(bool visible);
|
||||||
|
|
||||||
void reloadResourceCaches();
|
void reloadResourceCaches();
|
||||||
|
|
||||||
|
|
|
@ -247,6 +247,9 @@ Menu::Menu() {
|
||||||
0, true, qApp, SLOT(rotationModeChanged()),
|
0, true, qApp, SLOT(rotationModeChanged()),
|
||||||
UNSPECIFIED_POSITION, "Advanced");
|
UNSPECIFIED_POSITION, "Advanced");
|
||||||
|
|
||||||
|
// View > Overlays
|
||||||
|
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Overlays, 0, true,
|
||||||
|
qApp, SLOT(setOverlaysVisible(bool)));
|
||||||
|
|
||||||
// Navigate menu ----------------------------------
|
// Navigate menu ----------------------------------
|
||||||
MenuWrapper* navigateMenu = addMenu("Navigate");
|
MenuWrapper* navigateMenu = addMenu("Navigate");
|
||||||
|
|
|
@ -247,6 +247,7 @@ namespace MenuOption {
|
||||||
const QString OnePointCalibration = "1 Point Calibration";
|
const QString OnePointCalibration = "1 Point Calibration";
|
||||||
const QString OnlyDisplayTopTen = "Only Display Top Ten";
|
const QString OnlyDisplayTopTen = "Only Display Top Ten";
|
||||||
const QString OutputMenu = "Display";
|
const QString OutputMenu = "Display";
|
||||||
|
const QString Overlays = "Overlays";
|
||||||
const QString PackageModel = "Package Model...";
|
const QString PackageModel = "Package Model...";
|
||||||
const QString Pair = "Pair";
|
const QString Pair = "Pair";
|
||||||
const QString PhysicsShowHulls = "Draw Collision Hulls";
|
const QString PhysicsShowHulls = "Draw Collision Hulls";
|
||||||
|
|
|
@ -400,7 +400,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||||
frustum = qApp->getDisplayViewFrustum();
|
frustum = qApp->getDisplayViewFrustum();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) {
|
if (!frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) {
|
||||||
endRender();
|
endRender();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,25 +153,6 @@ std::shared_ptr<Avatar> AvatarActionHold::getTarget(float deltaTimeStep, glm::qu
|
||||||
palmPosition = holdingAvatar->getLeftPalmPosition();
|
palmPosition = holdingAvatar->getLeftPalmPosition();
|
||||||
palmRotation = holdingAvatar->getLeftPalmRotation();
|
palmRotation = holdingAvatar->getLeftPalmRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// In this case we are simulating the grab of another avatar.
|
|
||||||
// Because the hand controller velocity for their palms is not transmitted over the
|
|
||||||
// network, we have to synthesize our own.
|
|
||||||
|
|
||||||
if (_previousSet) {
|
|
||||||
// smooth linear velocity over two frames
|
|
||||||
glm::vec3 positionalDelta = palmPosition - _previousPositionalTarget;
|
|
||||||
linearVelocity = (positionalDelta + _previousPositionalDelta) / (deltaTimeStep + _previousDeltaTimeStep);
|
|
||||||
glm::quat deltaRotation = palmRotation * glm::inverse(_previousRotationalTarget);
|
|
||||||
float rotationAngle = glm::angle(deltaRotation);
|
|
||||||
if (rotationAngle > EPSILON) {
|
|
||||||
angularVelocity = glm::normalize(glm::axis(deltaRotation));
|
|
||||||
angularVelocity *= (rotationAngle / deltaTimeStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
_previousPositionalDelta = positionalDelta;
|
|
||||||
_previousDeltaTimeStep = deltaTimeStep;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rotation = palmRotation * _relativeRotation;
|
rotation = palmRotation * _relativeRotation;
|
||||||
|
@ -278,6 +259,7 @@ void AvatarActionHold::doKinematicUpdate(float deltaTimeStep) {
|
||||||
});
|
});
|
||||||
|
|
||||||
forceBodyNonStatic();
|
forceBodyNonStatic();
|
||||||
|
activateBody(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
bool AvatarActionHold::updateArguments(QVariantMap arguments) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ private:
|
||||||
float _textureAspectRatio { 1.0f };
|
float _textureAspectRatio { 1.0f };
|
||||||
int _hemiVerticesID { GeometryCache::UNKNOWN_ID };
|
int _hemiVerticesID { GeometryCache::UNKNOWN_ID };
|
||||||
|
|
||||||
float _alpha { 1.0f };
|
float _alpha { 0.0f }; // hidden by default
|
||||||
float _prevAlpha { 1.0f };
|
float _prevAlpha { 1.0f };
|
||||||
float _fadeInAlpha { true };
|
float _fadeInAlpha { true };
|
||||||
float _oculusUIRadius { 1.0f };
|
float _oculusUIRadius { 1.0f };
|
||||||
|
|
|
@ -58,10 +58,6 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||||
|
|
||||||
// TODO move to Application::idle()?
|
|
||||||
Stats::getInstance()->updateStats();
|
|
||||||
AvatarInputs::getInstance()->update();
|
|
||||||
|
|
||||||
buildFramebufferObject();
|
buildFramebufferObject();
|
||||||
|
|
||||||
if (!_overlayFramebuffer) {
|
if (!_overlayFramebuffer) {
|
||||||
|
|
|
@ -110,19 +110,12 @@ void OverlayConductor::setEnabled(bool enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Menu::getInstance()->setIsOptionChecked(MenuOption::Overlays, enabled);
|
||||||
|
|
||||||
|
_enabled = enabled; // set the new value
|
||||||
|
|
||||||
|
// if the new state is visible/enabled...
|
||||||
if (_enabled) {
|
if (_enabled) {
|
||||||
// alpha fadeOut the overlay mesh.
|
|
||||||
qApp->getApplicationCompositor().fadeOut();
|
|
||||||
|
|
||||||
// disable mouse clicks from script
|
|
||||||
qApp->getOverlays().disable();
|
|
||||||
|
|
||||||
// disable QML events
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
|
||||||
offscreenUi->getRootItem()->setEnabled(false);
|
|
||||||
|
|
||||||
_enabled = false;
|
|
||||||
} else {
|
|
||||||
// alpha fadeIn the overlay mesh.
|
// alpha fadeIn the overlay mesh.
|
||||||
qApp->getApplicationCompositor().fadeIn();
|
qApp->getApplicationCompositor().fadeIn();
|
||||||
|
|
||||||
|
@ -142,8 +135,16 @@ void OverlayConductor::setEnabled(bool enabled) {
|
||||||
t.setRotation(glm::quat_cast(camMat));
|
t.setRotation(glm::quat_cast(camMat));
|
||||||
qApp->getApplicationCompositor().setModelTransform(t);
|
qApp->getApplicationCompositor().setModelTransform(t);
|
||||||
}
|
}
|
||||||
|
} else { // other wise, if the new state is hidden/not enabled
|
||||||
|
// alpha fadeOut the overlay mesh.
|
||||||
|
qApp->getApplicationCompositor().fadeOut();
|
||||||
|
|
||||||
_enabled = true;
|
// disable mouse clicks from script
|
||||||
|
qApp->getOverlays().disable();
|
||||||
|
|
||||||
|
// disable QML events
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
offscreenUi->getRootItem()->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ private:
|
||||||
STANDING
|
STANDING
|
||||||
};
|
};
|
||||||
|
|
||||||
Mode _mode = FLAT;
|
Mode _mode { FLAT };
|
||||||
bool _enabled = true;
|
bool _enabled { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace controller {
|
||||||
makeButtonPair(Action::CONTEXT_MENU, "ContextMenu"),
|
makeButtonPair(Action::CONTEXT_MENU, "ContextMenu"),
|
||||||
makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"),
|
makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"),
|
||||||
makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"),
|
makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"),
|
||||||
|
makeButtonPair(Action::TOGGLE_OVERLAY, "ToggleOverlay"),
|
||||||
|
|
||||||
makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"),
|
makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"),
|
||||||
makeAxisPair(Action::RETICLE_X, "ReticleX"),
|
makeAxisPair(Action::RETICLE_X, "ReticleX"),
|
||||||
|
|
|
@ -52,6 +52,7 @@ enum class Action {
|
||||||
CONTEXT_MENU,
|
CONTEXT_MENU,
|
||||||
TOGGLE_MUTE,
|
TOGGLE_MUTE,
|
||||||
CYCLE_CAMERA,
|
CYCLE_CAMERA,
|
||||||
|
TOGGLE_OVERLAY,
|
||||||
|
|
||||||
SHIFT,
|
SHIFT,
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setModelTransform(transToCenter); // we want to include the scale as well
|
batch.setModelTransform(transToCenter); // we want to include the scale as well
|
||||||
if (_procedural->ready()) {
|
if (_procedural && _procedural->ready()) {
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions());
|
_procedural->prepare(batch, getPosition(), getDimensions());
|
||||||
auto color = _procedural->getColor(cubeColor);
|
auto color = _procedural->getColor(cubeColor);
|
||||||
batch._glColor4f(color.r, color.g, color.b, color.a);
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "EntityItemID.h"
|
#include "EntityItemID.h"
|
||||||
#include <VariantMapToScriptValue.h>
|
#include <VariantMapToScriptValue.h>
|
||||||
|
#include <SpatialParentFinder.h>
|
||||||
|
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
#include "EntityActionFactoryInterface.h"
|
#include "EntityActionFactoryInterface.h"
|
||||||
|
@ -1063,6 +1064,34 @@ QStringList EntityScriptingInterface::getJointNames(const QUuid& entityID) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<QUuid> EntityScriptingInterface::getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex) {
|
||||||
|
QVector<QUuid> result;
|
||||||
|
if (!_entityTree) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
_entityTree->withReadLock([&] {
|
||||||
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool success;
|
||||||
|
SpatiallyNestableWeakPointer parentWP = parentFinder->find(parentID, success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SpatiallyNestablePointer parent = parentWP.lock();
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parent->forEachChild([&](SpatiallyNestablePointer child) {
|
||||||
|
if (child->getParentJointIndex() == jointIndex) {
|
||||||
|
result.push_back(child->getID());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
float EntityScriptingInterface::calculateCost(float mass, float oldVelocity, float newVelocity) {
|
float EntityScriptingInterface::calculateCost(float mass, float oldVelocity, float newVelocity) {
|
||||||
return std::abs(mass * (newVelocity - oldVelocity));
|
return std::abs(mass * (newVelocity - oldVelocity));
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ public slots:
|
||||||
|
|
||||||
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name);
|
Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name);
|
||||||
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID);
|
Q_INVOKABLE QStringList getJointNames(const QUuid& entityID);
|
||||||
|
Q_INVOKABLE QVector<QUuid> getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||||
|
|
|
@ -18,51 +18,69 @@
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
#include "EntitiesLogging.h"
|
#include "EntitiesLogging.h"
|
||||||
|
|
||||||
const quint64 MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD = 2 * USECS_PER_SECOND;
|
const quint64 MAX_OWNERLESS_PERIOD = 2 * USECS_PER_SECOND;
|
||||||
|
|
||||||
void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
|
||||||
if (_entitiesWithSimulator.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now < _nextSimulationExpiry) {
|
|
||||||
// nothing has expired yet
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an Entity has a simulation owner but there has been no update for a while: clear the owner.
|
|
||||||
// If an Entity goes ownerless for too long: zero velocity and remove from _entitiesWithSimulator.
|
|
||||||
_nextSimulationExpiry = now + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD;
|
|
||||||
|
|
||||||
|
void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) {
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
SetOfEntities::iterator itemItr = _entitiesWithSimulator.begin();
|
SetOfEntities::iterator itemItr = _entitiesWithSimulationOwner.begin();
|
||||||
while (itemItr != _entitiesWithSimulator.end()) {
|
while (itemItr != _entitiesWithSimulationOwner.end()) {
|
||||||
EntityItemPointer entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
quint64 expiry = entity->getLastChangedOnServer() + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD;
|
if (entity->getSimulatorID() == ownerID) {
|
||||||
if (expiry < now) {
|
// the simulator has abandonded this object --> remove from owned list
|
||||||
if (entity->getSimulatorID().isNull()) {
|
qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID();
|
||||||
// no simulators are volunteering
|
itemItr = _entitiesWithSimulationOwner.erase(itemItr);
|
||||||
// zero the velocity on this entity so that it doesn't drift far away
|
|
||||||
entity->setVelocity(Vectors::ZERO);
|
if (entity->getDynamic() && entity->hasLocalVelocity()) {
|
||||||
entity->setAngularVelocity(Vectors::ZERO);
|
// it is still moving dynamically --> add to orphaned list
|
||||||
entity->setAcceleration(Vectors::ZERO);
|
_entitiesThatNeedSimulationOwner.insert(entity);
|
||||||
// remove from list
|
quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
|
||||||
itemItr = _entitiesWithSimulator.erase(itemItr);
|
if (expiry < _nextOwnerlessExpiry) {
|
||||||
continue;
|
_nextOwnerlessExpiry = expiry;
|
||||||
} else {
|
}
|
||||||
// the simulator has stopped updating this object
|
|
||||||
// clear ownership and restart timer, giving nearby simulators time to volunteer
|
|
||||||
qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID();
|
|
||||||
entity->clearSimulationOwnership();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove ownership and dirty all the tree elements that contain the it
|
||||||
|
entity->clearSimulationOwnership();
|
||||||
entity->markAsChangedOnServer();
|
entity->markAsChangedOnServer();
|
||||||
// dirty all the tree elements that contain the entity
|
|
||||||
DirtyOctreeElementOperator op(entity->getElement());
|
DirtyOctreeElementOperator op(entity->getElement());
|
||||||
getEntityTree()->recurseTreeWithOperator(&op);
|
getEntityTree()->recurseTreeWithOperator(&op);
|
||||||
} else if (expiry < _nextSimulationExpiry) {
|
} else {
|
||||||
_nextSimulationExpiry = expiry;
|
++itemItr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
||||||
|
if (now > _nextOwnerlessExpiry) {
|
||||||
|
// search for ownerless objects that have expired
|
||||||
|
QMutexLocker lock(&_mutex);
|
||||||
|
_nextOwnerlessExpiry = -1;
|
||||||
|
SetOfEntities::iterator itemItr = _entitiesThatNeedSimulationOwner.begin();
|
||||||
|
while (itemItr != _entitiesThatNeedSimulationOwner.end()) {
|
||||||
|
EntityItemPointer entity = *itemItr;
|
||||||
|
quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
|
||||||
|
if (expiry < now) {
|
||||||
|
// no simulators have volunteered ownership --> remove from list
|
||||||
|
itemItr = _entitiesThatNeedSimulationOwner.erase(itemItr);
|
||||||
|
|
||||||
|
if (entity->getSimulatorID().isNull() && entity->getDynamic() && entity->hasLocalVelocity()) {
|
||||||
|
// zero the derivatives
|
||||||
|
entity->setVelocity(Vectors::ZERO);
|
||||||
|
entity->setAngularVelocity(Vectors::ZERO);
|
||||||
|
entity->setAcceleration(Vectors::ZERO);
|
||||||
|
|
||||||
|
// dirty all the tree elements that contain it
|
||||||
|
entity->markAsChangedOnServer();
|
||||||
|
DirtyOctreeElementOperator op(entity->getElement());
|
||||||
|
getEntityTree()->recurseTreeWithOperator(&op);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++itemItr;
|
||||||
|
if (expiry < _nextOwnerlessExpiry) {
|
||||||
|
_nextOwnerlessExpiry = expiry;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++itemItr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,26 +88,47 @@ void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::addEntityInternal(entity);
|
EntitySimulation::addEntityInternal(entity);
|
||||||
if (!entity->getSimulatorID().isNull()) {
|
if (!entity->getSimulatorID().isNull()) {
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
_entitiesWithSimulator.insert(entity);
|
_entitiesWithSimulationOwner.insert(entity);
|
||||||
|
} else if (entity->getDynamic() && entity->hasLocalVelocity()) {
|
||||||
|
QMutexLocker lock(&_mutex);
|
||||||
|
_entitiesThatNeedSimulationOwner.insert(entity);
|
||||||
|
quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
|
||||||
|
if (expiry < _nextOwnerlessExpiry) {
|
||||||
|
_nextOwnerlessExpiry = expiry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::removeEntityInternal(entity);
|
EntitySimulation::removeEntityInternal(entity);
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
_entitiesWithSimulator.remove(entity);
|
_entitiesWithSimulationOwner.remove(entity);
|
||||||
|
_entitiesThatNeedSimulationOwner.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||||
EntitySimulation::changeEntityInternal(entity);
|
EntitySimulation::changeEntityInternal(entity);
|
||||||
if (!entity->getSimulatorID().isNull()) {
|
if (entity->getSimulatorID().isNull()) {
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
_entitiesWithSimulator.insert(entity);
|
_entitiesWithSimulationOwner.remove(entity);
|
||||||
|
if (entity->getDynamic() && entity->hasLocalVelocity()) {
|
||||||
|
_entitiesThatNeedSimulationOwner.insert(entity);
|
||||||
|
quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD;
|
||||||
|
if (expiry < _nextOwnerlessExpiry) {
|
||||||
|
_nextOwnerlessExpiry = expiry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QMutexLocker lock(&_mutex);
|
||||||
|
_entitiesWithSimulationOwner.insert(entity);
|
||||||
|
_entitiesThatNeedSimulationOwner.remove(entity);
|
||||||
}
|
}
|
||||||
entity->clearDirtyFlags();
|
entity->clearDirtyFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleEntitySimulation::clearEntitiesInternal() {
|
void SimpleEntitySimulation::clearEntitiesInternal() {
|
||||||
_entitiesWithSimulator.clear();
|
QMutexLocker lock(&_mutex);
|
||||||
|
_entitiesWithSimulationOwner.clear();
|
||||||
|
_entitiesThatNeedSimulationOwner.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
SimpleEntitySimulation() : EntitySimulation() { }
|
SimpleEntitySimulation() : EntitySimulation() { }
|
||||||
virtual ~SimpleEntitySimulation() { clearEntitiesInternal(); }
|
virtual ~SimpleEntitySimulation() { clearEntitiesInternal(); }
|
||||||
|
|
||||||
|
void clearOwnership(const QUuid& ownerID);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void updateEntitiesInternal(const quint64& now) override;
|
virtual void updateEntitiesInternal(const quint64& now) override;
|
||||||
virtual void addEntityInternal(EntityItemPointer entity) override;
|
virtual void addEntityInternal(EntityItemPointer entity) override;
|
||||||
|
@ -28,8 +30,9 @@ protected:
|
||||||
virtual void changeEntityInternal(EntityItemPointer entity) override;
|
virtual void changeEntityInternal(EntityItemPointer entity) override;
|
||||||
virtual void clearEntitiesInternal() override;
|
virtual void clearEntitiesInternal() override;
|
||||||
|
|
||||||
SetOfEntities _entitiesWithSimulator;
|
SetOfEntities _entitiesWithSimulationOwner;
|
||||||
quint64 _nextSimulationExpiry { 0 };
|
SetOfEntities _entitiesThatNeedSimulationOwner;
|
||||||
|
quint64 _nextOwnerlessExpiry { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SimpleEntitySimulation_h
|
#endif // hifi_SimpleEntitySimulation_h
|
||||||
|
|
|
@ -142,6 +142,8 @@ SunSkyStage::SunSkyStage() :
|
||||||
_skybox(std::make_shared<Skybox>())
|
_skybox(std::make_shared<Skybox>())
|
||||||
{
|
{
|
||||||
_sunLight->setType(Light::SUN);
|
_sunLight->setType(Light::SUN);
|
||||||
|
// Default ambient sphere (for lack of skybox)
|
||||||
|
_sunLight->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE);
|
||||||
|
|
||||||
setSunIntensity(1.0f);
|
setSunIntensity(1.0f);
|
||||||
setSunAmbientIntensity(0.5f);
|
setSunAmbientIntensity(0.5f);
|
||||||
|
|
|
@ -272,7 +272,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||||
|
|
||||||
if (_numInactiveUpdates > 0) {
|
if (_numInactiveUpdates > 0) {
|
||||||
const uint8_t MAX_NUM_INACTIVE_UPDATES = 3;
|
const uint8_t MAX_NUM_INACTIVE_UPDATES = 20;
|
||||||
if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) {
|
if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) {
|
||||||
// clear local ownership (stop sending updates) and let the server clear itself
|
// clear local ownership (stop sending updates) and let the server clear itself
|
||||||
_entity->clearSimulationOwnership();
|
_entity->clearSimulationOwnership();
|
||||||
|
@ -282,7 +282,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
|
||||||
// until it is removed from the outgoing updates
|
// until it is removed from the outgoing updates
|
||||||
// (which happens when we don't own the simulation and it isn't touching our simulation)
|
// (which happens when we don't own the simulation and it isn't touching our simulation)
|
||||||
const float INACTIVE_UPDATE_PERIOD = 0.5f;
|
const float INACTIVE_UPDATE_PERIOD = 0.5f;
|
||||||
return (dt > INACTIVE_UPDATE_PERIOD);
|
return (dt > INACTIVE_UPDATE_PERIOD * (float)_numInactiveUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_body->isActive()) {
|
if (!_body->isActive()) {
|
||||||
|
@ -404,8 +404,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q
|
||||||
assert(_entity);
|
assert(_entity);
|
||||||
assert(entityTreeIsLocked());
|
assert(entityTreeIsLocked());
|
||||||
|
|
||||||
bool active = _body->isActive();
|
if (!_body->isActive()) {
|
||||||
if (!active) {
|
|
||||||
// make sure all derivatives are zero
|
// make sure all derivatives are zero
|
||||||
glm::vec3 zero(0.0f);
|
glm::vec3 zero(0.0f);
|
||||||
_entity->setVelocity(zero);
|
_entity->setVelocity(zero);
|
||||||
|
@ -495,16 +494,12 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q
|
||||||
qCDebug(physics) << " lastSimulated:" << debugTime(lastSimulated, now);
|
qCDebug(physics) << " lastSimulated:" << debugTime(lastSimulated, now);
|
||||||
#endif //def WANT_DEBUG
|
#endif //def WANT_DEBUG
|
||||||
|
|
||||||
if (sessionID == _entity->getSimulatorID()) {
|
if (_numInactiveUpdates > 0) {
|
||||||
// we think we own the simulation
|
// we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID
|
||||||
if (!active) {
|
// but we remember that we do still own it... and rely on the server to tell us that we don't
|
||||||
// we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID
|
properties.clearSimulationOwner();
|
||||||
// but we remember that we do still own it... and rely on the server to tell us that we don't
|
_outgoingPriority = ZERO_SIMULATION_PRIORITY;
|
||||||
properties.clearSimulationOwner();
|
} else if (sessionID != _entity->getSimulatorID()) {
|
||||||
_outgoingPriority = ZERO_SIMULATION_PRIORITY;
|
|
||||||
}
|
|
||||||
// else the ownership is not changing so we don't bother to pack it
|
|
||||||
} else {
|
|
||||||
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
// we don't own the simulation for this entity yet, but we're sending a bid for it
|
||||||
properties.setSimulationOwner(sessionID, glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY));
|
properties.setSimulationOwner(sessionID, glm::max<uint8_t>(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY));
|
||||||
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS;
|
_nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS;
|
||||||
|
|
|
@ -87,14 +87,11 @@ void DeferredLightingEffect::init() {
|
||||||
_allocatedLights.push_back(std::make_shared<model::Light>());
|
_allocatedLights.push_back(std::make_shared<model::Light>());
|
||||||
|
|
||||||
model::LightPointer lp = _allocatedLights[0];
|
model::LightPointer lp = _allocatedLights[0];
|
||||||
|
lp->setType(model::Light::SUN);
|
||||||
|
|
||||||
// Add the global light to the light stage (for later shadow rendering)
|
// Add the global light to the light stage (for later shadow rendering)
|
||||||
_lightStage.addLight(lp);
|
_lightStage.addLight(lp);
|
||||||
|
|
||||||
lp->setDirection(-glm::vec3(1.0f, 1.0f, 1.0f));
|
|
||||||
lp->setColor(glm::vec3(1.0f));
|
|
||||||
lp->setIntensity(1.0f);
|
|
||||||
lp->setType(model::Light::SUN);
|
|
||||||
lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
|
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color,
|
||||||
|
@ -560,7 +557,13 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture) {
|
void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture) {
|
||||||
_allocatedLights.front() = light;
|
auto globalLight = _allocatedLights.front();
|
||||||
|
globalLight->setDirection(light->getDirection());
|
||||||
|
globalLight->setColor(light->getColor());
|
||||||
|
globalLight->setIntensity(light->getIntensity());
|
||||||
|
globalLight->setAmbientIntensity(light->getAmbientIntensity());
|
||||||
|
globalLight->setAmbientSphere(light->getAmbientSphere());
|
||||||
|
|
||||||
_skyboxTexture = skyboxTexture;
|
_skyboxTexture = skyboxTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "SpatiallyNestable.h"
|
#include "SpatiallyNestable.h"
|
||||||
|
|
||||||
const float defaultAACubeSize = 1.0f;
|
const float defaultAACubeSize = 1.0f;
|
||||||
|
const int maxParentingChain = 30;
|
||||||
|
|
||||||
SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
||||||
_nestableType(nestableType),
|
_nestableType(nestableType),
|
||||||
|
@ -56,14 +57,14 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform SpatiallyNestable::getParentTransform(bool& success) const {
|
Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const {
|
||||||
Transform result;
|
Transform result;
|
||||||
SpatiallyNestablePointer parent = getParentPointer(success);
|
SpatiallyNestablePointer parent = getParentPointer(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
Transform parentTransform = parent->getTransform(_parentJointIndex, success);
|
Transform parentTransform = parent->getTransform(_parentJointIndex, success, depth + 1);
|
||||||
result = parentTransform.setScale(1.0f); // TODO: scaling
|
result = parentTransform.setScale(1.0f); // TODO: scaling
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -393,11 +394,11 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation) {
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getVelocity(bool& success) const {
|
glm::vec3 SpatiallyNestable::getVelocity(bool& success) const {
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
glm::vec3 parentVelocity = getParentVelocity(success);
|
Transform parentTransform = getParentTransform(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
Transform parentTransform = getParentTransform(success);
|
glm::vec3 parentVelocity = getParentVelocity(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -448,11 +449,11 @@ glm::vec3 SpatiallyNestable::getParentVelocity(bool& success) const {
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getAngularVelocity(bool& success) const {
|
glm::vec3 SpatiallyNestable::getAngularVelocity(bool& success) const {
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
glm::vec3 parentAngularVelocity = getParentAngularVelocity(success);
|
Transform parentTransform = getParentTransform(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
Transform parentTransform = getParentTransform(success);
|
glm::vec3 parentAngularVelocity = getParentAngularVelocity(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -499,22 +500,36 @@ glm::vec3 SpatiallyNestable::getParentAngularVelocity(bool& success) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getTransform(bool& success) const {
|
const Transform SpatiallyNestable::getTransform(bool& success, int depth) const {
|
||||||
// return a world-space transform for this object's location
|
|
||||||
Transform parentTransform = getParentTransform(success);
|
|
||||||
Transform result;
|
Transform result;
|
||||||
|
// return a world-space transform for this object's location
|
||||||
|
Transform parentTransform = getParentTransform(success, depth);
|
||||||
_transformLock.withReadLock([&] {
|
_transformLock.withReadLock([&] {
|
||||||
Transform::mult(result, parentTransform, _transform);
|
Transform::mult(result, parentTransform, _transform);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success) const {
|
const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) const {
|
||||||
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
||||||
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
||||||
Transform jointInWorldFrame;
|
Transform jointInWorldFrame;
|
||||||
|
|
||||||
Transform worldTransform = getTransform(success);
|
if (depth > maxParentingChain) {
|
||||||
|
success = false;
|
||||||
|
// someone created a loop. break it...
|
||||||
|
qDebug() << "Parenting loop detected.";
|
||||||
|
SpatiallyNestablePointer _this = getThisPointer();
|
||||||
|
_this->setParentID(QUuid());
|
||||||
|
bool setPositionSuccess;
|
||||||
|
AACube aaCube = getQueryAACube(setPositionSuccess);
|
||||||
|
if (setPositionSuccess) {
|
||||||
|
_this->setPosition(aaCube.calcCenter());
|
||||||
|
}
|
||||||
|
return jointInWorldFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform worldTransform = getTransform(success, depth);
|
||||||
worldTransform.setScale(1.0f); // TODO -- scale;
|
worldTransform.setScale(1.0f); // TODO -- scale;
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return jointInWorldFrame;
|
return jointInWorldFrame;
|
||||||
|
@ -682,7 +697,7 @@ QList<SpatiallyNestablePointer> SpatiallyNestable::getChildren() const {
|
||||||
_childrenLock.withReadLock([&] {
|
_childrenLock.withReadLock([&] {
|
||||||
foreach(SpatiallyNestableWeakPointer childWP, _children.values()) {
|
foreach(SpatiallyNestableWeakPointer childWP, _children.values()) {
|
||||||
SpatiallyNestablePointer child = childWP.lock();
|
SpatiallyNestablePointer child = childWP.lock();
|
||||||
if (child) {
|
if (child && child->_parentKnowsMe && child->getParentID() == getID()) {
|
||||||
children << child;
|
children << child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,10 +52,10 @@ public:
|
||||||
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
||||||
|
|
||||||
// world frame
|
// world frame
|
||||||
virtual const Transform getTransform(bool& success) const;
|
virtual const Transform getTransform(bool& success, int depth = 0) const;
|
||||||
virtual void setTransform(const Transform& transform, bool& success);
|
virtual void setTransform(const Transform& transform, bool& success);
|
||||||
|
|
||||||
virtual Transform getParentTransform(bool& success) const;
|
virtual Transform getParentTransform(bool& success, int depth = 0) const;
|
||||||
|
|
||||||
virtual glm::vec3 getPosition(bool& success) const;
|
virtual glm::vec3 getPosition(bool& success) const;
|
||||||
virtual glm::vec3 getPosition() const;
|
virtual glm::vec3 getPosition() const;
|
||||||
|
@ -92,7 +92,7 @@ public:
|
||||||
virtual void setScale(const glm::vec3& scale);
|
virtual void setScale(const glm::vec3& scale);
|
||||||
|
|
||||||
// get world-frame values for a specific joint
|
// get world-frame values for a specific joint
|
||||||
virtual const Transform getTransform(int jointIndex, bool& success) const;
|
virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const;
|
||||||
virtual glm::vec3 getPosition(int jointIndex, bool& success) const;
|
virtual glm::vec3 getPosition(int jointIndex, bool& success) const;
|
||||||
virtual glm::vec3 getScale(int jointIndex) const;
|
virtual glm::vec3 getScale(int jointIndex) const;
|
||||||
|
|
||||||
|
|
|
@ -460,6 +460,7 @@ void OffscreenUi::unfocusWindows() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenUi::toggleMenu(const QPoint& screenPosition) {
|
void OffscreenUi::toggleMenu(const QPoint& screenPosition) {
|
||||||
|
emit showDesktop(); // we really only want to do this if you're showing the menu, but for now this works
|
||||||
auto virtualPos = mapToVirtualScreen(screenPosition, nullptr);
|
auto virtualPos = mapToVirtualScreen(screenPosition, nullptr);
|
||||||
QMetaObject::invokeMethod(_desktop, "toggleMenu", Q_ARG(QVariant, virtualPos));
|
QMetaObject::invokeMethod(_desktop, "toggleMenu", Q_ARG(QVariant, virtualPos));
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,10 +60,10 @@ void ViveControllerManager::activate() {
|
||||||
[this] (bool clicked) { this->setRenderControllers(clicked); },
|
[this] (bool clicked) { this->setRenderControllers(clicked); },
|
||||||
true, true);
|
true, true);
|
||||||
|
|
||||||
if (!_hmd) {
|
if (!_system) {
|
||||||
_hmd = acquireOpenVrSystem();
|
_system = acquireOpenVrSystem();
|
||||||
}
|
}
|
||||||
Q_ASSERT(_hmd);
|
Q_ASSERT(_system);
|
||||||
|
|
||||||
// OpenVR provides 3d mesh representations of the controllers
|
// OpenVR provides 3d mesh representations of the controllers
|
||||||
// Disabled controller rendering code
|
// Disabled controller rendering code
|
||||||
|
@ -71,7 +71,7 @@ void ViveControllerManager::activate() {
|
||||||
auto renderModels = vr::VRRenderModels();
|
auto renderModels = vr::VRRenderModels();
|
||||||
|
|
||||||
vr::RenderModel_t model;
|
vr::RenderModel_t model;
|
||||||
if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) {
|
if (!_system->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) {
|
||||||
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
|
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
|
||||||
} else {
|
} else {
|
||||||
model::Mesh* mesh = new model::Mesh();
|
model::Mesh* mesh = new model::Mesh();
|
||||||
|
@ -118,7 +118,7 @@ void ViveControllerManager::activate() {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// unregister with UserInputMapper
|
// register with UserInputMapper
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
userInputMapper->registerDevice(_inputDevice);
|
userInputMapper->registerDevice(_inputDevice);
|
||||||
_registeredWithInputMapper = true;
|
_registeredWithInputMapper = true;
|
||||||
|
@ -130,9 +130,9 @@ void ViveControllerManager::deactivate() {
|
||||||
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
||||||
_container->removeMenu(MENU_PATH);
|
_container->removeMenu(MENU_PATH);
|
||||||
|
|
||||||
if (_hmd) {
|
if (_system) {
|
||||||
releaseOpenVrSystem();
|
releaseOpenVrSystem();
|
||||||
_hmd = nullptr;
|
_system = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputDevice->_poseStateMap.clear();
|
_inputDevice->_poseStateMap.clear();
|
||||||
|
@ -226,56 +226,56 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
|
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
||||||
PerformanceTimer perfTimer("ViveControllerManager::update");
|
PerformanceTimer perfTimer("ViveControllerManager::update");
|
||||||
|
|
||||||
|
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
||||||
|
auto rightHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
|
||||||
|
|
||||||
|
if (!jointsCaptured) {
|
||||||
|
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
|
||||||
|
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
||||||
|
}
|
||||||
|
|
||||||
int numTrackedControllers = 0;
|
int numTrackedControllers = 0;
|
||||||
|
if (leftHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
||||||
for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
|
|
||||||
device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
|
|
||||||
|
|
||||||
if (!_hmd->IsTrackedDeviceConnected(device)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_trackedDevicePose[device].bPoseIsValid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
numTrackedControllers++;
|
numTrackedControllers++;
|
||||||
bool left = numTrackedControllers == 2;
|
}
|
||||||
|
if (rightHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
||||||
|
numTrackedControllers++;
|
||||||
|
}
|
||||||
|
_trackedControllers = numTrackedControllers;
|
||||||
|
}
|
||||||
|
|
||||||
if (!jointsCaptured) {
|
void ViveControllerManager::InputDevice::handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand) {
|
||||||
const mat4& mat = _trackedDevicePoseMat4[device];
|
|
||||||
const vec3 linearVelocity = _trackedDeviceLinearVelocities[device];
|
if (_system->IsTrackedDeviceConnected(deviceIndex) &&
|
||||||
const vec3 angularVelocity = _trackedDeviceAngularVelocities[device];
|
_system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_Controller &&
|
||||||
handlePoseEvent(inputCalibrationData, mat, linearVelocity, angularVelocity, numTrackedControllers - 1);
|
_trackedDevicePose[deviceIndex].bPoseIsValid) {
|
||||||
}
|
|
||||||
|
// process pose
|
||||||
|
const mat4& mat = _trackedDevicePoseMat4[deviceIndex];
|
||||||
|
const vec3 linearVelocity = _trackedDeviceLinearVelocities[deviceIndex];
|
||||||
|
const vec3 angularVelocity = _trackedDeviceAngularVelocities[deviceIndex];
|
||||||
|
handlePoseEvent(deltaTime, inputCalibrationData, mat, linearVelocity, angularVelocity, isLeftHand);
|
||||||
|
|
||||||
// handle inputs
|
|
||||||
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
||||||
if (_hmd->GetControllerState(device, &controllerState)) {
|
if (_system->GetControllerState(deviceIndex, &controllerState)) {
|
||||||
//qDebug() << (numTrackedControllers == 1 ? "Left: " : "Right: ");
|
|
||||||
//qDebug() << "Trackpad: " << controllerState.rAxis[0].x << " " << controllerState.rAxis[0].y;
|
// process each button
|
||||||
//qDebug() << "Trigger: " << controllerState.rAxis[1].x << " " << controllerState.rAxis[1].y;
|
|
||||||
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
for (uint32_t i = 0; i < vr::k_EButton_Max; ++i) {
|
||||||
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
auto mask = vr::ButtonMaskFromId((vr::EVRButtonId)i);
|
||||||
bool pressed = 0 != (controllerState.ulButtonPressed & mask);
|
bool pressed = 0 != (controllerState.ulButtonPressed & mask);
|
||||||
handleButtonEvent(i, pressed, left);
|
handleButtonEvent(deltaTime, i, pressed, isLeftHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process each axis
|
||||||
for (uint32_t i = 0; i < vr::k_unControllerStateAxisCount; i++) {
|
for (uint32_t i = 0; i < vr::k_unControllerStateAxisCount; i++) {
|
||||||
handleAxisEvent(i, controllerState.rAxis[i].x, controllerState.rAxis[i].y, left);
|
handleAxisEvent(deltaTime, i, controllerState.rAxis[i].x, controllerState.rAxis[i].y, isLeftHand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_trackedControllers = numTrackedControllers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::focusOutEvent() {
|
void ViveControllerManager::InputDevice::focusOutEvent() {
|
||||||
|
@ -284,42 +284,46 @@ void ViveControllerManager::InputDevice::focusOutEvent() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// These functions do translation from the Steam IDs to the standard controller IDs
|
// These functions do translation from the Steam IDs to the standard controller IDs
|
||||||
void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) {
|
void ViveControllerManager::InputDevice::handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand) {
|
||||||
//FIX ME? It enters here every frame: probably we want to enter only if an event occurs
|
//FIX ME? It enters here every frame: probably we want to enter only if an event occurs
|
||||||
axis += vr::k_EButton_Axis0;
|
axis += vr::k_EButton_Axis0;
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
|
|
||||||
if (axis == vr::k_EButton_SteamVR_Touchpad) {
|
if (axis == vr::k_EButton_SteamVR_Touchpad) {
|
||||||
_axisStateMap[left ? LX : RX] = x;
|
glm::vec2 stick(x, y);
|
||||||
_axisStateMap[left ? LY : RY] = y;
|
if (isLeftHand) {
|
||||||
|
stick = _filteredLeftStick.process(deltaTime, stick);
|
||||||
|
} else {
|
||||||
|
stick = _filteredRightStick.process(deltaTime, stick);
|
||||||
|
}
|
||||||
|
_axisStateMap[isLeftHand ? LX : RX] = stick.x;
|
||||||
|
_axisStateMap[isLeftHand ? LY : RY] = stick.y;
|
||||||
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
|
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
|
||||||
_axisStateMap[left ? LT : RT] = x;
|
_axisStateMap[isLeftHand ? LT : RT] = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions do translation from the Steam IDs to the standard controller IDs
|
// These functions do translation from the Steam IDs to the standard controller IDs
|
||||||
void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) {
|
void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool isLeftHand) {
|
||||||
if (!pressed) {
|
if (!pressed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace controller;
|
||||||
if (button == vr::k_EButton_ApplicationMenu) {
|
if (button == vr::k_EButton_ApplicationMenu) {
|
||||||
_buttonPressedMap.insert(left ? controller::LEFT_PRIMARY_THUMB : controller::RIGHT_PRIMARY_THUMB);
|
_buttonPressedMap.insert(isLeftHand ? LEFT_PRIMARY_THUMB : RIGHT_PRIMARY_THUMB);
|
||||||
} else if (button == vr::k_EButton_Grip) {
|
} else if (button == vr::k_EButton_Grip) {
|
||||||
// Tony says these are harder to reach, so make them the meta buttons
|
_buttonPressedMap.insert(isLeftHand ? LB : RB);
|
||||||
_buttonPressedMap.insert(left ? controller::LB : controller::RB);
|
|
||||||
} else if (button == vr::k_EButton_SteamVR_Trigger) {
|
} else if (button == vr::k_EButton_SteamVR_Trigger) {
|
||||||
_buttonPressedMap.insert(left ? controller::LT : controller::RT);
|
_buttonPressedMap.insert(isLeftHand ? LT : RT);
|
||||||
} else if (button == vr::k_EButton_SteamVR_Touchpad) {
|
} else if (button == vr::k_EButton_SteamVR_Touchpad) {
|
||||||
_buttonPressedMap.insert(left ? controller::LS : controller::RS);
|
_buttonPressedMap.insert(isLeftHand ? LS : RS);
|
||||||
} else if (button == vr::k_EButton_System) {
|
|
||||||
//FIX ME: not able to ovrewrite the behaviour of this button
|
|
||||||
_buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::handlePoseEvent(const controller::InputCalibrationData& inputCalibrationData,
|
void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData,
|
||||||
const mat4& mat, const vec3& linearVelocity,
|
const mat4& mat, const vec3& linearVelocity,
|
||||||
const vec3& angularVelocity, bool left) {
|
const vec3& angularVelocity, bool isLeftHand) {
|
||||||
// When the sensor-to-world rotation is identity the coordinate axes look like this:
|
// When the sensor-to-world rotation is identity the coordinate axes look like this:
|
||||||
//
|
//
|
||||||
// user
|
// user
|
||||||
|
@ -384,8 +388,8 @@ void ViveControllerManager::InputDevice::handlePoseEvent(const controller::Input
|
||||||
static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET;
|
static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET;
|
||||||
static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET;
|
static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET;
|
||||||
|
|
||||||
auto translationOffset = (left ? leftTranslationOffset : rightTranslationOffset);
|
auto translationOffset = (isLeftHand ? leftTranslationOffset : rightTranslationOffset);
|
||||||
auto rotationOffset = (left ? leftRotationOffset : rightRotationOffset);
|
auto rotationOffset = (isLeftHand ? leftRotationOffset : rightRotationOffset);
|
||||||
|
|
||||||
glm::vec3 position = extractTranslation(mat);
|
glm::vec3 position = extractTranslation(mat);
|
||||||
glm::quat rotation = glm::normalize(glm::quat_cast(mat));
|
glm::quat rotation = glm::normalize(glm::quat_cast(mat));
|
||||||
|
@ -399,7 +403,7 @@ void ViveControllerManager::InputDevice::handlePoseEvent(const controller::Input
|
||||||
// handle change in velocity due to translationOffset
|
// handle change in velocity due to translationOffset
|
||||||
avatarPose.velocity = linearVelocity + glm::cross(angularVelocity, position - extractTranslation(mat));
|
avatarPose.velocity = linearVelocity + glm::cross(angularVelocity, position - extractTranslation(mat));
|
||||||
avatarPose.angularVelocity = angularVelocity;
|
avatarPose.angularVelocity = angularVelocity;
|
||||||
_poseStateMap[left ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar);
|
_poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const {
|
controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const {
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
private:
|
private:
|
||||||
class InputDevice : public controller::InputDevice {
|
class InputDevice : public controller::InputDevice {
|
||||||
public:
|
public:
|
||||||
InputDevice(vr::IVRSystem*& hmd) : controller::InputDevice("Vive"), _hmd(hmd) {}
|
InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {}
|
||||||
private:
|
private:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
|
@ -58,20 +58,46 @@ private:
|
||||||
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
void handleButtonEvent(uint32_t button, bool pressed, bool left);
|
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
|
||||||
void handleAxisEvent(uint32_t axis, float x, float y, bool left);
|
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool isLeftHand);
|
||||||
void handlePoseEvent(const controller::InputCalibrationData& inputCalibrationData, const mat4& mat,
|
void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand);
|
||||||
const vec3& linearVelocity, const vec3& angularVelocity, bool left);
|
void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const mat4& mat,
|
||||||
|
const vec3& linearVelocity, const vec3& angularVelocity, bool isLeftHand);
|
||||||
|
|
||||||
|
class FilteredStick {
|
||||||
|
public:
|
||||||
|
glm::vec2 process(float deltaTime, const glm::vec2& stick) {
|
||||||
|
// Use a timer to prevent the stick going to back to zero.
|
||||||
|
// This to work around the noisy touch pad that will flash back to zero breifly
|
||||||
|
const float ZERO_HYSTERESIS_PERIOD = 0.2f; // 200 ms
|
||||||
|
if (glm::length(stick) == 0.0f) {
|
||||||
|
if (_timer <= 0.0f) {
|
||||||
|
return glm::vec2(0.0f, 0.0f);
|
||||||
|
} else {
|
||||||
|
_timer -= deltaTime;
|
||||||
|
return _stick;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_timer = ZERO_HYSTERESIS_PERIOD;
|
||||||
|
_stick = stick;
|
||||||
|
return stick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
float _timer { 0.0f };
|
||||||
|
glm::vec2 _stick { 0.0f, 0.0f };
|
||||||
|
};
|
||||||
|
|
||||||
|
FilteredStick _filteredLeftStick;
|
||||||
|
FilteredStick _filteredRightStick;
|
||||||
|
|
||||||
int _trackedControllers { 0 };
|
int _trackedControllers { 0 };
|
||||||
vr::IVRSystem*& _hmd;
|
vr::IVRSystem*& _system;
|
||||||
friend class ViveControllerManager;
|
friend class ViveControllerManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool _registeredWithInputMapper { false };
|
bool _registeredWithInputMapper { false };
|
||||||
bool _modelLoaded { false };
|
bool _modelLoaded { false };
|
||||||
model::Geometry _modelGeometry;
|
model::Geometry _modelGeometry;
|
||||||
|
@ -81,8 +107,8 @@ private:
|
||||||
int _rightHandRenderID { 0 };
|
int _rightHandRenderID { 0 };
|
||||||
|
|
||||||
bool _renderControllers { false };
|
bool _renderControllers { false };
|
||||||
vr::IVRSystem* _hmd { nullptr };
|
vr::IVRSystem* _system { nullptr };
|
||||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_hmd) };
|
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_system) };
|
||||||
|
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
|
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
// Copyright 2016 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
|
|
||||||
//
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.preload = function(entityId) {
|
|
||||||
//print('preload move randomly')
|
|
||||||
this.isConnected = false;
|
|
||||||
this.entityId = entityId;
|
|
||||||
this.updateInterval = 100;
|
|
||||||
this.posFrame = 0;
|
|
||||||
this.rotFrame = 0;
|
|
||||||
this.posInterval = 100;
|
|
||||||
this.rotInterval = 100;
|
|
||||||
this.minVelocity = 1;
|
|
||||||
this.maxVelocity = 5;
|
|
||||||
this.minAngularVelocity = 0.01;
|
|
||||||
this.maxAngularVelocity = 0.03;
|
|
||||||
|
|
||||||
this.initialize(entityId);
|
|
||||||
this.initTimeout = null;
|
|
||||||
|
|
||||||
|
|
||||||
var userData = {
|
|
||||||
ownershipKey: {
|
|
||||||
owner: MyAvatar.sessionUUID
|
|
||||||
},
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Entities.editEntity(entityId, {
|
|
||||||
userData: JSON.stringify(userData)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
this.initialize = function(entityId) {
|
|
||||||
//print('move randomly should initialize' + entityId)
|
|
||||||
var properties = Entities.getEntityProperties(entityId);
|
|
||||||
if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) {
|
|
||||||
self.initTimeout = Script.setTimeout(function() {
|
|
||||||
//print('no user data yet, try again in one second')
|
|
||||||
self.initialize(entityId);
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//print('userdata before parse attempt' + properties.userData)
|
|
||||||
self.userData = null;
|
|
||||||
try {
|
|
||||||
self.userData = JSON.parse(properties.userData);
|
|
||||||
} catch (err) {
|
|
||||||
//print('error parsing json');
|
|
||||||
//print('properties are:' + properties.userData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Script.update.connect(self.update);
|
|
||||||
this.isConnected = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.update = function(deltaTime) {
|
|
||||||
// print('jbp in update')
|
|
||||||
var data = Entities.getEntityProperties(self.entityId, 'userData').userData;
|
|
||||||
var userData;
|
|
||||||
try {
|
|
||||||
userData = JSON.parse(data)
|
|
||||||
} catch (e) {
|
|
||||||
//print('error parsing json' + data)
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// print('userdata is' + data)
|
|
||||||
//if the entity doesnt have an owner set yet
|
|
||||||
if (userData.hasOwnProperty('ownershipKey') !== true) {
|
|
||||||
//print('no movement owner yet')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//print('owner is:::' + userData.ownershipKey.owner)
|
|
||||||
//get all the avatars to see if the owner is around
|
|
||||||
var avatars = AvatarList.getAvatarIdentifiers();
|
|
||||||
var ownerIsAround = false;
|
|
||||||
|
|
||||||
//if the current owner is not me...
|
|
||||||
if (userData.ownershipKey.owner !== MyAvatar.sessionUUID) {
|
|
||||||
|
|
||||||
//look to see if the current owner is around anymore
|
|
||||||
for (var i = 0; i < avatars.length; i++) {
|
|
||||||
if (avatars[i] === userData.ownershipKey.owner) {
|
|
||||||
ownerIsAround = true
|
|
||||||
//the owner is around
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//if the owner is not around, then take ownership
|
|
||||||
if (ownerIsAround === false) {
|
|
||||||
//print('taking ownership')
|
|
||||||
|
|
||||||
var userData = {
|
|
||||||
ownershipKey: {
|
|
||||||
owner: MyAvatar.sessionUUID
|
|
||||||
},
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Entities.editEntity(self.entityId, {
|
|
||||||
userData: JSON.stringify(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//but if the current owner IS me, then move it
|
|
||||||
else {
|
|
||||||
//print('jbp im the owner so move it')
|
|
||||||
self.posFrame++;
|
|
||||||
self.rotFrame++;
|
|
||||||
|
|
||||||
if (self.posFrame > self.posInterval) {
|
|
||||||
|
|
||||||
self.posInterval = 100 * Math.random() + 300;
|
|
||||||
self.posFrame = 0;
|
|
||||||
|
|
||||||
var magnitudeV = self.maxVelocity;
|
|
||||||
var directionV = {
|
|
||||||
x: Math.random() - 0.5,
|
|
||||||
y: Math.random() - 0.5,
|
|
||||||
z: Math.random() - 0.5
|
|
||||||
};
|
|
||||||
|
|
||||||
//print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x);
|
|
||||||
Entities.editEntity(self.entityId, {
|
|
||||||
velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV))
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.rotFrame > self.rotInterval) {
|
|
||||||
|
|
||||||
self.rotInterval = 100 * Math.random() + 250;
|
|
||||||
self.rotFrame = 0;
|
|
||||||
|
|
||||||
var magnitudeAV = self.maxAngularVelocity;
|
|
||||||
|
|
||||||
var directionAV = {
|
|
||||||
x: Math.random() - 0.5,
|
|
||||||
y: Math.random() - 0.5,
|
|
||||||
z: Math.random() - 0.5
|
|
||||||
};
|
|
||||||
//print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x);
|
|
||||||
Entities.editEntity(self.entityId, {
|
|
||||||
angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV))
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this.unload = function() {
|
|
||||||
if (this.initTimeout !== null) {
|
|
||||||
Script.clearTimeout(this.initTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isConnected === true) {
|
|
||||||
Script.update.disconnect(this.update);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var version = 11;
|
var version = 12;
|
||||||
var added = false;
|
var added = false;
|
||||||
this.frame = 0;
|
this.frame = 0;
|
||||||
var utilsScript = Script.resolvePath('utils.js');
|
var utilsScript = Script.resolvePath('utils.js');
|
||||||
|
@ -23,22 +23,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialize = function(entityId) {
|
this.initialize = function(entityId) {
|
||||||
print('JBP nav button should initialize' + entityId)
|
|
||||||
var properties = Entities.getEntityProperties(entityId);
|
var properties = Entities.getEntityProperties(entityId);
|
||||||
if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) {
|
if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) {
|
||||||
self.initTimeout = Script.setTimeout(function() {
|
self.initTimeout = Script.setTimeout(function() {
|
||||||
print('JBP no user data yet, try again in one second')
|
// print(' no user data yet, try again in one second')
|
||||||
self.initialize(entityId);
|
self.initialize(entityId);
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
print('JBP userdata before parse attempt' + properties.userData)
|
// print('userdata before parse attempt' + properties.userData)
|
||||||
self.userData = null;
|
self.userData = null;
|
||||||
try {
|
try {
|
||||||
self.userData = JSON.parse(properties.userData);
|
self.userData = JSON.parse(properties.userData);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
print('JBP error parsing json');
|
// print(' error parsing json');
|
||||||
print('JBP properties are:' + properties.userData);
|
// print(' properties are:' + properties.userData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +45,9 @@
|
||||||
var mySavedSettings = Settings.getValue(entityId);
|
var mySavedSettings = Settings.getValue(entityId);
|
||||||
|
|
||||||
if (mySavedSettings.buttons !== undefined) {
|
if (mySavedSettings.buttons !== undefined) {
|
||||||
print('JBP preload buttons' + mySavedSettings.buttons)
|
// print(' preload buttons' + mySavedSettings.buttons)
|
||||||
mySavedSettings.buttons.forEach(function(b) {
|
mySavedSettings.buttons.forEach(function(b) {
|
||||||
print('JBP deleting button' + b)
|
// print(' deleting button' + b)
|
||||||
Overlays.deleteOverlay(b);
|
Overlays.deleteOverlay(b);
|
||||||
})
|
})
|
||||||
Settings.setValue(entityId, '')
|
Settings.setValue(entityId, '')
|
||||||
|
@ -56,16 +55,15 @@
|
||||||
|
|
||||||
|
|
||||||
self.buttonImageURL = baseURL + "GUI/GUI_" + self.userData.name + ".png?" + version;
|
self.buttonImageURL = baseURL + "GUI/GUI_" + self.userData.name + ".png?" + version;
|
||||||
print('JBP BUTTON IMAGE URL:' + self.buttonImageURL)
|
// print(' BUTTON IMAGE URL:' + self.buttonImageURL)
|
||||||
if (self.button === undefined) {
|
if (self.button === undefined) {
|
||||||
// print('NAV NO BUTTON ADDING ONE!!')
|
// print(' NO BUTTON ADDING ONE!!')
|
||||||
self.button = true;
|
self.button = true;
|
||||||
self.addButton();
|
self.addButton();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// print('NAV SELF ALREADY HAS A BUTTON!!')
|
//print(' SELF ALREADY HAS A BUTTON!!')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,6 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.addButton();
|
self.addButton();
|
||||||
self.buttonShowing = false;
|
self.buttonShowing = false;
|
||||||
self.showDistance = self.userData.showDistance;
|
self.showDistance = self.userData.showDistance;
|
||||||
|
@ -51,8 +49,6 @@
|
||||||
};
|
};
|
||||||
self.sound = SoundCache.getSound(this.soundURL);
|
self.sound = SoundCache.getSound(this.soundURL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addButton = function() {
|
this.addButton = function() {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
var baseURL = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseURL = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
|
|
||||||
var version = 2;
|
var version = 3;
|
||||||
this.preload = function(entityId) {
|
this.preload = function(entityId) {
|
||||||
this.soundPlaying = null;
|
this.soundPlaying = null;
|
||||||
this.entityId = entityId;
|
this.entityId = entityId;
|
||||||
|
|
|
@ -52,13 +52,7 @@
|
||||||
print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")");
|
print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")");
|
||||||
|
|
||||||
MyAvatar.position = data.location;
|
MyAvatar.position = data.location;
|
||||||
|
|
||||||
// if (data.hasOwnProperty('entryPoint') && data.hasOwnProperty('target')) {
|
|
||||||
// this.lookAtTarget(data.entryPoint, data.target);
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -103,10 +97,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hoverEnterEntity = function(entityID) {
|
|
||||||
Entities.editEntity(entityID, {
|
|
||||||
animationURL: animationURL,
|
|
||||||
animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
})
|
|
@ -7,7 +7,7 @@ var soundMap = [{
|
||||||
y: 15850,
|
y: 15850,
|
||||||
z: 15850
|
z: 15850
|
||||||
},
|
},
|
||||||
volume: 0.1,
|
volume: 0.03,
|
||||||
loop: true
|
loop: true
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -19,7 +19,7 @@ var soundMap = [{
|
||||||
y: 15950,
|
y: 15950,
|
||||||
z: 15950
|
z: 15950
|
||||||
},
|
},
|
||||||
volume: 0.1,
|
volume: 0.03,
|
||||||
loop: true
|
loop: true
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -31,7 +31,7 @@ var soundMap = [{
|
||||||
y: 15650,
|
y: 15650,
|
||||||
z: 15650
|
z: 15650
|
||||||
},
|
},
|
||||||
volume: 0.1,
|
volume: 0.03,
|
||||||
loop: true
|
loop: true
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -43,7 +43,7 @@ var soundMap = [{
|
||||||
y: 15750,
|
y: 15750,
|
||||||
z: 15750
|
z: 15750
|
||||||
},
|
},
|
||||||
volume: 0.1,
|
volume: 0.03,
|
||||||
loop: true
|
loop: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
var version = 1035;
|
var version = 1112;
|
||||||
var cellLayout;
|
var cellLayout;
|
||||||
var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/";
|
var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/";
|
||||||
|
|
||||||
|
@ -103,9 +103,9 @@ var scenes = [{
|
||||||
instances: [{
|
instances: [{
|
||||||
model: "Cell",
|
model: "Cell",
|
||||||
dimensions: {
|
dimensions: {
|
||||||
x: 550,
|
x: 500,
|
||||||
y: 620,
|
y: 570,
|
||||||
z: 550
|
z: 500
|
||||||
},
|
},
|
||||||
offset: {
|
offset: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -151,294 +151,253 @@ var scenes = [{
|
||||||
skybox: "cosmos_skybox_blurred"
|
skybox: "cosmos_skybox_blurred"
|
||||||
},
|
},
|
||||||
instances: [{
|
instances: [{
|
||||||
model: "translation",
|
model: "translation",
|
||||||
dimensions: {
|
dimensions: {
|
||||||
x: 10,
|
x: 10,
|
||||||
y: 16,
|
y: 16,
|
||||||
z: 10
|
z: 10
|
||||||
},
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 300,
|
|
||||||
number: 7,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
},
|
|
||||||
target: locations.ribosome[1],
|
|
||||||
location: locations.ribosome[0],
|
|
||||||
baseURL: baseLocation
|
|
||||||
}),
|
|
||||||
script: "zoom.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}, {
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 60,
|
|
||||||
y: 60,
|
|
||||||
z: 60
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 1000,
|
|
||||||
number: 22,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "moveRandomly.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}, { //golgi vesicles
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 10,
|
|
||||||
y: 10,
|
|
||||||
z: 10
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: -319,
|
|
||||||
y: 66,
|
|
||||||
z: 976
|
|
||||||
},
|
|
||||||
radius: 140,
|
|
||||||
number: 10,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "",
|
|
||||||
visible: true
|
|
||||||
}, { //golgi vesicles
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 15,
|
|
||||||
y: 15,
|
|
||||||
z: 15
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: -319,
|
|
||||||
y: 66,
|
|
||||||
z: 976
|
|
||||||
},
|
|
||||||
radius: 115,
|
|
||||||
number: 7,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "moveRandomly.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}, {
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 50,
|
|
||||||
y: 50,
|
|
||||||
z: 50
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 600,
|
|
||||||
number: 15,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "",
|
|
||||||
visible: true
|
|
||||||
}, { //outer vesicles
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 60,
|
|
||||||
y: 60,
|
|
||||||
z: 60
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 1600,
|
|
||||||
number: 22,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "",
|
|
||||||
visible: true
|
|
||||||
}, { //outer vesicles
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 40,
|
|
||||||
y: 40,
|
|
||||||
z: 40
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 1400,
|
|
||||||
number: 22,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "moveRandomly.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}, { //outer vesicles
|
|
||||||
model: "vesicle",
|
|
||||||
dimensions: {
|
|
||||||
x: 80,
|
|
||||||
y: 80,
|
|
||||||
z: 80
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
},
|
|
||||||
radius: 1800,
|
|
||||||
number: 22,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
script: "moveRandomly.js?" + version,
|
|
||||||
visible: true
|
|
||||||
},
|
},
|
||||||
// {//wigglies
|
offset: {
|
||||||
// model:"wiggly",
|
x: 0,
|
||||||
// dimensions:{x:320,y:40,z:160},
|
y: 0,
|
||||||
// randomSize: 10,
|
z: 0
|
||||||
// offset:{x:0,y:0,z:0},
|
},
|
||||||
// radius:1800,
|
radius: 300,
|
||||||
// number:50,
|
number: 7,
|
||||||
// userData:"",
|
userData: JSON.stringify({
|
||||||
// script:"moveRandomly",
|
grabbableKey: {
|
||||||
// visible:true
|
grabbable: false
|
||||||
// },
|
|
||||||
//// {//wigglies
|
|
||||||
// model:"wiggly",
|
|
||||||
// dimensions:{x:640,y:80,z:320},
|
|
||||||
// randomSize: 10,
|
|
||||||
// offset:{x:0,y:0,z:0},
|
|
||||||
// radius:2100,
|
|
||||||
// number:50,
|
|
||||||
// userData:"",
|
|
||||||
// script:"moveRandomly",
|
|
||||||
// visible:true
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
model: "hexokinase",
|
|
||||||
dimensions: {
|
|
||||||
x: 3,
|
|
||||||
y: 4,
|
|
||||||
z: 3
|
|
||||||
},
|
},
|
||||||
randomSize: 10,
|
target: locations.ribosome[1],
|
||||||
offset: {
|
location: locations.ribosome[0],
|
||||||
x: 236,
|
baseURL: baseLocation
|
||||||
y: 8,
|
}),
|
||||||
z: 771
|
script: "zoom.js?" + version,
|
||||||
|
visible: true
|
||||||
|
}, {
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 60,
|
||||||
|
y: 60,
|
||||||
|
z: 60
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
radius: 1000,
|
||||||
|
number: 22,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visible: true
|
||||||
|
}, { //golgi vesicles
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 10,
|
||||||
|
y: 10,
|
||||||
|
z: 10
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: -319,
|
||||||
|
y: 66,
|
||||||
|
z: 976
|
||||||
|
},
|
||||||
|
radius: 140,
|
||||||
|
number: 10,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
script: "",
|
||||||
|
visible: true
|
||||||
|
}, { //golgi vesicles
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 15,
|
||||||
|
y: 15,
|
||||||
|
z: 15
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: -319,
|
||||||
|
y: 66,
|
||||||
|
z: 976
|
||||||
|
},
|
||||||
|
radius: 115,
|
||||||
|
number: 7,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visible: true
|
||||||
|
}, {
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 50,
|
||||||
|
y: 50,
|
||||||
|
z: 50
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
radius: 600,
|
||||||
|
number: 15,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
script: "",
|
||||||
|
visible: true
|
||||||
|
}, { //outer vesicles
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 60,
|
||||||
|
y: 60,
|
||||||
|
z: 60
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
radius: 1600,
|
||||||
|
number: 22,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
script: "",
|
||||||
|
visible: true
|
||||||
|
}, { //outer vesicles
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 40,
|
||||||
|
y: 40,
|
||||||
|
z: 40
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
radius: 1400,
|
||||||
|
number: 22,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visible: true
|
||||||
|
}, { //outer vesicles
|
||||||
|
model: "vesicle",
|
||||||
|
dimensions: {
|
||||||
|
x: 80,
|
||||||
|
y: 80,
|
||||||
|
z: 80
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
},
|
||||||
|
radius: 1800,
|
||||||
|
number: 22,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visible: true
|
||||||
|
}, {
|
||||||
|
model: "hexokinase",
|
||||||
|
dimensions: {
|
||||||
|
x: 3,
|
||||||
|
y: 4,
|
||||||
|
z: 3
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 236,
|
||||||
|
y: 8,
|
||||||
|
z: 771
|
||||||
|
},
|
||||||
|
radius: 80,
|
||||||
|
number: 7,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
},
|
},
|
||||||
radius: 80,
|
target: locations.hexokinase[1],
|
||||||
number: 7,
|
location: locations.hexokinase[0],
|
||||||
userData: JSON.stringify({
|
baseURL: baseLocation
|
||||||
grabbableKey: {
|
}),
|
||||||
grabbable: false
|
script: "zoom.js?" + version,
|
||||||
},
|
visible: true
|
||||||
target: locations.hexokinase[1],
|
}, {
|
||||||
location: locations.hexokinase[0],
|
model: "pfructo_kinase",
|
||||||
baseURL: baseLocation
|
dimensions: {
|
||||||
}),
|
x: 3,
|
||||||
script: "zoom.js?" + version,
|
y: 4,
|
||||||
visible: true
|
z: 3
|
||||||
}, {
|
},
|
||||||
model: "pfructo_kinase",
|
randomSize: 10,
|
||||||
dimensions: {
|
offset: {
|
||||||
x: 3,
|
x: 236,
|
||||||
y: 4,
|
y: 8,
|
||||||
z: 3
|
z: 771
|
||||||
|
},
|
||||||
|
radius: 60,
|
||||||
|
number: 7,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
},
|
},
|
||||||
randomSize: 10,
|
target: locations.hexokinase[1],
|
||||||
offset: {
|
location: locations.hexokinase[0],
|
||||||
x: 236,
|
}),
|
||||||
y: 8,
|
script: "zoom.js?" + version,
|
||||||
z: 771
|
visible: true
|
||||||
|
}, {
|
||||||
|
model: "glucose_isomerase",
|
||||||
|
dimensions: {
|
||||||
|
x: 3,
|
||||||
|
y: 4,
|
||||||
|
z: 3
|
||||||
|
},
|
||||||
|
randomSize: 10,
|
||||||
|
offset: {
|
||||||
|
x: 236,
|
||||||
|
y: 8,
|
||||||
|
z: 771
|
||||||
|
},
|
||||||
|
radius: 70,
|
||||||
|
number: 7,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
},
|
},
|
||||||
radius: 60,
|
target: locations.hexokinase[1],
|
||||||
number: 7,
|
location: locations.hexokinase[0],
|
||||||
userData: JSON.stringify({
|
}),
|
||||||
grabbableKey: {
|
script: "zoom.js?" + version,
|
||||||
grabbable: false
|
visible: true
|
||||||
},
|
}],
|
||||||
target: locations.hexokinase[1],
|
|
||||||
location: locations.hexokinase[0],
|
|
||||||
}),
|
|
||||||
script: "zoom.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}, {
|
|
||||||
model: "glucose_isomerase",
|
|
||||||
dimensions: {
|
|
||||||
x: 3,
|
|
||||||
y: 4,
|
|
||||||
z: 3
|
|
||||||
},
|
|
||||||
randomSize: 10,
|
|
||||||
offset: {
|
|
||||||
x: 236,
|
|
||||||
y: 8,
|
|
||||||
z: 771
|
|
||||||
},
|
|
||||||
radius: 70,
|
|
||||||
number: 7,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
},
|
|
||||||
target: locations.hexokinase[1],
|
|
||||||
location: locations.hexokinase[0],
|
|
||||||
}),
|
|
||||||
script: "zoom.js?" + version,
|
|
||||||
visible: true
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
// model:"NPC",
|
|
||||||
// dimensions:{x:20,y:20,z:20},
|
|
||||||
// randomSize: 10,
|
|
||||||
// offset:{x:208.593693,y:6.113100222,z:153.3202277},
|
|
||||||
// radius:520,
|
|
||||||
// number:25,
|
|
||||||
// userData: "",
|
|
||||||
// script:"",
|
|
||||||
// visible:true
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
],
|
|
||||||
boundary: {
|
boundary: {
|
||||||
radius: locations.cellLayout[2],
|
radius: locations.cellLayout[2],
|
||||||
center: locations.cellLayout[0],
|
center: locations.cellLayout[0],
|
||||||
|
@ -600,7 +559,7 @@ function ImportScene(scene) {
|
||||||
|
|
||||||
CreateZone(scene);
|
CreateZone(scene);
|
||||||
CreateInstances(scene);
|
CreateInstances(scene);
|
||||||
CreateBoundary(scene);
|
// CreateBoundary(scene);
|
||||||
|
|
||||||
// print("done " + scene.name);
|
// print("done " + scene.name);
|
||||||
|
|
||||||
|
@ -609,12 +568,10 @@ function ImportScene(scene) {
|
||||||
clearAllNav();
|
clearAllNav();
|
||||||
|
|
||||||
function clearAllNav() {
|
function clearAllNav() {
|
||||||
// print('NAV CLEARING ALL NAV');
|
|
||||||
var result = Entities.findEntities(MyAvatar.position, 25000);
|
var result = Entities.findEntities(MyAvatar.position, 25000);
|
||||||
result.forEach(function(r) {
|
result.forEach(function(r) {
|
||||||
var properties = Entities.getEntityProperties(r, "name");
|
var properties = Entities.getEntityProperties(r, "name");
|
||||||
if (properties.name.indexOf('navigation button') > -1) {
|
if (properties.name.indexOf('navigation button') > -1) {
|
||||||
// print('NAV DELETING NAV BUTTON AT START:: '+r)
|
|
||||||
Entities.deleteEntity(r);
|
Entities.deleteEntity(r);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -645,9 +602,6 @@ function createLayoutLights() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function CreateNavigationButton(scene, number) {
|
function CreateNavigationButton(scene, number) {
|
||||||
// print('NAV NAVIGATION CREATING NAV!!' +scene.name + " " + number)
|
|
||||||
|
|
||||||
|
|
||||||
Entities.addEntity({
|
Entities.addEntity({
|
||||||
type: "Box",
|
type: "Box",
|
||||||
name: scene.name + " navigation button",
|
name: scene.name + " navigation button",
|
||||||
|
@ -818,7 +772,7 @@ function CreateInstances(scene) {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
}, idBounds, 150);
|
}, idBounds, 150, scene.instances[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
//print('SCRIPT AT CREATE ENTITY: ' + script)
|
//print('SCRIPT AT CREATE ENTITY: ' + script)
|
||||||
|
@ -831,6 +785,7 @@ function CreateInstances(scene) {
|
||||||
|
|
||||||
function CreateIdentification(name, position, rotation, dimensions, showDistance) {
|
function CreateIdentification(name, position, rotation, dimensions, showDistance) {
|
||||||
//print ("creating ID for " + name);
|
//print ("creating ID for " + name);
|
||||||
|
|
||||||
Entities.addEntity({
|
Entities.addEntity({
|
||||||
type: "Sphere",
|
type: "Sphere",
|
||||||
name: "ID for " + name,
|
name: "ID for " + name,
|
||||||
|
@ -9045,4 +9000,9 @@ createLayoutLights();
|
||||||
|
|
||||||
Script.scriptEnding.connect(function() {
|
Script.scriptEnding.connect(function() {
|
||||||
Entities.addingEntity.disconnect(makeUngrabbable);
|
Entities.addingEntity.disconnect(makeUngrabbable);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
print('JBP stopping cell science import');
|
||||||
|
Script.stop();
|
||||||
|
}, 30000)
|
|
@ -18,8 +18,6 @@ if (USE_LOCAL_HOST === true) {
|
||||||
|
|
||||||
var USE_LOCAL_HOST = false;
|
var USE_LOCAL_HOST = false;
|
||||||
|
|
||||||
Agent.isAvatar = true;
|
|
||||||
|
|
||||||
EntityViewer.setPosition({
|
EntityViewer.setPosition({
|
||||||
x: 3000,
|
x: 3000,
|
||||||
y: 13500,
|
y: 13500,
|
||||||
|
|
103
unpublishedScripts/DomainContent/CellScience/moveCellsAC.js
Normal file
103
unpublishedScripts/DomainContent/CellScience/moveCellsAC.js
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright 2016 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 basePosition = {
|
||||||
|
x: 3000,
|
||||||
|
y: 13500,
|
||||||
|
z: 3000
|
||||||
|
};
|
||||||
|
|
||||||
|
var initialized = false;
|
||||||
|
|
||||||
|
EntityViewer.setPosition(basePosition);
|
||||||
|
EntityViewer.setKeyholeRadius(60000);
|
||||||
|
var octreeQueryInterval = Script.setInterval(function() {
|
||||||
|
EntityViewer.queryOctree();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
var THROTTLE = true;
|
||||||
|
var THROTTLE_RATE = 5000;
|
||||||
|
|
||||||
|
var sinceLastUpdate = 0;
|
||||||
|
|
||||||
|
//print('cells script')
|
||||||
|
|
||||||
|
function findCells() {
|
||||||
|
var results = Entities.findEntities(basePosition, 60000);
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
// print('no entities found')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.forEach(function(v) {
|
||||||
|
var name = Entities.getEntityProperties(v, 'name').name;
|
||||||
|
// print('name is:: ' + name)
|
||||||
|
if (name === 'Cell') {
|
||||||
|
// print('found a cell!!' + v)
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
moveCell(v);
|
||||||
|
}, Math.random() * THROTTLE_RATE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var minAngularVelocity = 0.01;
|
||||||
|
var maxAngularVelocity = 0.03;
|
||||||
|
|
||||||
|
function moveCell(entityId) {
|
||||||
|
// print('moving a cell! ' + entityId)
|
||||||
|
|
||||||
|
var magnitudeAV = maxAngularVelocity;
|
||||||
|
|
||||||
|
var directionAV = {
|
||||||
|
x: Math.random() - 0.5,
|
||||||
|
y: Math.random() - 0.5,
|
||||||
|
z: Math.random() - 0.5
|
||||||
|
};
|
||||||
|
// print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x);
|
||||||
|
Entities.editEntity(entityId, {
|
||||||
|
angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV))
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
|
||||||
|
// print('deltaTime',deltaTime)
|
||||||
|
if (!initialized) {
|
||||||
|
print("checking for servers...");
|
||||||
|
if (Entities.serversExist() && Entities.canRez()) {
|
||||||
|
print("servers exist -- makeAll...");
|
||||||
|
Entities.setPacketsPerSecond(6000);
|
||||||
|
print("PPS:" + Entities.getPacketsPerSecond());
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (THROTTLE === true) {
|
||||||
|
sinceLastUpdate = sinceLastUpdate + deltaTime * 1000;
|
||||||
|
if (sinceLastUpdate > THROTTLE_RATE) {
|
||||||
|
// print('SHOULD FIND CELLS!!!')
|
||||||
|
sinceLastUpdate = 0;
|
||||||
|
findCells();
|
||||||
|
} else {
|
||||||
|
// print('returning in update ' + sinceLastUpdate)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function unload() {
|
||||||
|
Script.update.disconnect(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.update.connect(update);
|
||||||
|
Script.scriptEnding.connect(unload);
|
108
unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js
Normal file
108
unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2016 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 basePosition = {
|
||||||
|
x: 3000,
|
||||||
|
y: 13500,
|
||||||
|
z: 3000
|
||||||
|
};
|
||||||
|
|
||||||
|
var initialized = false;
|
||||||
|
|
||||||
|
EntityViewer.setPosition(basePosition);
|
||||||
|
EntityViewer.setKeyholeRadius(60000);
|
||||||
|
var octreeQueryInterval = Script.setInterval(function() {
|
||||||
|
EntityViewer.queryOctree();
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
var THROTTLE = true;
|
||||||
|
var THROTTLE_RATE = 5000;
|
||||||
|
|
||||||
|
var sinceLastUpdate = 0;
|
||||||
|
|
||||||
|
//print('vesicle script')
|
||||||
|
|
||||||
|
function findVesicles() {
|
||||||
|
var results = Entities.findEntities(basePosition, 60000);
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
// print('no entities found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.forEach(function(v) {
|
||||||
|
var name = Entities.getEntityProperties(v, 'name').name;
|
||||||
|
if (name === 'vesicle') {
|
||||||
|
//print('found a vesicle!!' + v)
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
moveVesicle(v);
|
||||||
|
}, Math.random() * THROTTLE_RATE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var minVelocity = 1;
|
||||||
|
var maxVelocity = 5;
|
||||||
|
var minAngularVelocity = 0.01;
|
||||||
|
var maxAngularVelocity = 0.03;
|
||||||
|
|
||||||
|
function moveVesicle(entityId) {
|
||||||
|
// print('moving a vesicle! ' + entityId)
|
||||||
|
var magnitudeV = maxVelocity;
|
||||||
|
var directionV = {
|
||||||
|
x: Math.random() - 0.5,
|
||||||
|
y: Math.random() - 0.5,
|
||||||
|
z: Math.random() - 0.5
|
||||||
|
};
|
||||||
|
|
||||||
|
// print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x);
|
||||||
|
|
||||||
|
var magnitudeAV = maxAngularVelocity;
|
||||||
|
|
||||||
|
var directionAV = {
|
||||||
|
x: Math.random() - 0.5,
|
||||||
|
y: Math.random() - 0.5,
|
||||||
|
z: Math.random() - 0.5
|
||||||
|
};
|
||||||
|
// print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x);
|
||||||
|
Entities.editEntity(entityId, {
|
||||||
|
velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)),
|
||||||
|
angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV))
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
if (!initialized) {
|
||||||
|
print("checking for servers...");
|
||||||
|
if (Entities.serversExist() && Entities.canRez()) {
|
||||||
|
print("servers exist -- makeAll...");
|
||||||
|
Entities.setPacketsPerSecond(6000);
|
||||||
|
print("PPS:" + Entities.getPacketsPerSecond());
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (THROTTLE === true) {
|
||||||
|
sinceLastUpdate = sinceLastUpdate + deltaTime * 1000;
|
||||||
|
if (sinceLastUpdate > THROTTLE_RATE) {
|
||||||
|
sinceLastUpdate = 0;
|
||||||
|
findVesicles();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function unload() {
|
||||||
|
Script.update.disconnect(update);
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.update.connect(update);
|
||||||
|
Script.scriptEnding.connect(unload);
|
Loading…
Reference in a new issue