3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-27 05:35:37 +02:00

pointer rendering, update teleport.js

This commit is contained in:
SamGondelman 2018-07-18 17:01:42 -07:00
parent 86c56195d3
commit 39fa3420ec
10 changed files with 682 additions and 94 deletions

View file

@ -14,8 +14,6 @@
#include "avatar/AvatarManager.h"
#include <DependencyManager.h>
#include <PickManager.h>
#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<RayPickResult>(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);
}
}

View file

@ -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;

View file

@ -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 <StencilMaskPass.h>
#include <DependencyManager.h>
#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<RenderState>(_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<ParabolaPickResult>(pickResult);
return (parabolaPickResult ? vec3FromVariant(parabolaPickResult->pickVariant["origin"]) : glm::vec3());
}
glm::vec3 ParabolaPointer::getPickEnd(const PickResultPointer& pickResult, float distance) {
auto parabolaPickResult = std::static_pointer_cast<ParabolaPickResult>(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<ParabolaPickResult>(pickResult);
return (parabolaPickResult ? parabolaPickResult->surfaceNormal : glm::vec3());
}
IntersectionType ParabolaPointer::getPickedObjectType(const PickResultPointer& pickResult) {
auto parabolaPickResult = std::static_pointer_cast<ParabolaPickResult>(pickResult);
return (parabolaPickResult ? parabolaPickResult->type : IntersectionType::NONE);
}
QUuid ParabolaPointer::getPickedObjectID(const PickResultPointer& pickResult) {
auto parabolaPickResult = std::static_pointer_cast<ParabolaPickResult>(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<ParabolaPickResult>(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<ParabolaRenderItem>(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled);
// TODO: update bounds properly
renderItem->editBound().setBox(glm::vec3(-16000.0f), 32000.0f);
transaction.resetItem(_pathID, std::make_shared<ParabolaRenderItem::Payload>(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<ParabolaRenderItem>(_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<ParabolaRenderItem>(_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<ParabolaPickResult>(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<ParabolaRenderItem>(_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<StartEndRenderState> 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<RenderState>(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<ParabolaPickResult>(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<AvatarManager>()->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<gpu::State>();
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<gpu::State>();
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();
}
}

View file

@ -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<ParabolaRenderItem>;
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<gpu::Buffer>() };
};
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<StartEndRenderState> 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

View file

@ -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));

View file

@ -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;

View file

@ -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<PointerManager>()->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<QVariant> 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<QVariant> 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<float, ParabolaPointer::RenderState>(distance, ParabolaPointer::buildRenderState(renderStateMap));
defaultRenderStates[name] = std::pair<float, std::shared_ptr<StartEndRenderState>>(distance, ParabolaPointer::buildRenderState(renderStateMap));
}
}
}
@ -333,7 +332,6 @@ unsigned int PointerScriptingInterface::createParabolaPointer(const QVariant& pr
return DependencyManager::get<PointerManager>()->addPointer(std::make_shared<ParabolaPointer>(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 {

View file

@ -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;
}

View file

@ -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)$>
}

View file

@ -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);
};
}