Work on porting laser pointers to local entities, removal of LaserPointer JS API

This commit is contained in:
ksuprynowicz 2023-03-26 21:09:46 +02:00
parent 4d03033c9e
commit 2a2cf3898b
13 changed files with 311 additions and 385 deletions

View file

@ -242,7 +242,6 @@
#include <PickManager.h>
#include <PointerManager.h>
#include <raypick/RayPickScriptingInterface.h>
#include <raypick/LaserPointerScriptingInterface.h>
#include <raypick/PickScriptingInterface.h>
#include <raypick/PointerScriptingInterface.h>
#include <raypick/RayPick.h>
@ -806,7 +805,6 @@ bool setupEssentials(int& argc, char** argv, const QCommandLineParser& parser, b
// Set dependencies
DependencyManager::set<PickManager>();
DependencyManager::set<PointerManager>();
DependencyManager::set<LaserPointerScriptingInterface>();
DependencyManager::set<RayPickScriptingInterface>();
DependencyManager::set<PointerScriptingInterface>();
DependencyManager::set<PickScriptingInterface>();
@ -7529,7 +7527,6 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptManage
scriptEngine->registerGlobalObject("LocationBookmarks", DependencyManager::get<LocationBookmarks>().data());
scriptEngine->registerGlobalObject("RayPick", DependencyManager::get<RayPickScriptingInterface>().data());
scriptEngine->registerGlobalObject("LaserPointers", DependencyManager::get<LaserPointerScriptingInterface>().data());
scriptEngine->registerGlobalObject("Picks", DependencyManager::get<PickScriptingInterface>().data());
scriptEngine->registerGlobalObject("Pointers", DependencyManager::get<PointerScriptingInterface>().data());

View file

@ -25,13 +25,15 @@
#include "scripting/ControllerScriptingInterface.h"
static const float SEARCH_SPHERE_SIZE = 0.0132f;
static const QVariantMap SEARCH_SPHERE = {{"x", SEARCH_SPHERE_SIZE},
/*static const QVariantMap SEARCH_SPHERE = {{"x", SEARCH_SPHERE_SIZE},
{"y", SEARCH_SPHERE_SIZE},
{"z", SEARCH_SPHERE_SIZE}};
{"z", SEARCH_SPHERE_SIZE}};*/
static const glm::vec3 SEARCH_SPHERE(SEARCH_SPHERE_SIZE, SEARCH_SPHERE_SIZE, SEARCH_SPHERE_SIZE);
static const int DEFAULT_SEARCH_SPHERE_DISTANCE = 1000; // how far from camera to search intersection?
static const QVariantMap COLORS_GRAB_SEARCHING_HALF_SQUEEZE = {{"red", 10},
/*static const QVariantMap COLORS_GRAB_SEARCHING_HALF_SQUEEZE = {{"red", 10},
{"green", 10},
{"blue", 255}};
@ -41,8 +43,13 @@ static const QVariantMap COLORS_GRAB_SEARCHING_FULL_SQUEEZE = {{"red", 250},
static const QVariantMap COLORS_GRAB_DISTANCE_HOLD = {{"red", 238},
{"green", 75},
{"blue", 214}};
{"blue", 214}};*/
static const glm::u8vec3 COLORS_GRAB_SEARCHING_HALF_SQUEEZE(10, 10, 255);
static const glm::u8vec3 COLORS_GRAB_SEARCHING_FULL_SQUEEZE(250, 10, 10);
static const glm::u8vec3 COLORS_GRAB_DISTANCE_HOLD(238, 75, 215);
void LoginStateManager::tearDown() {
@ -60,90 +67,88 @@ void LoginStateManager::tearDown() {
}
void LoginStateManager::setUp() {
QVariantMap fullPathRenderState {
{"type", "line3d"},
{"color", COLORS_GRAB_SEARCHING_FULL_SQUEEZE},
{"visible", true},
{"alpha", 1.0f},
{"solid", true},
{"glow", 1.0f},
{"ignoreRayIntersection", true}, // always ignore this
{"drawInFront", true}, // Even when burried inside of something, show it.
{"drawHUDLayer", false}
};
QVariantMap fullEndRenderState {
{"type", "sphere"},
{"dimensions", SEARCH_SPHERE},
{"solid", true},
{"color", COLORS_GRAB_SEARCHING_FULL_SQUEEZE},
{"alpha", 0.9f},
{"ignoreRayIntersection", true},
{"drawInFront", true}, // Even when burried inside of something, show it.
{"drawHUDLayer", false},
{"visible", true}
};
QVariantMap halfPathRenderState {
{"type", "line3d"},
{"color", COLORS_GRAB_SEARCHING_HALF_SQUEEZE},
{"visible", true},
{"alpha", 1.0f},
{"solid", true},
{"glow", 1.0f},
{"ignoreRayIntersection", true}, // always ignore this
{"drawInFront", true}, // Even when burried inside of something, show it.
{"drawHUDLayer", false}
};
QVariantMap halfEndRenderState {
{"type", "sphere"},
{"dimensions", SEARCH_SPHERE},
{"solid", true},
{"color", COLORS_GRAB_SEARCHING_HALF_SQUEEZE},
{"alpha", 0.9f},
{"ignoreRayIntersection", true},
{"drawInFront", true}, // Even when burried inside of something, show it.
{"drawHUDLayer", false},
{"visible", true}
};
QVariantMap holdPathRenderState {
{"type", "line3d"},
{"color", COLORS_GRAB_DISTANCE_HOLD},
{"visible", true},
{"alpha", 1.0f},
{"solid", true},
{"glow", 1.0f},
{"ignoreRayIntersection", true}, // always ignore this
{"drawInFront", true}, // Even when burried inside of something, show it.
{"drawHUDLayer", false},
};
QList<EntityItemProperties> entityProperties;
//V8TODO: are points and normals needed here
EntityItemProperties fullPathRenderState;
fullPathRenderState.setType(EntityTypes::PolyLine);
fullPathRenderState.setColor(COLORS_GRAB_SEARCHING_FULL_SQUEEZE);
fullPathRenderState.setGlow(true);
fullPathRenderState.setIgnorePickIntersection(true); // always ignore this
fullPathRenderState.setRenderLayer(RenderLayer::FRONT); // Even when buried inside of something, show it.
fullPathRenderState.setFaceCamera(true);
int fullPathRenderStateIndex = entityProperties.length();
entityProperties.append(fullPathRenderState);
EntityItemProperties fullEndRenderState;
fullEndRenderState.setType(EntityTypes::Sphere);
fullEndRenderState.setDimensions(SEARCH_SPHERE);
fullEndRenderState.setColor(COLORS_GRAB_SEARCHING_FULL_SQUEEZE);
fullEndRenderState.setAlpha(0.9f);
fullEndRenderState.setIgnorePickIntersection(true); // always ignore this
fullEndRenderState.setRenderLayer(RenderLayer::FRONT); // Even when buried inside of something, show it.
int fullEndRenderStateIndex = entityProperties.length();
entityProperties.append(fullEndRenderState);
EntityItemProperties halfPathRenderState;
halfPathRenderState.setType(EntityTypes::PolyLine);
halfPathRenderState.setColor(COLORS_GRAB_SEARCHING_HALF_SQUEEZE);
halfPathRenderState.setGlow(true);
halfPathRenderState.setIgnorePickIntersection(true); // always ignore this
halfPathRenderState.setRenderLayer(RenderLayer::FRONT); // Even when buried inside of something, show it.
halfPathRenderState.setFaceCamera(true);
int halfPathRenderStateIndex = entityProperties.length();
entityProperties.append(halfPathRenderState);
EntityItemProperties halfEndRenderState;
halfEndRenderState.setType(EntityTypes::Sphere);
halfEndRenderState.setDimensions(SEARCH_SPHERE);
halfEndRenderState.setColor(COLORS_GRAB_SEARCHING_HALF_SQUEEZE);
halfEndRenderState.setAlpha(0.9f);
halfEndRenderState.setIgnorePickIntersection(true); // always ignore this
halfEndRenderState.setRenderLayer(RenderLayer::FRONT); // Even when buried inside of something, show it.
int halfEndRenderStateIndex = entityProperties.length();
entityProperties.append(halfEndRenderState);
EntityItemProperties holdPathRenderState;
holdPathRenderState.setType(EntityTypes::PolyLine);
holdPathRenderState.setColor(COLORS_GRAB_DISTANCE_HOLD);
holdPathRenderState.setGlow(true);
holdPathRenderState.setIgnorePickIntersection(true); // always ignore this
holdPathRenderState.setRenderLayer(RenderLayer::FRONT); // Even when buried inside of something, show it.
holdPathRenderState.setFaceCamera(true);
int holdPathRenderStateIndex = entityProperties.length();
entityProperties.append(holdPathRenderState);
QVariantMap halfRenderStateIdentifier {
{"name", "half"},
{"path", halfPathRenderState},
{"end", halfEndRenderState}
{"pathPropertyIndex", halfPathRenderStateIndex},
{"endPropertyIndex", halfEndRenderStateIndex}
};
QVariantMap fullRenderStateIdentifier {
{"name", "full"},
{"path", fullPathRenderState},
{"end", fullEndRenderState}
{"pathPropertyIndex", fullPathRenderStateIndex},
{"endPropertyIndex", fullEndRenderStateIndex}
};
QVariantMap holdRenderStateIdentifier {
{"name", "hold"},
{"path", holdPathRenderState},
{"pathPropertyIndex", holdPathRenderStateIndex},
};
QVariantMap halfDefaultRenderStateIdentifier {
{"name", "half"},
{"distance", DEFAULT_SEARCH_SPHERE_DISTANCE},
{"path", halfPathRenderState}
{"pathPropertyIndex", halfPathRenderStateIndex}
};
QVariantMap fullDefaultRenderStateIdentifier {
{"name", "full"},
{"distance", DEFAULT_SEARCH_SPHERE_DISTANCE},
{"path", fullPathRenderState}
{"pathPropertyIndex", fullPathRenderStateIndex}
};
QVariantMap holdDefaultRenderStateIdentifier {
{"name", "hold"},
{"distance", DEFAULT_SEARCH_SPHERE_DISTANCE},
{"path", holdPathRenderState}
{"pathPropertyIndex", holdPathRenderStateIndex}
};
_renderStates = QList<QVariant>({halfRenderStateIdentifier, fullRenderStateIdentifier, holdRenderStateIdentifier});
@ -168,7 +173,7 @@ void LoginStateManager::setUp() {
leftPointerTriggerProperties = QList<QVariant>({ltClick1, ltClick2});
const unsigned int leftHand = 0;
QVariantMap leftPointerProperties {
QVariantMap leftPointerPropertiesMap {
{ "joint", "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND" },
{ "filter", PickScriptingInterface::getPickLocalEntities() },
{ "triggers", leftPointerTriggerProperties },
@ -178,9 +183,12 @@ void LoginStateManager::setUp() {
{ "distanceScaleEnd", true },
{ "hand", leftHand }
};
leftPointerProperties["renderStates"] = _renderStates;
leftPointerProperties["defaultRenderStates"] = _defaultRenderStates;
_leftLoginPointerID = pointers->createPointer(PickQuery::PickType::Ray, leftPointerProperties);
leftPointerPropertiesMap["renderStates"] = _renderStates;
leftPointerPropertiesMap["defaultRenderStates"] = _defaultRenderStates;
RayPointerProperties leftPointerProperties;
leftPointerProperties.properties = leftPointerPropertiesMap;
leftPointerProperties.entityProperties = entityProperties;
_leftLoginPointerID = pointers->createRayPointer(leftPointerProperties);
pointers->setRenderState(_leftLoginPointerID, "");
pointers->enablePointer(_leftLoginPointerID);
const unsigned int rightHand = 1;
@ -195,7 +203,7 @@ void LoginStateManager::setUp() {
{ "button", "Primary" }
};
rightPointerTriggerProperties = QList<QVariant>({rtClick1, rtClick2});
QVariantMap rightPointerProperties{
QVariantMap rightPointerPropertiesMap{
{ "joint", "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" },
{ "filter", PickScriptingInterface::getPickLocalEntities() },
{ "triggers", rightPointerTriggerProperties },
@ -205,9 +213,12 @@ void LoginStateManager::setUp() {
{ "distanceScaleEnd", true },
{ "hand", rightHand }
};
rightPointerProperties["renderStates"] = _renderStates;
rightPointerProperties["defaultRenderStates"] = _defaultRenderStates;
_rightLoginPointerID = pointers->createPointer(PickQuery::PickType::Ray, rightPointerProperties);
rightPointerPropertiesMap["renderStates"] = _renderStates;
rightPointerPropertiesMap["defaultRenderStates"] = _defaultRenderStates;
RayPointerProperties rightPointerProperties;
rightPointerProperties.properties = rightPointerPropertiesMap;
rightPointerProperties.entityProperties = entityProperties;
_rightLoginPointerID = pointers->createRayPointer(rightPointerProperties);
pointers->setRenderState(_rightLoginPointerID, "");
pointers->enablePointer(_rightLoginPointerID);
}

View file

@ -4,6 +4,7 @@
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -32,6 +33,7 @@ PickQuery::PickType LaserPointer::getType() const {
}
void LaserPointer::editRenderStatePath(const std::string& state, const QVariant& pathProps) {
//V8TODO pathProps are not a thing anymore
auto renderState = std::static_pointer_cast<RenderState>(_renderStates[state]);
if (renderState) {
updateRenderState(renderState->getPathID(), pathProps);
@ -51,6 +53,7 @@ PickResultPointer LaserPointer::getPickResultCopy(const PickResultPointer& pickR
}
QVariantMap LaserPointer::toVariantMap() const {
//V8TODO: this cannot be done anymore without script engine
QVariantMap qVariantMap = Parent::toVariantMap();
QVariantMap qRenderStates;
@ -175,6 +178,10 @@ void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3&
properties.setLinePoints(points);
properties.setVisible(true);
properties.setIgnorePickIntersection(doesPathIgnorePicks());
QVector<glm::vec3> normals;
normals.append(glm::vec3(0.0f, 0.0f, 1.0f));
normals.append(glm::vec3(0.0f, 0.0f, 1.0f));
properties.setNormals(normals);
QVector<float> widths;
float width = getLineWidth() * parentScale;
widths.append(width);
@ -184,33 +191,34 @@ void LaserPointer::RenderState::update(const glm::vec3& origin, const glm::vec3&
}
}
std::shared_ptr<StartEndRenderState> LaserPointer::buildRenderState(const QVariantMap& propMap) {
std::shared_ptr<StartEndRenderState> LaserPointer::buildRenderState(const QVariantMap& propMap, const QList<EntityItemProperties> &entityProperties) {
// FIXME: we have to keep using the Overlays interface here, because existing scripts use overlay properties to define pointers
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);
if (propMap["startPropertyIndex"].isValid()) {
int startPropertyIndex = propMap["startPropertyIndex"].toInt();
if (startPropertyIndex >= 0 && startPropertyIndex < entityProperties.length()) {
//startMap.remove("visible");
startID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties[startPropertyIndex], entity::HostType::LOCAL);
}
}
QUuid pathID;
if (propMap["path"].isValid()) {
QVariantMap pathMap = propMap["path"].toMap();
// laser paths must be line3ds
if (pathMap["type"].isValid() && pathMap["type"].toString() == "line3d") {
pathMap.remove("visible");
pathID = qApp->getOverlays().addOverlay(pathMap["type"].toString(), pathMap);
if (propMap["pathPropertyIndex"].isValid()) {
// laser paths must be PolyLine
int pathPropertyIndex = propMap["pathPropertyIndex"].toInt();
if (pathPropertyIndex >= 0 && pathPropertyIndex < entityProperties.length()) {
//startMap.remove("visible");
//pathMap["type"].toString() == "PolyLine"
pathID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties[pathPropertyIndex], entity::HostType::LOCAL);
}
}
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);
if (propMap["endPropertyIndex"].isValid()) {
int endPropertyIndex = propMap["endPropertyIndex"].toInt();
if (endPropertyIndex >= 0 && endPropertyIndex < entityProperties.length()) {
//startMap.remove("visible");
endID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties[endPropertyIndex], entity::HostType::LOCAL);
}
}

View file

@ -13,6 +13,8 @@
#include "PathPointer.h"
#include<EntityItemProperties.h>
class LaserPointer : public PathPointer {
using Parent = PathPointer;
public:
@ -46,7 +48,7 @@ public:
QVariantMap toVariantMap() const override;
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap, const QList<EntityItemProperties> &entityProperties);
protected:
PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const override;

View file

@ -1,37 +0,0 @@
//
// LaserPointerScriptingInterface.cpp
// interface/src/raypick
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// SPDX-License-Identifier: Apache-2.0
//
#include "LaserPointerScriptingInterface.h"
#include "PointerScriptingInterface.h"
#include <ScriptValueUtils.h>
void LaserPointerScriptingInterface::setIgnoreItems(unsigned int uid, const ScriptValue& ignoreItems) const {
DependencyManager::get<PointerManager>()->setIgnoreItems(uid, qVectorQUuidFromScriptValue(ignoreItems));
}
void LaserPointerScriptingInterface::setIncludeItems(unsigned int uid, const ScriptValue& includeItems) const {
DependencyManager::get<PointerManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}
unsigned int LaserPointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
return DependencyManager::get<PointerScriptingInterface>()->createPointer(PickQuery::PickType::Ray, properties);
}
void LaserPointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {
DependencyManager::get<PointerScriptingInterface>()->editRenderState(uid, renderState, properties);
}
QVariantMap LaserPointerScriptingInterface::getPrevRayPickResult(unsigned int uid) const {
return DependencyManager::get<PointerScriptingInterface>()->getPrevPickResult(uid);
}

View file

@ -1,172 +0,0 @@
//
// LaserPointerScriptingInterface.h
// interface/src/raypick
//
// Created by Sam Gondelman 7/11/2017
// Copyright 2017 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// SPDX-License-Identifier: Apache-2.0
//
#ifndef hifi_LaserPointerScriptingInterface_h
#define hifi_LaserPointerScriptingInterface_h
#include <QtCore/QObject>
#include "DependencyManager.h"
#include <PointerManager.h>
class ScriptValue;
class LaserPointerScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
/*@jsdoc
* The <code>LaserPointers</code> API is a subset of the {@link Pointers} API. It lets you create, manage, and visually
* represent objects for repeatedly calculating ray intersections with avatars, entities, and overlays. Ray pointers can also
* be configured to generate events on entities and overlays intersected.
*
* @namespace LaserPointers
*
* @deprecated This API is deprecated and will be removed. Use {@link Pointers} instead.
*
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
*
* @borrows Pointers.enablePointer as enableLaserPointer
* @borrows Pointers.disablePointer as disableLaserPointer
* @borrows Pointers.removePointer as removeLaserPointer
* @borrows Pointers.setPrecisionPicking as setPrecisionPicking
*/
public:
/*@jsdoc
* Creates a new ray pointer. The pointer can have a wide range of behaviors depending on the properties specified. For
* example, it may be a static ray pointer, a mouse ray pointer, or joint ray pointer.
* <p><strong>Warning:</strong> Pointers created using this method currently always intersect at least visible and
* collidable things but this may not always be the case.</p>
* @function LaserPointers.createLaserPointer
* @param {Pointers.RayPointerProperties} properties - The properties of the pointer, including the properties of the
* underlying pick that the pointer uses to do its picking.
* @returns {number} The ID of the pointer if successfully created, otherwise <code>0</code>.
*/
Q_INVOKABLE unsigned int createLaserPointer(const QVariant& properties) const;
// jsdoc @borrows from Pointers
Q_INVOKABLE void enableLaserPointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->enablePointer(uid); }
// jsdoc @borrows from Pointers
Q_INVOKABLE void disableLaserPointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->disablePointer(uid); }
// jsdoc @borrows from Pointers
Q_INVOKABLE void removeLaserPointer(unsigned int uid) const { DependencyManager::get<PointerManager>()->removePointer(uid); }
/*@jsdoc
* Edits a render state of a pointer, to change its visual appearance for the state when the pointer is intersecting
* something.
* <p><strong>Note:</strong> You can only edit the properties of the existing parts of the pointer; you cannot change the
* type of any part.</p>
* <p><strong>Note:</strong> You cannot use this method to change the appearance of a default render state.</p>
* @function LaserPointers.editRenderState
* @param {number} id - The ID of the pointer.
* @param {string} renderState - The name of the render state to edit.
* @param {Pointers.RayPointerRenderState} properties - The new properties for the render state. Only the overlay
* properties to change need be specified.
*/
Q_INVOKABLE void editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const;
/*@jsdoc
* Sets the render state of a pointer, to change its visual appearance and possibly disable or enable it.
* @function LaserPointers.setRenderState
* @param {string} renderState - <p>The name of the render state to set the pointer to. This may be:</p>
* <ul>
* <li>The name of one of the render states set in the pointer's properties.</li>
* <li><code>""</code>, to hide the pointer and disable emitting of events.</li>
* </ul>
* @param {number} id - The ID of the pointer.
*/
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) const { DependencyManager::get<PointerManager>()->setRenderState(uid, renderState.toStdString()); }
/*@jsdoc
* Gets the most recent intersection of a pointer. A pointer continues to be updated ready to return a result, as long as
* it is enabled, regardless of the render state.
* @function LaserPointers.getPrevRayPickResult
* @param {number} id - The ID of the pointer.
* @returns {RayPickResult} The most recent intersection of the pointer.
*/
Q_INVOKABLE QVariantMap getPrevRayPickResult(unsigned int uid) const;
// jsdoc @borrows from Pointers
Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking) const { DependencyManager::get<PointerManager>()->setPrecisionPicking(uid, precisionPicking); }
/*@jsdoc
* Sets the length of a pointer.
* @function LaserPointers.setLaserLength
* @param {number} id - The ID of the pointer.
* @param {number} laserLength - The desired length of the pointer.
*/
Q_INVOKABLE void setLaserLength(unsigned int uid, float laserLength) const { DependencyManager::get<PointerManager>()->setLength(uid, laserLength); }
/*@jsdoc
* Sets a list of entity and avatar IDs that a pointer should ignore during intersection.
* @function LaserPointers.setIgnoreItems
* @param {number} id - The ID of the pointer.
* @param {Uuid[]} ignoreItems - A list of IDs to ignore.
*/
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const ScriptValue& ignoreEntities) const;
/*@jsdoc
* Sets a list of entity and avatar IDs that a pointer should include during intersection, instead of intersecting with
* everything.
* @function LaserPointers.setIncludeItems
* @param {number} id - The ID of the pointer.
* @param {Uuid[]} includeItems - A list of IDs to include.
*/
Q_INVOKABLE void setIncludeItems(unsigned int uid, const ScriptValue& includeEntities) const;
/*@jsdoc
* Locks a pointer onto a specific entity or avatar.
* @function LaserPointers.setLockEndUUID
* @param {number} id - The ID of the pointer.
* @param {Uuid} targetID - The ID of the entity or avatar to lock the pointer on to.
* @param {boolean} isAvatar - <code>true</code> if the target is an avatar, <code>false</code> if it is an entity.
* @param {Mat4} [offset] - The offset of the target point from the center of the target item. If not specified, the
* pointer locks on to the center of the target item.
*/
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isAvatar, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get<PointerManager>()->setLockEndUUID(uid, objectID, isAvatar, offsetMat); }
/*@jsdoc
* Checks if a pointer is associated with the left hand: a pointer with <code>joint</code> property set to
* <code>"_CONTROLLER_LEFTHAND"</code> or <code>"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND"</code>.
* @function LaserPointers.isLeftHand
* @param {number} id - The ID of the pointer.
* @returns {boolean} <code>true</code> if the pointer is associated with the left hand, <code>false</code> if it isn't.
*/
Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isLeftHand(uid); }
/*@jsdoc
* Checks if a pointer is associated with the right hand: a pointer with <code>joint</code> property set to
* <code>"_CONTROLLER_RIGHTHAND"</code> or <code>"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND"</code>.
* @function LaserPointers.isRightHand
* @param {number} id - The ID of the pointer.
* @returns {boolean} <code>true</code> if the pointer is associated with the right hand, <code>false</code> if it isn't.
*/
Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get<PointerManager>()->isRightHand(uid); }
/*@jsdoc
* Checks if a pointer is associated with the system mouse: a pointer with <code>joint</code> property set to
* <code>"Mouse"</code>.
* @function LaserPointers.isMouse
* @param {number} id - The ID of the pointer.
* @returns {boolean} <code>true</code> if the pointer is associated with the system mouse, <code>false</code> if it isn't.
*/
Q_INVOKABLE bool isMouse(unsigned int uid) { return DependencyManager::get<PointerManager>()->isMouse(uid); }
};
#endif // hifi_LaserPointerScriptingInterface_h

