Merge branch 'master' of github.com:highfidelity/hifi into feat/hasScriptedBlendshapes

This commit is contained in:
Thijs Wenker 2018-04-04 17:04:11 +02:00
commit ceeff58fac
14 changed files with 152 additions and 86 deletions

View file

@ -105,8 +105,6 @@ EntityScriptServer::~EntityScriptServer() {
static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server"; static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
// about each other.
if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) {
auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID)); auto entityID = QUuid::fromRfc4122(message->read(NUM_BYTES_RFC4122_UUID));
@ -119,8 +117,6 @@ void EntityScriptServer::handleReloadEntityServerScriptPacket(QSharedPointer<Rec
} }
void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
// about each other.
if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) { if (senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified()) {
MessageID messageID; MessageID messageID;
message->readPrimitive(&messageID); message->readPrimitive(&messageID);
@ -190,15 +186,14 @@ void EntityScriptServer::updateEntityPPS() {
} }
void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) { void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them bool canRezAny = senderNode->getCanRez() || senderNode->getCanRezTmp() || senderNode->getCanRezCertified() || senderNode->getCanRezTmpCertified();
// about each other.
bool enable = false; bool enable = false;
message->readPrimitive(&enable); message->readPrimitive(&enable);
auto senderUUID = senderNode->getUUID(); auto senderUUID = senderNode->getUUID();
auto it = _logListeners.find(senderUUID); auto it = _logListeners.find(senderUUID);
if (enable && senderNode->getCanRez()) { if (enable && canRezAny) {
if (it == std::end(_logListeners)) { if (it == std::end(_logListeners)) {
_logListeners.insert(senderUUID); _logListeners.insert(senderUUID);
qCInfo(entity_script_server) << "Node" << senderUUID << "subscribed to log stream"; qCInfo(entity_script_server) << "Node" << senderUUID << "subscribed to log stream";

View file

@ -1042,41 +1042,7 @@ void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> mess
bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) { bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) {
auto nodeAData = static_cast<DomainServerNodeData*>(nodeA->getLinkedData()); auto nodeAData = static_cast<DomainServerNodeData*>(nodeA->getLinkedData());
auto nodeBData = static_cast<DomainServerNodeData*>(nodeB->getLinkedData()); return nodeAData && nodeAData->getNodeInterestSet().contains(nodeB->getType());
// if we have no linked data for node A then B can't possibly be in the interest set
if (!nodeAData) {
return false;
}
// first check if the general interest set A contains the type for B
if (nodeAData->getNodeInterestSet().contains(nodeB->getType())) {
// given that there is a match in the general interest set, do any special checks
// (1/19/17) Agents only need to connect to Entity Script Servers to perform administrative tasks
// related to entity server scripts. Only agents with rez permissions should be doing that, so
// if the agent does not have those permissions, we do not want them and the server to incur the
// overhead of connecting to one another. Additionally we exclude agents that do not care about the
// Entity Script Server and won't attempt to connect to it.
bool isAgentWithoutRights = nodeA->getType() == NodeType::Agent
&& nodeB->getType() == NodeType::EntityScriptServer
&& !nodeA->getCanRez() && !nodeA->getCanRezTmp()
&& !nodeA->getCanRezCertified() && !nodeA->getCanRezTmpCertified();
if (isAgentWithoutRights) {
return false;
}
bool isScriptServerForIneffectiveAgent =
(nodeA->getType() == NodeType::EntityScriptServer && nodeB->getType() == NodeType::Agent)
&& ((nodeBData && !nodeBData->getNodeInterestSet().contains(NodeType::EntityScriptServer))
|| (!nodeB->getCanRez() && !nodeB->getCanRezTmp() && !nodeB->getCanRezCertified() && !nodeB->getCanRezTmpCertified()));
return !isScriptServerForIneffectiveAgent;
} else {
return false;
}
} }
unsigned int DomainServer::countConnectedUsers() { unsigned int DomainServer::countConnectedUsers() {
@ -3476,4 +3442,4 @@ void DomainServer::handleOctreeFileReplacementRequest(QSharedPointer<ReceivedMes
if (node->getCanReplaceContent()) { if (node->getCanReplaceContent()) {
handleOctreeFileReplacement(message->readAll()); handleOctreeFileReplacement(message->readAll());
} }
} }

View file

@ -163,10 +163,18 @@ TextField {
text: textField.label text: textField.label
colorScheme: textField.colorScheme colorScheme: textField.colorScheme
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right
Binding on anchors.right {
when: parent.right
value: parent.right
}
Binding on wrapMode {
when: parent.right
value: Text.WordWrap
}
anchors.bottom: parent.top anchors.bottom: parent.top
anchors.bottomMargin: 3 anchors.bottomMargin: 3
wrapMode: Text.WordWrap
visible: label != "" visible: label != ""
} }
} }

View file

@ -6244,8 +6244,9 @@ bool Application::canAcceptURL(const QString& urlString) const {
bool Application::acceptURL(const QString& urlString, bool defaultUpload) { bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
QUrl url(urlString); QUrl url(urlString);
if (isDomainURL(url)) {
// this is a URL for a domain, either hifi:// or serverless - have the AddressManager handle it if (url.scheme() == URL_SCHEME_HIFI) {
// this is a hifi URL - have the AddressManager handle it
QMetaObject::invokeMethod(DependencyManager::get<AddressManager>().data(), "handleLookupString", QMetaObject::invokeMethod(DependencyManager::get<AddressManager>().data(), "handleLookupString",
Qt::AutoConnection, Q_ARG(const QString&, urlString)); Qt::AutoConnection, Q_ARG(const QString&, urlString));
return true; return true;

View file

@ -6,10 +6,43 @@
// 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
// //
// NOTE: we don't need to include this header unless/until we add additional symbols. #include "JSEndpoint.h"
// By removing this header we prevent these warnings on windows: #include "../../Logging.h"
//
// warning LNK4221: This object file does not define any previously undefined public symbols, using namespace controller;
// so it will not be used by any link operation that consumes this library
// QString formatException(const QJSValue& exception) {
//#include "JSEndpoint.h" QString note { "UncaughtException" };
QString result;
const auto message = exception.toString();
const auto fileName = exception.property("fileName").toString();
const auto lineNumber = exception.property("lineNumber").toString();
const auto stacktrace = exception.property("stack").toString();
const QString SCRIPT_EXCEPTION_FORMAT = "[%0] %1 in %2:%3";
const QString SCRIPT_BACKTRACE_SEP = "\n ";
result = QString(SCRIPT_EXCEPTION_FORMAT).arg(note, message, fileName, lineNumber);
if (!stacktrace.isEmpty()) {
result += QString("\n[Backtrace]%1%2").arg(SCRIPT_BACKTRACE_SEP).arg(stacktrace);
}
return result;
}
float JSEndpoint::peek() const {
QJSValue result = _callable.call();
if (result.isError()) {
qCDebug(controllers).noquote() << formatException(result);
return 0.0f;
} else {
return (float)result.toNumber();
}
}
void JSEndpoint::apply(float newValue, const Pointer& source) {
QJSValue result = _callable.call(QJSValueList({ QJSValue(newValue) }));
if (result.isError()) {
qCDebug(controllers).noquote() << formatException(result);
}
}

View file

@ -24,16 +24,11 @@ public:
: Endpoint(Input::INVALID_INPUT), _callable(callable) { : Endpoint(Input::INVALID_INPUT), _callable(callable) {
} }
virtual float peek() const override { virtual float peek() const override;
return (float)const_cast<JSEndpoint*>(this)->_callable.call().toNumber(); virtual void apply(float newValue, const Pointer& source) override;
}
virtual void apply(float newValue, const Pointer& source) override {
_callable.call(QJSValueList({ QJSValue(newValue) }));
}
private: private:
QJSValue _callable; mutable QJSValue _callable;
}; };
} }

