mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 03:08:00 +02:00
Merge branch 'master' into plugins
This commit is contained in:
commit
e6c241b75b
61 changed files with 1165 additions and 392 deletions
|
@ -45,10 +45,11 @@ if (WIN32)
|
||||||
# Caveats: http://stackoverflow.com/questions/2288728/drawbacks-of-using-largeaddressaware-for-32-bit-windows-executables
|
# Caveats: http://stackoverflow.com/questions/2288728/drawbacks-of-using-largeaddressaware-for-32-bit-windows-executables
|
||||||
# TODO: Remove when building 64-bit.
|
# TODO: Remove when building 64-bit.
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
|
||||||
elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
else ()
|
||||||
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter")
|
||||||
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas")
|
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter -ggdb")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
|
||||||
|
endif ()
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if (NOT MSVC12)
|
if (NOT MSVC12)
|
||||||
|
|
|
@ -114,7 +114,23 @@ void AssignmentClient::stopAssignmentClient() {
|
||||||
qDebug() << "Exiting.";
|
qDebug() << "Exiting.";
|
||||||
_requestTimer.stop();
|
_requestTimer.stop();
|
||||||
_statsTimerACM.stop();
|
_statsTimerACM.stop();
|
||||||
QCoreApplication::quit();
|
if (_currentAssignment) {
|
||||||
|
_currentAssignment->aboutToQuit();
|
||||||
|
QThread* currentAssignmentThread = _currentAssignment->thread();
|
||||||
|
currentAssignmentThread->quit();
|
||||||
|
currentAssignmentThread->wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AssignmentClient::aboutToQuit() {
|
||||||
|
stopAssignmentClient();
|
||||||
|
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||||
|
qInstallMessageHandler(0);
|
||||||
|
// clear out pointer to the assignment so the destructor gets called. if we don't do this here,
|
||||||
|
// it will get destroyed along with all the other "static" stuff. various static member variables
|
||||||
|
// will be destroyed first and things go wrong.
|
||||||
|
_currentAssignment.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,6 +213,7 @@ void AssignmentClient::readPendingDatagrams() {
|
||||||
|
|
||||||
// start the deployed assignment
|
// start the deployed assignment
|
||||||
AssignmentThread* workerThread = new AssignmentThread(_currentAssignment, this);
|
AssignmentThread* workerThread = new AssignmentThread(_currentAssignment, this);
|
||||||
|
workerThread->setObjectName("worker");
|
||||||
|
|
||||||
connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run);
|
connect(workerThread, &QThread::started, _currentAssignment.data(), &ThreadedAssignment::run);
|
||||||
connect(_currentAssignment.data(), &ThreadedAssignment::finished, workerThread, &QThread::quit);
|
connect(_currentAssignment.data(), &ThreadedAssignment::finished, workerThread, &QThread::quit);
|
||||||
|
|
|
@ -34,6 +34,9 @@ private slots:
|
||||||
void sendStatsPacketToACM();
|
void sendStatsPacketToACM();
|
||||||
void stopAssignmentClient();
|
void stopAssignmentClient();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void aboutToQuit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setUpStatsToMonitor(int ppid);
|
void setUpStatsToMonitor(int ppid);
|
||||||
Assignment _requestAssignment;
|
Assignment _requestAssignment;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
@ -180,14 +181,19 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QThread::currentThread()->setObjectName("main thread");
|
||||||
|
|
||||||
|
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||||
|
|
||||||
if (numForks || minForks || maxForks) {
|
if (numForks || minForks || maxForks) {
|
||||||
AssignmentClientMonitor monitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool,
|
AssignmentClientMonitor monitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool,
|
||||||
walletUUID, assignmentServerHostname, assignmentServerPort);
|
walletUUID, assignmentServerHostname, assignmentServerPort);
|
||||||
|
connect(this, &QCoreApplication::aboutToQuit, &monitor, &AssignmentClientMonitor::aboutToQuit);
|
||||||
exec();
|
exec();
|
||||||
} else {
|
} else {
|
||||||
AssignmentClient client(ppid, requestAssignmentType, assignmentPool,
|
AssignmentClient client(ppid, requestAssignmentType, assignmentPool,
|
||||||
walletUUID, assignmentServerHostname, assignmentServerPort);
|
walletUUID, assignmentServerHostname, assignmentServerPort);
|
||||||
|
connect(this, &QCoreApplication::aboutToQuit, &client, &AssignmentClient::aboutToQuit);
|
||||||
exec();
|
exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,17 @@ AssignmentClientMonitor::~AssignmentClientMonitor() {
|
||||||
stopChildProcesses();
|
stopChildProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssignmentClientMonitor::waitOnChildren(int msecs) {
|
||||||
|
QMutableListIterator<QProcess*> i(_childProcesses);
|
||||||
|
while (i.hasNext()) {
|
||||||
|
QProcess* childProcess = i.next();
|
||||||
|
bool finished = childProcess->waitForFinished(msecs);
|
||||||
|
if (finished) {
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AssignmentClientMonitor::stopChildProcesses() {
|
void AssignmentClientMonitor::stopChildProcesses() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
@ -78,11 +89,22 @@ void AssignmentClientMonitor::stopChildProcesses() {
|
||||||
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode);
|
||||||
nodeList->writeUnverifiedDatagram(diePacket, *node->getActiveSocket());
|
nodeList->writeUnverifiedDatagram(diePacket, *node->getActiveSocket());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// try to give all the children time to shutdown
|
||||||
|
waitOnChildren(15000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssignmentClientMonitor::aboutToQuit() {
|
||||||
|
stopChildProcesses();
|
||||||
|
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||||
|
qInstallMessageHandler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentClientMonitor::spawnChildClient() {
|
void AssignmentClientMonitor::spawnChildClient() {
|
||||||
QProcess *assignmentClient = new QProcess(this);
|
QProcess *assignmentClient = new QProcess(this);
|
||||||
|
|
||||||
|
_childProcesses.append(assignmentClient);
|
||||||
|
|
||||||
// unparse the parts of the command-line that the child cares about
|
// unparse the parts of the command-line that the child cares about
|
||||||
QStringList _childArguments;
|
QStringList _childArguments;
|
||||||
if (_assignmentPool != "") {
|
if (_assignmentPool != "") {
|
||||||
|
@ -119,8 +141,6 @@ void AssignmentClientMonitor::spawnChildClient() {
|
||||||
qDebug() << "Spawned a child client with PID" << assignmentClient->pid();
|
qDebug() << "Spawned a child client with PID" << assignmentClient->pid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AssignmentClientMonitor::checkSpares() {
|
void AssignmentClientMonitor::checkSpares() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
QUuid aSpareId = "";
|
QUuid aSpareId = "";
|
||||||
|
@ -156,6 +176,8 @@ void AssignmentClientMonitor::checkSpares() {
|
||||||
nodeList->writeUnverifiedDatagram(diePacket, childNode);
|
nodeList->writeUnverifiedDatagram(diePacket, childNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitOnChildren(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,16 @@ public:
|
||||||
QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname,
|
QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname,
|
||||||
quint16 assignmentServerPort);
|
quint16 assignmentServerPort);
|
||||||
~AssignmentClientMonitor();
|
~AssignmentClientMonitor();
|
||||||
|
|
||||||
|
void waitOnChildren(int msecs);
|
||||||
void stopChildProcesses();
|
void stopChildProcesses();
|
||||||
private slots:
|
private slots:
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
void checkSpares();
|
void checkSpares();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void aboutToQuit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void spawnChildClient();
|
void spawnChildClient();
|
||||||
QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children
|
QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children
|
||||||
|
@ -52,6 +56,7 @@ private:
|
||||||
QString _assignmentServerHostname;
|
QString _assignmentServerHostname;
|
||||||
quint16 _assignmentServerPort;
|
quint16 _assignmentServerPort;
|
||||||
|
|
||||||
|
QList<QProcess*> _childProcesses;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AssignmentClientMonitor_h
|
#endif // hifi_AssignmentClientMonitor_h
|
||||||
|
|
|
@ -45,6 +45,9 @@ AvatarMixer::AvatarMixer(const QByteArray& packet) :
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarMixer::~AvatarMixer() {
|
AvatarMixer::~AvatarMixer() {
|
||||||
|
if (_broadcastTimer) {
|
||||||
|
_broadcastTimer->deleteLater();
|
||||||
|
}
|
||||||
_broadcastThread.quit();
|
_broadcastThread.quit();
|
||||||
_broadcastThread.wait();
|
_broadcastThread.wait();
|
||||||
}
|
}
|
||||||
|
@ -343,13 +346,13 @@ void AvatarMixer::run() {
|
||||||
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
|
nodeList->linkedDataCreateCallback = attachAvatarDataToNode;
|
||||||
|
|
||||||
// setup the timer that will be fired on the broadcast thread
|
// setup the timer that will be fired on the broadcast thread
|
||||||
QTimer* broadcastTimer = new QTimer();
|
_broadcastTimer = new QTimer();
|
||||||
broadcastTimer->setInterval(AVATAR_DATA_SEND_INTERVAL_MSECS);
|
_broadcastTimer->setInterval(AVATAR_DATA_SEND_INTERVAL_MSECS);
|
||||||
broadcastTimer->moveToThread(&_broadcastThread);
|
_broadcastTimer->moveToThread(&_broadcastThread);
|
||||||
|
|
||||||
// connect appropriate signals and slots
|
// connect appropriate signals and slots
|
||||||
connect(broadcastTimer, &QTimer::timeout, this, &AvatarMixer::broadcastAvatarData, Qt::DirectConnection);
|
connect(_broadcastTimer, &QTimer::timeout, this, &AvatarMixer::broadcastAvatarData, Qt::DirectConnection);
|
||||||
connect(&_broadcastThread, SIGNAL(started()), broadcastTimer, SLOT(start()));
|
connect(&_broadcastThread, SIGNAL(started()), _broadcastTimer, SLOT(start()));
|
||||||
|
|
||||||
// start the broadcastThread
|
// start the broadcastThread
|
||||||
_broadcastThread.start();
|
_broadcastThread.start();
|
||||||
|
|
|
@ -47,6 +47,8 @@ private:
|
||||||
int _numStatFrames;
|
int _numStatFrames;
|
||||||
int _sumBillboardPackets;
|
int _sumBillboardPackets;
|
||||||
int _sumIdentityPackets;
|
int _sumIdentityPackets;
|
||||||
|
|
||||||
|
QTimer* _broadcastTimer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarMixer_h
|
#endif // hifi_AvatarMixer_h
|
||||||
|
|
|
@ -27,6 +27,11 @@ EntityServer::EntityServer(const QByteArray& packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityServer::~EntityServer() {
|
EntityServer::~EntityServer() {
|
||||||
|
if (_pruneDeletedEntitiesTimer) {
|
||||||
|
_pruneDeletedEntitiesTimer->stop();
|
||||||
|
_pruneDeletedEntitiesTimer->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
EntityTree* tree = (EntityTree*)_tree;
|
EntityTree* tree = (EntityTree*)_tree;
|
||||||
tree->removeNewlyCreatedHook(this);
|
tree->removeNewlyCreatedHook(this);
|
||||||
}
|
}
|
||||||
|
@ -48,10 +53,10 @@ Octree* EntityServer::createTree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityServer::beforeRun() {
|
void EntityServer::beforeRun() {
|
||||||
QTimer* pruneDeletedEntitiesTimer = new QTimer(this);
|
_pruneDeletedEntitiesTimer = new QTimer();
|
||||||
connect(pruneDeletedEntitiesTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedEntities()));
|
connect(_pruneDeletedEntitiesTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedEntities()));
|
||||||
const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second
|
const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second
|
||||||
pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
|
_pruneDeletedEntitiesTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
|
void EntityServer::entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode) {
|
||||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntitySimulation* _entitySimulation;
|
EntitySimulation* _entitySimulation;
|
||||||
|
QTimer* _pruneDeletedEntitiesTimer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_EntityServer_h
|
#endif // hifi_EntityServer_h
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
||||||
|
|
||||||
void shuttingDown() { _shuttingDown = true;}
|
virtual void terminating() { _shuttingDown = true; ReceivedPacketProcessor::terminating(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -266,16 +266,19 @@ OctreeServer::~OctreeServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_jurisdictionSender) {
|
if (_jurisdictionSender) {
|
||||||
|
_jurisdictionSender->terminating();
|
||||||
_jurisdictionSender->terminate();
|
_jurisdictionSender->terminate();
|
||||||
_jurisdictionSender->deleteLater();
|
_jurisdictionSender->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_octreeInboundPacketProcessor) {
|
if (_octreeInboundPacketProcessor) {
|
||||||
|
_octreeInboundPacketProcessor->terminating();
|
||||||
_octreeInboundPacketProcessor->terminate();
|
_octreeInboundPacketProcessor->terminate();
|
||||||
_octreeInboundPacketProcessor->deleteLater();
|
_octreeInboundPacketProcessor->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_persistThread) {
|
if (_persistThread) {
|
||||||
|
_persistThread->terminating();
|
||||||
_persistThread->terminate();
|
_persistThread->terminate();
|
||||||
_persistThread->deleteLater();
|
_persistThread->deleteLater();
|
||||||
}
|
}
|
||||||
|
@ -1095,8 +1098,6 @@ void OctreeServer::readConfiguration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreeServer::run() {
|
void OctreeServer::run() {
|
||||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
|
||||||
|
|
||||||
_safeServerName = getMyServerName();
|
_safeServerName = getMyServerName();
|
||||||
|
|
||||||
// Before we do anything else, create our tree...
|
// Before we do anything else, create our tree...
|
||||||
|
@ -1219,8 +1220,15 @@ void OctreeServer::forceNodeShutdown(SharedNodePointer node) {
|
||||||
void OctreeServer::aboutToFinish() {
|
void OctreeServer::aboutToFinish() {
|
||||||
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
|
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
|
||||||
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
|
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
|
||||||
_octreeInboundPacketProcessor->shuttingDown();
|
|
||||||
|
if (_octreeInboundPacketProcessor) {
|
||||||
|
_octreeInboundPacketProcessor->terminating();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_jurisdictionSender) {
|
||||||
|
_jurisdictionSender->terminating();
|
||||||
|
}
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->eachNode([this](const SharedNodePointer& node) {
|
DependencyManager::get<NodeList>()->eachNode([this](const SharedNodePointer& node) {
|
||||||
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
||||||
forceNodeShutdown(node);
|
forceNodeShutdown(node);
|
||||||
|
@ -1228,6 +1236,7 @@ void OctreeServer::aboutToFinish() {
|
||||||
|
|
||||||
if (_persistThread) {
|
if (_persistThread) {
|
||||||
_persistThread->aboutToFinish();
|
_persistThread->aboutToFinish();
|
||||||
|
_persistThread->terminating();
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
|
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
|
||||||
|
|
416
examples/avatarSelector.js
Normal file
416
examples/avatarSelector.js
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
//
|
||||||
|
// avatarSelector.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by David Rowe on 21 Apr 2015.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Based on lobby.js created by Stephen Birarda on 17 Oct 2014.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||||
|
|
||||||
|
var panelWall = false;
|
||||||
|
var orbShell = false;
|
||||||
|
var descriptionText = false;
|
||||||
|
var showText = false;
|
||||||
|
|
||||||
|
// used for formating the description text, in meters
|
||||||
|
var textWidth = 4;
|
||||||
|
var textHeight = .5;
|
||||||
|
var numberOfLines = 2;
|
||||||
|
var textMargin = 0.0625;
|
||||||
|
var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines;
|
||||||
|
|
||||||
|
var avatarStickPosition = {};
|
||||||
|
|
||||||
|
var orbNaturalExtentsMin = { x: -1.230354, y: -1.22077, z: -1.210487 };
|
||||||
|
var orbNaturalExtentsMax = { x: 1.230353, y: 1.229819, z: 1.210487 };
|
||||||
|
var panelsNaturalExtentsMin = { x: -1.223182, y: -0.348487, z: 0.0451369 };
|
||||||
|
var panelsNaturalExtentsMax = { x: 1.223039, y: 0.602978, z: 1.224298 };
|
||||||
|
|
||||||
|
var orbNaturalDimensions = Vec3.subtract(orbNaturalExtentsMax, orbNaturalExtentsMin);
|
||||||
|
var panelsNaturalDimensions = Vec3.subtract(panelsNaturalExtentsMax, panelsNaturalExtentsMin);
|
||||||
|
|
||||||
|
var SCALING_FACTOR = 10;
|
||||||
|
var orbDimensions = Vec3.multiply(orbNaturalDimensions, SCALING_FACTOR);
|
||||||
|
var panelsDimensions = Vec3.multiply(panelsNaturalDimensions, SCALING_FACTOR);
|
||||||
|
|
||||||
|
var orbNaturalCenter = Vec3.sum(orbNaturalExtentsMin, Vec3.multiply(orbNaturalDimensions, 0.5));
|
||||||
|
var panelsNaturalCenter = Vec3.sum(panelsNaturalExtentsMin, Vec3.multiply(panelsNaturalDimensions, 0.5));
|
||||||
|
var orbCenter = Vec3.multiply(orbNaturalCenter, SCALING_FACTOR);
|
||||||
|
var panelsCenter = Vec3.multiply(panelsNaturalCenter, SCALING_FACTOR);
|
||||||
|
var panelsCenterShift = Vec3.subtract(panelsCenter, orbCenter);
|
||||||
|
|
||||||
|
var ORB_SHIFT = { x: 0, y: -1.4, z: -0.8 };
|
||||||
|
|
||||||
|
var LOBBY_PANEL_WALL_URL = HIFI_PUBLIC_BUCKET + "models/sets/Lobby/PanelWallForInterface.fbx";
|
||||||
|
var LOBBY_BLANK_PANEL_TEXTURE_URL = HIFI_PUBLIC_BUCKET + "models/sets/Lobby/Texture.jpg";
|
||||||
|
var LOBBY_SHELL_URL = HIFI_PUBLIC_BUCKET + "models/sets/Lobby/LobbyShellForInterface.fbx";
|
||||||
|
|
||||||
|
var droneSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/drone.stereo.raw")
|
||||||
|
var currentDrone = null;
|
||||||
|
|
||||||
|
var latinSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/latin.stereo.raw")
|
||||||
|
var latinInjector = null;
|
||||||
|
var elevatorSound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Lobby/elevator.stereo.raw")
|
||||||
|
var elevatorInjector = null;
|
||||||
|
var currentMuzakInjector = null;
|
||||||
|
var currentSound = null;
|
||||||
|
|
||||||
|
function textOverlayPosition() {
|
||||||
|
var TEXT_DISTANCE_OUT = 6;
|
||||||
|
var TEXT_DISTANCE_DOWN = -2;
|
||||||
|
return Vec3.sum(Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), TEXT_DISTANCE_OUT)),
|
||||||
|
Vec3.multiply(Quat.getUp(Camera.orientation), TEXT_DISTANCE_DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
var panelPlaceOrder = [
|
||||||
|
7, 8, 9, 10, 11, 12, 13,
|
||||||
|
0, 1, 2, 3, 4, 5, 6,
|
||||||
|
14, 15, 16, 17, 18, 19, 20
|
||||||
|
];
|
||||||
|
|
||||||
|
// Avatar index is 0-based
|
||||||
|
function avatarIndexToPanelIndex(avatarIndex) {
|
||||||
|
return panelPlaceOrder.indexOf(avatarIndex) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panel index is 1-based
|
||||||
|
function panelIndexToPlaceIndex(panelIndex) {
|
||||||
|
return panelPlaceOrder[panelIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var MAX_NUM_PANELS = 21;
|
||||||
|
var DRONE_VOLUME = 0.3;
|
||||||
|
|
||||||
|
function drawLobby() {
|
||||||
|
if (!panelWall) {
|
||||||
|
print("Adding overlays for the avatar selector panel wall and orb shell.");
|
||||||
|
|
||||||
|
var cameraEuler = Quat.safeEulerAngles(Camera.orientation);
|
||||||
|
var towardsMe = Quat.angleAxis(cameraEuler.y + 180, { x: 0, y: 1, z: 0 });
|
||||||
|
|
||||||
|
var orbPosition = Vec3.sum(Camera.position, Vec3.multiplyQbyV(towardsMe, ORB_SHIFT));
|
||||||
|
|
||||||
|
var panelWallProps = {
|
||||||
|
url: LOBBY_PANEL_WALL_URL,
|
||||||
|
position: Vec3.sum(orbPosition, Vec3.multiplyQbyV(towardsMe, panelsCenterShift)),
|
||||||
|
rotation: towardsMe,
|
||||||
|
dimensions: panelsDimensions
|
||||||
|
};
|
||||||
|
|
||||||
|
var orbShellProps = {
|
||||||
|
url: LOBBY_SHELL_URL,
|
||||||
|
position: orbPosition,
|
||||||
|
rotation: towardsMe,
|
||||||
|
dimensions: orbDimensions,
|
||||||
|
ignoreRayIntersection: true
|
||||||
|
};
|
||||||
|
|
||||||
|
var windowDimensions = Controller.getViewportDimensions();
|
||||||
|
|
||||||
|
var descriptionTextProps = {
|
||||||
|
position: textOverlayPosition(),
|
||||||
|
dimensions: { x: textWidth, y: textHeight },
|
||||||
|
backgroundColor: { red: 0, green: 0, blue: 0 },
|
||||||
|
color: { red: 255, green: 255, blue: 255 },
|
||||||
|
topMargin: textMargin,
|
||||||
|
leftMargin: textMargin,
|
||||||
|
bottomMargin: textMargin,
|
||||||
|
rightMargin: textMargin,
|
||||||
|
text: "",
|
||||||
|
lineHeight: lineHeight,
|
||||||
|
alpha: 0.9,
|
||||||
|
backgroundAlpha: 0.9,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
visible: false,
|
||||||
|
isFacingAvatar: true
|
||||||
|
};
|
||||||
|
|
||||||
|
avatarStickPosition = MyAvatar.position;
|
||||||
|
|
||||||
|
panelWall = Overlays.addOverlay("model", panelWallProps);
|
||||||
|
orbShell = Overlays.addOverlay("model", orbShellProps);
|
||||||
|
descriptionText = Overlays.addOverlay("text3d", descriptionTextProps);
|
||||||
|
|
||||||
|
if (droneSound.downloaded) {
|
||||||
|
// start the drone sound
|
||||||
|
if (!currentDrone) {
|
||||||
|
currentDrone = Audio.playSound(droneSound, { stereo: true, loop: true, localOnly: true, volume: DRONE_VOLUME });
|
||||||
|
} else {
|
||||||
|
currentDrone.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start one of our muzak sounds
|
||||||
|
playRandomMuzak();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var avatars = {};
|
||||||
|
|
||||||
|
function changeLobbyTextures() {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.open("GET", "https://metaverse.highfidelity.com/api/v1/marketplace?category=head+%26+body&limit=21", false);
|
||||||
|
req.send(); // Data returned is randomized.
|
||||||
|
|
||||||
|
avatars = JSON.parse(req.responseText).data.items;
|
||||||
|
|
||||||
|
var NUM_PANELS = avatars.length;
|
||||||
|
|
||||||
|
var textureProp = {
|
||||||
|
textures: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var j = 0; j < NUM_PANELS; j++) {
|
||||||
|
var panelIndex = avatarIndexToPanelIndex(j);
|
||||||
|
textureProp["textures"]["file" + panelIndex] = avatars[j].preview_url;
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(panelWall, textureProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
var MUZAK_VOLUME = 0.1;
|
||||||
|
|
||||||
|
function playCurrentSound(secondOffset) {
|
||||||
|
if (currentSound == latinSound) {
|
||||||
|
if (!latinInjector) {
|
||||||
|
latinInjector = Audio.playSound(latinSound, { localOnly: true, secondOffset: secondOffset, volume: MUZAK_VOLUME });
|
||||||
|
} else {
|
||||||
|
latinInjector.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMuzakInjector = latinInjector;
|
||||||
|
} else if (currentSound == elevatorSound) {
|
||||||
|
if (!elevatorInjector) {
|
||||||
|
elevatorInjector = Audio.playSound(elevatorSound, { localOnly: true, secondOffset: secondOffset, volume: MUZAK_VOLUME });
|
||||||
|
} else {
|
||||||
|
elevatorInjector.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentMuzakInjector = elevatorInjector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function playNextMuzak() {
|
||||||
|
if (panelWall) {
|
||||||
|
if (currentSound == latinSound) {
|
||||||
|
if (elevatorSound.downloaded) {
|
||||||
|
currentSound = elevatorSound;
|
||||||
|
}
|
||||||
|
} else if (currentSound == elevatorSound) {
|
||||||
|
if (latinSound.downloaded) {
|
||||||
|
currentSound = latinSound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playCurrentSound(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function playRandomMuzak() {
|
||||||
|
currentSound = null;
|
||||||
|
|
||||||
|
if (latinSound.downloaded && elevatorSound.downloaded) {
|
||||||
|
currentSound = Math.random() < 0.5 ? latinSound : elevatorSound;
|
||||||
|
} else if (latinSound.downloaded) {
|
||||||
|
currentSound = latinSound;
|
||||||
|
} else if (elevatorSound.downloaded) {
|
||||||
|
currentSound = elevatorSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSound) {
|
||||||
|
// pick a random number of seconds from 0-10 to offset the muzak
|
||||||
|
var secondOffset = Math.random() * 10;
|
||||||
|
|
||||||
|
playCurrentSound(secondOffset);
|
||||||
|
} else {
|
||||||
|
currentMuzakInjector = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanupLobby() {
|
||||||
|
toggleEnvironmentRendering(true);
|
||||||
|
|
||||||
|
// for each of the 21 placeholder textures, set them back to default so the cached model doesn't have changed textures
|
||||||
|
var panelTexturesReset = {};
|
||||||
|
panelTexturesReset["textures"] = {};
|
||||||
|
|
||||||
|
for (var j = 0; j < MAX_NUM_PANELS; j++) {
|
||||||
|
panelTexturesReset["textures"]["file" + (j + 1)] = LOBBY_BLANK_PANEL_TEXTURE_URL;
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(panelWall, panelTexturesReset);
|
||||||
|
|
||||||
|
Overlays.deleteOverlay(panelWall);
|
||||||
|
Overlays.deleteOverlay(orbShell);
|
||||||
|
Overlays.deleteOverlay(descriptionText);
|
||||||
|
|
||||||
|
panelWall = false;
|
||||||
|
orbShell = false;
|
||||||
|
|
||||||
|
if (currentDrone) {
|
||||||
|
currentDrone.stop();
|
||||||
|
currentDrone = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentMuzakInjector) {
|
||||||
|
currentMuzakInjector.stop();
|
||||||
|
currentMuzakInjector = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
avatars = {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionStartEvent(event) {
|
||||||
|
if (panelWall) {
|
||||||
|
// we've got an action event and our panel wall is up
|
||||||
|
// check if we hit a panel and if we should jump there
|
||||||
|
var result = Overlays.findRayIntersection(event.actionRay);
|
||||||
|
if (result.intersects && result.overlayID == panelWall) {
|
||||||
|
|
||||||
|
var panelName = result.extraInfo;
|
||||||
|
|
||||||
|
var panelStringIndex = panelName.indexOf("Panel");
|
||||||
|
if (panelStringIndex != -1) {
|
||||||
|
var panelIndex = parseInt(panelName.slice(5));
|
||||||
|
var avatarIndex = panelIndexToPlaceIndex(panelIndex);
|
||||||
|
if (avatarIndex < avatars.length) {
|
||||||
|
var actionPlace = avatars[avatarIndex];
|
||||||
|
|
||||||
|
print("Changing avatar to " + actionPlace.name
|
||||||
|
+ " after click on panel " + panelIndex + " with avatar index " + avatarIndex);
|
||||||
|
|
||||||
|
MyAvatar.useFullAvatarURL(actionPlace.content_url);
|
||||||
|
|
||||||
|
maybeCleanupLobby();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var control = false;
|
||||||
|
|
||||||
|
function keyPressEvent(event) {
|
||||||
|
if (event.text === "CONTROL") {
|
||||||
|
control = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control && event.text === "a") {
|
||||||
|
if (!panelWall) {
|
||||||
|
toggleEnvironmentRendering(false);
|
||||||
|
drawLobby();
|
||||||
|
changeLobbyTextures();
|
||||||
|
} else {
|
||||||
|
cleanupLobby();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyReleaseEvent(event) {
|
||||||
|
if (event.text === "CONTROL") {
|
||||||
|
control = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var CLEANUP_EPSILON_DISTANCE = 0.05;
|
||||||
|
|
||||||
|
function maybeCleanupLobby() {
|
||||||
|
if (panelWall && Vec3.length(Vec3.subtract(avatarStickPosition, MyAvatar.position)) > CLEANUP_EPSILON_DISTANCE) {
|
||||||
|
cleanupLobby();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleEnvironmentRendering(shouldRender) {
|
||||||
|
Scene.shouldRenderAvatars = shouldRender;
|
||||||
|
Scene.shouldRenderEntities = shouldRender;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLookAt(pickRay) {
|
||||||
|
if (panelWall && descriptionText) {
|
||||||
|
// we've got an action event and our panel wall is up
|
||||||
|
// check if we hit a panel and if we should jump there
|
||||||
|
var result = Overlays.findRayIntersection(pickRay);
|
||||||
|
if (result.intersects && result.overlayID == panelWall) {
|
||||||
|
var panelName = result.extraInfo;
|
||||||
|
var panelStringIndex = panelName.indexOf("Panel");
|
||||||
|
if (panelStringIndex != -1) {
|
||||||
|
var panelIndex = parseInt(panelName.slice(5));
|
||||||
|
var avatarIndex = panelIndexToPlaceIndex(panelIndex);
|
||||||
|
if (avatarIndex < avatars.length) {
|
||||||
|
var actionPlace = avatars[avatarIndex];
|
||||||
|
|
||||||
|
if (actionPlace.description == "") {
|
||||||
|
Overlays.editOverlay(descriptionText, { text: actionPlace.name, visible: showText });
|
||||||
|
} else {
|
||||||
|
// handle line wrapping
|
||||||
|
var allWords = actionPlace.description.split(" ");
|
||||||
|
var currentGoodLine = "";
|
||||||
|
var currentTestLine = "";
|
||||||
|
var formatedDescription = "";
|
||||||
|
var wordsFormated = 0;
|
||||||
|
var currentTestWord = 0;
|
||||||
|
var wordsOnLine = 0;
|
||||||
|
while (wordsFormated < allWords.length) {
|
||||||
|
// first add the "next word" to the line and test it.
|
||||||
|
currentTestLine = currentGoodLine;
|
||||||
|
if (wordsOnLine > 0) {
|
||||||
|
currentTestLine += " " + allWords[currentTestWord];
|
||||||
|
} else {
|
||||||
|
currentTestLine = allWords[currentTestWord];
|
||||||
|
}
|
||||||
|
var lineLength = Overlays.textSize(descriptionText, currentTestLine).width;
|
||||||
|
if (lineLength < textWidth || wordsOnLine == 0) {
|
||||||
|
wordsFormated++;
|
||||||
|
currentTestWord++;
|
||||||
|
wordsOnLine++;
|
||||||
|
currentGoodLine = currentTestLine;
|
||||||
|
} else {
|
||||||
|
formatedDescription += currentGoodLine + "\n";
|
||||||
|
wordsOnLine = 0;
|
||||||
|
currentGoodLine = "";
|
||||||
|
currentTestLine = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formatedDescription += currentGoodLine;
|
||||||
|
Overlays.editOverlay(descriptionText, { text: formatedDescription, visible: showText });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Overlays.editOverlay(descriptionText, { text: "", visible: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
maybeCleanupLobby();
|
||||||
|
if (panelWall) {
|
||||||
|
Overlays.editOverlay(descriptionText, { position: textOverlayPosition() });
|
||||||
|
|
||||||
|
// if the reticle is up then we may need to play the next muzak
|
||||||
|
if (currentMuzakInjector && !currentMuzakInjector.isPlaying) {
|
||||||
|
playNextMuzak();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseMoveEvent(event) {
|
||||||
|
if (panelWall) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
handleLookAt(pickRay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.actionStartEvent.connect(actionStartEvent);
|
||||||
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||||
|
Script.update.connect(update);
|
||||||
|
Script.scriptEnding.connect(maybeCleanupLobby);
|
||||||
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
|
@ -592,7 +592,11 @@ var idleMouseTimerId = null;
|
||||||
var IDLE_MOUSE_TIMEOUT = 200;
|
var IDLE_MOUSE_TIMEOUT = 200;
|
||||||
var DEFAULT_ENTITY_DRAG_DROP_DISTANCE = 2.0;
|
var DEFAULT_ENTITY_DRAG_DROP_DISTANCE = 2.0;
|
||||||
|
|
||||||
function mouseMoveEvent(event) {
|
var lastMouseMoveEvent = null;
|
||||||
|
function mouseMoveEventBuffered(event) {
|
||||||
|
lastMouseMoveEvent = event;
|
||||||
|
}
|
||||||
|
function mouseMove(event) {
|
||||||
mouseHasMovedSincePress = true;
|
mouseHasMovedSincePress = true;
|
||||||
|
|
||||||
if (placingEntityID) {
|
if (placingEntityID) {
|
||||||
|
@ -661,6 +665,10 @@ function highlightEntityUnderCursor(position, accurateRay) {
|
||||||
|
|
||||||
|
|
||||||
function mouseReleaseEvent(event) {
|
function mouseReleaseEvent(event) {
|
||||||
|
if (lastMouseMoveEvent) {
|
||||||
|
mouseMove(lastMouseMoveEvent);
|
||||||
|
lastMouseMoveEvent = null;
|
||||||
|
}
|
||||||
if (propertyMenu.mouseReleaseEvent(event) || toolBar.mouseReleaseEvent(event)) {
|
if (propertyMenu.mouseReleaseEvent(event) || toolBar.mouseReleaseEvent(event)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -772,7 +780,7 @@ function mouseClickEvent(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.mousePressEvent.connect(mousePressEvent);
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
Controller.mouseMoveEvent.connect(mouseMoveEventBuffered);
|
||||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
|
|
||||||
|
|
||||||
|
@ -882,6 +890,10 @@ Script.update.connect(function (deltaTime) {
|
||||||
lastOrientation = Camera.orientation;
|
lastOrientation = Camera.orientation;
|
||||||
lastPosition = Camera.position;
|
lastPosition = Camera.position;
|
||||||
}
|
}
|
||||||
|
if (lastMouseMoveEvent) {
|
||||||
|
mouseMove(lastMouseMoveEvent);
|
||||||
|
lastMouseMoveEvent = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function insideBox(center, dimensions, point) {
|
function insideBox(center, dimensions, point) {
|
||||||
|
@ -1201,6 +1213,9 @@ PropertiesTool = function(opts) {
|
||||||
data.properties.rotation = Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z);
|
data.properties.rotation = Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z);
|
||||||
}
|
}
|
||||||
Entities.editEntity(selectionManager.selections[0], data.properties);
|
Entities.editEntity(selectionManager.selections[0], data.properties);
|
||||||
|
if (data.properties.name != undefined) {
|
||||||
|
entityListTool.sendUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pushCommandForSelections();
|
pushCommandForSelections();
|
||||||
selectionManager._update();
|
selectionManager._update();
|
||||||
|
|
213
examples/grab.js
213
examples/grab.js
|
@ -5,17 +5,13 @@ var deltaMouse = {
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
var entityProps;
|
var entityProps;
|
||||||
var box, box2, ground;
|
var targetPosition;
|
||||||
var baseMoveFactor = .001;
|
|
||||||
var finalMoveMultiplier;
|
|
||||||
var avatarEntityDistance;
|
|
||||||
var camYaw, dv;
|
|
||||||
var prevPosition;
|
|
||||||
var newPosition;
|
|
||||||
var flingVelocity;
|
|
||||||
var flingMultiplier = 10;
|
|
||||||
var moveUpDown = false;
|
var moveUpDown = false;
|
||||||
var savedGravity;
|
|
||||||
|
var currentPosition, currentVelocity;
|
||||||
|
|
||||||
|
var grabSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/CloseClamp.wav");
|
||||||
|
var releaseSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/ReleaseClamp.wav");
|
||||||
|
|
||||||
var DROP_DISTANCE = 5.0;
|
var DROP_DISTANCE = 5.0;
|
||||||
var DROP_COLOR = {
|
var DROP_COLOR = {
|
||||||
|
@ -23,14 +19,9 @@ var DROP_COLOR = {
|
||||||
green: 200,
|
green: 200,
|
||||||
blue: 200
|
blue: 200
|
||||||
};
|
};
|
||||||
var DROP_WIDTH = 4;
|
var DROP_WIDTH = 2;
|
||||||
|
|
||||||
|
|
||||||
var autoBox = false;
|
|
||||||
if (autoBox) {
|
|
||||||
setUpTestObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
var dropLine = Overlays.addOverlay("line3d", {
|
var dropLine = Overlays.addOverlay("line3d", {
|
||||||
start: {
|
start: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -50,89 +41,80 @@ var dropLine = Overlays.addOverlay("line3d", {
|
||||||
|
|
||||||
|
|
||||||
function mousePressEvent(event) {
|
function mousePressEvent(event) {
|
||||||
|
if (!event.isLeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var pickRay = Camera.computePickRay(event.x, event.y);
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
var intersection = Entities.findRayIntersection(pickRay);
|
var intersection = Entities.findRayIntersection(pickRay);
|
||||||
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
if (intersection.intersects && intersection.properties.collisionsWillMove) {
|
||||||
grabbedEntity = intersection.entityID;
|
grabbedEntity = intersection.entityID;
|
||||||
var props = Entities.getEntityProperties(grabbedEntity)
|
var props = Entities.getEntityProperties(grabbedEntity)
|
||||||
prevPosition = props.position;
|
|
||||||
isGrabbing = true;
|
isGrabbing = true;
|
||||||
savedGravity = props.gravity;
|
targetPosition = props.position;
|
||||||
Overlays.editOverlay(dropLine, {
|
currentPosition = props.position;
|
||||||
visible: true
|
currentVelocity = props.velocity;
|
||||||
|
updateDropLine(targetPosition);
|
||||||
|
Audio.playSound(grabSound, {
|
||||||
|
position: props.position,
|
||||||
|
volume: 0.4
|
||||||
});
|
});
|
||||||
Entities.editEntity(grabbedEntity, {
|
|
||||||
gravity: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 0
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//We need to store entity's current gravity, and then disable it while we move
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDropLine(position) {
|
||||||
|
Overlays.editOverlay(dropLine, {
|
||||||
|
visible: true,
|
||||||
|
start: position,
|
||||||
|
end: Vec3.sum(position, {
|
||||||
|
x: 0,
|
||||||
|
y: -DROP_DISTANCE,
|
||||||
|
z: 0
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function mouseReleaseEvent() {
|
function mouseReleaseEvent() {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
flingObject();
|
isGrabbing = false;
|
||||||
Entities.editEntity(grabbedEntity, {
|
Overlays.editOverlay(dropLine, {
|
||||||
gravity: savedGravity
|
visible: false
|
||||||
});
|
});
|
||||||
|
targetPosition = null;
|
||||||
|
Audio.playSound(grabSound, {
|
||||||
|
position: entityProps.position,
|
||||||
|
volume: 0.25
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
isGrabbing = false;
|
|
||||||
Overlays.editOverlay(dropLine, {
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function flingObject() {
|
|
||||||
//calculate velocity to give object base on current and previous position
|
|
||||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
|
||||||
|
|
||||||
flingVelocity = Vec3.subtract(entityProps.position, prevPosition);
|
|
||||||
flingVelocity = Vec3.multiply(flingMultiplier, flingVelocity);
|
|
||||||
flingVelocity.y = 0;
|
|
||||||
Entities.editEntity(grabbedEntity, {
|
|
||||||
velocity: flingVelocity
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mouseMoveEvent(event) {
|
function mouseMoveEvent(event) {
|
||||||
if (isGrabbing) {
|
if (isGrabbing) {
|
||||||
entityProps = Entities.getEntityProperties(grabbedEntity);
|
|
||||||
prevPosition = entityProps.position;
|
|
||||||
avatarEntityDistance = Vec3.distance(MyAvatar.position, entityProps.position);
|
|
||||||
finalMoveMultiplier = baseMoveFactor * Math.pow(avatarEntityDistance, 1.5);
|
|
||||||
deltaMouse.x = event.x - prevMouse.x;
|
deltaMouse.x = event.x - prevMouse.x;
|
||||||
if (!moveUpDown) {
|
if (!moveUpDown) {
|
||||||
deltaMouse.z = event.y - prevMouse.y;
|
deltaMouse.z = event.y - prevMouse.y;
|
||||||
|
deltaMouse.y = 0;
|
||||||
} else {
|
} else {
|
||||||
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
deltaMouse.y = (event.y - prevMouse.y) * -1;
|
||||||
|
deltaMouse.z = 0;
|
||||||
}
|
}
|
||||||
finalMoveMultiplier = baseMoveFactor * Math.pow(avatarEntityDistance, 1.5);
|
// Update the target position by the amount the mouse moved
|
||||||
deltaMouse = Vec3.multiply(deltaMouse, finalMoveMultiplier);
|
var camYaw = Quat.safeEulerAngles(Camera.getOrientation()).y;
|
||||||
camYaw = Quat.safeEulerAngles(Camera.getOrientation()).y;
|
var dPosition = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), deltaMouse);
|
||||||
dv = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), deltaMouse);
|
// Adjust target position for the object by the mouse move
|
||||||
newPosition = Vec3.sum(entityProps.position, dv);
|
var avatarEntityDistance = Vec3.distance(Camera.getPosition(), currentPosition);
|
||||||
Entities.editEntity(grabbedEntity, {
|
// Scale distance we want to move by the distance from the camera to the grabbed object
|
||||||
position: newPosition
|
// TODO: Correct SCREEN_TO_METERS to be correct for the actual FOV, resolution
|
||||||
});
|
var SCREEN_TO_METERS = 0.001;
|
||||||
Overlays.editOverlay(dropLine, {
|
targetPosition = Vec3.sum(targetPosition, Vec3.multiply(dPosition, avatarEntityDistance * SCREEN_TO_METERS));
|
||||||
start: newPosition,
|
|
||||||
end: Vec3.sum(newPosition, {
|
|
||||||
x: 0,
|
|
||||||
y: -DROP_DISTANCE,
|
|
||||||
z: 0
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
prevMouse.x = event.x;
|
prevMouse.x = event.x;
|
||||||
prevMouse.y = event.y;
|
prevMouse.y = event.y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function keyReleaseEvent(event) {
|
function keyReleaseEvent(event) {
|
||||||
if (event.text === "SHIFT") {
|
if (event.text === "SHIFT") {
|
||||||
moveUpDown = false;
|
moveUpDown = false;
|
||||||
|
@ -145,74 +127,34 @@ function keyPressEvent(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanup() {
|
function update(deltaTime) {
|
||||||
Entities.deleteEntity(box);
|
if (isGrabbing) {
|
||||||
Entities.deleteEntity(box2);
|
|
||||||
Entities.deleteEntity(ground);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUpTestObjects() {
|
entityProps = Entities.getEntityProperties(grabbedEntity);
|
||||||
var distance = 4;
|
currentPosition = entityProps.position;
|
||||||
box = Entities.addEntity({
|
currentVelocity = entityProps.velocity;
|
||||||
type: 'Box',
|
|
||||||
position: Vec3.sum(MyAvatar.position, Vec3.multiply(distance, Quat.getFront(Camera.getOrientation()))),
|
|
||||||
dimensions: {
|
|
||||||
x: .5,
|
|
||||||
y: .5,
|
|
||||||
z: .5
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
red: 200,
|
|
||||||
green: 50,
|
|
||||||
blue: 192
|
|
||||||
},
|
|
||||||
collisionsWillMove: true,
|
|
||||||
gravity: {
|
|
||||||
x: 0,
|
|
||||||
y: -1,
|
|
||||||
z: 0
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
box2 = Entities.addEntity({
|
var dPosition = Vec3.subtract(targetPosition, currentPosition);
|
||||||
type: 'Box',
|
var CLOSE_ENOUGH = 0.001;
|
||||||
position: Vec3.sum(MyAvatar.position, Vec3.multiply(distance + 1, Quat.getFront(Camera.getOrientation()))),
|
if (Vec3.length(dPosition) > CLOSE_ENOUGH) {
|
||||||
dimensions: {
|
// compute current velocity in the direction we want to move
|
||||||
x: .5,
|
var velocityTowardTarget = Vec3.dot(currentVelocity, Vec3.normalize(dPosition));
|
||||||
y: .5,
|
// compute the speed we would like to be going toward the target position
|
||||||
z: .5
|
var SPRING_RATE = 0.35;
|
||||||
},
|
var DAMPING_RATE = 0.55;
|
||||||
color: {
|
var desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE);
|
||||||
red: 200,
|
// compute how much we want to add to the existing velocity
|
||||||
green: 50,
|
var addedVelocity = Vec3.subtract(desiredVelocity, velocityTowardTarget);
|
||||||
blue: 192
|
var newVelocity = Vec3.sum(currentVelocity, addedVelocity);
|
||||||
},
|
// Add Damping
|
||||||
collisionsWillMove: true,
|
newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE));
|
||||||
gravity: {
|
// Update entity
|
||||||
x: 0,
|
Entities.editEntity(grabbedEntity, {
|
||||||
y: -1,
|
velocity: newVelocity
|
||||||
z: 0
|
})
|
||||||
}
|
}
|
||||||
});
|
updateDropLine(currentPosition);
|
||||||
|
}
|
||||||
ground = Entities.addEntity({
|
|
||||||
type: 'Box',
|
|
||||||
position: {
|
|
||||||
x: MyAvatar.position.x,
|
|
||||||
y: MyAvatar.position.y - 5,
|
|
||||||
z: MyAvatar.position.z
|
|
||||||
},
|
|
||||||
dimensions: {
|
|
||||||
x: 100,
|
|
||||||
y: 2,
|
|
||||||
z: 100
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
red: 20,
|
|
||||||
green: 200,
|
|
||||||
blue: 50
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
|
@ -220,4 +162,5 @@ Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
Controller.keyPressEvent.connect(keyPressEvent);
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||||
Script.scriptEnding.connect(cleanup);
|
Script.update.connect(update);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
var DESC_STRING = ' ▴';
|
var DESC_STRING = ' ▴';
|
||||||
|
|
||||||
function loaded() {
|
function loaded() {
|
||||||
entityList = new List('entity-list', { valueNames: ['type', 'url']});
|
entityList = new List('entity-list', { valueNames: ['name', 'type', 'url']});
|
||||||
entityList.clear();
|
entityList.clear();
|
||||||
elEntityTable = document.getElementById("entity-table");
|
elEntityTable = document.getElementById("entity-table");
|
||||||
elEntityTableBody = document.getElementById("entity-table-body");
|
elEntityTableBody = document.getElementById("entity-table-body");
|
||||||
|
@ -22,6 +22,9 @@
|
||||||
elTeleport = document.getElementById("teleport");
|
elTeleport = document.getElementById("teleport");
|
||||||
elNoEntitiesMessage = document.getElementById("no-entities");
|
elNoEntitiesMessage = document.getElementById("no-entities");
|
||||||
|
|
||||||
|
document.getElementById("entity-name").onclick = function() {
|
||||||
|
setSortColumn('name');
|
||||||
|
};
|
||||||
document.getElementById("entity-type").onclick = function() {
|
document.getElementById("entity-type").onclick = function() {
|
||||||
setSortColumn('type');
|
setSortColumn('type');
|
||||||
};
|
};
|
||||||
|
@ -56,31 +59,34 @@
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEntity(id, type, url) {
|
function addEntity(id, name, type, url) {
|
||||||
if (entities[id] === undefined) {
|
if (entities[id] === undefined) {
|
||||||
var urlParts = url.split('/');
|
var urlParts = url.split('/');
|
||||||
var filename = urlParts[urlParts.length - 1];
|
var filename = urlParts[urlParts.length - 1];
|
||||||
|
|
||||||
entityList.add([{ id: id, type: type, url: filename }], function(items) {
|
entityList.add([{ id: id, name: name, type: type, url: filename }], function(items) {
|
||||||
var el = items[0].elm;
|
var el = items[0].elm;
|
||||||
var id = items[0]._values.id;
|
var id = items[0]._values.id;
|
||||||
entities[id] = {
|
entities[id] = {
|
||||||
id: id,
|
id: id,
|
||||||
name: id,
|
name: name,
|
||||||
el: el,
|
el: el,
|
||||||
|
item: items[0],
|
||||||
};
|
};
|
||||||
el.setAttribute('id', 'entity_' + id);
|
el.setAttribute('id', 'entity_' + id);
|
||||||
el.setAttribute('title', url);
|
el.setAttribute('title', url);
|
||||||
el.dataset.entityId = id;
|
el.dataset.entityId = id;
|
||||||
el.onclick = onRowClicked;
|
el.onclick = onRowClicked;
|
||||||
el.ondblclick = onRowDoubleClicked;
|
el.ondblclick = onRowDoubleClicked;
|
||||||
el.innerHTML
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (refreshEntityListTimer) {
|
if (refreshEntityListTimer) {
|
||||||
clearTimeout(refreshEntityListTimer);
|
clearTimeout(refreshEntityListTimer);
|
||||||
}
|
}
|
||||||
refreshEntityListTimer = setTimeout(refreshEntityListObject, 50);
|
refreshEntityListTimer = setTimeout(refreshEntityListObject, 50);
|
||||||
|
} else {
|
||||||
|
var item = entities[id].item;
|
||||||
|
item.values({ name: name, url: url });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +96,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var elSortOrder = {
|
var elSortOrder = {
|
||||||
|
name: document.querySelector('#entity-name .sort-order'),
|
||||||
type: document.querySelector('#entity-type .sort-order'),
|
type: document.querySelector('#entity-type .sort-order'),
|
||||||
url: document.querySelector('#entity-url .sort-order'),
|
url: document.querySelector('#entity-url .sort-order'),
|
||||||
}
|
}
|
||||||
|
@ -164,7 +171,7 @@
|
||||||
elNoEntitiesMessage.style.display = "none";
|
elNoEntitiesMessage.style.display = "none";
|
||||||
for (var i = 0; i < newEntities.length; i++) {
|
for (var i = 0; i < newEntities.length; i++) {
|
||||||
var id = newEntities[i].id;
|
var id = newEntities[i].id;
|
||||||
addEntity(id, newEntities[i].type, newEntities[i].url);
|
addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url);
|
||||||
}
|
}
|
||||||
updateSelectedEntities(data.selectedIDs);
|
updateSelectedEntities(data.selectedIDs);
|
||||||
}
|
}
|
||||||
|
@ -190,6 +197,7 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th id="entity-type" data-sort="type">Type <span class="sort-order" style="display: inline"> ▾</span></th>
|
<th id="entity-type" data-sort="type">Type <span class="sort-order" style="display: inline"> ▾</span></th>
|
||||||
|
<th id="entity-name" data-sort="type">Name <span class="sort-order" style="display: inline"> ▾</span></th>
|
||||||
<th id="entity-url" data-sort="url">URL <span class="sort-order" style="display: none"> ▾</span></th>
|
<th id="entity-url" data-sort="url">URL <span class="sort-order" style="display: none"> ▾</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -197,6 +205,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td class="id" style="display: none">Type</td>
|
<td class="id" style="display: none">Type</td>
|
||||||
<td class="type">Type</td>
|
<td class="type">Type</td>
|
||||||
|
<td class="name">Name</td>
|
||||||
<td class="url"><div class='outer'><div class='inner'>URL</div></div></td>
|
<td class="url"><div class='outer'><div class='inner'>URL</div></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
var allSections = [];
|
var allSections = [];
|
||||||
var elID = document.getElementById("property-id");
|
var elID = document.getElementById("property-id");
|
||||||
var elType = document.getElementById("property-type");
|
var elType = document.getElementById("property-type");
|
||||||
|
var elName = document.getElementById("property-name");
|
||||||
var elLocked = document.getElementById("property-locked");
|
var elLocked = document.getElementById("property-locked");
|
||||||
var elVisible = document.getElementById("property-visible");
|
var elVisible = document.getElementById("property-visible");
|
||||||
var elPositionX = document.getElementById("property-pos-x");
|
var elPositionX = document.getElementById("property-pos-x");
|
||||||
|
@ -146,11 +147,10 @@
|
||||||
var elScriptURL = document.getElementById("property-script-url");
|
var elScriptURL = document.getElementById("property-script-url");
|
||||||
var elUserData = document.getElementById("property-user-data");
|
var elUserData = document.getElementById("property-user-data");
|
||||||
|
|
||||||
var elBoxSections = document.querySelectorAll(".box-section");
|
var elColorSection = document.getElementById("color-section");
|
||||||
allSections.push(elBoxSections);
|
var elColorRed = document.getElementById("property-color-red");
|
||||||
var elBoxColorRed = document.getElementById("property-box-red");
|
var elColorGreen = document.getElementById("property-color-green");
|
||||||
var elBoxColorGreen = document.getElementById("property-box-green");
|
var elColorBlue = document.getElementById("property-color-blue");
|
||||||
var elBoxColorBlue = document.getElementById("property-box-blue");
|
|
||||||
|
|
||||||
var elLightSections = document.querySelectorAll(".light-section");
|
var elLightSections = document.querySelectorAll(".light-section");
|
||||||
allSections.push(elLightSections);
|
allSections.push(elLightSections);
|
||||||
|
@ -262,6 +262,8 @@
|
||||||
enableChildren(document.getElementById("properties-list"), 'input');
|
enableChildren(document.getElementById("properties-list"), 'input');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elName.value = properties.name;
|
||||||
|
|
||||||
elVisible.checked = properties.visible;
|
elVisible.checked = properties.visible;
|
||||||
|
|
||||||
elPositionX.value = properties.position.x.toFixed(2);
|
elPositionX.value = properties.position.x.toFixed(2);
|
||||||
|
@ -310,16 +312,17 @@
|
||||||
allSections[i][j].style.display = 'none';
|
allSections[i][j].style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.type == "Box") {
|
|
||||||
for (var i = 0; i < elBoxSections.length; i++) {
|
|
||||||
elBoxSections[i].style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
elBoxColorRed.value = properties.color.red;
|
if (properties.type == "Box" || properties.type == "Sphere") {
|
||||||
elBoxColorGreen.value = properties.color.green;
|
elColorSection.style.display = 'block';
|
||||||
elBoxColorBlue.value = properties.color.blue;
|
elColorRed.value = properties.color.red;
|
||||||
} else if (properties.type == "Model") {
|
elColorGreen.value = properties.color.green;
|
||||||
|
elColorBlue.value = properties.color.blue;
|
||||||
|
} else {
|
||||||
|
elColorSection.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.type == "Model") {
|
||||||
for (var i = 0; i < elModelSections.length; i++) {
|
for (var i = 0; i < elModelSections.length; i++) {
|
||||||
elModelSections[i].style.display = 'block';
|
elModelSections[i].style.display = 'block';
|
||||||
}
|
}
|
||||||
|
@ -395,6 +398,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
|
||||||
|
elName.addEventListener('change', createEmitTextPropertyUpdateFunction('name'));
|
||||||
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
|
||||||
|
|
||||||
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||||
|
@ -454,11 +458,11 @@
|
||||||
elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script'));
|
elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script'));
|
||||||
elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData'));
|
elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData'));
|
||||||
|
|
||||||
var boxColorChangeFunction = createEmitColorPropertyUpdateFunction(
|
var colorChangeFunction = createEmitColorPropertyUpdateFunction(
|
||||||
'color', elBoxColorRed, elBoxColorGreen, elBoxColorBlue);
|
'color', elColorRed, elColorGreen, elColorBlue);
|
||||||
elBoxColorRed.addEventListener('change', boxColorChangeFunction);
|
elColorRed.addEventListener('change', colorChangeFunction);
|
||||||
elBoxColorGreen.addEventListener('change', boxColorChangeFunction);
|
elColorGreen.addEventListener('change', colorChangeFunction);
|
||||||
elBoxColorBlue.addEventListener('change', boxColorChangeFunction);
|
elColorBlue.addEventListener('change', colorChangeFunction);
|
||||||
|
|
||||||
elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight'));
|
elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight'));
|
||||||
|
|
||||||
|
@ -590,6 +594,12 @@
|
||||||
<label id="property-id" class="selectable"></label>
|
<label id="property-id" class="selectable"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="property">
|
||||||
|
<span class="label" style="float: left; margin-right: 6px">Name</span>
|
||||||
|
<div class="value" style="overflow: hidden;">
|
||||||
|
<input type="text" id="property-name"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="property">
|
<div class="property">
|
||||||
<span class="label">Locked</span>
|
<span class="label">Locked</span>
|
||||||
<span class="value">
|
<span class="value">
|
||||||
|
@ -743,12 +753,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="box-section property">
|
<div id="color-section" class="property">
|
||||||
<div class="label">Color</div>
|
<div class="label">Color</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<div class="input-area">R <input class="coord" type='number' id="property-box-red"></input></div>
|
<div class="input-area">R <input class="coord" type='number' id="property-color-red"></input></div>
|
||||||
<div class="input-area">G <input class="coord" type='number' id="property-box-green"></input></div>
|
<div class="input-area">G <input class="coord" type='number' id="property-color-green"></input></div>
|
||||||
<div class="input-area">B <input class="coord" type='number' id="property-box-blue"></input></div>
|
<div class="input-area">B <input class="coord" type='number' id="property-color-blue"></input></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -301,3 +301,7 @@ input[type="number"]::-webkit-inner-spin-button:hover,
|
||||||
input[type="number"]::-webkit-inner-spin-button:active{
|
input[type="number"]::-webkit-inner-spin-button:active{
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input#property-name {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ EntityListTool = function(opts) {
|
||||||
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
webView.eventBridge.emitScriptEvent(JSON.stringify(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
function sendUpdate() {
|
that.sendUpdate = function() {
|
||||||
var entities = [];
|
var entities = [];
|
||||||
var ids = Entities.findEntities(MyAvatar.position, 100);
|
var ids = Entities.findEntities(MyAvatar.position, 100);
|
||||||
for (var i = 0; i < ids.length; i++) {
|
for (var i = 0; i < ids.length; i++) {
|
||||||
|
@ -39,6 +39,7 @@ EntityListTool = function(opts) {
|
||||||
var properties = Entities.getEntityProperties(id);
|
var properties = Entities.getEntityProperties(id);
|
||||||
entities.push({
|
entities.push({
|
||||||
id: id.id,
|
id: id.id,
|
||||||
|
name: properties.name,
|
||||||
type: properties.type,
|
type: properties.type,
|
||||||
url: properties.type == "Model" ? properties.modelURL : "",
|
url: properties.type == "Model" ? properties.modelURL : "",
|
||||||
});
|
});
|
||||||
|
@ -76,7 +77,7 @@ EntityListTool = function(opts) {
|
||||||
Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
|
Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
|
||||||
}
|
}
|
||||||
} else if (data.type == "refresh") {
|
} else if (data.type == "refresh") {
|
||||||
sendUpdate();
|
that.sendUpdate();
|
||||||
} else if (data.type == "teleport") {
|
} else if (data.type == "teleport") {
|
||||||
if (selectionManager.hasSelection()) {
|
if (selectionManager.hasSelection()) {
|
||||||
MyAvatar.position = selectionManager.worldPosition;
|
MyAvatar.position = selectionManager.worldPosition;
|
||||||
|
|
63
examples/lotsoBlocks.js
Normal file
63
examples/lotsoBlocks.js
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
var NUM_BLOCKS = 200;
|
||||||
|
var size;
|
||||||
|
var SPAWN_RANGE = 10;
|
||||||
|
var boxes = [];
|
||||||
|
var basePosition, avatarRot;
|
||||||
|
var isAssignmentScript = false;
|
||||||
|
if(isAssignmentScript){
|
||||||
|
basePosition = {x: 8000, y: 8000, z: 8000};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
avatarRot = Quat.fromPitchYawRollDegrees(0, MyAvatar.bodyYaw, 0.0);
|
||||||
|
basePosition = Vec3.sum(MyAvatar.position, Vec3.multiply(SPAWN_RANGE * 3, Quat.getFront(avatarRot)));
|
||||||
|
}
|
||||||
|
basePosition.y -= SPAWN_RANGE;
|
||||||
|
|
||||||
|
var ground = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
modelURL: "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx",
|
||||||
|
dimensions: {
|
||||||
|
x: 100,
|
||||||
|
y: 2,
|
||||||
|
z: 100
|
||||||
|
},
|
||||||
|
position: basePosition,
|
||||||
|
shapeType: 'box'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
basePosition.y += SPAWN_RANGE + 2;
|
||||||
|
for (var i = 0; i < NUM_BLOCKS; i++) {
|
||||||
|
size = randFloat(-.2, 0.7);
|
||||||
|
boxes.push(Entities.addEntity({
|
||||||
|
type: 'Box',
|
||||||
|
dimensions: {
|
||||||
|
x: size,
|
||||||
|
y: size,
|
||||||
|
z: size
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
x: basePosition.x + randFloat(-SPAWN_RANGE, SPAWN_RANGE),
|
||||||
|
y: basePosition.y - randFloat(-SPAWN_RANGE, SPAWN_RANGE),
|
||||||
|
z: basePosition.z + randFloat(-SPAWN_RANGE, SPAWN_RANGE)
|
||||||
|
},
|
||||||
|
color: {red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255},
|
||||||
|
collisionsWillMove: true,
|
||||||
|
gravity: {x: 0, y: 0, z: 0}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
Entities.deleteEntity(ground);
|
||||||
|
boxes.forEach(function(box){
|
||||||
|
Entities.deleteEntity(box);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
|
||||||
|
function randFloat(low, high) {
|
||||||
|
return low + Math.random() * ( high - low );
|
||||||
|
}
|
|
@ -66,7 +66,7 @@ DialogBase {
|
||||||
|
|
||||||
// our close function performs the same way as the OffscreenUI class:
|
// our close function performs the same way as the OffscreenUI class:
|
||||||
// don't do anything but manipulate the enabled flag and let the other
|
// don't do anything but manipulate the enabled flag and let the other
|
||||||
// mechanisms decide if the window should be destoryed after the close
|
// mechanisms decide if the window should be destroyed after the close
|
||||||
// animation completes
|
// animation completes
|
||||||
function close() {
|
function close() {
|
||||||
if (destroyOnCloseButton) {
|
if (destroyOnCloseButton) {
|
||||||
|
|
|
@ -1152,7 +1152,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
case Qt::Key_A:
|
case Qt::Key_A:
|
||||||
if (isShifted) {
|
if (isShifted) {
|
||||||
Menu::getInstance()->triggerOption(MenuOption::Atmosphere);
|
Menu::getInstance()->triggerOption(MenuOption::Atmosphere);
|
||||||
} else {
|
} else if (!isMeta) {
|
||||||
_myAvatar->setDriveKeys(ROT_LEFT, 1.0f);
|
_myAvatar->setDriveKeys(ROT_LEFT, 1.0f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,16 +65,16 @@ static const int DDE_TO_FACESHIFT_MAPPING[] = {
|
||||||
// The DDE coefficients, overall, range from -0.2 to 1.5 or so. However, individual coefficients typically vary much
|
// The DDE coefficients, overall, range from -0.2 to 1.5 or so. However, individual coefficients typically vary much
|
||||||
// less than this.
|
// less than this.
|
||||||
static const float DDE_COEFFICIENT_SCALES[] = {
|
static const float DDE_COEFFICIENT_SCALES[] = {
|
||||||
4.0f, // EyeBlink_L
|
1.0f, // EyeBlink_L
|
||||||
4.0f, // EyeBlink_R
|
1.0f, // EyeBlink_R
|
||||||
1.0f, // EyeSquint_L
|
1.0f, // EyeSquint_L
|
||||||
1.0f, // EyeSquint_R
|
1.0f, // EyeSquint_R
|
||||||
1.0f, // EyeDown_L
|
1.0f, // EyeDown_L
|
||||||
1.0f, // EyeDown_R
|
1.0f, // EyeDown_R
|
||||||
1.0f, // EyeIn_L
|
1.0f, // EyeIn_L
|
||||||
1.0f, // EyeIn_R
|
1.0f, // EyeIn_R
|
||||||
4.0f, // EyeOpen_L
|
1.0f, // EyeOpen_L
|
||||||
4.0f, // EyeOpen_R
|
1.0f, // EyeOpen_R
|
||||||
1.0f, // EyeOut_L
|
1.0f, // EyeOut_L
|
||||||
1.0f, // EyeOut_R
|
1.0f, // EyeOut_R
|
||||||
1.0f, // EyeUp_L
|
1.0f, // EyeUp_L
|
||||||
|
@ -136,6 +136,16 @@ struct Packet {
|
||||||
|
|
||||||
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
||||||
|
|
||||||
|
const int FPS_TIMER_DELAY = 2000; // ms
|
||||||
|
const int FPS_TIMER_DURATION = 2000; // ms
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_lastEyeBlinks' will be default initialized
|
||||||
|
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_filteredEyeBlinks' will be default initialized
|
||||||
|
// warning C4351: new behavior: elements of array 'DdeFaceTracker::_lastEyeCoefficients' will be default initialized
|
||||||
|
#pragma warning(disable:4351)
|
||||||
|
#endif
|
||||||
|
|
||||||
DdeFaceTracker::DdeFaceTracker() :
|
DdeFaceTracker::DdeFaceTracker() :
|
||||||
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
||||||
{
|
{
|
||||||
|
@ -166,24 +176,35 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
||||||
_averageMessageTime(STARTING_DDE_MESSAGE_TIME),
|
_averageMessageTime(STARTING_DDE_MESSAGE_TIME),
|
||||||
_lastHeadTranslation(glm::vec3(0.0f)),
|
_lastHeadTranslation(glm::vec3(0.0f)),
|
||||||
_filteredHeadTranslation(glm::vec3(0.0f)),
|
_filteredHeadTranslation(glm::vec3(0.0f)),
|
||||||
_lastLeftEyeBlink(0.0f),
|
_lastBrowUp(0.0f),
|
||||||
_filteredLeftEyeBlink(0.0f),
|
_filteredBrowUp(0.0f),
|
||||||
_lastRightEyeBlink(0.0f),
|
_lastEyeBlinks(),
|
||||||
_filteredRightEyeBlink(0.0f)
|
_filteredEyeBlinks(),
|
||||||
|
_lastEyeCoefficients(),
|
||||||
|
_isCalculatingFPS(false),
|
||||||
|
_frameCount(0)
|
||||||
{
|
{
|
||||||
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||||
|
|
||||||
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||||
|
|
||||||
|
_eyeStates[0] = EYE_OPEN;
|
||||||
|
_eyeStates[1] = EYE_OPEN;
|
||||||
|
|
||||||
connect(&_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
|
connect(&_udpSocket, SIGNAL(readyRead()), SLOT(readPendingDatagrams()));
|
||||||
connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketErrorOccurred(QAbstractSocket::SocketError)));
|
connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketErrorOccurred(QAbstractSocket::SocketError)));
|
||||||
connect(&_udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
connect(&_udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||||
|
SLOT(socketStateChanged(QAbstractSocket::SocketState)));
|
||||||
}
|
}
|
||||||
|
|
||||||
DdeFaceTracker::~DdeFaceTracker() {
|
DdeFaceTracker::~DdeFaceTracker() {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(default:4351)
|
||||||
|
#endif
|
||||||
|
|
||||||
void DdeFaceTracker::setEnabled(bool enabled) {
|
void DdeFaceTracker::setEnabled(bool enabled) {
|
||||||
#ifdef HAVE_DDE
|
#ifdef HAVE_DDE
|
||||||
// isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket.
|
// isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket.
|
||||||
|
@ -350,49 +371,25 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate DDE coefficients to Faceshift compatible coefficients
|
// Translate DDE coefficients to Faceshift compatible coefficients
|
||||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
for (int i = 0; i < NUM_EXPRESSIONS; i++) {
|
||||||
_coefficients[DDE_TO_FACESHIFT_MAPPING[i]] = packet.expressions[i];
|
_coefficients[DDE_TO_FACESHIFT_MAPPING[i]] = packet.expressions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
|
||||||
static const float RELAXED_EYE_VALUE = 0.1f;
|
|
||||||
float leftEye = _coefficients[_leftBlinkIndex];
|
|
||||||
float rightEye = _coefficients[_rightBlinkIndex];
|
|
||||||
if (isFiltering) {
|
|
||||||
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
|
|
||||||
|
|
||||||
float velocity = fabs(leftEye - _lastLeftEyeBlink) / _averageMessageTime;
|
|
||||||
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
|
||||||
_filteredLeftEyeBlink = velocityFilter * leftEye + (1.0f - velocityFilter) * _filteredLeftEyeBlink;
|
|
||||||
_lastLeftEyeBlink = leftEye;
|
|
||||||
leftEye = _filteredLeftEyeBlink;
|
|
||||||
|
|
||||||
velocity = fabs(rightEye - _lastRightEyeBlink) / _averageMessageTime;
|
|
||||||
velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
|
||||||
_filteredRightEyeBlink = velocityFilter * rightEye + (1.0f - velocityFilter) * _filteredRightEyeBlink;
|
|
||||||
_lastRightEyeBlink = rightEye;
|
|
||||||
rightEye = _filteredRightEyeBlink;
|
|
||||||
}
|
|
||||||
if (leftEye > RELAXED_EYE_VALUE) {
|
|
||||||
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
|
|
||||||
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
|
||||||
} else {
|
|
||||||
_coefficients[_leftBlinkIndex] = 0.0f;
|
|
||||||
_coefficients[_leftEyeOpenIndex] = RELAXED_EYE_VALUE - leftEye;
|
|
||||||
}
|
|
||||||
if (rightEye > RELAXED_EYE_VALUE) {
|
|
||||||
_coefficients[_rightBlinkIndex] = rightEye - RELAXED_EYE_VALUE;
|
|
||||||
_coefficients[_rightEyeOpenIndex] = 0.0f;
|
|
||||||
} else {
|
|
||||||
_coefficients[_rightBlinkIndex] = 0.0f;
|
|
||||||
_coefficients[_rightEyeOpenIndex] = RELAXED_EYE_VALUE - rightEye;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use BrowsU_C to control both brows' up and down
|
// Use BrowsU_C to control both brows' up and down
|
||||||
_coefficients[_browDownLeftIndex] = -_coefficients[_browUpCenterIndex];
|
float browUp = _coefficients[_browUpCenterIndex];
|
||||||
_coefficients[_browDownRightIndex] = -_coefficients[_browUpCenterIndex];
|
if (isFiltering) {
|
||||||
_coefficients[_browUpLeftIndex] = _coefficients[_browUpCenterIndex];
|
const float BROW_VELOCITY_FILTER_STRENGTH = 0.75f;
|
||||||
_coefficients[_browUpRightIndex] = _coefficients[_browUpCenterIndex];
|
float velocity = fabs(browUp - _lastBrowUp) / _averageMessageTime;
|
||||||
|
float velocityFilter = glm::clamp(velocity * BROW_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||||
|
_filteredBrowUp = velocityFilter * browUp + (1.0f - velocityFilter) * _filteredBrowUp;
|
||||||
|
_lastBrowUp = browUp;
|
||||||
|
browUp = _filteredBrowUp;
|
||||||
|
_coefficients[_browUpCenterIndex] = browUp;
|
||||||
|
}
|
||||||
|
_coefficients[_browUpLeftIndex] = browUp;
|
||||||
|
_coefficients[_browUpRightIndex] = browUp;
|
||||||
|
_coefficients[_browDownLeftIndex] = -browUp;
|
||||||
|
_coefficients[_browDownRightIndex] = -browUp;
|
||||||
|
|
||||||
// Offset jaw open coefficient
|
// Offset jaw open coefficient
|
||||||
static const float JAW_OPEN_THRESHOLD = 0.16f;
|
static const float JAW_OPEN_THRESHOLD = 0.16f;
|
||||||
|
@ -403,9 +400,91 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||||
_coefficients[_mouthSmileLeftIndex] = _coefficients[_mouthSmileLeftIndex] - SMILE_THRESHOLD;
|
_coefficients[_mouthSmileLeftIndex] = _coefficients[_mouthSmileLeftIndex] - SMILE_THRESHOLD;
|
||||||
_coefficients[_mouthSmileRightIndex] = _coefficients[_mouthSmileRightIndex] - SMILE_THRESHOLD;
|
_coefficients[_mouthSmileRightIndex] = _coefficients[_mouthSmileRightIndex] - SMILE_THRESHOLD;
|
||||||
|
|
||||||
|
// Velocity filter EyeBlink values
|
||||||
|
const float DDE_EYEBLINK_SCALE = 3.0f;
|
||||||
|
float eyeBlinks[] = { DDE_EYEBLINK_SCALE * _coefficients[_leftBlinkIndex], DDE_EYEBLINK_SCALE * _coefficients[_rightBlinkIndex] };
|
||||||
|
if (isFiltering) {
|
||||||
|
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
float velocity = fabs(eyeBlinks[i] - _lastEyeBlinks[i]) / _averageMessageTime;
|
||||||
|
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||||
|
_filteredEyeBlinks[i] = velocityFilter * eyeBlinks[i] + (1.0f - velocityFilter) * _filteredEyeBlinks[i];
|
||||||
|
_lastEyeBlinks[i] = eyeBlinks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finesse EyeBlink values
|
||||||
|
float eyeCoefficients[2];
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
// Scale EyeBlink values so that they can be used to control both EyeBlink and EyeOpen
|
||||||
|
// -ve values control EyeOpen; +ve values control EyeBlink
|
||||||
|
static const float EYE_CONTROL_THRESHOLD = 0.5f; // Resting eye value
|
||||||
|
eyeCoefficients[i] = (_filteredEyeBlinks[i] - EYE_CONTROL_THRESHOLD) / (1.0f - EYE_CONTROL_THRESHOLD);
|
||||||
|
|
||||||
|
// Change to closing or opening states
|
||||||
|
const float EYE_CONTROL_HYSTERISIS = 0.25f;
|
||||||
|
const float EYE_CLOSING_THRESHOLD = 0.95f;
|
||||||
|
const float EYE_OPENING_THRESHOLD = EYE_CONTROL_THRESHOLD - EYE_CONTROL_HYSTERISIS;
|
||||||
|
if ((_eyeStates[i] == EYE_OPEN || _eyeStates[i] == EYE_OPENING) && eyeCoefficients[i] > EYE_CLOSING_THRESHOLD) {
|
||||||
|
_eyeStates[i] = EYE_CLOSING;
|
||||||
|
} else if ((_eyeStates[i] == EYE_CLOSED || _eyeStates[i] == EYE_CLOSING)
|
||||||
|
&& eyeCoefficients[i] < EYE_OPENING_THRESHOLD) {
|
||||||
|
_eyeStates[i] = EYE_OPENING;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float EYELID_MOVEMENT_RATE = 10.0f; // units/second
|
||||||
|
const float EYE_OPEN_SCALE = 0.2f;
|
||||||
|
if (_eyeStates[i] == EYE_CLOSING) {
|
||||||
|
// Close eyelid until it's fully closed
|
||||||
|
float closingValue = _lastEyeCoefficients[i] + EYELID_MOVEMENT_RATE * _averageMessageTime;
|
||||||
|
if (closingValue >= 1.0) {
|
||||||
|
_eyeStates[i] = EYE_CLOSED;
|
||||||
|
eyeCoefficients[i] = 1.0;
|
||||||
|
} else {
|
||||||
|
eyeCoefficients[i] = closingValue;
|
||||||
|
}
|
||||||
|
} else if (_eyeStates[i] == EYE_OPENING) {
|
||||||
|
// Open eyelid until it meets the current adjusted value
|
||||||
|
float openingValue = _lastEyeCoefficients[i] - EYELID_MOVEMENT_RATE * _averageMessageTime;
|
||||||
|
if (openingValue < eyeCoefficients[i] * EYE_OPEN_SCALE) {
|
||||||
|
_eyeStates[i] = EYE_OPEN;
|
||||||
|
eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
|
||||||
|
} else {
|
||||||
|
eyeCoefficients[i] = openingValue;
|
||||||
|
}
|
||||||
|
} else if (_eyeStates[i] == EYE_OPEN) {
|
||||||
|
// Reduce eyelid movement
|
||||||
|
eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
|
||||||
|
} else if (_eyeStates[i] == EYE_CLOSED) {
|
||||||
|
// Keep eyelid fully closed
|
||||||
|
eyeCoefficients[i] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_eyeStates[0] == EYE_OPEN && _eyeStates[1] == EYE_OPEN) {
|
||||||
|
// Couple eyelids
|
||||||
|
eyeCoefficients[0] = eyeCoefficients[1] = (eyeCoefficients[0] + eyeCoefficients[0]) / 2.0f;
|
||||||
|
}
|
||||||
|
_lastEyeCoefficients[0] = eyeCoefficients[0];
|
||||||
|
_lastEyeCoefficients[1] = eyeCoefficients[1];
|
||||||
|
|
||||||
|
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||||
|
if (eyeCoefficients[0] > 0) {
|
||||||
|
_coefficients[_leftBlinkIndex] = eyeCoefficients[0];
|
||||||
|
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
||||||
|
} else {
|
||||||
|
_coefficients[_leftBlinkIndex] = 0.0f;
|
||||||
|
_coefficients[_leftEyeOpenIndex] = -eyeCoefficients[0];
|
||||||
|
}
|
||||||
|
if (eyeCoefficients[1] > 0) {
|
||||||
|
_coefficients[_rightBlinkIndex] = eyeCoefficients[1];
|
||||||
|
_coefficients[_rightEyeOpenIndex] = 0.0f;
|
||||||
|
} else {
|
||||||
|
_coefficients[_rightBlinkIndex] = 0.0f;
|
||||||
|
_coefficients[_rightEyeOpenIndex] = -eyeCoefficients[1];
|
||||||
|
}
|
||||||
|
|
||||||
// Scale all coefficients
|
// Scale all coefficients
|
||||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
for (int i = 0; i < NUM_EXPRESSIONS; i++) {
|
||||||
_blendshapeCoefficients[i]
|
_blendshapeCoefficients[i]
|
||||||
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
|
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,12 +103,26 @@ private:
|
||||||
|
|
||||||
quint64 _lastMessageReceived;
|
quint64 _lastMessageReceived;
|
||||||
float _averageMessageTime;
|
float _averageMessageTime;
|
||||||
|
|
||||||
glm::vec3 _lastHeadTranslation;
|
glm::vec3 _lastHeadTranslation;
|
||||||
glm::vec3 _filteredHeadTranslation;
|
glm::vec3 _filteredHeadTranslation;
|
||||||
float _lastLeftEyeBlink;
|
|
||||||
float _filteredLeftEyeBlink;
|
float _lastBrowUp;
|
||||||
float _lastRightEyeBlink;
|
float _filteredBrowUp;
|
||||||
float _filteredRightEyeBlink;
|
|
||||||
|
enum EyeState {
|
||||||
|
EYE_OPEN,
|
||||||
|
EYE_CLOSING,
|
||||||
|
EYE_CLOSED,
|
||||||
|
EYE_OPENING
|
||||||
|
};
|
||||||
|
EyeState _eyeStates[2];
|
||||||
|
float _lastEyeBlinks[2];
|
||||||
|
float _filteredEyeBlinks[2];
|
||||||
|
float _lastEyeCoefficients[2];
|
||||||
|
|
||||||
|
bool _isCalculatingFPS;
|
||||||
|
int _frameCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DdeFaceTracker_h
|
#endif // hifi_DdeFaceTracker_h
|
||||||
|
|
|
@ -35,6 +35,14 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
glm::vec4 cubeColor(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
|
glm::vec4 cubeColor(getColor()[RED_INDEX] / MAX_COLOR, getColor()[GREEN_INDEX] / MAX_COLOR,
|
||||||
getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
|
getColor()[BLUE_INDEX] / MAX_COLOR, getLocalRenderAlpha());
|
||||||
|
|
||||||
|
|
||||||
|
bool highlightSimulationOwnership = false;
|
||||||
|
if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid& myNodeID = nodeList->getSessionUUID();
|
||||||
|
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
|
||||||
|
}
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
|
@ -43,8 +51,11 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
glm::vec3 positionToCenter = center - position;
|
glm::vec3 positionToCenter = center - position;
|
||||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f, cubeColor);
|
if (highlightSimulationOwnership) {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f, cubeColor);
|
||||||
|
} else {
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(1.0f, cubeColor);
|
||||||
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -109,6 +109,33 @@ void RenderableModelEntityItem::remapTextures() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderableModelEntityItem::renderBoundingBox(RenderArgs* args) {
|
||||||
|
glm::vec3 position = getPosition();
|
||||||
|
glm::vec3 center = getCenter();
|
||||||
|
glm::vec3 dimensions = getDimensions();
|
||||||
|
glm::quat rotation = getRotation();
|
||||||
|
// float size = glm::length(dimensions) / 2.0f;
|
||||||
|
|
||||||
|
const float MAX_COLOR = 255.0f;
|
||||||
|
glm::vec4 cubeColor(getColor()[RED_INDEX] / MAX_COLOR,
|
||||||
|
getColor()[GREEN_INDEX] / MAX_COLOR,
|
||||||
|
getColor()[BLUE_INDEX] / MAX_COLOR,
|
||||||
|
getLocalRenderAlpha());
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
|
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
glPushMatrix();
|
||||||
|
glm::vec3 positionToCenter = center - position;
|
||||||
|
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||||
|
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f, cubeColor);
|
||||||
|
glPopMatrix();
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderableModelEntityItem::render(RenderArgs* args) {
|
void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
PerformanceTimer perfTimer("RMEIrender");
|
PerformanceTimer perfTimer("RMEIrender");
|
||||||
assert(getType() == EntityTypes::Model);
|
assert(getType() == EntityTypes::Model);
|
||||||
|
@ -117,7 +144,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 position = getPosition();
|
||||||
glm::vec3 dimensions = getDimensions();
|
glm::vec3 dimensions = getDimensions();
|
||||||
float size = glm::length(dimensions);
|
|
||||||
|
|
||||||
bool highlightSimulationOwnership = false;
|
bool highlightSimulationOwnership = false;
|
||||||
if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) {
|
if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) {
|
||||||
|
@ -126,6 +152,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
|
highlightSimulationOwnership = (getSimulatorID() == myNodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool didDraw = false;
|
||||||
if (drawAsModel && !highlightSimulationOwnership) {
|
if (drawAsModel && !highlightSimulationOwnership) {
|
||||||
remapTextures();
|
remapTextures();
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -179,34 +206,20 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
|
if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
|
||||||
if (movingOrAnimating) {
|
if (movingOrAnimating) {
|
||||||
_model->renderInScene(alpha, args);
|
_model->renderInScene(alpha, args);
|
||||||
|
didDraw = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_model->renderInScene(alpha, args);
|
_model->renderInScene(alpha, args);
|
||||||
|
didDraw = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// if we couldn't get a model, then just draw a cube
|
|
||||||
glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(position.x, position.y, position.z);
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// if we couldn't get a model, then just draw a cube
|
|
||||||
glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(position.x, position.y, position.z);
|
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
} else {
|
}
|
||||||
glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f);
|
|
||||||
glPushMatrix();
|
if (!didDraw) {
|
||||||
glTranslatef(position.x, position.y, position.z);
|
renderBoundingBox(args);
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
|
|
||||||
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
||||||
|
|
||||||
|
void renderBoundingBox(RenderArgs* args);
|
||||||
virtual void render(RenderArgs* args);
|
virtual void render(RenderArgs* args);
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
|
|
|
@ -63,6 +63,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||||
_simulatorID(ENTITY_ITEM_DEFAULT_SIMULATOR_ID),
|
_simulatorID(ENTITY_ITEM_DEFAULT_SIMULATOR_ID),
|
||||||
_simulatorIDChangedTime(0),
|
_simulatorIDChangedTime(0),
|
||||||
_marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID),
|
_marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID),
|
||||||
|
_name(ENTITY_ITEM_DEFAULT_NAME),
|
||||||
_physicsInfo(NULL),
|
_physicsInfo(NULL),
|
||||||
_dirtyFlags(0),
|
_dirtyFlags(0),
|
||||||
_element(NULL)
|
_element(NULL)
|
||||||
|
@ -105,6 +106,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
||||||
requestedProperties += PROP_LOCKED;
|
requestedProperties += PROP_LOCKED;
|
||||||
requestedProperties += PROP_USER_DATA;
|
requestedProperties += PROP_USER_DATA;
|
||||||
requestedProperties += PROP_MARKETPLACE_ID;
|
requestedProperties += PROP_MARKETPLACE_ID;
|
||||||
|
requestedProperties += PROP_NAME;
|
||||||
requestedProperties += PROP_SIMULATOR_ID;
|
requestedProperties += PROP_SIMULATOR_ID;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
|
@ -231,6 +233,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
||||||
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, getUserData());
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, appendValue, getUserData());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, appendValue, getSimulatorID());
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, appendValue, getSimulatorID());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, getMarketplaceID());
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, getMarketplaceID());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_NAME, appendValue, getName());
|
||||||
|
|
||||||
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
||||||
requestedProperties,
|
requestedProperties,
|
||||||
|
@ -528,7 +531,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, updateDimensionsInDomainUnits);
|
READ_ENTITY_PROPERTY_SETTER(PROP_DIMENSIONS, glm::vec3, updateDimensionsInDomainUnits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_QUAT_SETTER(PROP_ROTATION, updateRotation);
|
READ_ENTITY_PROPERTY_QUAT_SETTER(PROP_ROTATION, updateRotation);
|
||||||
READ_ENTITY_PROPERTY_SETTER(PROP_DENSITY, float, updateDensity);
|
READ_ENTITY_PROPERTY_SETTER(PROP_DENSITY, float, updateDensity);
|
||||||
if (useMeters) {
|
if (useMeters) {
|
||||||
|
@ -566,6 +569,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
||||||
READ_ENTITY_PROPERTY_STRING(PROP_MARKETPLACE_ID, setMarketplaceID);
|
READ_ENTITY_PROPERTY_STRING(PROP_MARKETPLACE_ID, setMarketplaceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY_STRING(PROP_NAME, setName);
|
||||||
|
|
||||||
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
|
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
@ -897,6 +902,7 @@ EntityItemProperties EntityItem::getProperties() const {
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(userData, getUserData);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulatorID, getSimulatorID);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulatorID, getSimulatorID);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(marketplaceID, getMarketplaceID);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(marketplaceID, getMarketplaceID);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(name, getName);
|
||||||
|
|
||||||
properties._defaultSettings = false;
|
properties._defaultSettings = false;
|
||||||
|
|
||||||
|
@ -928,6 +934,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(userData, setUserData);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulatorID, setSimulatorID);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(simulatorID, setSimulatorID);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(marketplaceID, setMarketplaceID);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(marketplaceID, setMarketplaceID);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(name, setName);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
somethingChangedNotification(); // notify derived classes that something has changed
|
somethingChangedNotification(); // notify derived classes that something has changed
|
||||||
|
|
|
@ -229,6 +229,9 @@ public:
|
||||||
float getAngularDamping() const { return _angularDamping; }
|
float getAngularDamping() const { return _angularDamping; }
|
||||||
void setAngularDamping(float value) { _angularDamping = value; }
|
void setAngularDamping(float value) { _angularDamping = value; }
|
||||||
|
|
||||||
|
QString getName() const { return _name; }
|
||||||
|
void setName(const QString& value) { _name = value; }
|
||||||
|
|
||||||
bool getVisible() const { return _visible; }
|
bool getVisible() const { return _visible; }
|
||||||
void setVisible(bool value) { _visible = value; }
|
void setVisible(bool value) { _visible = value; }
|
||||||
bool isVisible() const { return _visible; }
|
bool isVisible() const { return _visible; }
|
||||||
|
@ -348,6 +351,7 @@ protected:
|
||||||
QUuid _simulatorID; // id of Node which is currently responsible for simulating this Entity
|
QUuid _simulatorID; // id of Node which is currently responsible for simulating this Entity
|
||||||
quint64 _simulatorIDChangedTime; // when was _simulatorID last updated?
|
quint64 _simulatorIDChangedTime; // when was _simulatorID last updated?
|
||||||
QString _marketplaceID;
|
QString _marketplaceID;
|
||||||
|
QString _name;
|
||||||
|
|
||||||
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
// NOTE: Damping is applied like this: v *= pow(1 - damping, dt)
|
||||||
//
|
//
|
||||||
|
|
|
@ -86,6 +86,7 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
CONSTRUCT_PROPERTY(stageAltitude, ZoneEntityItem::DEFAULT_STAGE_ALTITUDE),
|
CONSTRUCT_PROPERTY(stageAltitude, ZoneEntityItem::DEFAULT_STAGE_ALTITUDE),
|
||||||
CONSTRUCT_PROPERTY(stageDay, ZoneEntityItem::DEFAULT_STAGE_DAY),
|
CONSTRUCT_PROPERTY(stageDay, ZoneEntityItem::DEFAULT_STAGE_DAY),
|
||||||
CONSTRUCT_PROPERTY(stageHour, ZoneEntityItem::DEFAULT_STAGE_HOUR),
|
CONSTRUCT_PROPERTY(stageHour, ZoneEntityItem::DEFAULT_STAGE_HOUR),
|
||||||
|
CONSTRUCT_PROPERTY(name, ENTITY_ITEM_DEFAULT_NAME),
|
||||||
|
|
||||||
_id(UNKNOWN_ENTITY_ID),
|
_id(UNKNOWN_ENTITY_ID),
|
||||||
_idSet(false),
|
_idSet(false),
|
||||||
|
@ -281,6 +282,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_GRAVITY, localGravity);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_GRAVITY, localGravity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius);
|
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
|
CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_INTENSITY, keyLightIntensity);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity);
|
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_AMBIENT_INTENSITY, keyLightAmbientIntensity);
|
||||||
|
@ -295,20 +297,23 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
return changedProperties;
|
return changedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) const {
|
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const {
|
||||||
QScriptValue properties = engine->newObject();
|
QScriptValue properties = engine->newObject();
|
||||||
|
EntityItemProperties defaultEntityProperties;
|
||||||
|
|
||||||
if (_idSet) {
|
if (_idSet) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(id, _id.toString());
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(id, _id.toString());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(isKnownID, (_id != UNKNOWN_ENTITY_ID));
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(isKnownID, (_id != UNKNOWN_ENTITY_ID));
|
||||||
} else {
|
} else {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(isKnownID, false);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(isKnownID, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(type, EntityTypes::getEntityTypeName(_type));
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(type, EntityTypes::getEntityTypeName(_type));
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(position);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(position);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(dimensions);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(dimensions);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(naturalDimensions); // gettable, but not settable
|
if (!skipDefaults) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(naturalDimensions); // gettable, but not settable
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(rotation);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(rotation);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(velocity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(velocity);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(gravity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(gravity);
|
||||||
|
@ -316,8 +321,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(damping);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(damping);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(density);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(density);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(lifetime);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(lifetime);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(age, getAge()); // gettable, but not settable
|
if (!skipDefaults) {
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
||||||
|
}
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(script);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(script);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(registrationPoint);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(registrationPoint);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(angularVelocity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(angularVelocity);
|
||||||
|
@ -356,6 +363,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(localGravity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(localGravity);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(name);
|
||||||
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR(keyLightColor);
|
COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR(keyLightColor);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
|
||||||
|
@ -369,31 +377,37 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(stageHour);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(stageHour);
|
||||||
|
|
||||||
// Sitting properties support
|
// Sitting properties support
|
||||||
QScriptValue sittingPoints = engine->newObject();
|
if (!skipDefaults) {
|
||||||
for (int i = 0; i < _sittingPoints.size(); ++i) {
|
QScriptValue sittingPoints = engine->newObject();
|
||||||
QScriptValue sittingPoint = engine->newObject();
|
for (int i = 0; i < _sittingPoints.size(); ++i) {
|
||||||
sittingPoint.setProperty("name", _sittingPoints.at(i).name);
|
QScriptValue sittingPoint = engine->newObject();
|
||||||
sittingPoint.setProperty("position", vec3toScriptValue(engine, _sittingPoints.at(i).position));
|
sittingPoint.setProperty("name", _sittingPoints.at(i).name);
|
||||||
sittingPoint.setProperty("rotation", quatToScriptValue(engine, _sittingPoints.at(i).rotation));
|
sittingPoint.setProperty("position", vec3toScriptValue(engine, _sittingPoints.at(i).position));
|
||||||
sittingPoints.setProperty(i, sittingPoint);
|
sittingPoint.setProperty("rotation", quatToScriptValue(engine, _sittingPoints.at(i).rotation));
|
||||||
|
sittingPoints.setProperty(i, sittingPoint);
|
||||||
|
}
|
||||||
|
sittingPoints.setProperty("length", _sittingPoints.size());
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
||||||
}
|
}
|
||||||
sittingPoints.setProperty("length", _sittingPoints.size());
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(sittingPoints, sittingPoints); // gettable, but not settable
|
|
||||||
|
|
||||||
AABox aaBox = getAABox();
|
if (!skipDefaults) {
|
||||||
QScriptValue boundingBox = engine->newObject();
|
AABox aaBox = getAABox();
|
||||||
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
QScriptValue boundingBox = engine->newObject();
|
||||||
QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft());
|
QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner());
|
||||||
QScriptValue center = vec3toScriptValue(engine, aaBox.calcCenter());
|
QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft());
|
||||||
QScriptValue boundingBoxDimensions = vec3toScriptValue(engine, aaBox.getDimensions());
|
QScriptValue center = vec3toScriptValue(engine, aaBox.calcCenter());
|
||||||
boundingBox.setProperty("brn", bottomRightNear);
|
QScriptValue boundingBoxDimensions = vec3toScriptValue(engine, aaBox.getDimensions());
|
||||||
boundingBox.setProperty("tfl", topFarLeft);
|
boundingBox.setProperty("brn", bottomRightNear);
|
||||||
boundingBox.setProperty("center", center);
|
boundingBox.setProperty("tfl", topFarLeft);
|
||||||
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
boundingBox.setProperty("center", center);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(boundingBox, boundingBox); // gettable, but not settable
|
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(boundingBox, boundingBox); // gettable, but not settable
|
||||||
|
}
|
||||||
|
|
||||||
QString textureNamesList = _textureNames.join(",\n");
|
QString textureNamesList = _textureNames.join(",\n");
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(originalTextures, textureNamesList); // gettable, but not settable
|
if (!skipDefaults) {
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesList); // gettable, but not settable
|
||||||
|
}
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
@ -451,6 +465,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localGravity, setLocalGravity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localGravity, setLocalGravity);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(particleRadius, setParticleRadius);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(particleRadius, setParticleRadius);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(marketplaceID, setMarketplaceID);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(marketplaceID, setMarketplaceID);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(name, setName);
|
||||||
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_COLOR(keyLightColor, setKeyLightColor);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_COLOR(keyLightColor, setKeyLightColor);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightIntensity, setKeyLightIntensity);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(keyLightIntensity, setKeyLightIntensity);
|
||||||
|
@ -467,7 +482,11 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
||||||
return properties.copyToScriptValue(engine);
|
return properties.copyToScriptValue(engine, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
||||||
|
return properties.copyToScriptValue(engine, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties) {
|
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties) {
|
||||||
|
@ -666,6 +685,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
}
|
}
|
||||||
|
|
||||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, properties.getMarketplaceID());
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, properties.getMarketplaceID());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_NAME, appendValue, properties.getName());
|
||||||
}
|
}
|
||||||
if (propertyCount > 0) {
|
if (propertyCount > 0) {
|
||||||
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
||||||
|
@ -914,6 +934,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
}
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MARKETPLACE_ID, setMarketplaceID);
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MARKETPLACE_ID, setMarketplaceID);
|
||||||
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_NAME, setName);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
@ -963,6 +984,7 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_registrationPointChanged = true;
|
_registrationPointChanged = true;
|
||||||
_angularVelocityChanged = true;
|
_angularVelocityChanged = true;
|
||||||
_angularDampingChanged = true;
|
_angularDampingChanged = true;
|
||||||
|
_nameChanged = true;
|
||||||
_visibleChanged = true;
|
_visibleChanged = true;
|
||||||
_colorChanged = true;
|
_colorChanged = true;
|
||||||
_modelURLChanged = true;
|
_modelURLChanged = true;
|
||||||
|
|
|
@ -97,6 +97,7 @@ enum EntityPropertyList {
|
||||||
PROP_MARKETPLACE_ID,
|
PROP_MARKETPLACE_ID,
|
||||||
PROP_ACCELERATION,
|
PROP_ACCELERATION,
|
||||||
PROP_SIMULATOR_ID,
|
PROP_SIMULATOR_ID,
|
||||||
|
PROP_NAME,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// ATTENTION: add new properties ABOVE this line
|
// ATTENTION: add new properties ABOVE this line
|
||||||
|
@ -159,7 +160,7 @@ public:
|
||||||
EntityTypes::EntityType getType() const { return _type; }
|
EntityTypes::EntityType getType() const { return _type; }
|
||||||
void setType(EntityTypes::EntityType type) { _type = type; }
|
void setType(EntityTypes::EntityType type) { _type = type; }
|
||||||
|
|
||||||
virtual QScriptValue copyToScriptValue(QScriptEngine* engine) const;
|
virtual QScriptValue copyToScriptValue(QScriptEngine* engine, bool skipDefaults) const;
|
||||||
virtual void copyFromScriptValue(const QScriptValue& object);
|
virtual void copyFromScriptValue(const QScriptValue& object);
|
||||||
|
|
||||||
// editing related features supported by all entities
|
// editing related features supported by all entities
|
||||||
|
@ -239,6 +240,7 @@ public:
|
||||||
DEFINE_PROPERTY(PROP_STAGE_ALTITUDE, StageAltitude, stageAltitude, float);
|
DEFINE_PROPERTY(PROP_STAGE_ALTITUDE, StageAltitude, stageAltitude, float);
|
||||||
DEFINE_PROPERTY(PROP_STAGE_DAY, StageDay, stageDay, quint16);
|
DEFINE_PROPERTY(PROP_STAGE_DAY, StageDay, stageDay, quint16);
|
||||||
DEFINE_PROPERTY(PROP_STAGE_HOUR, StageHour, stageHour, float);
|
DEFINE_PROPERTY(PROP_STAGE_HOUR, StageHour, stageHour, float);
|
||||||
|
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -307,6 +309,7 @@ private:
|
||||||
};
|
};
|
||||||
Q_DECLARE_METATYPE(EntityItemProperties);
|
Q_DECLARE_METATYPE(EntityItemProperties);
|
||||||
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||||
|
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties);
|
||||||
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties);
|
void EntityItemPropertiesFromScriptValue(const QScriptValue &object, EntityItemProperties& properties);
|
||||||
|
|
||||||
|
|
||||||
|
@ -330,6 +333,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
||||||
|
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Dimensions, dimensions, "in meters");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Dimensions, dimensions, "in meters");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters");
|
||||||
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Name, name, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Visible, visible, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Visible, visible, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Rotation, rotation, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Rotation, rotation, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Density, density, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Density, density, "");
|
||||||
|
|
|
@ -55,4 +55,6 @@ const float ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING = 0.39347f; // approx timescale
|
||||||
const bool ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS = false;
|
const bool ENTITY_ITEM_DEFAULT_IGNORE_FOR_COLLISIONS = false;
|
||||||
const bool ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE = false;
|
const bool ENTITY_ITEM_DEFAULT_COLLISIONS_WILL_MOVE = false;
|
||||||
|
|
||||||
|
const QString ENTITY_ITEM_DEFAULT_NAME = QString("");
|
||||||
|
|
||||||
#endif // hifi_EntityItemPropertiesDefaults_h
|
#endif // hifi_EntityItemPropertiesDefaults_h
|
||||||
|
|
|
@ -198,26 +198,41 @@
|
||||||
|
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(P) \
|
||||||
QScriptValue P = vec3toScriptValue(engine, _##P); \
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
properties.setProperty(#P, P);
|
QScriptValue P = vec3toScriptValue(engine, _##P); \
|
||||||
|
properties.setProperty(#P, P); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_QUAT(P) \
|
||||||
QScriptValue P = quatToScriptValue(engine, _##P); \
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
properties.setProperty(#P, P);
|
QScriptValue P = quatToScriptValue(engine, _##P); \
|
||||||
|
properties.setProperty(#P, P); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR(P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR(P) \
|
||||||
QScriptValue P = xColorToScriptValue(engine, _##P); \
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
properties.setProperty(#P, P);
|
QScriptValue P = xColorToScriptValue(engine, _##P); \
|
||||||
|
properties.setProperty(#P, P); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(P,G) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_COLOR_GETTER(P,G) \
|
||||||
QScriptValue P = xColorToScriptValue(engine, G); \
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
properties.setProperty(#P, P);
|
QScriptValue P = xColorToScriptValue(engine, G); \
|
||||||
|
properties.setProperty(#P, P); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(P, G) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(P, G) \
|
||||||
properties.setProperty(#P, G);
|
properties.setProperty(#P, G);
|
||||||
|
|
||||||
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(P, G) \
|
||||||
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
|
properties.setProperty(#P, G); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE(P) \
|
#define COPY_PROPERTY_TO_QSCRIPTVALUE(P) \
|
||||||
properties.setProperty(#P, _##P);
|
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||||
|
properties.setProperty(#P, _##P); \
|
||||||
|
}
|
||||||
|
|
||||||
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(P, S) \
|
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(P, S) \
|
||||||
QScriptValue P = object.property(#P); \
|
QScriptValue P = object.property(#P); \
|
||||||
|
|
|
@ -1137,10 +1137,10 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElement* element) {
|
bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues) {
|
||||||
entityDescription["Entities"] = QVariantList();
|
entityDescription["Entities"] = QVariantList();
|
||||||
QScriptEngine scriptEngine;
|
QScriptEngine scriptEngine;
|
||||||
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine);
|
RecurseOctreeToMapOperator theOperator(entityDescription, element, &scriptEngine, skipDefaultValues);
|
||||||
recurseTreeWithOperator(&theOperator);
|
recurseTreeWithOperator(&theOperator);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public:
|
||||||
bool wantEditLogging() const { return _wantEditLogging; }
|
bool wantEditLogging() const { return _wantEditLogging; }
|
||||||
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
void setWantEditLogging(bool value) { _wantEditLogging = value; }
|
||||||
|
|
||||||
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element);
|
bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues);
|
||||||
bool readFromMap(QVariantMap& entityDescription);
|
bool readFromMap(QVariantMap& entityDescription);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -12,11 +12,15 @@
|
||||||
#include "RecurseOctreeToMapOperator.h"
|
#include "RecurseOctreeToMapOperator.h"
|
||||||
|
|
||||||
|
|
||||||
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine) :
|
RecurseOctreeToMapOperator::RecurseOctreeToMapOperator(QVariantMap& map,
|
||||||
|
OctreeElement *top,
|
||||||
|
QScriptEngine *engine,
|
||||||
|
bool skipDefaultValues) :
|
||||||
RecurseOctreeOperator(),
|
RecurseOctreeOperator(),
|
||||||
_map(map),
|
_map(map),
|
||||||
_top(top),
|
_top(top),
|
||||||
_engine(engine)
|
_engine(engine),
|
||||||
|
_skipDefaultValues(skipDefaultValues)
|
||||||
{
|
{
|
||||||
// if some element "top" was given, only save information for that element and it's children.
|
// if some element "top" was given, only save information for that element and it's children.
|
||||||
if (_top) {
|
if (_top) {
|
||||||
|
@ -36,6 +40,8 @@ bool RecurseOctreeToMapOperator::preRecursion(OctreeElement* element) {
|
||||||
|
|
||||||
bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
||||||
|
|
||||||
|
EntityItemProperties defaultProperties;
|
||||||
|
|
||||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
||||||
|
|
||||||
|
@ -43,7 +49,12 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
||||||
|
|
||||||
foreach (EntityItem* entityItem, entities) {
|
foreach (EntityItem* entityItem, entities) {
|
||||||
EntityItemProperties properties = entityItem->getProperties();
|
EntityItemProperties properties = entityItem->getProperties();
|
||||||
QScriptValue qScriptValues = EntityItemPropertiesToScriptValue(_engine, properties);
|
QScriptValue qScriptValues;
|
||||||
|
if (_skipDefaultValues) {
|
||||||
|
qScriptValues = EntityItemNonDefaultPropertiesToScriptValue(_engine, properties);
|
||||||
|
} else {
|
||||||
|
qScriptValues = EntityItemPropertiesToScriptValue(_engine, properties);
|
||||||
|
}
|
||||||
entitiesQList << qScriptValues.toVariant();
|
entitiesQList << qScriptValues.toVariant();
|
||||||
}
|
}
|
||||||
_map["Entities"] = entitiesQList;
|
_map["Entities"] = entitiesQList;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
class RecurseOctreeToMapOperator : public RecurseOctreeOperator {
|
class RecurseOctreeToMapOperator : public RecurseOctreeOperator {
|
||||||
public:
|
public:
|
||||||
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine);
|
RecurseOctreeToMapOperator(QVariantMap& map, OctreeElement *top, QScriptEngine *engine, bool skipDefaultValues);
|
||||||
bool preRecursion(OctreeElement* element);
|
bool preRecursion(OctreeElement* element);
|
||||||
bool postRecursion(OctreeElement* element);
|
bool postRecursion(OctreeElement* element);
|
||||||
private:
|
private:
|
||||||
|
@ -21,4 +21,5 @@ public:
|
||||||
OctreeElement *_top;
|
OctreeElement *_top;
|
||||||
QScriptEngine *_engine;
|
QScriptEngine *_engine;
|
||||||
bool _withinTop;
|
bool _withinTop;
|
||||||
|
bool _skipDefaultValues;
|
||||||
};
|
};
|
||||||
|
|
|
@ -203,6 +203,16 @@ public:
|
||||||
glm::quat rotation; // relative orientation
|
glm::quat rotation; // relative orientation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.name == rhs.name) && (lhs.position == rhs.position) && (lhs.rotation == rhs.rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const SittingPoint& lhs, const SittingPoint& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.name != rhs.name) || (lhs.position != rhs.position) || (lhs.rotation != rhs.rotation);
|
||||||
|
}
|
||||||
|
|
||||||
/// A set of meshes extracted from an FBX document.
|
/// A set of meshes extracted from an FBX document.
|
||||||
class FBXGeometry {
|
class FBXGeometry {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -74,6 +74,19 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if (GPU_FEATURE_PROFILE == GPU_LEGACY)
|
||||||
|
// for reasons that i don;t understand yet, it seems that on mac gl, a fbo must have a color buffer...
|
||||||
|
else {
|
||||||
|
GLuint renderBuffer = 0;
|
||||||
|
glGenRenderbuffers(1, &renderBuffer);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, framebuffer.getWidth(), framebuffer.getHeight());
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer);
|
||||||
|
CHECK_GL_ERROR();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (framebuffer.hasDepthStencil()) {
|
if (framebuffer.hasDepthStencil()) {
|
||||||
auto surface = framebuffer.getDepthStencilBuffer();
|
auto surface = framebuffer.getDepthStencilBuffer();
|
||||||
|
|
|
@ -237,8 +237,6 @@ protected:
|
||||||
HifiSockAddr _localSockAddr;
|
HifiSockAddr _localSockAddr;
|
||||||
HifiSockAddr _publicSockAddr;
|
HifiSockAddr _publicSockAddr;
|
||||||
HifiSockAddr _stunSockAddr;
|
HifiSockAddr _stunSockAddr;
|
||||||
|
|
||||||
QTimer* _silentNodeTimer;
|
|
||||||
|
|
||||||
// XXX can BandwidthRecorder be used for this?
|
// XXX can BandwidthRecorder be used for this?
|
||||||
int _numCollectedPackets;
|
int _numCollectedPackets;
|
||||||
|
|
|
@ -74,7 +74,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeEntityAddOrEdit:
|
case PacketTypeEntityAddOrEdit:
|
||||||
case PacketTypeEntityData:
|
case PacketTypeEntityData:
|
||||||
return VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE;
|
return VERSION_ENTITIES_HAVE_NAMES;
|
||||||
case PacketTypeEntityErase:
|
case PacketTypeEntityErase:
|
||||||
return 2;
|
return 2;
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
|
|
|
@ -139,5 +139,6 @@ const PacketVersion VERSION_ENTITIES_HAVE_ACCELERATION = 15;
|
||||||
const PacketVersion VERSION_ENTITIES_HAVE_UUIDS = 16;
|
const PacketVersion VERSION_ENTITIES_HAVE_UUIDS = 16;
|
||||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17;
|
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17;
|
||||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18;
|
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18;
|
||||||
|
const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
|
@ -47,6 +47,8 @@ public:
|
||||||
/// How many received packets waiting are to be processed
|
/// How many received packets waiting are to be processed
|
||||||
int packetsToProcessCount() const { return _packets.size(); }
|
int packetsToProcessCount() const { return _packets.size(); }
|
||||||
|
|
||||||
|
virtual void terminating();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void nodeKilled(SharedNodePointer node);
|
void nodeKilled(SharedNodePointer node);
|
||||||
|
|
||||||
|
@ -71,8 +73,6 @@ protected:
|
||||||
/// Override to do work after the packets processing loop. Default does nothing.
|
/// Override to do work after the packets processing loop. Default does nothing.
|
||||||
virtual void postProcess() { }
|
virtual void postProcess() { }
|
||||||
|
|
||||||
virtual void terminating();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QVector<NetworkPacket> _packets;
|
QVector<NetworkPacket> _packets;
|
||||||
|
|
|
@ -30,6 +30,17 @@ void ThreadedAssignment::setFinished(bool isFinished) {
|
||||||
_isFinished = isFinished;
|
_isFinished = isFinished;
|
||||||
|
|
||||||
if (_isFinished) {
|
if (_isFinished) {
|
||||||
|
if (_domainServerTimer) {
|
||||||
|
_domainServerTimer->stop();
|
||||||
|
delete _domainServerTimer;
|
||||||
|
_domainServerTimer = nullptr;
|
||||||
|
}
|
||||||
|
if (_statsTimer) {
|
||||||
|
_statsTimer->stop();
|
||||||
|
delete _statsTimer;
|
||||||
|
_statsTimer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
aboutToFinish();
|
aboutToFinish();
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
@ -63,15 +74,15 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy
|
||||||
// this is a temp fix for Qt 5.3 - rebinding the node socket gives us readyRead for the socket on this thread
|
// this is a temp fix for Qt 5.3 - rebinding the node socket gives us readyRead for the socket on this thread
|
||||||
nodeList->rebindNodeSocket();
|
nodeList->rebindNodeSocket();
|
||||||
|
|
||||||
QTimer* domainServerTimer = new QTimer(this);
|
_domainServerTimer = new QTimer();
|
||||||
connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit()));
|
connect(_domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit()));
|
||||||
domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);
|
_domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);
|
||||||
|
|
||||||
if (shouldSendStats) {
|
if (shouldSendStats) {
|
||||||
// send a stats packet every 1 second
|
// send a stats packet every 1 second
|
||||||
QTimer* statsTimer = new QTimer(this);
|
_statsTimer = new QTimer();
|
||||||
connect(statsTimer, &QTimer::timeout, this, &ThreadedAssignment::sendStatsPacket);
|
connect(_statsTimer, &QTimer::timeout, this, &ThreadedAssignment::sendStatsPacket);
|
||||||
statsTimer->start(1000);
|
_statsTimer->start(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,15 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
/// threaded run of assignment
|
/// threaded run of assignment
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
Q_INVOKABLE virtual void stop() { setFinished(true); }
|
||||||
virtual void readPendingDatagrams() = 0;
|
virtual void readPendingDatagrams() = 0;
|
||||||
virtual void sendStatsPacket();
|
virtual void sendStatsPacket();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void aboutToQuit() {
|
||||||
|
QMetaObject::invokeMethod(this, "stop");
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
|
@ -38,6 +45,8 @@ protected:
|
||||||
void commonInit(const QString& targetName, NodeType_t nodeType, bool shouldSendStats = true);
|
void commonInit(const QString& targetName, NodeType_t nodeType, bool shouldSendStats = true);
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
QThread* _datagramProcessingThread;
|
QThread* _datagramProcessingThread;
|
||||||
|
QTimer* _domainServerTimer = nullptr;
|
||||||
|
QTimer* _statsTimer = nullptr;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void checkInWithDomainServerOrExit();
|
void checkInWithDomainServerOrExit();
|
||||||
|
|
|
@ -2087,7 +2087,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
|
||||||
QFile persistFile(fileName);
|
QFile persistFile(fileName);
|
||||||
QVariantMap entityDescription;
|
QVariantMap entityDescription;
|
||||||
|
|
||||||
qCDebug(octree, "Saving to file %s...", fileName);
|
qCDebug(octree, "Saving JSON SVO to file %s...", fileName);
|
||||||
|
|
||||||
OctreeElement* top;
|
OctreeElement* top;
|
||||||
if (element) {
|
if (element) {
|
||||||
|
@ -2096,7 +2096,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
|
||||||
top = _rootElement;
|
top = _rootElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool entityDescriptionSuccess = writeToMap(entityDescription, top);
|
bool entityDescriptionSuccess = writeToMap(entityDescription, top, true);
|
||||||
if (entityDescriptionSuccess && persistFile.open(QIODevice::WriteOnly)) {
|
if (entityDescriptionSuccess && persistFile.open(QIODevice::WriteOnly)) {
|
||||||
persistFile.write(QJsonDocument::fromVariant(entityDescription).toJson());
|
persistFile.write(QJsonDocument::fromVariant(entityDescription).toJson());
|
||||||
} else {
|
} else {
|
||||||
|
@ -2108,7 +2108,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) {
|
||||||
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
std::ofstream file(fileName, std::ios::out|std::ios::binary);
|
||||||
|
|
||||||
if(file.is_open()) {
|
if(file.is_open()) {
|
||||||
qCDebug(octree, "Saving to file %s...", fileName);
|
qCDebug(octree, "Saving binary SVO to file %s...", fileName);
|
||||||
|
|
||||||
PacketType expectedType = expectedDataPacketType();
|
PacketType expectedType = expectedDataPacketType();
|
||||||
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
PacketVersion expectedVersion = versionForPacketType(expectedType);
|
||||||
|
|
|
@ -331,7 +331,7 @@ public:
|
||||||
void writeToFile(const char* filename, OctreeElement* element = NULL, QString persistAsFileType = "svo");
|
void writeToFile(const char* filename, OctreeElement* element = NULL, QString persistAsFileType = "svo");
|
||||||
void writeToJSONFile(const char* filename, OctreeElement* element = NULL);
|
void writeToJSONFile(const char* filename, OctreeElement* element = NULL);
|
||||||
void writeToSVOFile(const char* filename, OctreeElement* element = NULL);
|
void writeToSVOFile(const char* filename, OctreeElement* element = NULL);
|
||||||
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElement* element) = 0;
|
virtual bool writeToMap(QVariantMap& entityDescription, OctreeElement* element, bool skipDefaultValues) = 0;
|
||||||
|
|
||||||
// Octree importers
|
// Octree importers
|
||||||
bool readFromFile(const char* filename);
|
bool readFromFile(const char* filename);
|
||||||
|
|
|
@ -228,6 +228,7 @@ void OctreePersistThread::aboutToFinish() {
|
||||||
qCDebug(octree) << "Persist thread about to finish...";
|
qCDebug(octree) << "Persist thread about to finish...";
|
||||||
persist();
|
persist();
|
||||||
qCDebug(octree) << "Persist thread done with about to finish...";
|
qCDebug(octree) << "Persist thread done with about to finish...";
|
||||||
|
_stopThread = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OctreePersistThread::persist() {
|
void OctreePersistThread::persist() {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ void main(void) {
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
|
||||||
packDeferredFragment(
|
packDeferredFragment(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
||||||
getMaterialSpecular(mat),
|
getMaterialSpecular(mat),
|
||||||
|
|
|
@ -20,7 +20,7 @@ const int MAX_TEXCOORDS = 2;
|
||||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ void main(void) {
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, gl_Normal, normal.xyz)$>
|
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
||||||
|
|
||||||
normal = vec4(normalize(normal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ uniform sampler2D emissiveMap;
|
||||||
uniform vec2 emissiveParams;
|
uniform vec2 emissiveParams;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ void main(void) {
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
||||||
getMaterialSpecular(mat),
|
getMaterialSpecular(mat),
|
||||||
|
|
|
@ -23,7 +23,7 @@ uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||||
attribute vec2 texcoord1;
|
attribute vec2 texcoord1;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
// the interpolated texcoord1
|
// the interpolated texcoord1
|
||||||
varying vec2 interpolatedTexcoord1;
|
varying vec2 interpolatedTexcoord1;
|
||||||
|
@ -44,8 +44,8 @@ void main(void) {
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, gl_Normal, normal.xyz)$>
|
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
||||||
|
|
||||||
normal = vec4(normalize(normal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ uniform vec2 emissiveParams;
|
||||||
uniform sampler2D specularMap;
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec2 interpolatedTexcoord1;
|
varying vec2 interpolatedTexcoord1;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ void main(void) {
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
|
||||||
packDeferredFragmentLightmap(
|
packDeferredFragmentLightmap(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
||||||
specular, // no use of getMaterialSpecular(mat)
|
specular, // no use of getMaterialSpecular(mat)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<@include gpu/Config.slh@>
|
<@include gpu/Config.slh@>
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// model.vert
|
// model.vert
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
const int MAX_TEXCOORDS = 2;
|
const int MAX_TEXCOORDS = 2;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ varying vec4 interpolatedNormal;
|
||||||
// the interpolated tangent
|
// the interpolated tangent
|
||||||
varying vec4 interpolatedTangent;
|
varying vec4 interpolatedTangent;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// transform and store the normal and tangent for interpolation
|
// transform and store the normal and tangent for interpolation
|
||||||
|
@ -42,13 +42,13 @@ void main(void) {
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
<$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$>
|
||||||
<$transformModelToEyeDir(cam, obj, tangent, interpolatedTangent.xyz)$>
|
<$transformModelToEyeDir(cam, obj, tangent, interpolatedTangent.xyz)$>
|
||||||
|
|
||||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ uniform sampler2D diffuseMap;
|
||||||
uniform sampler2D specularMap;
|
uniform sampler2D specularMap;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ void main(void) {
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
|
||||||
packDeferredFragment(
|
packDeferredFragment(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a),
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
||||||
specular, //getMaterialSpecular(mat),
|
specular, //getMaterialSpecular(mat),
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ void main(void) {
|
||||||
Material mat = getMaterial();
|
Material mat = getMaterial();
|
||||||
|
|
||||||
packDeferredFragmentTranslucent(
|
packDeferredFragmentTranslucent(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
getMaterialOpacity(mat) * diffuse.a,
|
getMaterialOpacity(mat) * diffuse.a,
|
||||||
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
getMaterialDiffuse(mat) * diffuse.rgb * color,
|
||||||
getMaterialSpecular(mat),
|
getMaterialSpecular(mat),
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<@include DeferredBufferWrite.slh@>
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
// the glow intensity
|
// the glow intensity
|
||||||
//uniform float glowIntensity;
|
//uniform float glowIntensity;
|
||||||
|
@ -28,7 +28,7 @@ void main(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
packDeferredFragment(
|
packDeferredFragment(
|
||||||
normalize(normal.xyz),
|
normalize(interpolatedNormal.xyz),
|
||||||
glowIntensity,
|
glowIntensity,
|
||||||
gl_Color.rgb,
|
gl_Color.rgb,
|
||||||
gl_FrontMaterial.specular.rgb,
|
gl_FrontMaterial.specular.rgb,
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// transform and store the normal for interpolation
|
// transform and store the normal for interpolation
|
||||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
interpolatedNormal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||||
|
|
||||||
// pass along the diffuse color
|
// pass along the diffuse color
|
||||||
gl_FrontColor = gl_Color;
|
gl_FrontColor = gl_Color;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<@include gpu/Config.slh@>
|
<@include gpu/Config.slh@>
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// skin_model.vert
|
// skin_model.vert
|
||||||
|
@ -12,8 +12,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
const int MAX_TEXCOORDS = 2;
|
const int MAX_TEXCOORDS = 2;
|
||||||
const int MAX_CLUSTERS = 128;
|
const int MAX_CLUSTERS = 128;
|
||||||
|
@ -26,18 +26,18 @@ attribute vec4 clusterIndices;
|
||||||
attribute vec4 clusterWeights;
|
attribute vec4 clusterWeights;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 interpolatedNormal;
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
normal = vec4(0.0, 0.0, 0.0, 0.0);
|
interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||||
mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])];
|
mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])];
|
||||||
float clusterWeight = clusterWeights[i];
|
float clusterWeight = clusterWeights[i];
|
||||||
position += clusterMatrix * gl_Vertex * clusterWeight;
|
position += clusterMatrix * gl_Vertex * clusterWeight;
|
||||||
normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass along the diffuse color
|
// pass along the diffuse color
|
||||||
|
@ -46,11 +46,11 @@ void main(void) {
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, position, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, position, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, normal.xyz, normal.xyz)$>
|
<$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
|
||||||
|
|
||||||
normal = vec4(normalize(normal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<@include gpu/Config.slh@>
|
<@include gpu/Config.slh@>
|
||||||
<$VERSION_HEADER$>
|
<$VERSION_HEADER$>
|
||||||
// Generated on <$_SCRIBE_DATE$>
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
//
|
//
|
||||||
// skin_model_normal_map.vert
|
// skin_model_normal_map.vert
|
||||||
|
@ -12,8 +12,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
const int MAX_TEXCOORDS = 2;
|
const int MAX_TEXCOORDS = 2;
|
||||||
const int MAX_CLUSTERS = 128;
|
const int MAX_CLUSTERS = 128;
|
||||||
|
@ -54,16 +54,16 @@ void main(void) {
|
||||||
// and the texture coordinates
|
// and the texture coordinates
|
||||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||||
|
|
||||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, interpolatedPosition, gl_Position)$>
|
<$transformModelToClipPos(cam, obj, interpolatedPosition, gl_Position)$>
|
||||||
<$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
|
<$transformModelToEyeDir(cam, obj, interpolatedNormal.xyz, interpolatedNormal.xyz)$>
|
||||||
<$transformModelToEyeDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>
|
<$transformModelToEyeDir(cam, obj, interpolatedTangent.xyz, interpolatedTangent.xyz)$>
|
||||||
|
|
||||||
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0);
|
||||||
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,17 @@ inline QDebug& operator<<(QDebug& dbg, const xColor& c) {
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const xColor& lhs, const xColor& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.red == rhs.red) && (lhs.green == rhs.green) && (lhs.blue == rhs.blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const xColor& lhs, const xColor& rhs)
|
||||||
|
{
|
||||||
|
return (lhs.red != rhs.red) || (lhs.green != rhs.green) || (lhs.blue != rhs.blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const float ZERO = 0.0f;
|
static const float ZERO = 0.0f;
|
||||||
static const float ONE = 1.0f;
|
static const float ONE = 1.0f;
|
||||||
static const float ONE_HALF = 0.5f;
|
static const float ONE_HALF = 0.5f;
|
||||||
|
|
Loading…
Reference in a new issue