View file

@ -1,6 +1,7 @@
//
// Created by Sam Gondelman 7/17/2018
// Copyright 2018 High Fidelity, Inc.
// Copyright 2023 Overte e.V.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -232,14 +233,13 @@ void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::ve
}
}
std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVariantMap& propMap) {
// FIXME: we have to keep using the Overlays interface here, because existing scripts use overlay properties to define pointers
std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVariantMap& propMap, const QList<EntityItemProperties> &entityProperties) {
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);
if (propMap["startPropertyIndex"].isValid()) {
int startPropertyIndex = propMap["startPropertyIndex"].toInt();
if (startPropertyIndex >= 0 && startPropertyIndex < entityProperties.length()) {
//startMap.remove("visible");
startID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties[startPropertyIndex], entity::HostType::LOCAL);
}
}
@ -249,36 +249,25 @@ std::shared_ptr<StartEndRenderState> ParabolaPointer::buildRenderState(const QVa
bool isVisibleInSecondaryCamera = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA;
bool drawInFront = RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_DRAWINFRONT;
bool enabled = false;
if (propMap["path"].isValid()) {
enabled = true;
QVariantMap pathMap = propMap["path"].toMap();
if (pathMap["color"].isValid()) {
color = toGlm(u8vec3FromVariant(pathMap["color"]));
}
if (pathMap["alpha"].isValid()) {
alpha = pathMap["alpha"].toFloat();
}
if (pathMap["width"].isValid()) {
width = pathMap["width"].toFloat();
}
if (pathMap["isVisibleInSecondaryCamera"].isValid()) {
isVisibleInSecondaryCamera = pathMap["isVisibleInSecondaryCamera"].toBool();
}
if (pathMap["drawInFront"].isValid()) {
drawInFront = pathMap["drawInFront"].toBool();
if (propMap["pathPropertyIndex"].isValid()) {
int pathPropertyIndex = propMap["pathPropertyIndex"].toInt();
if (pathPropertyIndex >= 0 && pathPropertyIndex < entityProperties.length()) {
const EntityItemProperties &pathProperties(entityProperties[pathPropertyIndex]);
enabled = true;
color = pathProperties.getColor();
alpha = pathProperties.getAlpha();
//V8TODO I'm not sure how to do this one
//width = pathProperties.getWidth;
drawInFront = (pathProperties.getRenderLayer() == RenderLayer::FRONT);
}
}
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);
if (propMap["endPropertyIndex"].isValid()) {
int endPropertyIndex = propMap["endPropertyIndex"].toInt();
if (endPropertyIndex >= 0 && endPropertyIndex < entityProperties.length()) {
//endMap.remove("visible");
endID = DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties[endPropertyIndex], entity::HostType::LOCAL);
}
}

View file

@ -10,6 +10,8 @@
#include "PathPointer.h"
#include<EntityItemProperties.h>
#include <render/Item.h>
class ParabolaPointer : public PathPointer {
@ -105,7 +107,7 @@ public:
QVariantMap toVariantMap() const override;
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap);
static std::shared_ptr<StartEndRenderState> buildRenderState(const QVariantMap& propMap, const QList<EntityItemProperties> &entityProperties);
protected:
virtual PickResultPointer getPickResultCopy(const PickResultPointer& pickResult) const override;

View file

@ -22,6 +22,13 @@
#include "StylusPointer.h"
#include "ParabolaPointer.h"
#include "StylusPick.h"
#include <ScriptManager.h>
STATIC_SCRIPT_TYPES_INITIALIZER((+[](ScriptManager* manager){
qDebug() << "STATIC_SCRIPT_TYPES_INITIALIZER PointerScriptingInterface";
auto scriptEngine = manager->engine().get();
scriptRegisterMetaType<RayPointerProperties, rayPointerPropertiesToScriptValue, rayPointerPropertiesFromScriptValue>(scriptEngine);
}));
static const glm::quat X_ROT_NEG_90{ 0.70710678f, -0.70710678f, 0.0f, 0.0f };
static const glm::vec3 DEFAULT_POSITION_OFFSET{0.0f, 0.0f, -StylusPick::WEB_STYLUS_LENGTH / 2.0f};
@ -35,26 +42,26 @@ void PointerScriptingInterface::setIncludeItems(unsigned int uid, const ScriptVa
DependencyManager::get<PointerManager>()->setIncludeItems(uid, qVectorQUuidFromScriptValue(includeItems));
}
unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType& type, const QVariant& properties) {
unsigned int PointerScriptingInterface::createPointerInternal(const PickQuery::PickType& type, const PointerProperties& properties) {
// Interaction with managers should always happen on the main thread
if (QThread::currentThread() != qApp->thread()) {
unsigned int result;
BLOCKING_INVOKE_METHOD(this, "createPointer", Q_RETURN_ARG(unsigned int, result), Q_ARG(PickQuery::PickType, type), Q_ARG(QVariant, properties));
BLOCKING_INVOKE_METHOD(this, "createPointerInternal", Q_RETURN_ARG(unsigned int, result), Q_ARG(PickQuery::PickType, type), Q_ARG(PointerProperties, properties));
return result;
}
QVariantMap propertyMap = properties.toMap();
QVariantMap propertyMap = properties.properties;
std::shared_ptr<Pointer> pointer;
switch (type) {
case PickQuery::PickType::Ray:
pointer = buildLaserPointer(propertyMap);
pointer = buildLaserPointer(properties);
break;
case PickQuery::PickType::Stylus:
pointer = buildStylus(propertyMap);
pointer = buildStylus(properties);
break;
case PickQuery::PickType::Parabola:
pointer = buildParabolaPointer(propertyMap);
pointer = buildParabolaPointer(properties);
break;
default:
break;
@ -71,6 +78,10 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
return DependencyManager::get<PointerManager>()->addPointer(pointer);
}
unsigned int PointerScriptingInterface::createRayPointer(RayPointerProperties properties) {
return createPointerInternal(PickQuery::PickType::Ray, properties);
}
bool PointerScriptingInterface::isPointerEnabled(unsigned int uid) const {
return DependencyManager::get<PointerManager>()->isPointerEnabled(uid);
}
@ -109,8 +120,8 @@ QVariantMap PointerScriptingInterface::getPointerScriptParameters(unsigned int u
* offset.
* @property {Quat} [rotationOffset] - The rotation offset of the model from the hand, to override the default rotation offset.
*/
std::shared_ptr<Pointer> PointerScriptingInterface::buildStylus(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
std::shared_ptr<Pointer> PointerScriptingInterface::buildStylus(const PointerProperties& properties) {
QVariantMap propertyMap = properties.properties;
bool hover = false;
if (propertyMap["hover"].isValid()) {
@ -142,7 +153,7 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildStylus(const QVariant&
}
}
return std::make_shared<StylusPointer>(properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset, modelRotationOffset, modelDimensions);
return std::make_shared<StylusPointer>(properties.properties, StylusPointer::buildStylus(propertyMap), hover, enabled, modelPositionOffset, modelRotationOffset, modelDimensions);
}
/*@jsdoc
@ -221,8 +232,8 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildStylus(const QVariant&
* {@link Pointers.getPointerProperties}.
* @see {@link Picks.RayPickProperties} for additional properties from the underlying ray pick.
*/
std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const PointerProperties& properties) {
QVariantMap propertyMap = properties.properties;
#if defined (Q_OS_ANDROID)
QString jointName { "" };
@ -284,7 +295,7 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVar
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
renderStates[name] = LaserPointer::buildRenderState(renderStateMap);
renderStates[name] = LaserPointer::buildRenderState(renderStateMap, properties.entityProperties);
}
}
}
@ -299,7 +310,8 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVar
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
float distance = renderStateMap["distance"].toFloat();
defaultRenderStates[name] = std::pair<float, std::shared_ptr<StartEndRenderState>>(distance, LaserPointer::buildRenderState(renderStateMap));
defaultRenderStates[name] = std::pair<float, std::shared_ptr<StartEndRenderState>>(distance,
LaserPointer::buildRenderState(renderStateMap, properties.entityProperties));
}
}
}
@ -328,7 +340,7 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVar
}
}
return std::make_shared<LaserPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
return std::make_shared<LaserPointer>(properties.properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd,
distanceScaleEnd, scaleWithParent, enabled);
}
@ -416,8 +428,8 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildLaserPointer(const QVar
* {@link Pointers.getPointerProperties}.
* @see {@link Picks.ParabolaPickProperties} for additional properties from the underlying parabola pick.
*/
std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const QVariant& properties) {
QVariantMap propertyMap = properties.toMap();
std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const PointerProperties& properties) {
QVariantMap propertyMap = properties.properties;
bool faceAvatar = false;
if (propertyMap["faceAvatar"].isValid()) {
@ -468,7 +480,7 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const Q
QVariantMap renderStateMap = renderStateVariant.toMap();
if (renderStateMap["name"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
renderStates[name] = ParabolaPointer::buildRenderState(renderStateMap);
renderStates[name] = ParabolaPointer::buildRenderState(renderStateMap, properties.entityProperties);
}
}
}
@ -483,7 +495,8 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const Q
if (renderStateMap["name"].isValid() && renderStateMap["distance"].isValid()) {
std::string name = renderStateMap["name"].toString().toStdString();
float distance = renderStateMap["distance"].toFloat();
defaultRenderStates[name] = std::pair<float, std::shared_ptr<StartEndRenderState>>(distance, ParabolaPointer::buildRenderState(renderStateMap));
defaultRenderStates[name] = std::pair<float, std::shared_ptr<StartEndRenderState>>(distance,
ParabolaPointer::buildRenderState(renderStateMap, properties.entityProperties));
}
}
}
@ -512,12 +525,13 @@ std::shared_ptr<Pointer> PointerScriptingInterface::buildParabolaPointer(const Q
}
}
return std::make_shared<ParabolaPointer>(properties, renderStates, defaultRenderStates, hover, triggers,
return std::make_shared<ParabolaPointer>(properties.properties, renderStates, defaultRenderStates, hover, triggers,
faceAvatar, followNormal, followNormalStrength, centerEndY, lockEnd, distanceScaleEnd,
scaleWithParent, enabled);
}
void PointerScriptingInterface::editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const {
//V8TODO: this won't work for now
QVariantMap propMap = properties.toMap();
QVariant startProps;
@ -546,3 +560,52 @@ QVariantMap PointerScriptingInterface::getPrevPickResult(unsigned int uid) const
}
return result;
}
ScriptValue rayPointerPropertiesToScriptValue(ScriptEngine* engine, const RayPointerProperties& in) {
return engine->newVariant(QVariant(in.properties));
}
bool rayPointerPropertiesFromScriptValue(const ScriptValue& value, RayPointerProperties& out) {
// This copies properties from script value, but also converts entity properties of entities used in render states
// from JS objects into EntityItemProperties
out.properties = value.engine()->fromScriptValue<QVariantMap>(value);
if (out.properties["renderStates"].canConvert<QVariantList>()) {
QVariantList renderStates = out.properties["renderStates"].value<QVariantList>();
for( int i = 0; i < renderStates.length(); i++) {
if (renderStates[i].canConvert<QVariantMap>()) {
QVariantMap stateMap = renderStates[i].value<QVariantMap>();
if (stateMap["name"].canConvert<QString>()) {
stateMap["name"].value<QString>();
}
if (stateMap["start"].isValid()) {
ScriptValue start = value.property("renderStates").property(i).property("start");
EntityItemProperties startProperties;
startProperties.copyFromScriptValue(start, false);
stateMap.insert("startPropertyIndex", QVariant(out.entityProperties.length()));
out.entityProperties.append(startProperties);
}
if (stateMap["path"].isValid()) {
ScriptValue path = value.property("renderStates").property(i).property("path");
EntityItemProperties pathProperties;
pathProperties.copyFromScriptValue(path, false);
stateMap.insert("pathPropertyIndex", QVariant(out.entityProperties.length()));
out.entityProperties.append(pathProperties);
}
if (stateMap["end"].isValid()) {
ScriptValue end = value.property("renderStates").property(i).property("end");
EntityItemProperties endProperties;
endProperties.copyFromScriptValue(end, false);
stateMap.insert("endPropertyIndex", QVariant(out.entityProperties.length()));
out.entityProperties.append(endProperties);
}
// V8TODO: Check if path is a polyline and if values are valid
renderStates[i].setValue(stateMap);
}
}
out.properties["renderStates"].setValue(renderStates);
}
qDebug() << "rayPointerPropertiesFromScriptValue" << out.properties;
return true;
}

View file

@ -14,14 +14,15 @@
#include "DependencyManager.h"
#include "RegisteredMetaTypes.h"
#include <EntityItemProperties.h>
#include <PointerManager.h>
#include <Pick.h>
class ScriptValue;
/*@jsdoc
* The <code>Pointers</code> API lets you create, manage, and visually represent objects for repeatedly calculating
* intersections with avatars, entities, and overlays. Pointers can also be configured to generate events on entities and
* The <code>Pointers</code> API lets you create, manage, and visually represent objects for repeatedly calculating
* intersections with avatars, entities, and overlays. Pointers can also be configured to generate events on entities and
* overlays intersected.
*
* @namespace Pointers
@ -31,12 +32,34 @@ class ScriptValue;
* @hifi-avatar
*/
class PointerProperties {
public:
QVariantMap properties;
QList<EntityItemProperties> entityProperties;
};
class RayPointerProperties : public PointerProperties {
};
class ParabolaPointerProperties : public PointerProperties {
};
class StylusPointerProperties : public PointerProperties {
};
Q_DECLARE_METATYPE(RayPointerProperties);
Q_DECLARE_METATYPE(PointerProperties);
class PointerScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
// The purpose of registering different classes is to let the script engine know what data structure it has to
// expect in JS object that will be converted to PointerProperties
/*@jsdoc
* Specifies that a {@link Controller} action or function should trigger events on the entity or overlay currently
* intersected by a {@link Pointers.RayPointerProperties|Ray} or {@link Pointers.ParabolaPointerProperties|Parabola}
@ -133,7 +156,9 @@ public:
* });
*/
// TODO: expand Pointers to be able to be fully configurable with PickFilters
Q_INVOKABLE unsigned int createPointer(const PickQuery::PickType& type, const QVariant& properties);
// V8TODO: add documentation
Q_INVOKABLE unsigned int createRayPointer(RayPointerProperties properties);
/*@jsdoc
* Enables and shows a pointer. Enabled pointers update their pick results and generate events.
@ -479,9 +504,15 @@ public:
Q_INVOKABLE QVariantMap getPointerProperties(unsigned int uid) const;
protected:
static std::shared_ptr<Pointer> buildLaserPointer(const QVariant& properties);
static std::shared_ptr<Pointer> buildStylus(const QVariant& properties);
static std::shared_ptr<Pointer> buildParabolaPointer(const QVariant& properties);
static std::shared_ptr<Pointer> buildLaserPointer(const PointerProperties& properties);
static std::shared_ptr<Pointer> buildStylus(const PointerProperties& properties);
static std::shared_ptr<Pointer> buildParabolaPointer(const PointerProperties& properties);
private:
Q_INVOKABLE unsigned int createPointerInternal(const PickQuery::PickType& type, const PointerProperties& properties);
};
ScriptValue rayPointerPropertiesToScriptValue(ScriptEngine* engine, const RayPointerProperties& in);
bool rayPointerPropertiesFromScriptValue(const ScriptValue& value, RayPointerProperties& out);
#endif // hifi_PointerScriptingInterface_h

View file

@ -49,7 +49,7 @@ PickQuery::PickType StylusPointer::getType() const {
QUuid StylusPointer::buildStylus(const QVariantMap& properties) {
// FIXME: we have to keep using the Overlays interface here, because existing scripts use overlay properties to define pointers
QVariantMap propertiesMap;
/*QVariantMap propertiesMap;
QString modelUrl = DEFAULT_STYLUS_MODEL_URL;
@ -69,7 +69,30 @@ QUuid StylusPointer::buildStylus(const QVariantMap& properties) {
propertiesMap["ignorePickIntersection"] = true;
propertiesMap["drawInFront"] = false;
return qApp->getOverlays().addOverlay("model", propertiesMap);
return qApp->getOverlays().addOverlay("model", propertiesMap);*/
EntityItemProperties entityProperties;
QString modelURL = DEFAULT_STYLUS_MODEL_URL;
if (properties["model"].isValid()) {
QVariantMap modelData = properties["model"].toMap();
if (modelData["url"].isValid()) {
modelURL = modelData["url"].toString();
}
}
// TODO: make these configurable per pointer
entityProperties.setType(EntityTypes::Model);
entityProperties.setName("stylus");
entityProperties.setModelURL(modelURL);
// V8TODO: I can't find equivalent for entities
//propertiesMap["loadPriority"] = 10.0f;
entityProperties.setPrimitiveMode(PrimitiveMode::SOLID);
entityProperties.setVisible(true);
entityProperties.setIgnorePickIntersection(true);
// V8TODO: I can't find equivalent for entities but shouldn't be necessary
//propertiesMap["drawInFront"] = false;
return DependencyManager::get<EntityScriptingInterface>()->addEntityInternal(entityProperties, entity::HostType::LOCAL);
}
void StylusPointer::updateVisuals(const PickResultPointer& pickResult) {

View file

@ -1051,7 +1051,11 @@ void ScriptMethodV8Proxy::call(const v8::FunctionCallbackInfo<v8::Value>& argume
for (int arg = 0; arg < numArgs; ++arg) {
int methodArgTypeId = meta.parameterType(arg);
Q_ASSERT(methodArgTypeId != QMetaType::UnknownType);
if (methodArgTypeId == QMetaType::UnknownType) {
QString methodName = fullName();
qCDebug(scriptengine_v8) << "One of the arguments is QMetaType::UnknownType for method " << methodName;
Q_ASSERT(false);
}
v8::Local<v8::Value> argVal = arguments[arg];
if (methodArgTypeId == scriptValueTypeId) {
qScriptArgLists[i].append(ScriptValue(new ScriptValueV8Wrapper(_engine, V8ScriptValue(_engine, argVal))));

View file

@ -23,58 +23,62 @@ var Pointer = function(hudLayer, pickType, pointerData) {
this.SEARCH_SPHERE_SIZE = 0.0132;
this.dim = {x: this.SEARCH_SPHERE_SIZE, y: this.SEARCH_SPHERE_SIZE, z: this.SEARCH_SPHERE_SIZE};
this.halfPath = {
type: "line3d",
type: "PolyLine",
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
visible: true,
alpha: 1,
solid: true,
glow: 1.0,
ignoreRayIntersection: true, // always ignore this
drawInFront: !hudLayer, // Even when burried inside of something, show it.
glow: true,
billboardMode: "yaw",
ignorePickIntersection: true, // always ignore this
//V8TODO
drawInFront: !hudLayer, // Even when buried inside of something, show it.
drawHUDLayer: hudLayer,
};
this.halfEnd = {
type: "sphere",
type: "Sphere",
dimensions: this.dim,
solid: true,
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
alpha: 0.9,
ignoreRayIntersection: true,
drawInFront: !hudLayer, // Even when burried inside of something, show it.
ignorePickIntersection: true,
drawInFront: !hudLayer, // Even when buried inside of something, show it.
drawHUDLayer: hudLayer,
visible: true
};
this.fullPath = {
type: "line3d",
type: "PolyLine",
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
visible: true,
alpha: 1,
solid: true,
glow: 1.0,
ignoreRayIntersection: true, // always ignore this
drawInFront: !hudLayer, // Even when burried inside of something, show it.
glow: true,
billboardMode: "yaw",
ignorePickIntersection: true, // always ignore this
drawInFront: !hudLayer, // Even when buried inside of something, show it.
drawHUDLayer: hudLayer,
};
this.fullEnd = {
type: "sphere",
type: "Sphere",
dimensions: this.dim,
solid: true,
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
alpha: 0.9,
ignoreRayIntersection: true,
drawInFront: !hudLayer, // Even when burried inside of something, show it.
ignorePickIntersection: true,
drawInFront: !hudLayer, // Even when buried inside of something, show it.
drawHUDLayer: hudLayer,
visible: true
};
this.holdPath = {
type: "line3d",
type: "PolyLine",
color: COLORS_GRAB_DISTANCE_HOLD,
visible: true,
alpha: 1,
solid: true,
glow: 1.0,
ignoreRayIntersection: true, // always ignore this
drawInFront: !hudLayer, // Even when burried inside of something, show it.
glow: true,
billboardMode: "yaw",
ignorePickIntersection: true, // always ignore this
drawInFront: !hudLayer, // Even when buried inside of something, show it.
drawHUDLayer: hudLayer,
};
@ -99,6 +103,7 @@ var Pointer = function(hudLayer, pickType, pointerData) {
delete pointerData.hand;
function createPointer(pickType, pointerData) {
//V8TODO
var pointerID = Pointers.createPointer(pickType, pointerData);
Pointers.setRenderState(pointerID, "");
Pointers.enablePointer(pointerID);