View file

@ -7,6 +7,7 @@
// //
#include "ScriptEndpoint.h" #include "ScriptEndpoint.h"
#include "../../Logging.h"
#include <QtCore/QThread> #include <QtCore/QThread>
@ -14,6 +15,25 @@
using namespace controller; using namespace controller;
QString formatException(const QScriptValue& exception) {
QString note { "UncaughtException" };
QString result;
const auto message = exception.toString();
const auto fileName = exception.property("fileName").toString();
const auto lineNumber = exception.property("lineNumber").toString();
const auto stacktrace = exception.property("stack").toString();
const QString SCRIPT_EXCEPTION_FORMAT = "[%0] %1 in %2:%3";
const QString SCRIPT_BACKTRACE_SEP = "\n ";
result = QString(SCRIPT_EXCEPTION_FORMAT).arg(note, message, fileName, lineNumber);
if (!stacktrace.isEmpty()) {
result += QString("\n[Backtrace]%1%2").arg(SCRIPT_BACKTRACE_SEP).arg(stacktrace);
}
return result;
}
float ScriptEndpoint::peek() const { float ScriptEndpoint::peek() const {
const_cast<ScriptEndpoint*>(this)->updateValue(); const_cast<ScriptEndpoint*>(this)->updateValue();
return _lastValueRead; return _lastValueRead;
@ -26,10 +46,11 @@ void ScriptEndpoint::updateValue() {
} }
QScriptValue result = _callable.call(); QScriptValue result = _callable.call();
if (result.isError()) {
// If the callable ever returns a non-number, we assume it's a pose // print JavaScript exception
// and start reporting ourselves as a pose. qCDebug(controllers).noquote() << formatException(result);
if (result.isNumber()) { _lastValueRead = 0.0f;
} else if (result.isNumber()) {
_lastValueRead = (float)_callable.call().toNumber(); _lastValueRead = (float)_callable.call().toNumber();
} else { } else {
Pose::fromScriptValue(result, _lastPoseRead); Pose::fromScriptValue(result, _lastPoseRead);
@ -52,8 +73,12 @@ void ScriptEndpoint::internalApply(float value, int sourceID) {
Q_ARG(int, sourceID)); Q_ARG(int, sourceID));
return; return;
} }
_callable.call(QScriptValue(), QScriptValue result = _callable.call(QScriptValue(),
QScriptValueList({ QScriptValue(value), QScriptValue(sourceID) })); QScriptValueList({ QScriptValue(value), QScriptValue(sourceID) }));
if (result.isError()) {
// print JavaScript exception
qCDebug(controllers).noquote() << formatException(result);
}
} }
Pose ScriptEndpoint::peekPose() const { Pose ScriptEndpoint::peekPose() const {
@ -67,6 +92,10 @@ void ScriptEndpoint::updatePose() {
return; return;
} }
QScriptValue result = _callable.call(); QScriptValue result = _callable.call();
if (result.isError()) {
// print JavaScript exception
qCDebug(controllers).noquote() << formatException(result);
}
Pose::fromScriptValue(result, _lastPoseRead); Pose::fromScriptValue(result, _lastPoseRead);
} }
@ -85,6 +114,10 @@ void ScriptEndpoint::internalApply(const Pose& newPose, int sourceID) {
Q_ARG(int, sourceID)); Q_ARG(int, sourceID));
return; return;
} }
_callable.call(QScriptValue(), QScriptValue result = _callable.call(QScriptValue(),
QScriptValueList({ Pose::toScriptValue(_callable.engine(), newPose), QScriptValue(sourceID) })); QScriptValueList({ Pose::toScriptValue(_callable.engine(), newPose), QScriptValue(sourceID) }));
if (result.isError()) {
// print JavaScript exception
qCDebug(controllers).noquote() << formatException(result);
}
} }

