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:
parent
86c56195d3
commit
39fa3420ec
10 changed files with 682 additions and 94 deletions
interface/src/raypick
LaserPointer.cppLaserPointer.hParabolaPointer.cppParabolaPointer.hPathPointer.cppPathPointer.hPointerScriptingInterface.cpp
libraries/render-utils/src
scripts/system/controllers/controllerModules
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
390
interface/src/raypick/ParabolaPointer.cpp
Normal file
390
interface/src/raypick/ParabolaPointer.cpp
Normal 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();
|
||||
}
|
||||
}
|
118
interface/src/raypick/ParabolaPointer.h
Normal file
118
interface/src/raypick/ParabolaPointer.h
Normal 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
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
18
libraries/render-utils/src/parabola.slf
Normal file
18
libraries/render-utils/src/parabola.slf
Normal 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;
|
||||
}
|
53
libraries/render-utils/src/parabola.slv
Normal file
53
libraries/render-utils/src/parabola.slv
Normal 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)$>
|
||||
}
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue