diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 27de800091..16bb4e25e1 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -14,8 +14,6 @@ #include "avatar/AvatarManager.h" #include -#include -#include "PickScriptingInterface.h" #include "RayPick.h" LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, @@ -69,12 +67,14 @@ QUuid LaserPointer::getPickedObjectID(const PickResultPointer& pickResult) { void LaserPointer::setVisualPickResultInternal(PickResultPointer pickResult, IntersectionType type, const QUuid& id, const glm::vec3& intersection, float distance, const glm::vec3& surfaceNormal) { auto rayPickResult = std::static_pointer_cast(pickResult); - rayPickResult->type = type; - rayPickResult->objectID = id; - rayPickResult->intersection = intersection; - rayPickResult->distance = distance; - rayPickResult->surfaceNormal = surfaceNormal; - rayPickResult->pickVariant["direction"] = vec3toVariant(-surfaceNormal); + if (rayPickResult) { + rayPickResult->type = type; + rayPickResult->objectID = id; + rayPickResult->intersection = intersection; + rayPickResult->distance = distance; + rayPickResult->surfaceNormal = surfaceNormal; + rayPickResult->pickVariant["direction"] = vec3toVariant(-surfaceNormal); + } } LaserPointer::RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : @@ -103,8 +103,9 @@ void LaserPointer::RenderState::disable() { } } -void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal) { - StartEndRenderState::update(origin, end, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal); +void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { + StartEndRenderState::update(origin, end, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); QVariant endVariant = vec3toVariant(end); if (!getPathID().isNull()) { QVariantMap pathProps; @@ -188,11 +189,11 @@ PointerEvent LaserPointer::buildPointerEvent(const PickedObject& target, const P glm::vec3 LaserPointer::findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction) { switch (pickedObject.type) { - case ENTITY: - return RayPick::intersectRayWithEntityXYPlane(pickedObject.objectID, origin, direction); - case OVERLAY: - return RayPick::intersectRayWithOverlayXYPlane(pickedObject.objectID, origin, direction); - default: - return glm::vec3(NAN); + case ENTITY: + return RayPick::intersectRayWithEntityXYPlane(pickedObject.objectID, origin, direction); + case OVERLAY: + return RayPick::intersectRayWithOverlayXYPlane(pickedObject.objectID, origin, direction); + default: + return glm::vec3(NAN); } } diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 3afb3d262e..5030c90186 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -29,7 +29,8 @@ public: void cleanup() override; void disable() override; - void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal) override; + void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) override; private: OverlayID _pathID; diff --git a/interface/src/raypick/ParabolaPointer.cpp b/interface/src/raypick/ParabolaPointer.cpp new file mode 100644 index 0000000000..aee5b8cfa1 --- /dev/null +++ b/interface/src/raypick/ParabolaPointer.cpp @@ -0,0 +1,390 @@ +// +// Created by Sam Gondelman 7/17/2018 +// Copyright 2018 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 +// +#include "ParabolaPointer.h" + +#include "Application.h" +#include "avatar/AvatarManager.h" +#include + +#include +#include "ParabolaPick.h" + +#include "render-utils/parabola_vert.h" +#include "render-utils/parabola_frag.h" + +const glm::vec4 ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR { 1.0f }; +const float ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_WIDTH { 0.01f }; +const bool ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA { false }; + +gpu::PipelinePointer ParabolaPointer::RenderState::ParabolaRenderItem::_parabolaPipeline { nullptr }; +gpu::PipelinePointer ParabolaPointer::RenderState::ParabolaRenderItem::_transparentParabolaPipeline { nullptr }; + +ParabolaPointer::ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, + const PointerTriggers& triggers, bool faceAvatar, bool followNormal, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithAvatar, bool enabled) : + PathPointer(PickQuery::Parabola, rayProps, renderStates, defaultRenderStates, hover, triggers, faceAvatar, followNormal, + centerEndY, lockEnd, distanceScaleEnd, scaleWithAvatar, enabled) +{ +} + +void ParabolaPointer::editRenderStatePath(const std::string& state, const QVariant& pathProps) { + auto renderState = std::static_pointer_cast(_renderStates[state]); + if (renderState) { + QVariantMap pathMap = pathProps.toMap(); + glm::vec3 color = glm::vec3(RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR); + float alpha = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR.a; + float width = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_WIDTH; + bool isVisibleInSecondaryCamera = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA; + bool enabled = false; + if (!pathMap.isEmpty()) { + enabled = true; + if (pathMap["color"].isValid()) { + bool valid; + color = toGlm(xColorFromVariant(pathMap["color"], valid)); + } + if (pathMap["alpha"].isValid()) { + alpha = pathMap["alpha"].toFloat(); + } + if (pathMap["width"].isValid()) { + width = pathMap["width"].toFloat(); + } + if (pathMap["isVisibleInSecondaryCamera"].isValid()) { + isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool(); + } + } + renderState->editParabola(color, alpha, width, isVisibleInSecondaryCamera, enabled); + } +} + +glm::vec3 ParabolaPointer::getPickOrigin(const PickResultPointer& pickResult) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + return (parabolaPickResult ? vec3FromVariant(parabolaPickResult->pickVariant["origin"]) : glm::vec3()); +} + +glm::vec3 ParabolaPointer::getPickEnd(const PickResultPointer& pickResult, float distance) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + if (distance > 0.0f) { + PickParabola pick = PickParabola(parabolaPickResult->pickVariant); + return pick.origin + pick.velocity * distance + 0.5f * pick.acceleration * distance * distance; + } else { + return parabolaPickResult->intersection; + } +} + +glm::vec3 ParabolaPointer::getPickedObjectNormal(const PickResultPointer& pickResult) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + return (parabolaPickResult ? parabolaPickResult->surfaceNormal : glm::vec3()); +} + +IntersectionType ParabolaPointer::getPickedObjectType(const PickResultPointer& pickResult) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + return (parabolaPickResult ? parabolaPickResult->type : IntersectionType::NONE); +} + +QUuid ParabolaPointer::getPickedObjectID(const PickResultPointer& pickResult) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + return (parabolaPickResult ? parabolaPickResult->objectID : QUuid()); +} + +void ParabolaPointer::setVisualPickResultInternal(PickResultPointer pickResult, IntersectionType type, const QUuid& id, + const glm::vec3& intersection, float distance, const glm::vec3& surfaceNormal) { + auto parabolaPickResult = std::static_pointer_cast(pickResult); + if (parabolaPickResult) { + parabolaPickResult->type = type; + parabolaPickResult->objectID = id; + parabolaPickResult->intersection = intersection; + parabolaPickResult->distance = distance; + parabolaPickResult->surfaceNormal = surfaceNormal; + PickParabola parabola = PickParabola(parabolaPickResult->pickVariant); + parabolaPickResult->pickVariant["velocity"] = vec3toVariant((intersection - parabola.origin - + 0.5f * parabola.acceleration * parabolaPickResult->parabolicDistance * parabolaPickResult->parabolicDistance) / parabolaPickResult->parabolicDistance); + } +} + +ParabolaPointer::RenderState::RenderState(const OverlayID& startID, const OverlayID& endID, const glm::vec3& pathColor, float pathAlpha, float pathWidth, + bool isVisibleInSecondaryCamera, bool pathEnabled) : + StartEndRenderState(startID, endID) +{ + render::Transaction transaction; + auto scene = qApp->getMain3DScene(); + _pathID = scene->allocateID(); + if (render::Item::isValidID(_pathID)) { + auto renderItem = std::make_shared(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled); + // TODO: update bounds properly + renderItem->editBound().setBox(glm::vec3(-16000.0f), 32000.0f); + transaction.resetItem(_pathID, std::make_shared(renderItem)); + scene->enqueueTransaction(transaction); + } +} + +void ParabolaPointer::RenderState::cleanup() { + StartEndRenderState::cleanup(); + if (render::Item::isValidID(_pathID)) { + render::Transaction transaction; + auto scene = qApp->getMain3DScene(); + transaction.removeItem(_pathID); + scene->enqueueTransaction(transaction); + } +} + +void ParabolaPointer::RenderState::disable() { + StartEndRenderState::disable(); + if (render::Item::isValidID(_pathID)) { + render::Transaction transaction; + auto scene = qApp->getMain3DScene(); + transaction.updateItem(_pathID, [](ParabolaRenderItem& item) { + item.setVisible(false); + }); + scene->enqueueTransaction(transaction); + } +} + +void ParabolaPointer::RenderState::editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled) { + if (render::Item::isValidID(_pathID)) { + render::Transaction transaction; + auto scene = qApp->getMain3DScene(); + transaction.updateItem(_pathID, [color, alpha, width, isVisibleInSecondaryCamera, enabled](ParabolaRenderItem& item) { + item.setColor(color); + item.setAlpha(alpha); + item.setWidth(width); + item.setIsVisibleInSecondaryCamera(isVisibleInSecondaryCamera); + item.setEnabled(enabled); + item.updateKey(); + item.updateUniformBuffer(); + }); + scene->enqueueTransaction(transaction); + } +} + +void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { + StartEndRenderState::update(origin, end, scaleWithAvatar, distanceScaleEnd, centerEndY, faceAvatar, followNormal, distance, pickResult); + auto parabolaPickResult = std::static_pointer_cast(pickResult); + if (parabolaPickResult && render::Item::isValidID(_pathID)) { + render::Transaction transaction; + auto scene = qApp->getMain3DScene(); + + PickParabola parabola = PickParabola(parabolaPickResult->pickVariant); + glm::vec3 velocity = parabola.velocity; + glm::vec3 acceleration = parabola.acceleration; + float parabolicDistance = distance > 0.0f ? distance : parabolaPickResult->parabolicDistance; + transaction.updateItem(_pathID, [origin, velocity, acceleration, parabolicDistance](ParabolaRenderItem& item) { + item.setVisible(true); + item.setOrigin(origin); + item.setVelocity(velocity); + item.setAcceleration(acceleration); + item.setParabolicDistance(parabolicDistance); + item.updateUniformBuffer(); + }); + scene->enqueueTransaction(transaction); + } +} + +std::shared_ptr ParabolaPointer::buildRenderState(const QVariantMap& propMap) { + QUuid startID; + if (propMap["start"].isValid()) { + QVariantMap startMap = propMap["start"].toMap(); + if (startMap["type"].isValid()) { + startMap.remove("visible"); + startID = qApp->getOverlays().addOverlay(startMap["type"].toString(), startMap); + } + } + + glm::vec3 color = glm::vec3(RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR); + float alpha = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR.a; + float width = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_WIDTH; + bool isVisibleInSecondaryCamera = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA; + bool enabled = false; + if (propMap["path"].isValid()) { + enabled = true; + QVariantMap pathMap = propMap["path"].toMap(); + if (pathMap["color"].isValid()) { + bool valid; + color = toGlm(xColorFromVariant(pathMap["color"], valid)); + } + + if (pathMap["alpha"].isValid()) { + alpha = pathMap["alpha"].toFloat(); + } + + if (pathMap["width"].isValid()) { + width = pathMap["width"].toFloat(); + } + + if (pathMap["isVisibleInSecondaryCamera"].isValid()) { + isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool(); + } + } + + QUuid endID; + if (propMap["end"].isValid()) { + QVariantMap endMap = propMap["end"].toMap(); + if (endMap["type"].isValid()) { + endMap.remove("visible"); + endID = qApp->getOverlays().addOverlay(endMap["type"].toString(), endMap); + } + } + + return std::make_shared(startID, endID, color, alpha, width, isVisibleInSecondaryCamera, enabled); +} + +PointerEvent ParabolaPointer::buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button, bool hover) { + QUuid pickedID; + glm::vec3 intersection, surfaceNormal, origin, velocity, acceleration; + auto parabolaPickResult = std::static_pointer_cast(pickResult); + if (parabolaPickResult) { + intersection = parabolaPickResult->intersection; + surfaceNormal = parabolaPickResult->surfaceNormal; + const QVariantMap& parabola = parabolaPickResult->pickVariant; + origin = vec3FromVariant(parabola["origin"]); + velocity = vec3FromVariant(parabola["velocity"]); + acceleration = vec3FromVariant(parabola["acceleration"]); + pickedID = parabolaPickResult->objectID; + } + + if (pickedID != target.objectID) { + intersection = findIntersection(target, origin, velocity, acceleration); + } + glm::vec2 pos2D = findPos2D(target, intersection); + + // If we just started triggering and we haven't moved too much, don't update intersection and pos2D + TriggerState& state = hover ? _latestState : _states[button]; + float sensorToWorldScale = DependencyManager::get()->getMyAvatar()->getSensorToWorldScale(); + float deadspotSquared = TOUCH_PRESS_TO_MOVE_DEADSPOT_SQUARED * sensorToWorldScale * sensorToWorldScale; + bool withinDeadspot = usecTimestampNow() - state.triggerStartTime < POINTER_MOVE_DELAY && glm::distance2(pos2D, state.triggerPos2D) < deadspotSquared; + if ((state.triggering || state.wasTriggering) && !state.deadspotExpired && withinDeadspot) { + pos2D = state.triggerPos2D; + intersection = state.intersection; + surfaceNormal = state.surfaceNormal; + } + if (!withinDeadspot) { + state.deadspotExpired = true; + } + + return PointerEvent(pos2D, intersection, surfaceNormal, velocity); +} + +glm::vec3 ParabolaPointer::findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration) { + // TODO: implement + switch (pickedObject.type) { + case ENTITY: + //return ParabolaPick::intersectParabolaWithEntityXYPlane(pickedObject.objectID, origin, velocity, acceleration); + case OVERLAY: + //return ParabolaPick::intersectParabolaWithOverlayXYPlane(pickedObject.objectID, origin, velocity, acceleration); + default: + return glm::vec3(NAN); + } +} + +ParabolaPointer::RenderState::ParabolaRenderItem::ParabolaRenderItem(const glm::vec3& color, float alpha, float width, + bool isVisibleInSecondaryCamera, bool enabled) : + _isVisibleInSecondaryCamera(isVisibleInSecondaryCamera), _enabled(enabled) +{ + _uniformBuffer->resize(sizeof(ParabolaData)); + setColor(color); + setAlpha(alpha); + setWidth(width); + updateKey(); + updateUniformBuffer(); +} + +void ParabolaPointer::RenderState::ParabolaRenderItem::setVisible(bool visible) { + if (visible && _enabled) { + _key = render::ItemKey::Builder(_key).withVisible(); + } else { + _key = render::ItemKey::Builder(_key).withInvisible(); + } +} + +void ParabolaPointer::RenderState::ParabolaRenderItem::updateKey() { + auto builder = _parabolaData.color.a < 1.0f ? render::ItemKey::Builder::transparentShape() : render::ItemKey::Builder::opaqueShape(); + + if (_enabled) { + builder.withVisible(); + } else { + builder.withInvisible(); + } + + if (_isVisibleInSecondaryCamera) { + builder.withTagBits(render::hifi::TAG_ALL_VIEWS); + } else { + builder.withTagBits(render::hifi::TAG_MAIN_VIEW); + } + + _key = builder.build(); +} + +const gpu::PipelinePointer ParabolaPointer::RenderState::ParabolaRenderItem::getParabolaPipeline() { + if (!_parabolaPipeline || !_transparentParabolaPipeline) { + auto vs = parabola_vert::getShader(); + auto ps = parabola_frag::getShader(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("parabolaData"), 0)); + gpu::Shader::makeProgram(*program, slotBindings); + + { + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMaskDrawShape(*state); + state->setCullMode(gpu::State::CULL_NONE); + _parabolaPipeline = gpu::Pipeline::create(program, state); + } + + { + auto state = std::make_shared(); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + PrepareStencil::testMask(*state); + state->setCullMode(gpu::State::CULL_NONE); + _transparentParabolaPipeline = gpu::Pipeline::create(program, state); + } + } + return (_parabolaData.color.a < 1.0f ? _transparentParabolaPipeline : _parabolaPipeline); +} + +void ParabolaPointer::RenderState::ParabolaRenderItem::render(RenderArgs* args) { + gpu::Batch& batch = *(args->_batch); + + Transform transform; + transform.setTranslation(_origin); + batch.setModelTransform(transform); + + batch.setPipeline(getParabolaPipeline()); + + batch.setUniformBuffer(0, _uniformBuffer); + + const int NUM_SECTIONS = 25; // must match value in parabola.slv + // We draw 2 * n + 2 vertices for a triangle strip + batch.draw(gpu::TRIANGLE_STRIP, 2 * NUM_SECTIONS + 2, 0); +} + +namespace render { + template <> const ItemKey payloadGetKey(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload) { + return payload->getKey(); + } + template <> const Item::Bound payloadGetBound(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return Item::Bound(); + } + template <> void payloadRender(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload, RenderArgs* args) { + if (payload) { + payload->render(args); + } + } + template <> const ShapeKey shapeGetShapeKey(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload) { + return ShapeKey::Builder::ownPipeline(); + } +} \ No newline at end of file diff --git a/interface/src/raypick/ParabolaPointer.h b/interface/src/raypick/ParabolaPointer.h new file mode 100644 index 0000000000..827134eaf5 --- /dev/null +++ b/interface/src/raypick/ParabolaPointer.h @@ -0,0 +1,118 @@ +// +// Created by Sam Gondelman 7/17/2018 +// Copyright 2018 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 +// +#ifndef hifi_ParabolaPointer_h +#define hifi_ParabolaPointer_h + +#include "PathPointer.h" + +class ParabolaPointer : public PathPointer { + using Parent = PathPointer; +public: + class RenderState : public StartEndRenderState { + public: + class ParabolaRenderItem { + public: + using Payload = render::Payload; + using Pointer = Payload::DataPointer; + + ParabolaRenderItem(const glm::vec3& color, float alpha, float width, + bool isVisibleInSecondaryCamera, bool enabled); + ~ParabolaRenderItem() {} + + static gpu::PipelinePointer _parabolaPipeline; + static gpu::PipelinePointer _transparentParabolaPipeline; + const gpu::PipelinePointer getParabolaPipeline(); + + void render(RenderArgs* args); + render::Item::Bound& editBound() { return _bound; } + const render::Item::Bound& getBound() { return _bound; } + render::ItemKey getKey() const { return _key; } + + void setVisible(bool visible); + void updateKey(); + void updateUniformBuffer() { _uniformBuffer->setSubData(0, _parabolaData); } + + void setColor(const glm::vec3& color) { _parabolaData.color = glm::vec4(color, _parabolaData.color.a); } + void setAlpha(const float& alpha) { _parabolaData.color.a = alpha; } + void setWidth(const float& width) { _parabolaData.width = width; } + void setParabolicDistance(const float& parabolicDistance) { _parabolaData.parabolicDistance = parabolicDistance; } + void setVelocity(const glm::vec3& velocity) { _parabolaData.velocity = velocity; } + void setAcceleration(const glm::vec3& acceleration) { _parabolaData.acceleration = acceleration; } + void setOrigin(const glm::vec3& origin) { _origin = origin; } + void setIsVisibleInSecondaryCamera(const bool& isVisibleInSecondaryCamera) { _isVisibleInSecondaryCamera = isVisibleInSecondaryCamera; } + void setEnabled(const bool& enabled) { _enabled = enabled; } + + static const glm::vec4 DEFAULT_PARABOLA_COLOR; + static const float DEFAULT_PARABOLA_WIDTH; + static const bool DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA; + + private: + render::Item::Bound _bound; + render::ItemKey _key; + + glm::vec3 _origin { 0.0f }; + bool _isVisibleInSecondaryCamera { DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA }; + bool _enabled { false }; + + struct ParabolaData { + glm::vec3 velocity { 0.0f }; + float parabolicDistance { 0.0f }; + vec3 acceleration { 0.0f }; + float width { DEFAULT_PARABOLA_WIDTH }; + vec4 color { vec4(DEFAULT_PARABOLA_COLOR)}; + }; + + ParabolaData _parabolaData; + gpu::BufferPointer _uniformBuffer { std::make_shared() }; + }; + + RenderState() {} + RenderState(const OverlayID& startID, const OverlayID& endID, const glm::vec3& pathColor, float pathAlpha, float pathWidth, + bool isVisibleInSecondaryCamera, bool pathEnabled); + + void cleanup() override; + void disable() override; + void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) override; + + void editParabola(const glm::vec3& color, float alpha, float width, bool isVisibleInSecondaryCamera, bool enabled); + + private: + int _pathID; + }; + + ParabolaPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates, bool hover, const PointerTriggers& triggers, + bool faceAvatar, bool followNormal, bool centerEndY, bool lockEnd, bool distanceScaleEnd, bool scaleWithAvatar, bool enabled); + + static std::shared_ptr buildRenderState(const QVariantMap& propMap); + +protected: + void editRenderStatePath(const std::string& state, const QVariant& pathProps) override; + + glm::vec3 getPickOrigin(const PickResultPointer& pickResult) override; + glm::vec3 getPickEnd(const PickResultPointer& pickResult, float distance) override; + glm::vec3 getPickedObjectNormal(const PickResultPointer& pickResult) override; + IntersectionType getPickedObjectType(const PickResultPointer& pickResult) override; + QUuid getPickedObjectID(const PickResultPointer& pickResult) override; + void setVisualPickResultInternal(PickResultPointer pickResult, IntersectionType type, const QUuid& id, + const glm::vec3& intersection, float distance, const glm::vec3& surfaceNormal) override; + + PointerEvent buildPointerEvent(const PickedObject& target, const PickResultPointer& pickResult, const std::string& button = "", bool hover = true) override; + +private: + static glm::vec3 findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration); +}; + +namespace render { + template <> const ItemKey payloadGetKey(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload); + template <> const Item::Bound payloadGetBound(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload); + template <> void payloadRender(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload, RenderArgs* args); + template <> const ShapeKey shapeGetShapeKey(const ParabolaPointer::RenderState::ParabolaRenderItem::Pointer& payload); +} + +#endif // hifi_ParabolaPointer_h diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index b625c0d3da..1582b62ab2 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -78,6 +78,8 @@ void PathPointer::setLockEndUUID(const QUuid& objectID, const bool isOverlay, co }); } +#include "ParabolaPick.h" + PickResultPointer PathPointer::getVisualPickResult(const PickResultPointer& pickResult) { PickResultPointer visualPickResult = pickResult; glm::vec3 origin = getPickOrigin(pickResult); @@ -144,10 +146,11 @@ PickResultPointer PathPointer::getVisualPickResult(const PickResultPointer& pick void PathPointer::updateVisuals(const PickResultPointer& pickResult) { IntersectionType type = getPickedObjectType(pickResult); if (_enabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && - (type != IntersectionType::NONE || _pathLength > 0.0f || !_lockEndObject.id.isNull())) { + (type != IntersectionType::NONE || _pathLength > 0.0f)) { glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 end = getPickEnd(pickResult, _pathLength); - _renderStates[_currentRenderState]->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, _followNormal); + _renderStates[_currentRenderState]->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, + _followNormal, _pathLength, pickResult); if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { _defaultRenderStates[_currentRenderState].second->disable(); } @@ -157,7 +160,8 @@ void PathPointer::updateVisuals(const PickResultPointer& pickResult) { } glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 end = getPickEnd(pickResult, _defaultRenderStates[_currentRenderState].first); - _defaultRenderStates[_currentRenderState].second->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, _followNormal); + _defaultRenderStates[_currentRenderState].second->update(origin, end, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, + _faceAvatar, _followNormal, _defaultRenderStates[_currentRenderState].first, pickResult); } else if (!_currentRenderState.empty()) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) { _renderStates[_currentRenderState]->disable(); @@ -180,7 +184,7 @@ void PathPointer::editRenderState(const std::string& state, const QVariant& star if (endDim.isValid()) { _renderStates[state]->setEndDim(vec3FromVariant(endDim)); } - QVariant rotation = pathProps.toMap()["rotation"]; + QVariant rotation = endProps.toMap()["rotation"]; if (rotation.isValid()) { _renderStates[state]->setEndRot(quatFromVariant(rotation)); } @@ -271,7 +275,8 @@ void StartEndRenderState::disable() { } } -void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal) { +void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult) { if (!getStartID().isNull()) { QVariantMap startProps; startProps.insert("position", vec3toVariant(origin)); diff --git a/interface/src/raypick/PathPointer.h b/interface/src/raypick/PathPointer.h index ea8e2eff6e..ff40f47646 100644 --- a/interface/src/raypick/PathPointer.h +++ b/interface/src/raypick/PathPointer.h @@ -44,7 +44,8 @@ public: virtual void cleanup(); virtual void disable(); - virtual void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal); + virtual void update(const glm::vec3& origin, const glm::vec3& end, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, + bool faceAvatar, bool followNormal, float distance, const PickResultPointer& pickResult); protected: OverlayID _startID; @@ -69,7 +70,7 @@ public: virtual ~PathPointer(); void setRenderState(const std::string& state) override; - // You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays. + // You cannot use editRenderState to change the type of any part of the pointer. You can only edit the properties of the existing overlays. void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) override; void setLength(float length) override; diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index fdcdee2218..486e208647 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -15,6 +15,7 @@ #include "Application.h" #include "LaserPointer.h" #include "StylusPointer.h" +#include "ParabolaPointer.h" void PointerScriptingInterface::setIgnoreItems(unsigned int uid, const QScriptValue& ignoreItems) const { DependencyManager::get()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems)); @@ -239,8 +240,6 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope * @property {Pointers.Trigger[]} [triggers] A list of different triggers mechanisms that control this Pointer's click event generation. */ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& properties) const { - return 0; -#if 0 QVariantMap propertyMap = properties.toMap(); bool faceAvatar = false; @@ -278,7 +277,7 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr enabled = propertyMap["enabled"].toBool(); } - ParabolaPointer::RenderStateMap renderStates; + RenderStateMap renderStates; if (propertyMap["renderStates"].isValid()) { QList renderStateVariants = propertyMap["renderStates"].toList(); for (const QVariant& renderStateVariant : renderStateVariants) { @@ -292,7 +291,7 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr } } - ParabolaPointer::DefaultRenderStateMap defaultRenderStates; + DefaultRenderStateMap defaultRenderStates; if (propertyMap["defaultRenderStates"].isValid()) { QList renderStateVariants = propertyMap["defaultRenderStates"].toList(); for (const QVariant& renderStateVariant : renderStateVariants) { @@ -301,7 +300,7 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) { std::string name = renderStateMap["name"].toString().toStdString(); float distance = renderStateMap["distance"].toFloat(); - defaultRenderStates[name] = std::pair(distance, ParabolaPointer::buildRenderState(renderStateMap)); + defaultRenderStates[name] = std::pair>(distance, ParabolaPointer::buildRenderState(renderStateMap)); } } } @@ -333,7 +332,6 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr return DependencyManager::get()->addPointer(std::make_shared(properties, renderStates, defaultRenderStates, hover, triggers, faceAvatar, followNormal, centerEndY, lockEnd, distanceScaleEnd, scaleWithAvatar, enabled)); -#endif } void PointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const { diff --git a/libraries/render-utils/src/parabola.slf b/libraries/render-utils/src/parabola.slf new file mode 100644 index 0000000000..ae7a44ddd1 --- /dev/null +++ b/libraries/render-utils/src/parabola.slf @@ -0,0 +1,18 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gondelman on 7/18/2018 +// Copyright 2018 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 +// + +in vec4 _color; + +out vec4 _fragColor; + +void main(void) { + _fragColor = _color; +} diff --git a/libraries/render-utils/src/parabola.slv b/libraries/render-utils/src/parabola.slv new file mode 100644 index 0000000000..a8c892ab00 --- /dev/null +++ b/libraries/render-utils/src/parabola.slv @@ -0,0 +1,53 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gondelman on 7/18/2018 +// Copyright 2018 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 +// + +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + +layout(std140) uniform parabolaData { + vec3 velocity; + float parabolicDistance; + vec3 acceleration; + float width; + vec4 color; +}; + +out vec4 _color; + +void main(void) { + _color = color; + + const int NUM_SECTIONS = 25; // must match value in ParabolaPointer.cpp + float t = parabolicDistance * (floor(gl_VertexID / 2) / float(NUM_SECTIONS)); + + vec4 pos = vec4(velocity * t + 0.5 * acceleration * t * t, 1); + const float EPSILON = 0.00001; + vec4 normal; + + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + if (dot(acceleration, acceleration) < EPSILON) { + // Handle case where acceleration == (0, 0, 0) + vec3 eyeUp = vec3(0, 1, 0); + vec3 worldUp; + <$transformEyeToWorldDir(cam, eyeUp, worldUp)$> + normal = vec4(normalize(cross(velocity, worldUp)), 0); + } else { + normal = vec4(normalize(cross(velocity, acceleration)), 0); + } + if (gl_VertexID % 2 == 0) { + pos += 0.5 * width * normal; + } else { + pos -= 0.5 * width * normal; + } + + <$transformModelToClipPos(cam, obj, pos, gl_Position)$> +} \ No newline at end of file diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 3bf99ca26a..12e3f6ab3a 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -62,49 +62,37 @@ Script.include("/~/system/libraries/controllers.js"); }; var cancelPath = { - type: "line3d", color: COLORS_TELEPORT_CANCEL, - ignoreRayIntersection: true, alpha: 1, - solid: true, - drawInFront: true, - glow: 1.0 + width: 0.025 }; var teleportPath = { - type: "line3d", color: COLORS_TELEPORT_CAN_TELEPORT, - ignoreRayIntersection: true, alpha: 1, - solid: true, - drawInFront: true, - glow: 1.0 + width: 0.025 }; var seatPath = { - type: "line3d", color: COLORS_TELEPORT_SEAT, - ignoreRayIntersection: true, alpha: 1, - solid: true, - drawInFront: true, - glow: 1.0 + width: 0.025 }; var cancelEnd = { type: "model", url: TOO_CLOSE_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreRayIntersection: true + ignoreParabolaIntersection: true }; var teleportEnd = { type: "model", url: TARGET_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreRayIntersection: true + ignoreParabolaIntersection: true }; var seatEnd = { type: "model", url: SEAT_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, - ignoreRayIntersection: true + ignoreParabolaIntersection: true }; @@ -112,7 +100,7 @@ Script.include("/~/system/libraries/controllers.js"); {name: "teleport", path: teleportPath, end: teleportEnd}, {name: "seat", path: seatPath, end: seatEnd}]; - var DEFAULT_DISTANCE = 50; + var DEFAULT_DISTANCE = 10; var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}]; var coolInTimeout = null; @@ -134,6 +122,9 @@ Script.include("/~/system/libraries/controllers.js"); SEAT: 'seat' // The current target is a seat }; + var speed = 7.0; + var accelerationAxis = {x: 0.0, y: -5.0, z: 0.0}; + function Teleporter(hand) { var _this = this; this.hand = hand; @@ -149,46 +140,58 @@ Script.include("/~/system/libraries/controllers.js"); return otherModule; }; - this.teleportRayHandVisible = Pointers.createPointer(PickType.Ray, { + this.teleportParabolaHandVisible = Pointers.createPointer(PickType.Parabola, { joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand", filter: Picks.PICK_ENTITIES, faceAvatar: true, scaleWithAvatar: true, centerEndY: false, + followNormal: true, + speed: speed, + accelerationAxis: accelerationAxis, renderStates: teleportRenderStates, defaultRenderStates: teleportDefaultRenderStates }); - this.teleportRayHandInvisible = Pointers.createPointer(PickType.Ray, { + this.teleportParabolaHandInvisible = Pointers.createPointer(PickType.Parabola, { joint: (_this.hand === RIGHT_HAND) ? "RightHand" : "LeftHand", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, scaleWithAvatar: true, centerEndY: false, + followNormal: true, + speed: speed, + accelerationAxis: accelerationAxis, renderStates: teleportRenderStates }); - this.teleportRayHeadVisible = Pointers.createPointer(PickType.Ray, { + this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", filter: Picks.PICK_ENTITIES, faceAvatar: true, scaleWithAvatar: true, centerEndY: false, + followNormal: true, + speed: speed, + accelerationAxis: accelerationAxis, renderStates: teleportRenderStates, defaultRenderStates: teleportDefaultRenderStates }); - this.teleportRayHeadInvisible = Pointers.createPointer(PickType.Ray, { + this.teleportParabolaHeadInvisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, faceAvatar: true, scaleWithAvatar: true, centerEndY: false, + followNormal: true, + speed: speed, + accelerationAxis: accelerationAxis, renderStates: teleportRenderStates }); this.cleanup = function() { - Pointers.removePointer(this.teleportRayHandVisible); - Pointers.removePointer(this.teleportRayHandInvisible); - Pointers.removePointer(this.teleportRayHeadVisible); - Pointers.removePointer(this.teleportRayHeadInvisible); + Pointers.removePointer(this.teleportParabolaHandVisible); + Pointers.removePointer(this.teleportParabolaHandInvisible); + Pointers.removePointer(this.teleportParabolaHeadVisible); + Pointers.removePointer(this.teleportParabolaHeadInvisible); }; this.buttonPress = function(value) { @@ -225,20 +228,20 @@ Script.include("/~/system/libraries/controllers.js"); {name: "teleport", path: teleportPath, end: teleportEnd}, {name: "seat", path: seatPath, end: seatEnd}]; - Pointers.editRenderState(this.teleportRayHandVisible, "cancel", teleportRenderStates[0]); - Pointers.editRenderState(this.teleportRayHandInvisible, "cancel", teleportRenderStates[0]); - Pointers.editRenderState(this.teleportRayHeadVisible, "cancel", teleportRenderStates[0]); - Pointers.editRenderState(this.teleportRayHeadInvisible, "cancel", teleportRenderStates[0]); + Pointers.editRenderState(this.teleportParabolaHandVisible, "cancel", teleportRenderStates[0]); + Pointers.editRenderState(this.teleportParabolaHandInvisible, "cancel", teleportRenderStates[0]); + Pointers.editRenderState(this.teleportParabolaHeadVisible, "cancel", teleportRenderStates[0]); + Pointers.editRenderState(this.teleportParabolaHeadInvisible, "cancel", teleportRenderStates[0]); - Pointers.editRenderState(this.teleportRayHandVisible, "teleport", teleportRenderStates[1]); - Pointers.editRenderState(this.teleportRayHandInvisible, "teleport", teleportRenderStates[1]); - Pointers.editRenderState(this.teleportRayHeadVisible, "teleport", teleportRenderStates[1]); - Pointers.editRenderState(this.teleportRayHeadInvisible, "teleport", teleportRenderStates[1]); + Pointers.editRenderState(this.teleportParabolaHandVisible, "teleport", teleportRenderStates[1]); + Pointers.editRenderState(this.teleportParabolaHandInvisible, "teleport", teleportRenderStates[1]); + Pointers.editRenderState(this.teleportParabolaHeadVisible, "teleport", teleportRenderStates[1]); + Pointers.editRenderState(this.teleportParabolaHeadInvisible, "teleport", teleportRenderStates[1]); - Pointers.editRenderState(this.teleportRayHandVisible, "seat", teleportRenderStates[2]); - Pointers.editRenderState(this.teleportRayHandInvisible, "seat", teleportRenderStates[2]); - Pointers.editRenderState(this.teleportRayHeadVisible, "seat", teleportRenderStates[2]); - Pointers.editRenderState(this.teleportRayHeadInvisible, "seat", teleportRenderStates[2]); + Pointers.editRenderState(this.teleportParabolaHandVisible, "seat", teleportRenderStates[2]); + Pointers.editRenderState(this.teleportParabolaHandInvisible, "seat", teleportRenderStates[2]); + Pointers.editRenderState(this.teleportParabolaHeadVisible, "seat", teleportRenderStates[2]); + Pointers.editRenderState(this.teleportParabolaHeadInvisible, "seat", teleportRenderStates[2]); } }; @@ -258,18 +261,18 @@ Script.include("/~/system/libraries/controllers.js"); var pose = Controller.getPoseValue(handInfo[(_this.hand === RIGHT_HAND) ? 'right' : 'left'].controllerInput); var mode = pose.valid ? _this.hand : 'head'; if (!pose.valid) { - Pointers.disablePointer(_this.teleportRayHandVisible); - Pointers.disablePointer(_this.teleportRayHandInvisible); - Pointers.enablePointer(_this.teleportRayHeadVisible); - Pointers.enablePointer(_this.teleportRayHeadInvisible); + Pointers.disablePointer(_this.teleportParabolaHandVisible); + Pointers.disablePointer(_this.teleportParabolaHandInvisible); + Pointers.enablePointer(_this.teleportParabolaHeadVisible); + Pointers.enablePointer(_this.teleportParabolaHeadInvisible); } else { - Pointers.enablePointer(_this.teleportRayHandVisible); - Pointers.enablePointer(_this.teleportRayHandInvisible); - Pointers.disablePointer(_this.teleportRayHeadVisible); - Pointers.disablePointer(_this.teleportRayHeadInvisible); + Pointers.enablePointer(_this.teleportParabolaHandVisible); + Pointers.enablePointer(_this.teleportParabolaHandInvisible); + Pointers.disablePointer(_this.teleportParabolaHeadVisible); + Pointers.disablePointer(_this.teleportParabolaHeadInvisible); } - // We do up to 2 ray picks to find a teleport location. + // We do up to 2 picks to find a teleport location. // There are 2 types of teleport locations we are interested in: // 1. A visible floor. This can be any entity surface that points within some degree of "up" // 2. A seat. The seat can be visible or invisible. @@ -280,17 +283,17 @@ Script.include("/~/system/libraries/controllers.js"); // var result; if (mode === 'head') { - result = Pointers.getPrevPickResult(_this.teleportRayHeadInvisible); + result = Pointers.getPrevPickResult(_this.teleportParabolaHeadInvisible); } else { - result = Pointers.getPrevPickResult(_this.teleportRayHandInvisible); + result = Pointers.getPrevPickResult(_this.teleportParabolaHandInvisible); } var teleportLocationType = getTeleportTargetType(result); if (teleportLocationType === TARGET.INVISIBLE) { if (mode === 'head') { - result = Pointers.getPrevPickResult(_this.teleportRayHeadVisible); + result = Pointers.getPrevPickResult(_this.teleportParabolaHeadVisible); } else { - result = Pointers.getPrevPickResult(_this.teleportRayHandVisible); + result = Pointers.getPrevPickResult(_this.teleportParabolaHandVisible); } teleportLocationType = getTeleportTargetType(result); } @@ -336,27 +339,27 @@ Script.include("/~/system/libraries/controllers.js"); }; this.disableLasers = function() { - Pointers.disablePointer(_this.teleportRayHandVisible); - Pointers.disablePointer(_this.teleportRayHandInvisible); - Pointers.disablePointer(_this.teleportRayHeadVisible); - Pointers.disablePointer(_this.teleportRayHeadInvisible); + Pointers.disablePointer(_this.teleportParabolaHandVisible); + Pointers.disablePointer(_this.teleportParabolaHandInvisible); + Pointers.disablePointer(_this.teleportParabolaHeadVisible); + Pointers.disablePointer(_this.teleportParabolaHeadInvisible); }; this.setTeleportState = function(mode, visibleState, invisibleState) { if (mode === 'head') { - Pointers.setRenderState(_this.teleportRayHeadVisible, visibleState); - Pointers.setRenderState(_this.teleportRayHeadInvisible, invisibleState); + Pointers.setRenderState(_this.teleportParabolaHeadVisible, visibleState); + Pointers.setRenderState(_this.teleportParabolaHeadInvisible, invisibleState); } else { - Pointers.setRenderState(_this.teleportRayHandVisible, visibleState); - Pointers.setRenderState(_this.teleportRayHandInvisible, invisibleState); + Pointers.setRenderState(_this.teleportParabolaHandVisible, visibleState); + Pointers.setRenderState(_this.teleportParabolaHandInvisible, invisibleState); } }; this.setIgnoreEntities = function(entitiesToIgnore) { - Pointers.setIgnoreItems(this.teleportRayHandVisible, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportRayHandInvisible, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportRayHeadVisible, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportRayHeadInvisible, entitiesToIgnore); + Pointers.setIgnoreItems(this.teleportParabolaHandVisible, entitiesToIgnore); + Pointers.setIgnoreItems(this.teleportParabolaHandInvisible, entitiesToIgnore); + Pointers.setIgnoreItems(this.teleportParabolaHeadVisible, entitiesToIgnore); + Pointers.setIgnoreItems(this.teleportParabolaHeadInvisible, entitiesToIgnore); }; }