View file

@ -131,6 +131,8 @@ ItemKey ShapeEntityRenderer::getKey() {
withReadLock([&] { withReadLock([&] {
if (isTransparent()) { if (isTransparent()) {
builder.withTransparent(); builder.withTransparent();
} else if (_canCastShadow) {
builder.withShadowCaster();
} }
}); });

View file

@ -425,8 +425,8 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti
if (!childEntity) { if (!childEntity) {
continue; continue;
} }
EntityTreeElementPointer containingElement = childEntity->getElement(); EntityTreeElementPointer childContainingElement = childEntity->getElement();
if (!containingElement) { if (!childContainingElement) {
continue; continue;
} }
@ -440,7 +440,7 @@ bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperti
addToNeedsParentFixupList(childEntity); addToNeedsParentFixupList(childEntity);
} }
UpdateEntityOperator theChildOperator(getThisPointer(), containingElement, childEntity, queryCube); UpdateEntityOperator theChildOperator(getThisPointer(), childContainingElement, childEntity, queryCube);
recurseTreeWithOperator(&theChildOperator); recurseTreeWithOperator(&theChildOperator);
foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) { foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) {
if (childChild && childChild->getNestableType() == NestableType::Entity) { if (childChild && childChild->getNestableType() == NestableType::Entity) {

View file

@ -288,7 +288,7 @@ OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(const OctreeEle
int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityBox); int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityBox);
if (childIndex == indexOfChildContainingNewEntity) { if (childIndex == indexOfChildContainingNewEntity) {
return element->addChildAtIndex(childIndex);; return element->addChildAtIndex(childIndex);
} }
} }
} }

View file

@ -380,6 +380,8 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, nullptr);
batch.setResourceTexture(AntialiasingPass_NextMapSlot, nullptr); batch.setResourceTexture(AntialiasingPass_NextMapSlot, nullptr);
}); });
args->popViewFrustum();
} }
@ -520,7 +522,7 @@ void JitterSample::run(const render::RenderContextPointer& renderContext) {
viewFrustum.setProjection(projMat); viewFrustum.setProjection(projMat);
viewFrustum.calculate(); viewFrustum.calculate();
args->setViewFrustum(viewFrustum); args->pushViewFrustum(viewFrustum);
} else { } else {
mat4 projMats[2]; mat4 projMats[2];
args->_context->getStereoProjections(projMats); args->_context->getStereoProjections(projMats);
@ -538,4 +540,4 @@ void JitterSample::run(const render::RenderContextPointer& renderContext) {
} }
#endif #endif

View file

@ -46,7 +46,7 @@ void printOctalCode(const unsigned char* octalCode) {
} }
char sectionValue(const unsigned char* startByte, char startIndexInByte) { char sectionValue(const unsigned char* startByte, char startIndexInByte) {
char rightShift = 8 - startIndexInByte - 3; int8_t rightShift = 8 - startIndexInByte - 3;
if (rightShift < 0) { if (rightShift < 0) {
return ((startByte[0] << -rightShift) & 7) + (startByte[1] >> (8 + rightShift)); return ((startByte[0] << -rightShift) & 7) + (startByte[1] >> (8 + rightShift));
@ -73,7 +73,7 @@ int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsi
return sectionValue(descendantOctalCode + 1 + (branchStartBit / 8), branchStartBit % 8); return sectionValue(descendantOctalCode + 1 + (branchStartBit / 8), branchStartBit % 8);
} }
unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNumber) { unsigned char* childOctalCode(const unsigned char* parentOctalCode, int childNumber) {
// find the length (in number of three bit code sequences) // find the length (in number of three bit code sequences)
// in the parent // in the parent
@ -111,7 +111,7 @@ unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNu
// calculate the amount of left shift required // calculate the amount of left shift required
// this will be -1 or -2 if there's wrap // this will be -1 or -2 if there's wrap
char leftShift = 8 - (startBit % 8) - 3; int8_t leftShift = 8 - (startBit % 8) - 3;
if (leftShift < 0) { if (leftShift < 0) {
// we have a wrap-around to accomodate // we have a wrap-around to accomodate

View file

@ -30,7 +30,7 @@ using OctalCodePtrList = std::vector<OctalCodePtr>;
void printOctalCode(const unsigned char* octalCode); void printOctalCode(const unsigned char* octalCode);
size_t bytesRequiredForCodeLength(unsigned char threeBitCodes); size_t bytesRequiredForCodeLength(unsigned char threeBitCodes);
int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsigned char* descendantOctalCode); int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsigned char* descendantOctalCode);
unsigned char* childOctalCode(const unsigned char* parentOctalCode, char childNumber); unsigned char* childOctalCode(const unsigned char* parentOctalCode, int childNumber);
const int OVERFLOWED_OCTCODE_BUFFER = -1; const int OVERFLOWED_OCTCODE_BUFFER = -1;
const int UNKNOWN_OCTCODE_LENGTH = -2; const int UNKNOWN_OCTCODE_LENGTH = -2;

View file

@ -1618,8 +1618,18 @@ SelectionDisplay = (function() {
grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly), grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly),
cornerPosition); cornerPosition);
for (var i = 0; i < SelectionManager.selections.length; i++) { // editing a parent will cause all the children to automatically follow along, so don't
var properties = SelectionManager.savedProperties[SelectionManager.selections[i]]; // edit any entity who has an ancestor in SelectionManager.selections
var toMove = SelectionManager.selections.filter(function (selection) {
if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
return false; // a parent is also being moved, so don't issue an edit for this entity
} else {
return true;
}
});
for (var i = 0; i < toMove.length; i++) {
var properties = SelectionManager.savedProperties[toMove[i]];
if (!properties) { if (!properties) {
continue; continue;
} }
@ -1628,7 +1638,7 @@ SelectionDisplay = (function() {
y: 0, y: 0,
z: vector.z z: vector.z
}); });
Entities.editEntity(SelectionManager.selections[i], { Entities.editEntity(toMove[i], {
position: newPosition position: newPosition
}); });
@ -1727,9 +1737,19 @@ SelectionDisplay = (function() {
Vec3.print(" newIntersection:", newIntersection); Vec3.print(" newIntersection:", newIntersection);
Vec3.print(" vector:", vector); Vec3.print(" vector:", vector);
} }
for (var i = 0; i < SelectionManager.selections.length; i++) { // editing a parent will cause all the children to automatically follow along, so don't
var id = SelectionManager.selections[i]; // edit any entity who has an ancestor in SelectionManager.selections
var toMove = SelectionManager.selections.filter(function (selection) {
if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
return false; // a parent is also being moved, so don't issue an edit for this entity
} else {
return true;
}
});
for (var i = 0; i < toMove.length; i++) {
var id = toMove[i];
var properties = SelectionManager.savedProperties[id]; var properties = SelectionManager.savedProperties[id];
var newPosition = Vec3.sum(properties.position, vector); var newPosition = Vec3.sum(properties.position, vector);
Entities.editEntity(id, { position: newPosition }); Entities.editEntity(id, { position: newPosition });
@ -2166,8 +2186,19 @@ SelectionDisplay = (function() {
// the selections center point. Otherwise, the rotation will be around the entities // the selections center point. Otherwise, the rotation will be around the entities
// registration point which does not need repositioning. // registration point which does not need repositioning.
var reposition = (SelectionManager.selections.length > 1); var reposition = (SelectionManager.selections.length > 1);
for (var i = 0; i < SelectionManager.selections.length; i++) {
var entityID = SelectionManager.selections[i]; // editing a parent will cause all the children to automatically follow along, so don't
// edit any entity who has an ancestor in SelectionManager.selections
var toRotate = SelectionManager.selections.filter(function (selection) {
if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
return false; // a parent is also being moved, so don't issue an edit for this entity
} else {
return true;
}
});
for (var i = 0; i < toRotate.length; i++) {
var entityID = toRotate[i];
var initialProperties = SelectionManager.savedProperties[entityID]; var initialProperties = SelectionManager.savedProperties[entityID];
var newProperties = { var newProperties = {