mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-05 23:27:38 +02:00
add workload job to help debug entity proxies
This commit is contained in:
parent
5f2f647dfb
commit
cf08a4162a
12 changed files with 275 additions and 6 deletions
|
@ -87,6 +87,8 @@ class PickScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
||||||
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
|
Q_PROPERTY(unsigned int PICK_ALL_INTERSECTIONS READ PICK_ALL_INTERSECTIONS CONSTANT)
|
||||||
|
|
||||||
|
Q_PROPERTY(unsigned int PICK_BYPASS_IGNORE READ PICK_BYPASS_IGNORE CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT)
|
Q_PROPERTY(unsigned int INTERSECTED_NONE READ INTERSECTED_NONE CONSTANT)
|
||||||
Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT)
|
Q_PROPERTY(unsigned int INTERSECTED_ENTITY READ INTERSECTED_ENTITY CONSTANT)
|
||||||
Q_PROPERTY(unsigned int INTERSECTED_LOCAL_ENTITY READ INTERSECTED_LOCAL_ENTITY CONSTANT)
|
Q_PROPERTY(unsigned int INTERSECTED_LOCAL_ENTITY READ INTERSECTED_LOCAL_ENTITY CONSTANT)
|
||||||
|
@ -282,6 +284,8 @@ public:
|
||||||
unsigned int getPerFrameTimeBudget() const;
|
unsigned int getPerFrameTimeBudget() const;
|
||||||
void setPerFrameTimeBudget(unsigned int numUsecs);
|
void setPerFrameTimeBudget(unsigned int numUsecs);
|
||||||
|
|
||||||
|
static constexpr unsigned int PICK_BYPASS_IGNORE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_BYPASS_IGNORE); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
|
|
@ -17,7 +17,7 @@ GameplayObjects::GameplayObjects() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameplayObjects::addToGameplayObjects(const QUuid& avatarID) {
|
bool GameplayObjects::addToGameplayObjects(const QUuid& avatarID) {
|
||||||
containsData = true;
|
_containsData = true;
|
||||||
if (std::find(_avatarIDs.begin(), _avatarIDs.end(), avatarID) == _avatarIDs.end()) {
|
if (std::find(_avatarIDs.begin(), _avatarIDs.end(), avatarID) == _avatarIDs.end()) {
|
||||||
_avatarIDs.push_back(avatarID);
|
_avatarIDs.push_back(avatarID);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ bool GameplayObjects::removeFromGameplayObjects(const QUuid& avatarID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameplayObjects::addToGameplayObjects(const EntityItemID& entityID) {
|
bool GameplayObjects::addToGameplayObjects(const EntityItemID& entityID) {
|
||||||
containsData = true;
|
_containsData = true;
|
||||||
if (std::find(_entityIDs.begin(), _entityIDs.end(), entityID) == _entityIDs.end()) {
|
if (std::find(_entityIDs.begin(), _entityIDs.end(), entityID) == _entityIDs.end()) {
|
||||||
_entityIDs.push_back(entityID);
|
_entityIDs.push_back(entityID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class GameplayObjects {
|
||||||
public:
|
public:
|
||||||
GameplayObjects();
|
GameplayObjects();
|
||||||
|
|
||||||
bool getContainsData() const { return containsData; }
|
bool getContainsData() const { return _containsData; }
|
||||||
|
|
||||||
std::vector<QUuid> getAvatarIDs() const { return _avatarIDs; }
|
std::vector<QUuid> getAvatarIDs() const { return _avatarIDs; }
|
||||||
bool addToGameplayObjects(const QUuid& avatarID);
|
bool addToGameplayObjects(const QUuid& avatarID);
|
||||||
|
@ -37,7 +37,7 @@ public:
|
||||||
bool removeFromGameplayObjects(const EntityItemID& entityID);
|
bool removeFromGameplayObjects(const EntityItemID& entityID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool containsData { false };
|
bool _containsData { false };
|
||||||
std::vector<QUuid> _avatarIDs;
|
std::vector<QUuid> _avatarIDs;
|
||||||
std::vector<EntityItemID> _entityIDs;
|
std::vector<EntityItemID> _entityIDs;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
#include "GameWorkload.h"
|
#include "GameWorkload.h"
|
||||||
#include "GameWorkloadRenderer.h"
|
#include "GameWorkloadRenderer.h"
|
||||||
|
#include "SelectedWorkloadRenderer.h"
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
#include <workload/RegionTracker.h>
|
#include <workload/RegionTracker.h>
|
||||||
#include <workload/SpaceClassifier.h>
|
#include <workload/SpaceClassifier.h>
|
||||||
|
@ -35,6 +36,7 @@ public:
|
||||||
model.addJob<PhysicsBoundary>("PhysicsBoundary", regionTrackerOut);
|
model.addJob<PhysicsBoundary>("PhysicsBoundary", regionTrackerOut);
|
||||||
|
|
||||||
model.addJob<GameSpaceToRender>("SpaceToRender");
|
model.addJob<GameSpaceToRender>("SpaceToRender");
|
||||||
|
model.addJob<SelectedWorkloadRenderer>("SelectedWorkloadRender");
|
||||||
|
|
||||||
out = regionTrackerOut;
|
out = regionTrackerOut;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <GeometryCache.h>
|
#include <GeometryCache.h>
|
||||||
#include <shaders/Shaders.h>
|
#include <shaders/Shaders.h>
|
||||||
|
|
||||||
|
#include "SelectedWorkloadRenderer.h"
|
||||||
|
|
||||||
void GameSpaceToRender::configure(const Config& config) {
|
void GameSpaceToRender::configure(const Config& config) {
|
||||||
_freezeViews = config.freezeViews;
|
_freezeViews = config.freezeViews;
|
||||||
|
|
88
interface/src/workload/SelectedWorkloadRenderer.cpp
Normal file
88
interface/src/workload/SelectedWorkloadRenderer.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// SelectedWorkloadRenderer.cpp
|
||||||
|
//
|
||||||
|
// Created by Andrew Meadows 2019.11.08
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "SelectedWorkloadRenderer.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include <workload/Space.h>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "GameWorkloadRenderer.h"
|
||||||
|
#include "scripting/SelectionScriptingInterface.h"
|
||||||
|
|
||||||
|
void SelectedWorkloadRenderer::run(const workload::WorkloadContextPointer& runContext, Outputs& outputs) {
|
||||||
|
auto gameWorkloadContext = std::dynamic_pointer_cast<GameWorkloadContext>(runContext);
|
||||||
|
if (!gameWorkloadContext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto space = gameWorkloadContext->_space;
|
||||||
|
if (!space) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
render::Transaction transaction;
|
||||||
|
auto scene = gameWorkloadContext->_scene;
|
||||||
|
|
||||||
|
auto selection = DependencyManager::get<SelectionScriptingInterface>();
|
||||||
|
// Note: the "DebugWorkloadSelection" name is a secret hard-coded C++ debug feature.
|
||||||
|
// If you create such a named list using JS and the "Selection" API then it will be picked up here
|
||||||
|
// and the workload proxies for corresponding entities will be rendered.
|
||||||
|
GameplayObjects selectedObjects = selection->getList("DebugWorkloadSelection");
|
||||||
|
|
||||||
|
if (!selectedObjects.getContainsData()) {
|
||||||
|
// nothing to render
|
||||||
|
// clear item if it exists and bail
|
||||||
|
if (render::Item::isValidID(_spaceRenderItemID)) {
|
||||||
|
transaction.updateItem<GameWorkloadRenderItem>(_spaceRenderItemID, [](GameWorkloadRenderItem& item) {
|
||||||
|
item.setVisible(false);
|
||||||
|
});
|
||||||
|
scene->enqueueTransaction(transaction);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<EntityItemID> entityIDs = selectedObjects.getEntityIDs();
|
||||||
|
workload::indexed_container::Indices indices;
|
||||||
|
indices.reserve(entityIDs.size());
|
||||||
|
|
||||||
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
|
auto entityTree = entityTreeRenderer->getTree();
|
||||||
|
for (auto id : entityIDs) {
|
||||||
|
EntityItemPointer entity = entityTree->findEntityByID(id);
|
||||||
|
if (entity) {
|
||||||
|
indices.push_back(entity->getSpaceIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workload::Proxy::Vector proxies;
|
||||||
|
proxies.reserve(indices.size());
|
||||||
|
space->copySelectedProxyValues(proxies, indices);
|
||||||
|
|
||||||
|
if (!render::Item::isValidID(_spaceRenderItemID)) {
|
||||||
|
_spaceRenderItemID = scene->allocateID();
|
||||||
|
auto renderItem = std::make_shared<GameWorkloadRenderItem>();
|
||||||
|
renderItem->editBound().setBox(glm::vec3(-16000.0f), 32000.0f);
|
||||||
|
transaction.resetItem(_spaceRenderItemID, std::make_shared<GameWorkloadRenderItem::Payload>(renderItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showProxies = true;
|
||||||
|
bool showViews = false;
|
||||||
|
bool visible = true;
|
||||||
|
workload::Views views(0);
|
||||||
|
transaction.updateItem<GameWorkloadRenderItem>(_spaceRenderItemID, [visible, showProxies, proxies, showViews, views](GameWorkloadRenderItem& item) {
|
||||||
|
item.setVisible(visible);
|
||||||
|
item.showProxies(showProxies);
|
||||||
|
item.setAllProxies(proxies);
|
||||||
|
item.showViews(showViews);
|
||||||
|
item.setAllViews(views);
|
||||||
|
});
|
||||||
|
scene->enqueueTransaction(transaction);
|
||||||
|
}
|
32
interface/src/workload/SelectedWorkloadRenderer.h
Normal file
32
interface/src/workload/SelectedWorkloadRenderer.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// GameWorkloadRender.h
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 2/20/2018.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#ifndef hifi_SelectedWorkloadRenderer_h
|
||||||
|
#define hifi_SelectedWorkloadRenderer_h
|
||||||
|
|
||||||
|
#include "GameWorkload.h"
|
||||||
|
|
||||||
|
#include "GameWorkloadRenderer.h"
|
||||||
|
|
||||||
|
class SelectedWorkloadRenderer {
|
||||||
|
public:
|
||||||
|
using Config = GameSpaceToRenderConfig;
|
||||||
|
using Outputs = render::Transaction;
|
||||||
|
using JobModel = workload::Job::ModelO<SelectedWorkloadRenderer, Outputs, Config>;
|
||||||
|
|
||||||
|
SelectedWorkloadRenderer() {}
|
||||||
|
|
||||||
|
void configure(const Config& config) {}
|
||||||
|
void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
render::ItemID _spaceRenderItemID{ render::Item::INVALID_ITEM_ID };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -197,7 +197,7 @@ EntityItemID EntityTreeElement::evalDetailedRayIntersection(const glm::vec3& ori
|
||||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
EntityItemID entityID;
|
EntityItemID entityID;
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
if (entity->getIgnorePickIntersection()) {
|
if (entity->getIgnorePickIntersection() && !searchFilter.bypassIgnore()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ EntityItemID EntityTreeElement::evalDetailedParabolaIntersection(const glm::vec3
|
||||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
EntityItemID entityID;
|
EntityItemID entityID;
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
if (entity->getIgnorePickIntersection()) {
|
if (entity->getIgnorePickIntersection() && !searchFilter.bypassIgnore()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define hifi_PickFilter_h
|
#define hifi_PickFilter_h
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <iostream> // adebug
|
||||||
|
|
||||||
class PickFilter {
|
class PickFilter {
|
||||||
public:
|
public:
|
||||||
|
@ -60,6 +61,8 @@ public:
|
||||||
// NOT YET IMPLEMENTED
|
// NOT YET IMPLEMENTED
|
||||||
PICK_ALL_INTERSECTIONS, // if not set, returns closest intersection, otherwise, returns list of all intersections
|
PICK_ALL_INTERSECTIONS, // if not set, returns closest intersection, otherwise, returns list of all intersections
|
||||||
|
|
||||||
|
PICK_BYPASS_IGNORE, // for debug purposes
|
||||||
|
|
||||||
NUM_FLAGS, // Not a valid flag
|
NUM_FLAGS, // Not a valid flag
|
||||||
};
|
};
|
||||||
typedef std::bitset<NUM_FLAGS> Flags;
|
typedef std::bitset<NUM_FLAGS> Flags;
|
||||||
|
@ -93,6 +96,8 @@ public:
|
||||||
|
|
||||||
bool doesWantAllIntersections() const { return _flags[PICK_ALL_INTERSECTIONS]; }
|
bool doesWantAllIntersections() const { return _flags[PICK_ALL_INTERSECTIONS]; }
|
||||||
|
|
||||||
|
bool bypassIgnore() const { return _flags[PICK_BYPASS_IGNORE]; }
|
||||||
|
|
||||||
// Helpers for RayPickManager
|
// Helpers for RayPickManager
|
||||||
Flags getEntityFlags() const {
|
Flags getEntityFlags() const {
|
||||||
unsigned int toReturn = 0;
|
unsigned int toReturn = 0;
|
||||||
|
|
|
@ -127,6 +127,18 @@ uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const {
|
||||||
return numCopied;
|
return numCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Space::copySelectedProxyValues(Proxy::Vector& proxies, const workload::indexed_container::Indices& indices) const {
|
||||||
|
std::unique_lock<std::mutex> lock(_proxiesMutex);
|
||||||
|
uint32_t numCopied = 0;
|
||||||
|
for (auto index : indices) {
|
||||||
|
if (isAllocatedID(index) && (index < (Index)_proxies.size())) {
|
||||||
|
proxies.push_back(_proxies[index]);
|
||||||
|
++numCopied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numCopied;
|
||||||
|
}
|
||||||
|
|
||||||
const Owner Space::getOwner(int32_t proxyID) const {
|
const Owner Space::getOwner(int32_t proxyID) const {
|
||||||
std::unique_lock<std::mutex> lock(_proxiesMutex);
|
std::unique_lock<std::mutex> lock(_proxiesMutex);
|
||||||
if (isAllocatedID(proxyID) && (proxyID < (Index)_proxies.size())) {
|
if (isAllocatedID(proxyID) && (proxyID < (Index)_proxies.size())) {
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
|
|
||||||
void categorizeAndGetChanges(std::vector<Change>& changes);
|
void categorizeAndGetChanges(std::vector<Change>& changes);
|
||||||
uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const;
|
uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const;
|
||||||
|
uint32_t copySelectedProxyValues(Proxy::Vector& proxies, const workload::indexed_container::Indices& indices) const;
|
||||||
|
|
||||||
const Owner getOwner(int32_t proxyID) const;
|
const Owner getOwner(int32_t proxyID) const;
|
||||||
uint8_t getRegion(int32_t proxyID) const;
|
uint8_t getRegion(int32_t proxyID) const;
|
||||||
|
|
124
scripts/developer/debugging/debugWorkloadWithMouseHover.js
Normal file
124
scripts/developer/debugging/debugWorkloadWithMouseHover.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
//
|
||||||
|
// debugWorkloadWithMouseHover.js - render workload proxy for entity under mouse hover
|
||||||
|
//
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(function () {
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create a Laser pointer used to pick and add entity to selection
|
||||||
|
var END_DIMENSIONS = { x: 0.05, y: 0.05, z: 0.05 };
|
||||||
|
var COLOR1 = {red: 255, green: 0, blue: 255}; // magenta
|
||||||
|
var COLOR2 = {red: 255, green: 255, blue: 0}; // yellow
|
||||||
|
var end1 = {
|
||||||
|
type: "sphere",
|
||||||
|
dimensions: END_DIMENSIONS,
|
||||||
|
color: COLOR1,
|
||||||
|
ignorePickIntersection: true
|
||||||
|
}
|
||||||
|
var end2 = {
|
||||||
|
type: "sphere",
|
||||||
|
dimensions: END_DIMENSIONS,
|
||||||
|
color: COLOR2,
|
||||||
|
ignorePickIntersection: true
|
||||||
|
}
|
||||||
|
var laser = Pointers.createPointer(PickType.Ray, {
|
||||||
|
joint: "Mouse",
|
||||||
|
filter: Picks.PICK_ENTITIES | Picks.PICK_BYPASS_IGNORE | Picks.PICK_INCLUDE_COLLIDABLE | Picks.PICK_INCLUDE_NONCOLLIDABLE,
|
||||||
|
renderStates: [{name: "one", end: end1}],
|
||||||
|
defaultRenderStates: [{name: "one", end: end2, distance: 2.0}],
|
||||||
|
enabled: true
|
||||||
|
});
|
||||||
|
Pointers.setRenderState(laser, "one");
|
||||||
|
var hoveredObject = undefined;
|
||||||
|
|
||||||
|
var SelectionListName = "DebugWorkloadSelection"; // sekret undocumented selection list (hard coded in C++)
|
||||||
|
var selectionStyle = {
|
||||||
|
isOutlineSmooth: true,
|
||||||
|
outlineWidth: 5,
|
||||||
|
outlineUnoccludedColor: {red: 255, green: 128, blue: 128},
|
||||||
|
outlineUnoccludedAlpha: 0.88,
|
||||||
|
outlineOccludedColor: {red: 255, green: 128, blue: 128},
|
||||||
|
outlineOccludedAlpha:0.5,
|
||||||
|
fillUnoccludedColor: {red: 26, green: 0, blue: 0},
|
||||||
|
fillUnoccludedAlpha: 0.0,
|
||||||
|
fillOccludedColor: {red: 26, green: 0, blue: 0},
|
||||||
|
fillOccludedAlpha: 0.0
|
||||||
|
}
|
||||||
|
Selection.enableListHighlight(SelectionListName, selectionStyle)
|
||||||
|
|
||||||
|
var isSelectionEnabled = false
|
||||||
|
|
||||||
|
function setSelectionEnabled(enabled) {
|
||||||
|
if (isSelectionEnabled != enabled) {
|
||||||
|
isSelectionEnabled = enabled;
|
||||||
|
//print("isSelectionEnabled set to " + isSelectionEnabled.toString())
|
||||||
|
if (isSelectionEnabled) {
|
||||||
|
Pointers.enablePointer(laser)
|
||||||
|
} else {
|
||||||
|
Pointers.disablePointer(laser)
|
||||||
|
Selection.clearSelectedItemsList(SelectionListName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setSelectionEnabled(true);
|
||||||
|
|
||||||
|
function getIntersectionTypeString(type) {
|
||||||
|
if (type === Picks.INTERSECTED_ENTITY) {
|
||||||
|
return "entity";
|
||||||
|
} else if (type === Picks.INTERSECTED_OVERLAY) {
|
||||||
|
return "overlay";
|
||||||
|
} else if (type === Picks.INTERSECTED_AVATAR) {
|
||||||
|
return "avatar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
var result = Pointers.getPrevPickResult(laser);
|
||||||
|
if (result.intersects) {
|
||||||
|
if (hoveredObject !== undefined && result.objectID !== hoveredObject.objectID) {
|
||||||
|
// Hovering on something different
|
||||||
|
if (isSelectionEnabled) {
|
||||||
|
Selection.removeFromSelectedItemsList(SelectionListName, getIntersectionTypeString(hoveredObject.type), hoveredObject.objectID)
|
||||||
|
//print("remove helloDebugHighlight " + hoveredObject.objectID.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelectionEnabled) {
|
||||||
|
if (hoveredObject === undefined || result.objectID !== hoveredObject.objectID) {
|
||||||
|
// Hovering over something new
|
||||||
|
Selection.addToSelectedItemsList(SelectionListName, getIntersectionTypeString(result.type), result.objectID);
|
||||||
|
hoveredObject = result;
|
||||||
|
//print("add helloDebugHighlight " + hoveredObject.objectID.toString() + " type = '" + getIntersectionTypeString(result.type) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (hoveredObject !== undefined) {
|
||||||
|
// Stopped hovering
|
||||||
|
if (isSelectionEnabled) {
|
||||||
|
Selection.removeFromSelectedItemsList(SelectionListName, getIntersectionTypeString(hoveredObject.type), hoveredObject.objectID)
|
||||||
|
hoveredObject = undefined;
|
||||||
|
//print("clear helloDebugHighlight");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Script.update.connect(update);
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
Pointers.removePointer(laser);
|
||||||
|
Selection.disableListHighlight(SelectionListName)
|
||||||
|
Selection.removeListFromMap(SelectionListName)
|
||||||
|
|
||||||
|
}
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue