mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 01:27:20 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into model-scripting-2
This commit is contained in:
commit
b5786befc3
15 changed files with 302 additions and 131 deletions
|
@ -58,6 +58,8 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
|
||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||
|
||||
DependencyManager::set<AudioScriptingInterface>();
|
||||
|
||||
DependencyManager::set<ResourceCacheSharedItems>();
|
||||
DependencyManager::set<SoundCache>();
|
||||
DependencyManager::set<AudioInjectorManager>();
|
||||
|
@ -324,7 +326,26 @@ void EntityScriptServer::nodeActivated(SharedNodePointer activatedNode) {
|
|||
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
|
||||
switch (killedNode->getType()) {
|
||||
case NodeType::EntityServer: {
|
||||
clear();
|
||||
// Before we clear, make sure this was our only entity server.
|
||||
// Otherwise we're assuming that we have "trading" entity servers
|
||||
// (an old one going away and a new one coming onboard)
|
||||
// and that we shouldn't clear here because we're still doing work.
|
||||
bool hasAnotherEntityServer = false;
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
nodeList->eachNodeBreakable([&hasAnotherEntityServer, &killedNode](const SharedNodePointer& node){
|
||||
if (node->getType() == NodeType::EntityServer && node->getUUID() != killedNode->getUUID()) {
|
||||
// we're talking to > 1 entity servers, we know we won't clear
|
||||
hasAnotherEntityServer = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!hasAnotherEntityServer) {
|
||||
clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -395,7 +416,8 @@ void EntityScriptServer::selectAudioFormat(const QString& selectedCodecName) {
|
|||
|
||||
void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||
auto engineName = QString("about:Entities %1").arg(++_entitiesScriptEngineCount);
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName));
|
||||
auto newEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(ScriptEngine::ENTITY_SERVER_SCRIPT, NO_SCRIPT, engineName),
|
||||
&ScriptEngine::deleteLater);
|
||||
|
||||
auto webSocketServerConstructorValue = newEngine->newFunction(WebSocketServerClass::constructor);
|
||||
newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||
|
|
|
@ -740,23 +740,24 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
auto& audioScriptingInterface = AudioScriptingInterface::getInstance();
|
||||
auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface>();
|
||||
connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
|
||||
connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
|
||||
connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
|
||||
connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled);
|
||||
connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO.data(), &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO.data(), &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) {
|
||||
auto audioClient = DependencyManager::get<AudioClient>();
|
||||
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
|
||||
auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition();
|
||||
float distance = glm::distance(myAvatarPosition, position);
|
||||
bool shouldMute = !audioClient->isMuted() && (distance < radius);
|
||||
|
||||
if (shouldMute) {
|
||||
audioClient->toggleMute();
|
||||
AudioScriptingInterface::getInstance().environmentMuted();
|
||||
audioScriptingInterface->environmentMuted();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1181,10 +1182,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
// set the local loopback interface for local sounds
|
||||
AudioInjector::setLocalAudioInterface(audioIO.data());
|
||||
AudioScriptingInterface::getInstance().setLocalAudioInterface(audioIO.data());
|
||||
connect(audioIO.data(), &AudioClient::noiseGateOpened, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO.data(), &AudioClient::noiseGateClosed, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::inputReceived);
|
||||
audioScriptingInterface->setLocalAudioInterface(audioIO.data());
|
||||
connect(audioIO.data(), &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO.data(), &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived);
|
||||
|
||||
|
||||
this->installEventFilter(this);
|
||||
|
@ -1949,7 +1950,7 @@ void Application::initializeUi() {
|
|||
// For some reason there is already an "Application" object in the QML context,
|
||||
// though I can't find it. Hence, "ApplicationInterface"
|
||||
rootContext->setContextProperty("ApplicationInterface", this);
|
||||
rootContext->setContextProperty("Audio", &AudioScriptingInterface::getInstance());
|
||||
rootContext->setContextProperty("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
rootContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
||||
rootContext->setContextProperty("AudioScope", DependencyManager::get<AudioScope>().data());
|
||||
|
||||
|
|
|
@ -431,7 +431,9 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionInternal(const PickR
|
|||
if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance,
|
||||
thisFace, thisSurfaceNormal, thisExtraInfo)) {
|
||||
bool isDrawInFront = thisOverlay->getDrawInFront();
|
||||
if (thisDistance < bestDistance && (!bestIsFront || isDrawInFront)) {
|
||||
if ((bestIsFront && isDrawInFront && thisDistance < bestDistance)
|
||||
|| (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) {
|
||||
|
||||
bestIsFront = isDrawInFront;
|
||||
bestDistance = thisDistance;
|
||||
result.intersects = true;
|
||||
|
|
|
@ -19,11 +19,6 @@ void registerAudioMetaTypes(QScriptEngine* engine) {
|
|||
qScriptRegisterMetaType(engine, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue);
|
||||
}
|
||||
|
||||
AudioScriptingInterface& AudioScriptingInterface::getInstance() {
|
||||
static AudioScriptingInterface staticInstance;
|
||||
return staticInstance;
|
||||
}
|
||||
|
||||
AudioScriptingInterface::AudioScriptingInterface() :
|
||||
_localAudioInterface(NULL)
|
||||
{
|
||||
|
|
|
@ -14,18 +14,20 @@
|
|||
|
||||
#include <AbstractAudioInterface.h>
|
||||
#include <AudioInjector.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <Sound.h>
|
||||
|
||||
class ScriptAudioInjector;
|
||||
|
||||
class AudioScriptingInterface : public QObject {
|
||||
class AudioScriptingInterface : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AudioScriptingInterface& getInstance();
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; }
|
||||
|
||||
protected:
|
||||
|
||||
// this method is protected to stop C++ callers from calling, but invokable from script
|
||||
Q_INVOKABLE ScriptAudioInjector* playSound(SharedSoundPointer sound, const AudioInjectorOptions& injectorOptions = AudioInjectorOptions());
|
||||
|
||||
|
@ -42,6 +44,7 @@ signals:
|
|||
|
||||
private:
|
||||
AudioScriptingInterface();
|
||||
|
||||
AbstractAudioInterface* _localAudioInterface;
|
||||
};
|
||||
|
||||
|
|
|
@ -464,17 +464,17 @@ void ScriptEngine::loadURL(const QUrl& scriptURL, bool reload) {
|
|||
|
||||
void ScriptEngine::scriptErrorMessage(const QString& message) {
|
||||
qCCritical(scriptengine) << qPrintable(message);
|
||||
emit errorMessage(message);
|
||||
emit errorMessage(message, getFilename());
|
||||
}
|
||||
|
||||
void ScriptEngine::scriptWarningMessage(const QString& message) {
|
||||
qCWarning(scriptengine) << message;
|
||||
emit warningMessage(message);
|
||||
emit warningMessage(message, getFilename());
|
||||
}
|
||||
|
||||
void ScriptEngine::scriptInfoMessage(const QString& message) {
|
||||
qCInfo(scriptengine) << message;
|
||||
emit infoMessage(message);
|
||||
emit infoMessage(message, getFilename());
|
||||
}
|
||||
|
||||
// Even though we never pass AnimVariantMap directly to and from javascript, the queued invokeMethod of
|
||||
|
@ -627,6 +627,9 @@ void ScriptEngine::init() {
|
|||
qScriptRegisterMetaType(this, qWSCloseCodeToScriptValue, qWSCloseCodeFromScriptValue);
|
||||
qScriptRegisterMetaType(this, wscReadyStateToScriptValue, wscReadyStateFromScriptValue);
|
||||
|
||||
// NOTE: You do not want to end up creating new instances of singletons here. They will be on the ScriptEngine thread
|
||||
// and are likely to be unusable if we "reset" the ScriptEngine by creating a new one (on a whole new thread).
|
||||
|
||||
registerGlobalObject("Script", this);
|
||||
|
||||
{
|
||||
|
@ -638,7 +641,8 @@ void ScriptEngine::init() {
|
|||
resetModuleCache();
|
||||
}
|
||||
|
||||
registerGlobalObject("Audio", &AudioScriptingInterface::getInstance());
|
||||
registerGlobalObject("Audio", DependencyManager::get<AudioScriptingInterface>().data());
|
||||
|
||||
registerGlobalObject("Entities", entityScriptingInterface.data());
|
||||
registerGlobalObject("Quat", &_quatLibrary);
|
||||
registerGlobalObject("Vec3", &_vec3Library);
|
||||
|
@ -1347,7 +1351,7 @@ QUrl ScriptEngine::resourcesPath() const {
|
|||
}
|
||||
|
||||
void ScriptEngine::print(const QString& message) {
|
||||
emit printedMessage(message);
|
||||
emit printedMessage(message, getFilename());
|
||||
}
|
||||
|
||||
// Script.require.resolve -- like resolvePath, but performs more validation and throws exceptions on invalid module identifiers (for consistency with Node.js)
|
||||
|
|
|
@ -236,10 +236,10 @@ signals:
|
|||
void scriptEnding();
|
||||
void finished(const QString& fileNameString, ScriptEngine* engine);
|
||||
void cleanupMenuItem(const QString& menuItemString);
|
||||
void printedMessage(const QString& message);
|
||||
void errorMessage(const QString& message);
|
||||
void warningMessage(const QString& message);
|
||||
void infoMessage(const QString& message);
|
||||
void printedMessage(const QString& message, const QString& scriptName);
|
||||
void errorMessage(const QString& message, const QString& scriptName);
|
||||
void warningMessage(const QString& message, const QString& scriptName);
|
||||
void infoMessage(const QString& message, const QString& scriptName);
|
||||
void runningStateChanged();
|
||||
void loadScript(const QString& scriptName, bool isUserLoaded);
|
||||
void reloadScript(const QString& scriptName, bool isUserLoaded);
|
||||
|
|
|
@ -34,34 +34,24 @@ ScriptsModel& getScriptsModel() {
|
|||
return scriptsModel;
|
||||
}
|
||||
|
||||
void ScriptEngines::onPrintedMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onPrintedMessage(const QString& message, const QString& scriptName) {
|
||||
emit printedMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onErrorMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onErrorMessage(const QString& message, const QString& scriptName) {
|
||||
emit errorMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onWarningMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onWarningMessage(const QString& message, const QString& scriptName) {
|
||||
emit warningMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onInfoMessage(const QString& message) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
void ScriptEngines::onInfoMessage(const QString& message, const QString& scriptName) {
|
||||
emit infoMessage(message, scriptName);
|
||||
}
|
||||
|
||||
void ScriptEngines::onErrorLoadingScript(const QString& url) {
|
||||
auto scriptEngine = qobject_cast<ScriptEngine*>(sender());
|
||||
auto scriptName = scriptEngine ? scriptEngine->getFilename() : "";
|
||||
emit errorLoadingScript(url, scriptName);
|
||||
emit errorLoadingScript(url);
|
||||
}
|
||||
|
||||
ScriptEngines::ScriptEngines(ScriptEngine::Context context)
|
||||
|
|
|
@ -79,13 +79,13 @@ signals:
|
|||
void errorMessage(const QString& message, const QString& engineName);
|
||||
void warningMessage(const QString& message, const QString& engineName);
|
||||
void infoMessage(const QString& message, const QString& engineName);
|
||||
void errorLoadingScript(const QString& url, const QString& engineName);
|
||||
void errorLoadingScript(const QString& url);
|
||||
|
||||
public slots:
|
||||
void onPrintedMessage(const QString& message);
|
||||
void onErrorMessage(const QString& message);
|
||||
void onWarningMessage(const QString& message);
|
||||
void onInfoMessage(const QString& message);
|
||||
void onPrintedMessage(const QString& message, const QString& scriptName);
|
||||
void onErrorMessage(const QString& message, const QString& scriptName);
|
||||
void onWarningMessage(const QString& message, const QString& scriptName);
|
||||
void onInfoMessage(const QString& message, const QString& scriptName);
|
||||
void onErrorLoadingScript(const QString& url);
|
||||
|
||||
protected slots:
|
||||
|
|
29
scripts/system/assets/images/icon-particles.svg
Normal file
29
scripts/system/assets/images/icon-particles.svg
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path d="M331.8,283.4c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C342.1,306.6,331.8,296.2,331.8,283.4z"/>
|
||||
<path d="M277.8,350.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C288.1,374.2,277.8,363.8,277.8,350.9z"/>
|
||||
<path d="M216.3,368.8c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C226.7,392,216.3,381.6,216.3,368.8z"/>
|
||||
<path d="M169.9,308.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C180.3,332.1,169.9,321.7,169.9,308.9z"/>
|
||||
<path d="M251.2,447.4c-4.9-3.6-8.3-9.1-9.2-15.3c-0.9-6,0.6-12.3,4.2-17.2c3.6-4.9,9.1-8.3,15.2-9.1c6-0.9,12.3,0.6,17.3,4.3
|
||||
c4.9,3.6,8.3,9.1,9.1,15.2c0.9,6-0.6,12.3-4.2,17.2s-9.1,8.3-15.2,9.1C262.4,452.6,256.1,451,251.2,447.4z"/>
|
||||
<path d="M67.6,246.1c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C78,269.3,67.6,258.8,67.6,246.1z"/>
|
||||
<path d="M178.8,199.5c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C189.1,222.7,178.8,212.2,178.8,199.5z"/>
|
||||
<path d="M250.3,293.9c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C260.7,317.1,250.3,306.6,250.3,293.9z"/>
|
||||
<path d="M413,242.1c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C423.5,265.3,413,255,413,242.1z"/>
|
||||
<path d="M302.1,203.7c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C312.6,226.9,302.1,216.5,302.1,203.7z"/>
|
||||
<path d="M132.3,113.5c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C142.8,136.6,132.3,126.2,132.3,113.5z"/>
|
||||
<path d="M366.6,136.7c0-12.8,10.4-23.2,23.2-23.2l0,0c12.8,0,23.2,10.4,23.2,23.2l0,0c0,12.8-10.4,23.2-23.2,23.2l0,0
|
||||
C377.1,159.9,366.6,149.5,366.6,136.7z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
57
scripts/system/assets/images/icon-point-light.svg
Normal file
57
scripts/system/assets/images/icon-point-light.svg
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 960 560" style="enable-background:new 0 0 960 560;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path style="fill:#333333;" d="M478.879,127.676c-83.872,0-152.325,68.454-152.325,152.325s68.454,152.325,152.325,152.325
|
||||
s152.325-67.837,152.325-152.325C631.204,196.13,563.366,127.676,478.879,127.676z"/>
|
||||
<path style="fill:#FFFFFF;" d="M478.881,437.281C392.156,437.281,321.6,366.725,321.6,280s70.557-157.281,157.281-157.281
|
||||
S636.157,193.275,636.157,280S565.606,437.281,478.881,437.281z M478.881,132.627c-81.263,0-147.373,66.115-147.373,147.373
|
||||
s66.11,147.373,147.373,147.373c81.258,0,147.368-66.115,147.368-147.373S560.138,132.627,478.881,132.627z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="459.145" y="4.952" style="fill:#333333;" width="40.086" height="75.237"/>
|
||||
<path style="fill:#FFFFFF;" d="M504.183,85.147h-49.99V0h49.99V85.147z M464.1,75.239h30.174V9.908H464.1V75.239z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="272.766" y="90.696" transform="matrix(-0.707 -0.7072 0.7072 -0.707 451.5123 408.5368)" style="fill:#333333;" width="75.236" height="40.085"/>
|
||||
<path style="fill:#FFFFFF;" d="M322.809,158.519l-60.198-60.212l35.351-35.346l60.198,60.212L322.809,158.519z M276.621,98.307
|
||||
l46.188,46.202l21.34-21.335l-46.188-46.202L276.621,98.307z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="201.98" y="257.8" style="fill:#333333;" width="75.237" height="40.086"/>
|
||||
<path style="fill:#FFFFFF;" d="M282.17,302.845h-85.142V252.85h85.142V302.845z M206.936,292.937h65.327v-30.179h-65.327V292.937z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="287.46" y="408.97" transform="matrix(0.7072 0.707 -0.707 0.7072 405.7749 -86.6482)" style="fill:#333333;" width="40.085" height="75.236"/>
|
||||
<path style="fill:#FFFFFF;" d="M295.083,494.359l-35.355-35.346l60.198-60.212l35.355,35.346L295.083,494.359z M273.738,459.013
|
||||
l21.345,21.335l46.187-46.202l-21.345-21.335L273.738,459.013z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="454.827" y="479.812" style="fill:#333333;" width="40.086" height="75.237"/>
|
||||
<path style="fill:#FFFFFF;" d="M499.868,560h-49.995v-85.137h49.995V560z M459.781,550.091h30.179V484.77h-30.179V550.091z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="606.017" y="429.505" transform="matrix(0.707 0.7072 -0.7072 0.707 506.5034 -323.4691)" style="fill:#333333;" width="75.236" height="40.085"/>
|
||||
<path style="fill:#FFFFFF;" d="M656.06,497.32l-60.198-60.212l35.351-35.346l60.198,60.212L656.06,497.32z M609.872,437.107
|
||||
l46.187,46.202l21.34-21.335l-46.188-46.202L609.872,437.107z"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="676.839" y="262.117" style="fill:#333333;" width="75.237" height="40.086"/>
|
||||
<path style="fill:#FFFFFF;" d="M757.032,307.16h-85.147v-49.995h85.147V307.16z M681.792,297.252h65.332v-30.179h-65.332V297.252z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="626.205" y="75.756" transform="matrix(-0.7072 -0.707 0.707 -0.7072 1023.1211 650.4535)" style="fill:#333333;" width="40.085" height="75.236"/>
|
||||
<path style="fill:#FFFFFF;" d="M633.825,161.161l-35.351-35.346l60.198-60.212l35.351,35.346L633.825,161.161z M612.485,125.815
|
||||
l21.34,21.335l46.188-46.202l-21.34-21.335L612.485,125.815z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
37
scripts/system/assets/images/icon-spot-light.svg
Normal file
37
scripts/system/assets/images/icon-spot-light.svg
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="3.44 0 735.338 557.9" style="enable-background:new 3.44 0 735.338 557.9;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<rect x="503.95" y="260.767" style="fill:#333333;" width="227.728" height="36.376"/>
|
||||
<path style="fill:#FFFFFF;" d="M738.778,304.24H496.854v-50.566h241.924V304.24z M511.052,290.042H724.58v-22.17H511.052V290.042z
|
||||
"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="426.085" y="465.518" transform="matrix(-0.9213 -0.3888 0.3888 -0.9213 849.3369 1139.2869)" style="fill:#333333;" width="227.719" height="36.374"/>
|
||||
<path style="fill:#FFFFFF;" d="M641.55,554.032l-222.88-94.06l19.668-46.6l222.88,94.06L641.55,554.032z M437.277,452.401
|
||||
l196.717,83.024l8.617-20.423l-196.717-83.024L437.277,452.401z"/>
|
||||
</g>
|
||||
<g>
|
||||
|
||||
<rect x="426.295" y="56.081" transform="matrix(0.9213 -0.3888 0.3888 0.9213 13.624 215.8596)" style="fill:#333333;" width="227.719" height="36.374"/>
|
||||
<path style="fill:#FFFFFF;" d="M438.545,144.598l-19.668-46.6l222.887-94.06l19.667,46.6L438.545,144.598z M437.484,105.568
|
||||
l8.617,20.423l196.724-83.024l-8.617-20.423L437.484,105.568z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#333333;" d="M430.774,280.311c0-50.839-32.955-93.895-78.642-109.198V13.262L124.404,165.081H10.54v227.728
|
||||
h113.864l227.728,151.819V389.51C397.818,374.206,430.774,331.151,430.774,280.311z"/>
|
||||
<path style="fill:#FFFFFF;" d="M359.23,557.9L122.257,399.908H3.44V157.978h118.816L359.23,0v166.117
|
||||
c47.245,18.038,78.642,63.308,78.642,114.192s-31.397,96.154-78.642,114.192V557.9z M17.638,385.711h108.917l218.478,145.652
|
||||
V384.407l4.846-1.622c44.139-14.794,73.796-55.973,73.796-102.476s-29.657-87.682-73.796-102.476l-4.846-1.622V26.538
|
||||
L126.555,172.176H17.638V385.711z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -33,13 +33,27 @@ Script.include([
|
|||
"libraries/gridTool.js",
|
||||
"libraries/entityList.js",
|
||||
"particle_explorer/particleExplorerTool.js",
|
||||
"libraries/lightOverlayManager.js"
|
||||
"libraries/entityIconOverlayManager.js"
|
||||
]);
|
||||
|
||||
var selectionDisplay = SelectionDisplay;
|
||||
var selectionManager = SelectionManager;
|
||||
|
||||
var lightOverlayManager = new LightOverlayManager();
|
||||
const PARTICLE_SYSTEM_URL = Script.resolvePath("assets/images/icon-particles.svg");
|
||||
const POINT_LIGHT_URL = Script.resolvePath("assets/images/icon-point-light.svg");
|
||||
const SPOT_LIGHT_URL = Script.resolvePath("assets/images/icon-spot-light.svg");
|
||||
entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleEffect'], function(entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['type', 'isSpotlight']);
|
||||
if (properties.type === 'Light') {
|
||||
return {
|
||||
url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
url: PARTICLE_SYSTEM_URL,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var cameraManager = new CameraManager();
|
||||
|
||||
|
@ -53,7 +67,45 @@ var entityListTool = new EntityListTool();
|
|||
|
||||
selectionManager.addEventListener(function () {
|
||||
selectionDisplay.updateHandles();
|
||||
lightOverlayManager.updatePositions();
|
||||
entityIconOverlayManager.updatePositions();
|
||||
|
||||
// Update particle explorer
|
||||
var needToDestroyParticleExplorer = false;
|
||||
if (selectionManager.selections.length === 1) {
|
||||
var selectedEntityID = selectionManager.selections[0];
|
||||
if (selectedEntityID === selectedParticleEntityID) {
|
||||
return;
|
||||
}
|
||||
var type = Entities.getEntityProperties(selectedEntityID, "type").type;
|
||||
if (type === "ParticleEffect") {
|
||||
// Destroy the old particles web view first
|
||||
particleExplorerTool.destroyWebView();
|
||||
particleExplorerTool.createWebView();
|
||||
var properties = Entities.getEntityProperties(selectedEntityID);
|
||||
var particleData = {
|
||||
messageType: "particle_settings",
|
||||
currentProperties: properties
|
||||
};
|
||||
selectedParticleEntityID = selectedEntityID;
|
||||
particleExplorerTool.setActiveParticleEntity(selectedParticleEntityID);
|
||||
|
||||
particleExplorerTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.messageType === "page_loaded") {
|
||||
particleExplorerTool.webView.emitScriptEvent(JSON.stringify(particleData));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
needToDestroyParticleExplorer = true;
|
||||
}
|
||||
} else {
|
||||
needToDestroyParticleExplorer = true;
|
||||
}
|
||||
|
||||
if (needToDestroyParticleExplorer && selectedParticleEntityID !== null) {
|
||||
selectedParticleEntityID = null;
|
||||
particleExplorerTool.destroyWebView();
|
||||
}
|
||||
});
|
||||
|
||||
const KEY_P = 80; //Key code for letter p used for Parenting hotkey.
|
||||
|
@ -82,13 +134,13 @@ var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS);
|
|||
|
||||
var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select";
|
||||
var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
|
||||
var MENU_SHOW_LIGHTS_IN_EDIT_MODE = "Show Lights in Edit Mode";
|
||||
var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Edit Mode";
|
||||
var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Edit Mode";
|
||||
|
||||
var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
|
||||
var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
|
||||
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
|
||||
var SETTING_SHOW_LIGHTS_IN_EDIT_MODE = "showLightsInEditMode";
|
||||
var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode";
|
||||
var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode";
|
||||
|
||||
|
||||
|
@ -506,7 +558,7 @@ var toolBar = (function () {
|
|||
toolBar.writeProperty("shown", false);
|
||||
toolBar.writeProperty("shown", true);
|
||||
}
|
||||
lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
};
|
||||
|
||||
|
@ -571,8 +623,8 @@ function findClickedEntity(event) {
|
|||
}
|
||||
|
||||
var entityResult = Entities.findRayIntersection(pickRay, true); // want precision picking
|
||||
var lightResult = lightOverlayManager.findRayIntersection(pickRay);
|
||||
lightResult.accurate = true;
|
||||
var iconResult = entityIconOverlayManager.findRayIntersection(pickRay);
|
||||
iconResult.accurate = true;
|
||||
|
||||
if (pickZones) {
|
||||
Entities.setZonesArePickable(false);
|
||||
|
@ -580,18 +632,12 @@ function findClickedEntity(event) {
|
|||
|
||||
var result;
|
||||
|
||||
if (!entityResult.intersects && !lightResult.intersects) {
|
||||
return null;
|
||||
} else if (entityResult.intersects && !lightResult.intersects) {
|
||||
if (iconResult.intersects) {
|
||||
result = iconResult;
|
||||
} else if (entityResult.intersects) {
|
||||
result = entityResult;
|
||||
} else if (!entityResult.intersects && lightResult.intersects) {
|
||||
result = lightResult;
|
||||
} else {
|
||||
if (entityResult.distance < lightResult.distance) {
|
||||
result = entityResult;
|
||||
} else {
|
||||
result = lightResult;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!result.accurate) {
|
||||
|
@ -945,18 +991,18 @@ function setupModelMenus() {
|
|||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
|
||||
menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
|
||||
afterItem: MENU_EASE_ON_FOCUS,
|
||||
isCheckable: true,
|
||||
isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE) === "true",
|
||||
isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
Menu.addMenuItem({
|
||||
menuName: "Edit",
|
||||
menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE,
|
||||
afterItem: MENU_SHOW_LIGHTS_IN_EDIT_MODE,
|
||||
afterItem: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
|
||||
isCheckable: true,
|
||||
isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) === "true",
|
||||
isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false",
|
||||
grouping: "Advanced"
|
||||
});
|
||||
|
||||
|
@ -987,7 +1033,7 @@ function cleanupModelMenus() {
|
|||
|
||||
Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT);
|
||||
Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE);
|
||||
}
|
||||
|
||||
|
@ -995,7 +1041,7 @@ Script.scriptEnding.connect(function () {
|
|||
toolBar.setActive(false);
|
||||
Settings.setValue(SETTING_AUTO_FOCUS_ON_SELECT, Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT));
|
||||
Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
|
||||
Settings.setValue(SETTING_SHOW_LIGHTS_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
|
||||
progressDialog.cleanup();
|
||||
|
@ -1184,7 +1230,7 @@ function parentSelectedEntities() {
|
|||
}
|
||||
function deleteSelectedEntities() {
|
||||
if (SelectionManager.hasSelection()) {
|
||||
selectedParticleEntity = 0;
|
||||
selectedParticleEntityID = null;
|
||||
particleExplorerTool.destroyWebView();
|
||||
SelectionManager.saveProperties();
|
||||
var savedProperties = [];
|
||||
|
@ -1283,8 +1329,8 @@ function handeMenuEvent(menuItem) {
|
|||
selectAllEtitiesInCurrentSelectionBox(false);
|
||||
} else if (menuItem === "Select All Entities Touching Box") {
|
||||
selectAllEtitiesInCurrentSelectionBox(true);
|
||||
} else if (menuItem === MENU_SHOW_LIGHTS_IN_EDIT_MODE) {
|
||||
lightOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_IN_EDIT_MODE));
|
||||
} else if (menuItem === MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) {
|
||||
entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
|
||||
} else if (menuItem === MENU_SHOW_ZONES_IN_EDIT_MODE) {
|
||||
Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
|
||||
}
|
||||
|
@ -1959,43 +2005,13 @@ var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace");
|
|||
|
||||
var propertiesTool = new PropertiesTool();
|
||||
var particleExplorerTool = new ParticleExplorerTool();
|
||||
var selectedParticleEntity = 0;
|
||||
var selectedParticleEntityID = null;
|
||||
entityListTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if(data.type === 'parent') {
|
||||
if (data.type === 'parent') {
|
||||
parentSelectedEntities();
|
||||
} else if(data.type === 'unparent') {
|
||||
unparentSelectedEntities();
|
||||
} else if (data.type === "selectionUpdate") {
|
||||
var ids = data.entityIds;
|
||||
if (ids.length === 1) {
|
||||
if (Entities.getEntityProperties(ids[0], "type").type === "ParticleEffect") {
|
||||
if (JSON.stringify(selectedParticleEntity) === JSON.stringify(ids[0])) {
|
||||
// This particle entity is already selected, so return
|
||||
return;
|
||||
}
|
||||
// Destroy the old particles web view first
|
||||
particleExplorerTool.destroyWebView();
|
||||
particleExplorerTool.createWebView();
|
||||
var properties = Entities.getEntityProperties(ids[0]);
|
||||
var particleData = {
|
||||
messageType: "particle_settings",
|
||||
currentProperties: properties
|
||||
};
|
||||
selectedParticleEntity = ids[0];
|
||||
particleExplorerTool.setActiveParticleEntity(ids[0]);
|
||||
|
||||
particleExplorerTool.webView.webEventReceived.connect(function (data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.messageType === "page_loaded") {
|
||||
particleExplorerTool.webView.emitScriptEvent(JSON.stringify(particleData));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
selectedParticleEntity = 0;
|
||||
particleExplorerTool.destroyWebView();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
var POINT_LIGHT_URL = "http://s3.amazonaws.com/hifi-public/images/tools/point-light.svg";
|
||||
var SPOT_LIGHT_URL = "http://s3.amazonaws.com/hifi-public/images/tools/spot-light.svg";
|
||||
|
||||
LightOverlayManager = function() {
|
||||
var self = this;
|
||||
/* globals EntityIconOverlayManager:true */
|
||||
|
||||
EntityIconOverlayManager = function(entityTypes, getOverlayPropertiesFunc) {
|
||||
var visible = false;
|
||||
|
||||
// List of all created overlays
|
||||
|
@ -22,9 +19,16 @@ LightOverlayManager = function() {
|
|||
for (var id in entityIDs) {
|
||||
var entityID = entityIDs[id];
|
||||
var properties = Entities.getEntityProperties(entityID);
|
||||
Overlays.editOverlay(entityOverlays[entityID], {
|
||||
var overlayProperties = {
|
||||
position: properties.position
|
||||
});
|
||||
};
|
||||
if (getOverlayPropertiesFunc) {
|
||||
var customProperties = getOverlayPropertiesFunc(entityID, properties);
|
||||
for (var key in customProperties) {
|
||||
overlayProperties[key] = customProperties[key];
|
||||
}
|
||||
}
|
||||
Overlays.editOverlay(entityOverlays[entityID], overlayProperties);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,7 +38,7 @@ LightOverlayManager = function() {
|
|||
|
||||
if (result.intersects) {
|
||||
for (var id in entityOverlays) {
|
||||
if (result.overlayID == entityOverlays[id]) {
|
||||
if (result.overlayID === entityOverlays[id]) {
|
||||
result.entityID = entityIDs[id];
|
||||
found = true;
|
||||
break;
|
||||
|
@ -50,7 +54,7 @@ LightOverlayManager = function() {
|
|||
};
|
||||
|
||||
this.setVisible = function(isVisible) {
|
||||
if (visible != isVisible) {
|
||||
if (visible !== isVisible) {
|
||||
visible = isVisible;
|
||||
for (var id in entityOverlays) {
|
||||
Overlays.editOverlay(entityOverlays[id], {
|
||||
|
@ -62,12 +66,13 @@ LightOverlayManager = function() {
|
|||
|
||||
// Allocate or get an unused overlay
|
||||
function getOverlay() {
|
||||
if (unusedOverlays.length == 0) {
|
||||
var overlay = Overlays.addOverlay("image3d", {});
|
||||
var overlay;
|
||||
if (unusedOverlays.length === 0) {
|
||||
overlay = Overlays.addOverlay("image3d", {});
|
||||
allOverlays.push(overlay);
|
||||
} else {
|
||||
var overlay = unusedOverlays.pop();
|
||||
};
|
||||
overlay = unusedOverlays.pop();
|
||||
}
|
||||
return overlay;
|
||||
}
|
||||
|
||||
|
@ -79,24 +84,32 @@ LightOverlayManager = function() {
|
|||
}
|
||||
|
||||
function addEntity(entityID) {
|
||||
var properties = Entities.getEntityProperties(entityID);
|
||||
if (properties.type == "Light" && !(entityID in entityOverlays)) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['position', 'type']);
|
||||
if (entityTypes.indexOf(properties.type) > -1 && !(entityID in entityOverlays)) {
|
||||
var overlay = getOverlay();
|
||||
entityOverlays[entityID] = overlay;
|
||||
entityIDs[entityID] = entityID;
|
||||
Overlays.editOverlay(overlay, {
|
||||
var overlayProperties = {
|
||||
position: properties.position,
|
||||
url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL,
|
||||
rotation: Quat.fromPitchYawRollDegrees(0, 0, 270),
|
||||
visible: visible,
|
||||
alpha: 0.9,
|
||||
scale: 0.5,
|
||||
drawInFront: true,
|
||||
isFacingAvatar: true,
|
||||
color: {
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 255
|
||||
}
|
||||
});
|
||||
};
|
||||
if (getOverlayPropertiesFunc) {
|
||||
var customProperties = getOverlayPropertiesFunc(entityID, properties);
|
||||
for (var key in customProperties) {
|
||||
overlayProperties[key] = customProperties[key];
|
||||
}
|
||||
}
|
||||
Overlays.editOverlay(overlay, overlayProperties);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,4 +143,4 @@ LightOverlayManager = function() {
|
|||
Overlays.deleteOverlay(allOverlays[i]);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
|
@ -1032,10 +1032,12 @@ SelectionDisplay = (function() {
|
|||
var pickRay = controllerComputePickRay();
|
||||
if (pickRay) {
|
||||
var entityIntersection = Entities.findRayIntersection(pickRay, true);
|
||||
|
||||
|
||||
var iconIntersection = entityIconOverlayManager.findRayIntersection(pickRay);
|
||||
var overlayIntersection = Overlays.findRayIntersection(pickRay);
|
||||
if (entityIntersection.intersects &&
|
||||
|
||||
if (iconIntersection.intersects) {
|
||||
selectionManager.setSelections([iconIntersection.entityID]);
|
||||
} else if (entityIntersection.intersects &&
|
||||
(!overlayIntersection.intersects || (entityIntersection.distance < overlayIntersection.distance))) {
|
||||
|
||||
if (HMD.tabletID === entityIntersection.entityID) {
|
||||
|
|
Loading…
Reference in a new issue