mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Work on porting laser pointers to local entities, removal of LaserPointer JS API
This commit is contained in:
parent
4d03033c9e
commit
2a2cf3898b
13 changed files with 311 additions and 385 deletions
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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))));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue