diff --git a/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx b/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx deleted file mode 100644 index 6d46791fa2..0000000000 Binary files a/interface/resources/images/+gles/Default-Sky-9-cubemap.ktx and /dev/null differ diff --git a/interface/resources/images/Default-Sky-9-cubemap.ktx b/interface/resources/images/Default-Sky-9-cubemap.ktx deleted file mode 100644 index 70f495c3ab..0000000000 Binary files a/interface/resources/images/Default-Sky-9-cubemap.ktx and /dev/null differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg new file mode 100644 index 0000000000..7977396159 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.jpg differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx new file mode 100644 index 0000000000..4231bf7650 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.ktx differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json new file mode 100644 index 0000000000..28512662d9 --- /dev/null +++ b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json @@ -0,0 +1,8 @@ +{ + "compressed": { + "COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT": "Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx", + "COMPRESSED_SRGB8_ETC2": "Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx" + }, + "original": "Default-Sky-9-cubemap.jpg", + "uncompressed": "Default-Sky-9-cubemap.ktx" +} diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx new file mode 100644 index 0000000000..c789fa4ac5 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx differ diff --git a/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx new file mode 100644 index 0000000000..deede32614 Binary files /dev/null and b/interface/resources/images/Default-Sky-9-cubemap/Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx differ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index aa2b382c58..2dc3645be0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -152,6 +152,8 @@ #include #include #include +#include +#include "recording/ClipCache.h" #include "AudioClient.h" #include "audio/AudioScope.h" @@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains #endif #if !defined(Q_OS_ANDROID) -static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; +static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; #else -static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4; +static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4; #endif // For processing on QThreadPool, we target a number of threads after reserving some @@ -1327,7 +1329,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads"); bool success; - int concurrentDownloads = concurrentDownloadsStr.toInt(&success); + uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success); if (!success) { concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS; } @@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } properties["active_downloads"] = loadingRequests.size(); - properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); + properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount(); properties["active_downloads_details"] = loadingRequestsStats; auto statTracker = DependencyManager::get(); @@ -4653,8 +4655,8 @@ void Application::idle() { PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate()); } PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate()); - PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length()); - PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount()); + PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount()); + PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", uint32_t, ResourceCache::getPendingRequestCount()); PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get()->getStat("Processing").toInt()); PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get()->getStat("PendingProcessing").toInt()); auto renderConfig = _renderEngine->getConfiguration(); @@ -5399,13 +5401,21 @@ void Application::reloadResourceCaches() { queryOctree(NodeType::EntityServer, PacketType::EntityQuery); + // Clear the entities and their renderables + getEntities()->clear(); + DependencyManager::get()->clearCache(); DependencyManager::get()->clearCache(); + // Clear all the resource caches + DependencyManager::get()->clear(); DependencyManager::get()->refreshAll(); - DependencyManager::get()->refreshAll(); DependencyManager::get()->refreshAll(); + MaterialCache::instance().refreshAll(); + DependencyManager::get()->refreshAll(); + ShaderCache::instance().refreshAll(); DependencyManager::get()->refreshAll(); + DependencyManager::get()->refreshAll(); DependencyManager::get()->reset(); // Force redownload of .fst models @@ -6470,9 +6480,12 @@ void Application::clearDomainOctreeDetails() { skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT); DependencyManager::get()->clearUnusedResources(); - DependencyManager::get()->clearUnusedResources(); DependencyManager::get()->clearUnusedResources(); + MaterialCache::instance().clearUnusedResources(); + DependencyManager::get()->clearUnusedResources(); + ShaderCache::instance().clearUnusedResources(); DependencyManager::get()->clearUnusedResources(); + DependencyManager::get()->clearUnusedResources(); getMyAvatar()->setAvatarEntityDataChanged(true); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b347963cf1..c61b424bce 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1942,7 +1942,7 @@ void MyAvatar::updateMotors() { horizontalMotorTimescale = FLYING_MOTOR_TIMESCALE; verticalMotorTimescale = FLYING_MOTOR_TIMESCALE; } else { - horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE; + horizontalMotorTimescale = WALKING_MOTOR_TIMESCALE * getSensorToWorldScale(); verticalMotorTimescale = INVALID_MOTOR_TIMESCALE; } diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 625998eb95..c2687fd525 100644 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -11,12 +11,12 @@ #include "AvatarMotionState.h" -static xColor getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) { +static glm::u8vec3 getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) { - const xColor NO_MODEL_COLOR(0xe3, 0xe3, 0xe3); - const xColor LOAD_MODEL_COLOR(0xef, 0x93, 0xd1); - const xColor LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6); - const xColor LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47); + const glm::u8vec3 NO_MODEL_COLOR(0xe3, 0xe3, 0xe3); + const glm::u8vec3 LOAD_MODEL_COLOR(0xef, 0x93, 0xd1); + const glm::u8vec3 LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6); + const glm::u8vec3 LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47); switch (loadingStatus) { case Avatar::LoadingStatus::NoModel: return NO_MODEL_COLOR; diff --git a/interface/src/raypick/ParabolaPointer.cpp b/interface/src/raypick/ParabolaPointer.cpp index dde0daf0df..e45b11b479 100644 --- a/interface/src/raypick/ParabolaPointer.cpp +++ b/interface/src/raypick/ParabolaPointer.cpp @@ -52,8 +52,7 @@ void ParabolaPointer::editRenderStatePath(const std::string& state, const QVaria if (!pathMap.isEmpty()) { enabled = true; if (pathMap["color"].isValid()) { - bool valid; - color = toGlm(xColorFromVariant(pathMap["color"], valid)); + color = toGlm(u8vec3FromVariant(pathMap["color"])); } if (pathMap["alpha"].isValid()) { alpha = pathMap["alpha"].toFloat(); @@ -250,8 +249,7 @@ std::shared_ptr ParabolaPointer::buildRenderState(const QVa enabled = true; QVariantMap pathMap = propMap["path"].toMap(); if (pathMap["color"].isValid()) { - bool valid; - color = toGlm(xColorFromVariant(pathMap["color"], valid)); + color = toGlm(u8vec3FromVariant(pathMap["color"])); } if (pathMap["alpha"].isValid()) { diff --git a/interface/src/scripting/SelectionScriptingInterface.cpp b/interface/src/scripting/SelectionScriptingInterface.cpp index 9716b7e665..4a8a72b16d 100644 --- a/interface/src/scripting/SelectionScriptingInterface.cpp +++ b/interface/src/scripting/SelectionScriptingInterface.cpp @@ -421,7 +421,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { auto colorVariant = properties["outlineUnoccludedColor"]; if (colorVariant.isValid()) { bool isValid; - auto color = xColorFromVariant(colorVariant, isValid); + auto color = u8vec3FromVariant(colorVariant, isValid); if (isValid) { _style._outlineUnoccluded.color = toGlm(color); } @@ -429,7 +429,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { colorVariant = properties["outlineOccludedColor"]; if (colorVariant.isValid()) { bool isValid; - auto color = xColorFromVariant(colorVariant, isValid); + auto color = u8vec3FromVariant(colorVariant, isValid); if (isValid) { _style._outlineOccluded.color = toGlm(color); } @@ -437,7 +437,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { colorVariant = properties["fillUnoccludedColor"]; if (colorVariant.isValid()) { bool isValid; - auto color = xColorFromVariant(colorVariant, isValid); + auto color = u8vec3FromVariant(colorVariant, isValid); if (isValid) { _style._fillUnoccluded.color = toGlm(color); } @@ -445,7 +445,7 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { colorVariant = properties["fillOccludedColor"]; if (colorVariant.isValid()) { bool isValid; - auto color = xColorFromVariant(colorVariant, isValid); + auto color = u8vec3FromVariant(colorVariant, isValid); if (isValid) { _style._fillOccluded.color = toGlm(color); } @@ -497,10 +497,11 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) { QVariantMap SelectionHighlightStyle::toVariantMap() const { QVariantMap properties; - properties["outlineUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineUnoccluded.color)); - properties["outlineOccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineOccluded.color)); - properties["fillUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillUnoccluded.color)); - properties["fillOccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillOccluded.color)); + const float MAX_COLOR = 255.0f; + properties["outlineUnoccludedColor"] = u8vec3ColortoVariant(_style._outlineUnoccluded.color * MAX_COLOR); + properties["outlineOccludedColor"] = u8vec3ColortoVariant(_style._outlineOccluded.color * MAX_COLOR); + properties["fillUnoccludedColor"] = u8vec3ColortoVariant(_style._fillUnoccluded.color * MAX_COLOR); + properties["fillOccludedColor"] = u8vec3ColortoVariant(_style._fillOccluded.color * MAX_COLOR); properties["outlineUnoccludedAlpha"] = _style._outlineUnoccluded.alpha; properties["outlineOccludedAlpha"] = _style._outlineOccluded.alpha; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 8faa51bc58..495e29f986 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -267,8 +267,8 @@ void Stats::updateStats(bool force) { auto loadingRequests = ResourceCache::getLoadingRequests(); STAT_UPDATE(downloads, loadingRequests.size()); - STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit()) - STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount()); + STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit()) + STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount()); STAT_UPDATE(processing, DependencyManager::get()->getStat("Processing").toInt()); STAT_UPDATE(processingPending, DependencyManager::get()->getStat("PendingProcessing").toInt()); diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 1d8db69e26..14c1f1a15a 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { if (properties["parentID"].isValid()) { setParentID(QUuid(properties["parentID"].toString())); - bool success; - getParentPointer(success); // call this to hook-up the parent's back-pointers to its child overlays needRenderItemUpdate = true; } if (properties["parentJointIndex"].isValid()) { diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 1d418d966e..a98ea7070e 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -75,7 +75,6 @@ void Circle3DOverlay::render(RenderArgs* args) { const float FULL_CIRCLE = 360.0f; const float SLICES = 180.0f; // The amount of segment to create the circle const float SLICE_ANGLE_RADIANS = glm::radians(FULL_CIRCLE / SLICES); - const float MAX_COLOR = 255.0f; auto geometryCache = DependencyManager::get(); @@ -246,20 +245,15 @@ void Circle3DOverlay::render(RenderArgs* args) { angle += tickMarkAngle; } } - - xColor majorColorX = getMajorTickMarksColor(); - glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha); - + + glm::vec4 majorColor(toGlm(getMajorTickMarksColor()), alpha); geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor); - - xColor minorColorX = getMinorTickMarksColor(); - glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha); - + glm::vec4 minorColor(toGlm(getMinorTickMarksColor()), alpha); geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor); } - + geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID); - + geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID); } } @@ -280,8 +274,8 @@ template T fromVariant(const QVariant& v, bool& valid) { return qvariant_cast(v); } -template<> xColor fromVariant(const QVariant& v, bool& valid) { - return xColorFromVariant(v, valid); +template<> glm::u8vec3 fromVariant(const QVariant& v, bool& valid) { + return u8vec3FromVariant(v, valid); } template @@ -344,11 +338,11 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) { _dirty |= updateIfValid(properties, "outerStartAlpha", _outerStartAlpha); _dirty |= updateIfValid(properties, "outerEndAlpha", _outerEndAlpha); - _dirty |= updateIfValid(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor }); - _dirty |= updateIfValid(properties, "startColor", { _innerStartColor, _outerStartColor } ); - _dirty |= updateIfValid(properties, "endColor", { _innerEndColor, _outerEndColor } ); - _dirty |= updateIfValid(properties, "innerColor", { _innerStartColor, _innerEndColor } ); - _dirty |= updateIfValid(properties, "outerColor", { _outerStartColor, _outerEndColor } ); + _dirty |= updateIfValid(properties, "color", { _innerStartColor, _innerEndColor, _outerStartColor, _outerEndColor }); + _dirty |= updateIfValid(properties, "startColor", { _innerStartColor, _outerStartColor } ); + _dirty |= updateIfValid(properties, "endColor", { _innerEndColor, _outerEndColor } ); + _dirty |= updateIfValid(properties, "innerColor", { _innerStartColor, _innerEndColor } ); + _dirty |= updateIfValid(properties, "outerColor", { _outerStartColor, _outerEndColor } ); _dirty |= updateIfValid(properties, "innerStartColor", _innerStartColor); _dirty |= updateIfValid(properties, "innerEndColor", _innerEndColor); _dirty |= updateIfValid(properties, "outerStartColor", _outerStartColor); @@ -421,7 +415,7 @@ void Circle3DOverlay::setProperties(const QVariantMap& properties) { * @property {number} endAt=360 - The counter-clockwise angle from the overlay's x-axis that drawing ends at, in degrees. * @property {number} outerRadius=1 - The outer radius of the overlay, in meters. Synonym: radius. * @property {number} innerRadius=0 - The inner radius of the overlay, in meters. - * @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of + * @property {Color} color=255,255,255 - The color of the overlay. Setting this value also sets the values of * innerStartColor, innerEndColor, outerStartColor, and outerEndColor. * @property {Color} startColor - Sets the values of innerStartColor and outerStartColor. * Write-only. @@ -478,16 +472,16 @@ QVariant Circle3DOverlay::getProperty(const QString& property) { return _innerRadius; } if (property == "innerStartColor") { - return xColorToVariant(_innerStartColor); + return u8vec3ColortoVariant(_innerStartColor); } if (property == "innerEndColor") { - return xColorToVariant(_innerEndColor); + return u8vec3ColortoVariant(_innerEndColor); } if (property == "outerStartColor") { - return xColorToVariant(_outerStartColor); + return u8vec3ColortoVariant(_outerStartColor); } if (property == "outerEndColor") { - return xColorToVariant(_outerEndColor); + return u8vec3ColortoVariant(_outerEndColor); } if (property == "innerStartAlpha") { return _innerStartAlpha; @@ -517,10 +511,10 @@ QVariant Circle3DOverlay::getProperty(const QString& property) { return _minorTickMarksLength; } if (property == "majorTickMarksColor") { - return xColorToVariant(_majorTickMarksColor); + return u8vec3ColortoVariant(_majorTickMarksColor); } if (property == "minorTickMarksColor") { - return xColorToVariant(_minorTickMarksColor); + return u8vec3ColortoVariant(_minorTickMarksColor); } return Planar3DOverlay::getProperty(property); diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index b3fa24fb16..ca5e05a53b 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -39,8 +39,8 @@ public: float getMinorTickMarksAngle() const { return _minorTickMarksAngle; } float getMajorTickMarksLength() const { return _majorTickMarksLength; } float getMinorTickMarksLength() const { return _minorTickMarksLength; } - xColor getMajorTickMarksColor() const { return _majorTickMarksColor; } - xColor getMinorTickMarksColor() const { return _minorTickMarksColor; } + glm::u8vec3 getMajorTickMarksColor() const { return _majorTickMarksColor; } + glm::u8vec3 getMinorTickMarksColor() const { return _minorTickMarksColor; } void setStartAt(float value) { _startAt = value; } void setEndAt(float value) { _endAt = value; } @@ -51,8 +51,8 @@ public: void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; } void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; } void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; } - void setMajorTickMarksColor(const xColor& value) { _majorTickMarksColor = value; } - void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; } + void setMajorTickMarksColor(const glm::u8vec3& value) { _majorTickMarksColor = value; } + void setMinorTickMarksColor(const glm::u8vec3& value) { _minorTickMarksColor = value; } virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal, bool precisionPicking = false) override; @@ -67,10 +67,10 @@ protected: float _outerRadius { 1 }; float _innerRadius { 0 }; - xColor _innerStartColor { DEFAULT_OVERLAY_COLOR }; - xColor _innerEndColor { DEFAULT_OVERLAY_COLOR }; - xColor _outerStartColor { DEFAULT_OVERLAY_COLOR }; - xColor _outerEndColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _innerStartColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _innerEndColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _outerStartColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _outerEndColor { DEFAULT_OVERLAY_COLOR }; float _innerStartAlpha { DEFAULT_ALPHA }; float _innerEndAlpha { DEFAULT_ALPHA }; float _outerStartAlpha { DEFAULT_ALPHA }; @@ -81,8 +81,8 @@ protected: float _minorTickMarksAngle { 0 }; float _majorTickMarksLength { 0 }; float _minorTickMarksLength { 0 }; - xColor _majorTickMarksColor { DEFAULT_OVERLAY_COLOR }; - xColor _minorTickMarksColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _majorTickMarksColor { DEFAULT_OVERLAY_COLOR }; + glm::u8vec3 _minorTickMarksColor { DEFAULT_OVERLAY_COLOR }; gpu::Primitive _solidPrimitive { gpu::TRIANGLE_FAN }; int _quadVerticesID { 0 }; int _lineVerticesID { 0 }; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 5de8bb1a2a..9f1018f6c7 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -83,7 +83,7 @@ ContextOverlayInterface::ContextOverlayInterface() { _challengeOwnershipTimeoutTimer.setSingleShot(true); } -static const xColor CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; +static const glm::u8vec3 CONTEXT_OVERLAY_COLOR = { 255, 255, 255 }; static const float CONTEXT_OVERLAY_INSIDE_DISTANCE = 1.0f; // in meters static const float CONTEXT_OVERLAY_SIZE = 0.09f; // in meters, same x and y dims static const float CONTEXT_OVERLAY_OFFSET_DISTANCE = 0.1f; @@ -142,14 +142,15 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& glm::vec3 cameraPosition = qApp->getCamera().getPosition(); glm::vec3 entityDimensions = entityProperties.getDimensions(); glm::vec3 entityPosition = entityProperties.getPosition(); + glm::vec3 registrationPoint = entityProperties.getRegistrationPoint(); glm::vec3 contextOverlayPosition = entityProperties.getPosition(); glm::vec2 contextOverlayDimensions; // Update the position of the overlay if the registration point of the entity // isn't default - if (entityProperties.getRegistrationPoint() != glm::vec3(0.5f)) { - glm::vec3 adjustPos = entityProperties.getRegistrationPoint() - glm::vec3(0.5f); - entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityProperties.getDimensions())); + if (registrationPoint != glm::vec3(0.5f)) { + glm::vec3 adjustPos = registrationPoint - glm::vec3(0.5f); + entityPosition = entityPosition - (entityProperties.getRotation() * (adjustPos * entityDimensions)); } enableEntityHighlight(entityItemID); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 38fff5f26f..581db672a3 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -49,11 +49,8 @@ void Cube3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - xColor color = getColor(); - const float MAX_COLOR = 255.0f; - glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - - + glm::u8vec3 color = getColor(); + glm::vec4 cubeColor(toGlm(color), alpha); auto batch = args->_batch; if (batch) { diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 15eb9eef76..87ab0fb2e8 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -57,11 +57,9 @@ void Grid3DOverlay::render(RenderArgs* args) { return; // do nothing if we're not visible } - const float MAX_COLOR = 255.0f; - float alpha = getAlpha(); - xColor color = getColor(); - glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::u8vec3 color = getColor(); + glm::vec4 gridColor(toGlm(color), alpha); auto batch = args->_batch; diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index 608e7eb72f..18da15f019 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -107,17 +107,16 @@ void Image3DOverlay::render(RenderArgs* args) { glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width() - 0.5f) / imageWidth, (fromImage.y() + fromImage.height() - 0.5f) / imageHeight); - const float MAX_COLOR = 255.0f; - xColor color = getColor(); float alpha = getAlpha(); + glm::u8vec3 color = getColor(); + glm::vec4 imageColor(toGlm(color), alpha); batch->setModelTransform(getRenderTransform()); batch->setResourceTexture(0, _texture->getGPUTexture()); DependencyManager::get()->renderQuad( *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, - glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha), - _geometryId + imageColor, _geometryId ); batch->setResourceTexture(0, nullptr); // restore default white color after me diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index af6c3c2472..e6546686b0 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -128,9 +128,8 @@ void Line3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - xColor color = getColor(); - const float MAX_COLOR = 255.0f; - glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::u8vec3 color = getColor(); + glm::vec4 colorv4(toGlm(color), alpha); auto batch = args->_batch; if (batch) { batch->setModelTransform(Transform()); diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index faa15ee2b4..22cf924727 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -15,7 +15,7 @@ #include "Application.h" -const xColor Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 }; +const glm::u8vec3 Overlay::DEFAULT_OVERLAY_COLOR = { 255, 255, 255 }; const float Overlay::DEFAULT_ALPHA = 0.7f; Overlay::Overlay() : @@ -57,7 +57,7 @@ Overlay::~Overlay() { void Overlay::setProperties(const QVariantMap& properties) { bool valid; - auto color = xColorFromVariant(properties["color"], valid); + auto color = u8vec3FromVariant(properties["color"], valid); if (valid) { _color = color; } @@ -116,7 +116,7 @@ QVariant Overlay::getProperty(const QString& property) { return QVariant(getType()); } if (property == "color") { - return xColorToVariant(_color); + return u8vec3ColortoVariant(_color); } if (property == "alpha") { return _alpha; @@ -143,21 +143,21 @@ QVariant Overlay::getProperty(const QString& property) { return QVariant(); } -xColor Overlay::getColor() { +glm::u8vec3 Overlay::getColor() { if (_colorPulse == 0.0f) { return _color; } float pulseLevel = updatePulse(); - xColor result = _color; + glm::u8vec3 result = _color; if (_colorPulse < 0.0f) { - result.red *= (1.0f - pulseLevel); - result.green *= (1.0f - pulseLevel); - result.blue *= (1.0f - pulseLevel); + result.x *= (1.0f - pulseLevel); + result.y *= (1.0f - pulseLevel); + result.z *= (1.0f - pulseLevel); } else { - result.red *= pulseLevel; - result.green *= pulseLevel; - result.blue *= pulseLevel; + result.x *= pulseLevel; + result.y *= pulseLevel; + result.z *= pulseLevel; } return result; } diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 45fc77a452..8e430f7e85 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -11,8 +11,6 @@ #ifndef hifi_Overlay_h #define hifi_Overlay_h -// include this before QGLWidget, which includes an earlier version of OpenGL -#include // for xColor #include class OverlayID : public QUuid { @@ -59,7 +57,7 @@ public: virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; }; virtual bool getIsVisibleInSecondaryCamera() const { return false; } - xColor getColor(); + glm::u8vec3 getColor(); float getAlpha(); float getPulseMax() const { return _pulseMax; } @@ -73,7 +71,7 @@ public: // setters virtual void setVisible(bool visible) { _visible = visible; } void setDrawHUDLayer(bool drawHUDLayer); - void setColor(const xColor& color) { _color = color; } + void setColor(const glm::u8vec3& color) { _color = color; } void setAlpha(float alpha) { _alpha = alpha; } void setPulseMax(float value) { _pulseMax = value; } @@ -115,12 +113,12 @@ protected: float _alphaPulse; // ratio of the pulse to the alpha float _colorPulse; // ratio of the pulse to the color - xColor _color; + glm::u8vec3 _color; bool _visible; // should the overlay be drawn at all unsigned int _stackOrder { 0 }; - static const xColor DEFAULT_OVERLAY_COLOR; + static const glm::u8vec3 DEFAULT_OVERLAY_COLOR; static const float DEFAULT_ALPHA; std::unordered_map _materials; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index de4ff94719..e05c44c264 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -629,9 +629,9 @@ QScriptValue RayToOverlayIntersectionResultToScriptValue(QScriptEngine* engine, obj.setProperty("distance", value.distance); obj.setProperty("face", boxFaceToString(value.face)); - QScriptValue intersection = vec3toScriptValue(engine, value.intersection); + QScriptValue intersection = vec3ToScriptValue(engine, value.intersection); obj.setProperty("intersection", intersection); - QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal); + QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal); obj.setProperty("surfaceNormal", surfaceNormal); obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo)); return obj; diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index cf2691bb13..c33d3a0c39 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -64,7 +64,7 @@ void Planar3DOverlay::setProperties(const QVariantMap& properties) { */ QVariant Planar3DOverlay::getProperty(const QString& property) { if (property == "dimensions" || property == "scale" || property == "size") { - return vec2toVariant(getDimensions()); + return vec2ToVariant(getDimensions()); } return Base3DOverlay::getProperty(property); diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 48d89fab1c..73606c0467 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -51,9 +51,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - xColor color = getColor(); - const float MAX_COLOR = 255.0f; - glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::u8vec3 color = getColor(); + glm::vec4 rectangleColor(toGlm(color), alpha); auto batch = args->_batch; if (batch) { diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index b0d3cf32af..b424424369 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -30,9 +30,8 @@ void Shape3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - xColor color = getColor(); - const float MAX_COLOR = 255.0f; - glm::vec4 cubeColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::u8vec3 color = getColor(); + glm::vec4 shapeColor(toGlm(color), alpha); auto batch = args->_batch; if (batch) { @@ -44,9 +43,9 @@ void Shape3DOverlay::render(RenderArgs* args) { batch->setModelTransform(getRenderTransform()); if (_isSolid) { - geometryCache->renderSolidShapeInstance(args, *batch, _shape, cubeColor, shapePipeline); + geometryCache->renderSolidShapeInstance(args, *batch, _shape, shapeColor, shapePipeline); } else { - geometryCache->renderWireShapeInstance(args, *batch, _shape, cubeColor, shapePipeline); + geometryCache->renderWireShapeInstance(args, *batch, _shape, shapeColor, shapePipeline); } } } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 00a0dd686c..97294ae871 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -77,9 +77,8 @@ void Sphere3DOverlay::render(RenderArgs* args) { } float alpha = getAlpha(); - xColor color = getColor(); - const float MAX_COLOR = 255.0f; - glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::u8vec3 color = getColor(); + glm::vec4 sphereColor(toGlm(color), alpha); auto batch = args->_batch; diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 40e49ccefd..c8f8550e8e 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -64,21 +64,21 @@ void Text3DOverlay::setText(const QString& text) { _text = text; } -xColor Text3DOverlay::getBackgroundColor() { +glm::u8vec3 Text3DOverlay::getBackgroundColor() { if (_colorPulse == 0.0f) { return _backgroundColor; } float pulseLevel = updatePulse(); - xColor result = _backgroundColor; + glm::u8vec3 result = _backgroundColor; if (_colorPulse < 0.0f) { - result.red *= (1.0f - pulseLevel); - result.green *= (1.0f - pulseLevel); - result.blue *= (1.0f - pulseLevel); + result.x *= (1.0f - pulseLevel); + result.y *= (1.0f - pulseLevel); + result.z *= (1.0f - pulseLevel); } else { - result.red *= pulseLevel; - result.green *= pulseLevel; - result.blue *= pulseLevel; + result.x *= pulseLevel; + result.y *= pulseLevel; + result.z *= pulseLevel; } return result; } @@ -94,10 +94,8 @@ void Text3DOverlay::render(RenderArgs* args) { auto transform = getRenderTransform(); batch.setModelTransform(transform); - const float MAX_COLOR = 255.0f; - xColor backgroundColor = getBackgroundColor(); - glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, - backgroundColor.blue / MAX_COLOR, getBackgroundAlpha()); + glm::u8vec3 backgroundColor = getBackgroundColor(); + glm::vec4 quadColor(toGlm(backgroundColor), getBackgroundAlpha()); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; @@ -122,8 +120,7 @@ void Text3DOverlay::render(RenderArgs* args) { transform.setScale(scaleFactor); batch.setModelTransform(transform); - glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR, - _color.blue / MAX_COLOR, getTextAlpha() }; + glm::vec4 textColor = { toGlm(_color), getTextAlpha() }; // FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline for a gpu performance increase. _textRenderer->draw(batch, 0, 0, getText(), textColor, glm::vec2(-1.0f), true); @@ -164,7 +161,7 @@ void Text3DOverlay::setProperties(const QVariantMap& properties) { bool valid; auto backgroundColor = properties["backgroundColor"]; if (backgroundColor.isValid()) { - auto color = xColorFromVariant(backgroundColor, valid); + auto color = u8vec3FromVariant(backgroundColor, valid); if (valid) { _backgroundColor = color; } @@ -260,7 +257,7 @@ QVariant Text3DOverlay::getProperty(const QString& property) { return _textAlpha; } if (property == "backgroundColor") { - return xColorToVariant(_backgroundColor); + return u8vec3ColortoVariant(_backgroundColor); } if (property == "backgroundAlpha") { return Billboard3DOverlay::getProperty("alpha"); diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index 21163101d0..16bbdcb4c4 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -39,7 +39,7 @@ public: float getTopMargin() const { return _topMargin; } float getRightMargin() const { return _rightMargin; } float getBottomMargin() const { return _bottomMargin; } - xColor getBackgroundColor(); + glm::u8vec3 getBackgroundColor(); float getTextAlpha() { return _textAlpha; } float getBackgroundAlpha() { return getAlpha(); } bool isTransparent() override { return Overlay::isTransparent() || _textAlpha < 1.0f; } @@ -65,7 +65,7 @@ private: QString _text; mutable QMutex _mutex; // used to make get/setText threadsafe, mutable so can be used in const functions - xColor _backgroundColor = xColor { 0, 0, 0 }; + glm::u8vec3 _backgroundColor { 0, 0, 0 }; float _textAlpha { 1.0f }; float _lineHeight { 1.0f }; float _leftMargin { 0.1f }; diff --git a/libraries/animation/src/AnimVariant.cpp b/libraries/animation/src/AnimVariant.cpp index 21fe234f7b..fe43fd8855 100644 --- a/libraries/animation/src/AnimVariant.cpp +++ b/libraries/animation/src/AnimVariant.cpp @@ -40,7 +40,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine, target.setProperty(name, value.getString()); break; case AnimVariant::Type::Vec3: - target.setProperty(name, vec3toScriptValue(engine, value.getVec3())); + target.setProperty(name, vec3ToScriptValue(engine, value.getVec3())); break; case AnimVariant::Type::Quat: target.setProperty(name, quatToScriptValue(engine, value.getQuat())); diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index f30d5605d7..04b7952ddb 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) : } AnimationPointer AnimationCache::getAnimation(const QUrl& url) { - if (QThread::currentThread() != thread()) { - AnimationPointer result; - BLOCKING_INVOKE_METHOD(this, "getAnimation", - Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url)); - return result; - } return getResource(url).staticCast(); } diff --git a/libraries/audio/src/AudioInjectorOptions.cpp b/libraries/audio/src/AudioInjectorOptions.cpp index 0f4ab7ff42..295da1506e 100644 --- a/libraries/audio/src/AudioInjectorOptions.cpp +++ b/libraries/audio/src/AudioInjectorOptions.cpp @@ -34,7 +34,7 @@ AudioInjectorOptions::AudioInjectorOptions() : QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInjectorOptions& injectorOptions) { QScriptValue obj = engine->newObject(); - obj.setProperty("position", vec3toScriptValue(engine, injectorOptions.position)); + obj.setProperty("position", vec3ToScriptValue(engine, injectorOptions.position)); obj.setProperty("volume", injectorOptions.volume); obj.setProperty("loop", injectorOptions.loop); obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation)); diff --git a/libraries/audio/src/SoundCache.cpp b/libraries/audio/src/SoundCache.cpp index 162e833da2..2877de3d6f 100644 --- a/libraries/audio/src/SoundCache.cpp +++ b/libraries/audio/src/SoundCache.cpp @@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) : } SharedSoundPointer SoundCache::getSound(const QUrl& url) { - if (QThread::currentThread() != thread()) { - SharedSoundPointer result; - BLOCKING_INVOKE_METHOD(this, "getSound", - Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url)); - return result; - } return getResource(url).staticCast(); } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d78d83bc09..6cd2101a0e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -75,8 +75,11 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints) totalSize += numJoints * sizeof(SixByteTrans); // Translations size_t NUM_FAUX_JOINT = 2; - size_t num_grab_joints = (hasGrabJoints ? 2 : 0); - totalSize += (NUM_FAUX_JOINT + num_grab_joints) * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints + totalSize += NUM_FAUX_JOINT * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints + + if (hasGrabJoints) { + totalSize += sizeof(AvatarDataPacket::FarGrabJoints); + } return totalSize; } @@ -690,7 +693,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasGrabJoints) { // the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); + glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix); glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix); glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix); @@ -698,28 +701,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix); glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix); - AVATAR_MEMCPY(leftFarGrabPosition); - // Can't do block copy as struct order is x, y, z, w. - data->leftFarGrabRotation[0] = leftFarGrabRotation.w; - data->leftFarGrabRotation[1] = leftFarGrabRotation.x; - data->leftFarGrabRotation[2] = leftFarGrabRotation.y; - data->leftFarGrabRotation[3] = leftFarGrabRotation.z; - destinationBuffer += sizeof(data->leftFarGrabPosition); - - AVATAR_MEMCPY(rightFarGrabPosition); - data->rightFarGrabRotation[0] = rightFarGrabRotation.w; - data->rightFarGrabRotation[1] = rightFarGrabRotation.x; - data->rightFarGrabRotation[2] = rightFarGrabRotation.y; - data->rightFarGrabRotation[3] = rightFarGrabRotation.z; - destinationBuffer += sizeof(data->rightFarGrabRotation); - - AVATAR_MEMCPY(mouseFarGrabPosition); - data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w; - data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x; - data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y; - data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z; - destinationBuffer += sizeof(data->mouseFarGrabRotation); + AvatarDataPacket::FarGrabJoints farGrabJoints = { + { leftFarGrabPosition.x, leftFarGrabPosition.y, leftFarGrabPosition.z }, + { leftFarGrabRotation.w, leftFarGrabRotation.x, leftFarGrabRotation.y, leftFarGrabRotation.z }, + { rightFarGrabPosition.x, rightFarGrabPosition.y, rightFarGrabPosition.z }, + { rightFarGrabRotation.w, rightFarGrabRotation.x, rightFarGrabRotation.y, rightFarGrabRotation.z }, + { mouseFarGrabPosition.x, mouseFarGrabPosition.y, mouseFarGrabPosition.z }, + { mouseFarGrabRotation.w, mouseFarGrabRotation.x, mouseFarGrabRotation.y, mouseFarGrabRotation.z } + }; + memcpy(destinationBuffer, &farGrabJoints, sizeof(farGrabJoints)); + destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints); int numBytes = destinationBuffer - startSection; if (outboundDataRateOut) { @@ -1250,25 +1242,37 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { auto startSection = sourceBuffer; PACKET_READ_CHECK(FarGrabJoints, sizeof(AvatarDataPacket::FarGrabJoints)); - auto data = reinterpret_cast(sourceBuffer); - glm::vec3 leftFarGrabPosition = glm::vec3(data->leftFarGrabPosition[0], data->leftFarGrabPosition[1], - data->leftFarGrabPosition[2]); - glm::quat leftFarGrabRotation = glm::quat(data->leftFarGrabRotation[0], data->leftFarGrabRotation[1], - data->leftFarGrabRotation[2], data->leftFarGrabRotation[3]); - glm::vec3 rightFarGrabPosition = glm::vec3(data->rightFarGrabPosition[0], data->rightFarGrabPosition[1], - data->rightFarGrabPosition[2]); - glm::quat rightFarGrabRotation = glm::quat(data->rightFarGrabRotation[0], data->rightFarGrabRotation[1], - data->rightFarGrabRotation[2], data->rightFarGrabRotation[3]); - glm::vec3 mouseFarGrabPosition = glm::vec3(data->mouseFarGrabPosition[0], data->mouseFarGrabPosition[1], - data->mouseFarGrabPosition[2]); - glm::quat mouseFarGrabRotation = glm::quat(data->mouseFarGrabRotation[0], data->mouseFarGrabRotation[1], - data->mouseFarGrabRotation[2], data->mouseFarGrabRotation[3]); + + AvatarDataPacket::FarGrabJoints farGrabJoints; + memcpy(&farGrabJoints, sourceBuffer, sizeof(farGrabJoints)); // to avoid misaligned floats + + glm::vec3 leftFarGrabPosition = glm::vec3(farGrabJoints.leftFarGrabPosition[0], + farGrabJoints.leftFarGrabPosition[1], + farGrabJoints.leftFarGrabPosition[2]); + glm::quat leftFarGrabRotation = glm::quat(farGrabJoints.leftFarGrabRotation[0], + farGrabJoints.leftFarGrabRotation[1], + farGrabJoints.leftFarGrabRotation[2], + farGrabJoints.leftFarGrabRotation[3]); + glm::vec3 rightFarGrabPosition = glm::vec3(farGrabJoints.rightFarGrabPosition[0], + farGrabJoints.rightFarGrabPosition[1], + farGrabJoints.rightFarGrabPosition[2]); + glm::quat rightFarGrabRotation = glm::quat(farGrabJoints.rightFarGrabRotation[0], + farGrabJoints.rightFarGrabRotation[1], + farGrabJoints.rightFarGrabRotation[2], + farGrabJoints.rightFarGrabRotation[3]); + glm::vec3 mouseFarGrabPosition = glm::vec3(farGrabJoints.mouseFarGrabPosition[0], + farGrabJoints.mouseFarGrabPosition[1], + farGrabJoints.mouseFarGrabPosition[2]); + glm::quat mouseFarGrabRotation = glm::quat(farGrabJoints.mouseFarGrabRotation[0], + farGrabJoints.mouseFarGrabRotation[1], + farGrabJoints.mouseFarGrabRotation[2], + farGrabJoints.mouseFarGrabRotation[3]); _farGrabLeftMatrixCache.set(createMatFromQuatAndPos(leftFarGrabRotation, leftFarGrabPosition)); _farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition)); _farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition)); - sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition); + sourceBuffer += sizeof(AvatarDataPacket::FarGrabJoints); int numBytesRead = sourceBuffer - startSection; _farGrabJointRate.increment(numBytesRead); _farGrabJointUpdateRate.increment(); @@ -2828,10 +2832,10 @@ QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, c obj.setProperty("avatarID", avatarIDValue); obj.setProperty("distance", value.distance); obj.setProperty("face", boxFaceToString(value.face)); + QScriptValue intersection = vec3ToScriptValue(engine, value.intersection); - QScriptValue intersection = vec3toScriptValue(engine, value.intersection); obj.setProperty("intersection", intersection); - QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal); + QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal); obj.setProperty("surfaceNormal", surfaceNormal); obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo)); return obj; diff --git a/libraries/controllers/src/controllers/Pose.cpp b/libraries/controllers/src/controllers/Pose.cpp index 967838ef84..6df4b4af81 100644 --- a/libraries/controllers/src/controllers/Pose.cpp +++ b/libraries/controllers/src/controllers/Pose.cpp @@ -41,10 +41,10 @@ namespace controller { */ QScriptValue Pose::toScriptValue(QScriptEngine* engine, const Pose& pose) { QScriptValue obj = engine->newObject(); - obj.setProperty("translation", vec3toScriptValue(engine, pose.translation)); + obj.setProperty("translation", vec3ToScriptValue(engine, pose.translation)); obj.setProperty("rotation", quatToScriptValue(engine, pose.rotation)); - obj.setProperty("velocity", vec3toScriptValue(engine, pose.velocity)); - obj.setProperty("angularVelocity", vec3toScriptValue(engine, pose.angularVelocity)); + obj.setProperty("velocity", vec3ToScriptValue(engine, pose.velocity)); + obj.setProperty("angularVelocity", vec3ToScriptValue(engine, pose.angularVelocity)); obj.setProperty("valid", pose.valid); return obj; } diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index a0d5cb0920..d3cb602e5b 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -494,7 +494,7 @@ glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point, float si QVariant ReticleInterface::getPosition() const { - return vec2toVariant(_compositor->getReticlePosition()); + return vec2ToVariant(_compositor->getReticlePosition()); } void ReticleInterface::setPosition(QVariant position) { diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 4ea293a3da..d746ec1ea9 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -41,7 +41,7 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint float largestDiameter = glm::compMax(dimensions); light->setMaximumRadius(largestDiameter / 2.0f); - light->setColor(toGlm(entity->getXColor())); + light->setColor(toGlm(entity->getColor())); float intensity = entity->getIntensity();//* entity->getFadingRatio(); light->setIntensity(intensity); diff --git a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp index 9ac7e9921f..6a472cab1e 100644 --- a/libraries/entities-renderer/src/RenderableLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLineEntityItem.cpp @@ -37,7 +37,7 @@ void LineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { _lineVerticesID = geometryCache->allocateID(); } - glm::vec4 lineColor(toGlm(entity->getXColor()), entity->getLocalRenderAlpha()); + glm::vec4 lineColor(toGlm(entity->getColor()), entity->getLocalRenderAlpha()); geometryCache->updateVertices(_lineVerticesID, _linePoints, lineColor); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 095283b1e5..0452587439 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -308,7 +308,7 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 } void RenderableModelEntityItem::getCollisionGeometryResource() { - QUrl hullURL(getCompoundShapeURL()); + QUrl hullURL(getCollisionShapeURL()); QUrlQuery queryArgs(hullURL); queryArgs.addQueryItem("collision-hull", ""); hullURL.setQuery(queryArgs); @@ -325,8 +325,9 @@ bool RenderableModelEntityItem::computeShapeFailedToLoad() { void RenderableModelEntityItem::setShapeType(ShapeType type) { ModelEntityItem::setShapeType(type); - if (getShapeType() == SHAPE_TYPE_COMPOUND) { - if (!_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + if (!_compoundShapeResource && !getCollisionShapeURL().isEmpty()) { getCollisionGeometryResource(); } } else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { @@ -352,18 +353,21 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { bool RenderableModelEntityItem::isReadyToComputeShape() const { ShapeType type = getShapeType(); auto model = getModel(); - if (type == SHAPE_TYPE_COMPOUND) { - if (!model || getCompoundShapeURL().isEmpty()) { + auto shapeType = getShapeType(); + if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { + auto shapeURL = getCollisionShapeURL(); + + if (!model || shapeURL.isEmpty()) { return false; } - if (model->getURL().isEmpty()) { + if (model->getURL().isEmpty() || !_dimensionsInitialized) { // we need a render geometry with a scale to proceed, so give up. return false; } if (model->isLoaded()) { - if (!getCompoundShapeURL().isEmpty() && !_compoundShapeResource) { + if (!shapeURL.isEmpty() && !_compoundShapeResource) { const_cast(this)->getCollisionGeometryResource(); } @@ -518,7 +522,16 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { return; } - auto& meshes = model->getGeometry()->getMeshes(); + std::vector> meshes; + if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { + auto& fbxMeshes = _compoundShapeResource->getFBXGeometry().meshes; + meshes.reserve(fbxMeshes.size()); + for (auto& fbxMesh : fbxMeshes) { + meshes.push_back(fbxMesh._mesh); + } + } else { + meshes = model->getGeometry()->getMeshes(); + } int32_t numMeshes = (int32_t)(meshes.size()); const int MAX_ALLOWED_MESH_COUNT = 1000; @@ -752,7 +765,7 @@ bool RenderableModelEntityItem::shouldBePhysical() const { auto model = getModel(); // If we have a model, make sure it hasn't failed to download. // If it has, we'll report back that we shouldn't be physical so that physics aren't held waiting for us to be ready. - if (model && getShapeType() == SHAPE_TYPE_COMPOUND && model->didCollisionGeometryRequestFail()) { + if (model && (getShapeType() == SHAPE_TYPE_COMPOUND || getShapeType() == SHAPE_TYPE_SIMPLE_COMPOUND) && model->didCollisionGeometryRequestFail()) { return false; } else if (model && getShapeType() != SHAPE_TYPE_NONE && model->didVisualGeometryRequestFail()) { return false; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index f51a3f7740..38027a80ed 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -320,7 +320,7 @@ void ParticleEffectEntityRenderer::stepSimulation() { } void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { - if (!_visible) { + if (!_visible || !(_networkTexture && _networkTexture->isLoaded())) { return; } @@ -328,11 +328,7 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { stepSimulation(); gpu::Batch& batch = *args->_batch; - if (_networkTexture && _networkTexture->isLoaded()) { - batch.setResourceTexture(0, _networkTexture->getGPUTexture()); - } else { - batch.setResourceTexture(0, DependencyManager::get()->getWhiteTexture()); - } + batch.setResourceTexture(0, _networkTexture->getGPUTexture()); Transform transform; // The particles are in world space, so the transform is unused, except for the rotation, which we use diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 743df477ac..0d9e948db8 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -142,7 +142,7 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } if (strokeColorsChanged) { _lastStrokeColors = entity->getStrokeColors(); - _lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector({ toGlm(entity->getXColor()) }); + _lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector({ toGlm(entity->getColor()) }); } if (pointsChanged || strokeWidthsChanged || normalsChanged || strokeColorsChanged) { _empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2; @@ -161,10 +161,10 @@ void PolyLineEntityRenderer::updateGeometry(const std::vector& vertices) _verticesBuffer->setSubData(0, vertices); } -std::vector PolyLineEntityRenderer::updateVertices(const QVector& points, - const QVector& normals, +std::vector PolyLineEntityRenderer::updateVertices(const QVector& points, + const QVector& normals, const QVector& strokeWidths, - const QVector& strokeColors, + const QVector& strokeColors, const bool isUVModeStretch, const float textureAspectRatio) { // Calculate the minimum vector size out of normals, points, and stroke widths diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 3ba26c74df..8130171da8 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -52,10 +52,10 @@ protected: }; void updateGeometry(const std::vector& vertices); - static std::vector updateVertices(const QVector& points, - const QVector& normals, + static std::vector updateVertices(const QVector& points, + const QVector& normals, const QVector& strokeWidths, - const QVector& strokeColors, + const QVector& strokeColors, const bool isUVModeStretch, const float textureAspectRatio); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 08a3b585e4..ce9e7ab764 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -47,11 +47,11 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return true; } - if (_textColor != toGlm(entity->getTextColorX())) { + if (_textColor != toGlm(entity->getTextColor())) { return true; } - if (_backgroundColor != toGlm(entity->getBackgroundColorX())) { + if (_backgroundColor != toGlm(entity->getBackgroundColor())) { return true; } @@ -77,8 +77,8 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen } void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { - _textColor = toGlm(entity->getTextColorX()); - _backgroundColor = toGlm(entity->getBackgroundColorX()); + _textColor = toGlm(entity->getTextColor()); + _backgroundColor = toGlm(entity->getBackgroundColor()); _faceCamera = entity->getFaceCamera(); _lineHeight = entity->getLineHeight(); _text = entity->getText(); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index cf452c9cf7..2c017da71d 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -413,10 +413,10 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect()); haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange())); - xColor hazeColor = _hazeProperties.getHazeColor(); - haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0)); - xColor hazeGlareColor = _hazeProperties.getHazeGlareColor(); - haze->setHazeGlareColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0)); + glm::u8vec3 hazeColor = _hazeProperties.getHazeColor(); + haze->setHazeColor(toGlm(hazeColor)); + glm::u8vec3 hazeGlareColor = _hazeProperties.getHazeGlareColor(); + haze->setHazeGlareColor(toGlm(hazeGlareColor)); haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare()); haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle())); @@ -447,7 +447,7 @@ void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& setSkyboxMode((ComponentMode)entity->getSkyboxMode()); editBackground(); - setSkyboxColor(_skyboxProperties.getColorVec3()); + setSkyboxColor(toGlm(_skyboxProperties.getColor())); setProceduralUserData(entity->getUserData()); setSkyboxURL(_skyboxProperties.getURL()); } diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 94df7eb465..6f7e012bc4 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -104,10 +104,10 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper AABox aaBox = zoneEntity->getAABox(success); if (success) { QScriptValue boundingBox = filterData.engine->newObject(); - QScriptValue bottomRightNear = vec3toScriptValue(filterData.engine, aaBox.getCorner()); - QScriptValue topFarLeft = vec3toScriptValue(filterData.engine, aaBox.calcTopFarLeft()); - QScriptValue center = vec3toScriptValue(filterData.engine, aaBox.calcCenter()); - QScriptValue boundingBoxDimensions = vec3toScriptValue(filterData.engine, aaBox.getDimensions()); + QScriptValue bottomRightNear = vec3ToScriptValue(filterData.engine, aaBox.getCorner()); + QScriptValue topFarLeft = vec3ToScriptValue(filterData.engine, aaBox.calcTopFarLeft()); + QScriptValue center = vec3ToScriptValue(filterData.engine, aaBox.calcCenter()); + QScriptValue boundingBoxDimensions = vec3ToScriptValue(filterData.engine, aaBox.getDimensions()); boundingBox.setProperty("brn", bottomRightNear); boundingBox.setProperty("tfl", topFarLeft); boundingBox.setProperty("center", center); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 184bb054ea..6279f0bae0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -131,6 +131,10 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_CLONE_AVATAR_ENTITY; requestedProperties += PROP_CLONE_ORIGIN_ID; + withReadLock([&] { + requestedProperties += _grabProperties.getEntityProperties(params); + }); + return requestedProperties; } @@ -168,6 +172,9 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet EntityPropertyFlags propertyFlags(PROP_LAST_ITEM); EntityPropertyFlags requestedProperties = getEntityProperties(params); + requestedProperties -= PROP_CLIENT_ONLY; + requestedProperties -= PROP_OWNING_AVATAR_ID; + // If we are being called for a subsequent pass at appendEntityData() that failed to completely encode this item, // then our entityTreeElementExtraEncodeData should include data about which properties we need to append. if (entityTreeElementExtraEncodeData && entityTreeElementExtraEncodeData->entities.contains(getEntityItemID())) { @@ -300,7 +307,12 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, getCloneLimit()); APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, getCloneDynamic()); APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, getCloneAvatarEntity()); - APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID()); + APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID()); + + withReadLock([&] { + _grabProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); + }); appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -892,7 +904,15 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_CLONE_LIMIT, float, setCloneLimit); READ_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, bool, setCloneDynamic); READ_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity); - READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID); + READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID); + + withWriteLock([&] { + int bytesFromGrab = _grabProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData, + somethingChanged); + bytesRead += bytesFromGrab; + dataAt += bytesFromGrab; + }); bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, somethingChanged); @@ -1329,6 +1349,10 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneAvatarEntity, getCloneAvatarEntity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneOriginID, getCloneOriginID); + withReadLock([&] { + _grabProperties.getProperties(properties); + }); + properties._defaultSettings = false; return properties; @@ -1465,6 +1489,11 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneAvatarEntity, setCloneAvatarEntity); SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneOriginID, setCloneOriginID); + withWriteLock([&] { + bool grabPropertiesChanged = _grabProperties.setProperties(properties); + somethingChanged |= grabPropertiesChanged; + }); + if (updateQueryAACube()) { somethingChanged = true; } @@ -1784,6 +1813,12 @@ void EntityItem::setUnscaledDimensions(const glm::vec3& value) { } } +glm::vec3 EntityItem::getUnscaledDimensions() const { + return resultWithReadLock([&] { + return _unscaledDimensions; + }); +} + void EntityItem::setRotation(glm::quat rotation) { if (getLocalOrientation() != rotation) { setLocalOrientation(rotation); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 0e5cae66b6..e4063eac3b 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -35,6 +35,7 @@ #include "SimulationOwner.h" #include "SimulationFlags.h" #include "EntityDynamicInterface.h" +#include "GrabPropertyGroup.h" #include "graphics/Material.h" @@ -191,7 +192,7 @@ public: virtual void setScaledDimensions(const glm::vec3& value); virtual glm::vec3 getRaycastDimensions() const { return getScaledDimensions(); } - inline const glm::vec3 getUnscaledDimensions() const { return _unscaledDimensions; } + glm::vec3 getUnscaledDimensions() const; virtual void setUnscaledDimensions(const glm::vec3& value); float getLocalRenderAlpha() const; @@ -263,9 +264,8 @@ public: void setCollisionSoundURL(const QString& value); glm::vec3 getRegistrationPoint() const; /// registration point as ratio of entity - /// registration point as ratio of entity - virtual void setRegistrationPoint(const glm::vec3& value); // FIXME: this is suspicious! + virtual void setRegistrationPoint(const glm::vec3& value); // FIXME: this is suspicious! bool hasAngularVelocity() const { return getWorldAngularVelocity() != ENTITY_ITEM_ZERO_VEC3; } bool hasLocalAngularVelocity() const { return getLocalAngularVelocity() != ENTITY_ITEM_ZERO_VEC3; } @@ -533,6 +533,8 @@ public: void setCloneIDs(const QVector& cloneIDs); void setVisuallyReady(bool visuallyReady) { _visuallyReady = visuallyReady; } + const GrabPropertyGroup& getGrabProperties() const { return _grabProperties; } + signals: void requestRenderUpdate(); void spaceUpdate(std::pair data); @@ -711,6 +713,8 @@ protected: QUuid _cloneOriginID; QVector _cloneIDs; + GrabPropertyGroup _grabProperties; + private: std::unordered_map _materials; std::mutex _materialsLock; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 7e404afa3f..dd5c2020c8 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -40,6 +40,7 @@ HazePropertyGroup EntityItemProperties::_staticHaze; BloomPropertyGroup EntityItemProperties::_staticBloom; KeyLightPropertyGroup EntityItemProperties::_staticKeyLight; AmbientLightPropertyGroup EntityItemProperties::_staticAmbientLight; +GrabPropertyGroup EntityItemProperties::_staticGrab; EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1); @@ -61,8 +62,8 @@ EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties } -void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const glm::vec3& max) { - glm::vec3 halfDimension = (max - min) / 2.0f; +void EntityItemProperties::calculateNaturalPosition(const vec3& min, const vec3& max) { + vec3 halfDimension = (max - min) / 2.0f; _naturalPosition = max - halfDimension; } @@ -86,6 +87,7 @@ void EntityItemProperties::debugDump() const { getKeyLight().debugDump(); getAmbientLight().debugDump(); getBloom().debugDump(); + getGrab().debugDump(); qCDebug(entities) << " changed properties..."; EntityPropertyFlags props = getChangedProperties(); @@ -471,6 +473,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { changedProperties += _skybox.getChangedProperties(); changedProperties += _haze.getChangedProperties(); changedProperties += _bloom.getChangedProperties(); + changedProperties += _grab.getChangedProperties(); return changedProperties; } @@ -628,6 +631,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * avatar entities: their clientOnly property will be set to true. * @property {Uuid} cloneOriginID - The ID of the entity that this entity was cloned from. * + * @property {Entities.Grab} grab - The grab-related properties. + * * @property {string} itemName="" - Certifiable name of the Marketplace item. * @property {string} itemDescription="" - Certifiable description of the Marketplace item. * @property {string} itemCategories="" - Certifiable category of the Marketplace item. @@ -872,9 +877,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number} emitSpeed=5 - The speed, in m/s, that each particle is emitted at. * @property {number} speedSpread=1 - The spread in speeds at which particles are emitted at. If emitSpeed == 5 * and speedSpread == 1, particles will be emitted with speeds in the range 4m/s – 6m/s. - * @property {vec3} emitAcceleration=0,-9.8,0 - The acceleration that is applied to each particle during its lifetime. The + * @property {Vec3} emitAcceleration=0,-9.8,0 - The acceleration that is applied to each particle during its lifetime. The * default is Earth's gravity value. - * @property {vec3} accelerationSpread=0,0,0 - The spread in accelerations that each particle is given. If + * @property {Vec3} accelerationSpread=0,0,0 - The spread in accelerations that each particle is given. If * emitAccelerations == {x: 0, y: -9.8, z: 0} and accelerationSpread == * {x: 0, y: 1, z: 0}, each particle will have an acceleration in the range {x: 0, y: -10.8, z: 0} * – {x: 0, y: -8.8, z: 0}. @@ -887,7 +892,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * default, particles emit along the entity's local z-axis, and azimuthStart and azimuthFinish * are relative to the entity's local x-axis. The default value is a rotation of -90 degrees about the local x-axis, i.e., * the particles emit vertically. - * @property {vec3} emitDimensions=0,0,0 - The dimensions of the ellipsoid from which particles are emitted. + * @property {Vec3} emitDimensions=0,0,0 - The dimensions of the ellipsoid from which particles are emitted. * @property {number} emitRadiusStart=1 - The starting radius within the ellipsoid at which particles start being emitted; * range 0.01.0 for the ellipsoid center to the ellipsoid surface, respectively. * Particles are emitted from the portion of the ellipsoid that lies between emitRadiusStart and the @@ -916,9 +921,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * and radiusSpread == 0.25, each particle will have a radius in the range 0.25 – * 0.75. * @property {Color} color=255,255,255 - The color of each particle at the middle of its life. - * @property {Color} colorStart={} - The color of each particle at the start of its life. If any of the component values are + * @property {ColorFloat} colorStart={} - The color of each particle at the start of its life. If any of the component values are * undefined, the color value is used. - * @property {Color} colorFinish={} - The color of each particle at the end of its life. If any of the component values are + * @property {ColorFloat} colorFinish={} - The color of each particle at the end of its life. If any of the component values are * undefined, the color value is used. * @property {Color} colorSpread=0,0,0 - The spread in color that each particle is given. If * color == {red: 100, green: 100, blue: 100} and colorSpread == @@ -1314,9 +1319,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL); - // Light, Line, Model, ParticleEffect, PolyLine, Shape - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR, color); - // Particles only if (_type == EntityTypes::ParticleEffect) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMITTING_PARTICLES, isEmitting); @@ -1338,9 +1340,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_SPREAD, radiusSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_START, radiusStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_FINISH, radiusFinish); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_SPREAD, colorSpread); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_START, colorStart); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR_FINISH, colorFinish); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_SPREAD, colorSpread, u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_START, colorStart, vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_FINISH, colorFinish, vec3Color); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish); @@ -1363,6 +1366,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); } if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { @@ -1379,6 +1383,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Box || _type == EntityTypes::Sphere || _type == EntityTypes::Shape) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHAPE, shape); + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); } // FIXME - it seems like ParticleEffect should also support this @@ -1393,6 +1398,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Lights only if (_type == EntityTypes::Light) { + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_SPOTLIGHT, isSpotlight); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_INTENSITY, intensity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FALLOFF_RADIUS, falloffRadius); @@ -1404,8 +1410,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Text) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT, text); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_HEIGHT, lineHeight); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_TEXT_COLOR, textColor, getTextColor()); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BACKGROUND_COLOR, backgroundColor, getBackgroundColor()); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_TYPED(PROP_TEXT_COLOR, textColor, getTextColor(), u8vec3Color); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_TYPED(PROP_BACKGROUND_COLOR, backgroundColor, getBackgroundColor(), u8vec3Color); } // Zones only @@ -1459,10 +1465,11 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Lines & PolyLines if (_type == EntityTypes::Line || _type == EntityTypes::PolyLine) { + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals); // Polyline only. - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors); // Polyline only. + COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_STROKE_COLORS, strokeColors, qVectorVec3Color); // Polyline only. COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths); // Polyline only. COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); // Polyline only. COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch); // Polyline only. @@ -1493,10 +1500,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool AABox aaBox = getAABox(); QScriptValue boundingBox = engine->newObject(); - QScriptValue bottomRightNear = vec3toScriptValue(engine, aaBox.getCorner()); - QScriptValue topFarLeft = vec3toScriptValue(engine, aaBox.calcTopFarLeft()); - QScriptValue center = vec3toScriptValue(engine, aaBox.calcCenter()); - QScriptValue boundingBoxDimensions = vec3toScriptValue(engine, aaBox.getDimensions()); + QScriptValue bottomRightNear = vec3ToScriptValue(engine, aaBox.getCorner()); + QScriptValue topFarLeft = vec3ToScriptValue(engine, aaBox.calcTopFarLeft()); + QScriptValue center = vec3ToScriptValue(engine, aaBox.calcCenter()); + QScriptValue boundingBoxDimensions = vec3ToScriptValue(engine, aaBox.getDimensions()); boundingBox.setProperty("brn", bottomRightNear); boundingBox.setProperty("tfl", topFarLeft); boundingBox.setProperty("center", center); @@ -1530,6 +1537,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_AVATAR_ENTITY, cloneAvatarEntity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_ORIGIN_ID, cloneOriginID); + _grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + // Rendering info if (!skipDefaults && !strictSemantics && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::RenderInfo))) { @@ -1598,10 +1607,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping); COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow); - COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor); - COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread); - COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, vec3, setColorStart); - COPY_PROPERTY_FROM_QSCRIPTVALUE(colorFinish, vec3, setColorFinish); + COPY_PROPERTY_FROM_QSCRIPTVALUE(color, u8vec3Color, setColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, u8vec3Color, setColorSpread); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, vec3Color, setColorStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorFinish, vec3Color, setColorFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart); @@ -1626,8 +1635,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(userData, QString, setUserData); COPY_PROPERTY_FROM_QSCRIPTVALUE(text, QString, setText); COPY_PROPERTY_FROM_QSCRIPTVALUE(lineHeight, float, setLineHeight); - COPY_PROPERTY_FROM_QSCRIPTVALUE(textColor, xColor, setTextColor); - COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundColor, xColor, setBackgroundColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(textColor, u8vec3Color, setTextColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundColor, u8vec3Color, setBackgroundColor); COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(shapeType, ShapeType); COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, quint32, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); @@ -1700,7 +1709,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors); COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths); COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch); - + if (!honorReadOnly) { // this is used by the json reader to set things that we don't want javascript to able to affect. @@ -1718,6 +1727,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool _skybox.copyFromScriptValue(object, _defaultSettings); _haze.copyFromScriptValue(object, _defaultSettings); _bloom.copyFromScriptValue(object, _defaultSettings); + _grab.copyFromScriptValue(object, _defaultSettings); COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL); @@ -1883,6 +1893,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) { _skybox.merge(other._skybox); _haze.merge(other._haze); _bloom.merge(other._bloom); + _grab.merge(other._grab); COPY_PROPERTY_IF_CHANGED(xTextureURL); COPY_PROPERTY_IF_CHANGED(yTextureURL); @@ -1973,13 +1984,13 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue std::call_once(initMap, [](){ ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool); ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool); - ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, glm::quat); + ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, vec3); + ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, vec3); + ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, quat); ADD_PROPERTY_TO_MAP(PROP_DENSITY, Density, density, float); - ADD_PROPERTY_TO_MAP(PROP_VELOCITY, Velocity, velocity, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_GRAVITY, Gravity, gravity, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_ACCELERATION, Acceleration, acceleration, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_VELOCITY, Velocity, velocity, vec3); + ADD_PROPERTY_TO_MAP(PROP_GRAVITY, Gravity, gravity, vec3); + ADD_PROPERTY_TO_MAP(PROP_ACCELERATION, Acceleration, acceleration, vec3); ADD_PROPERTY_TO_MAP(PROP_DAMPING, Damping, damping, float); ADD_PROPERTY_TO_MAP(PROP_RESTITUTION, Restitution, restitution, float); ADD_PROPERTY_TO_MAP(PROP_FRICTION, Friction, friction, float); @@ -1988,10 +1999,10 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); ADD_PROPERTY_TO_MAP(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString); ADD_PROPERTY_TO_MAP(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString); - ADD_PROPERTY_TO_MAP(PROP_COLOR, Color, color, xColor); - ADD_PROPERTY_TO_MAP(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); - ADD_PROPERTY_TO_MAP(PROP_COLOR_START, ColorStart, colorStart, vec3); - ADD_PROPERTY_TO_MAP(PROP_COLOR_FINISH, ColorFinish, colorFinish, vec3); + ADD_PROPERTY_TO_MAP(PROP_COLOR, Color, color, u8vec3Color); + ADD_PROPERTY_TO_MAP(PROP_COLOR_SPREAD, ColorSpread, colorSpread, u8vec3Color); + ADD_PROPERTY_TO_MAP(PROP_COLOR_START, ColorStart, colorStart, vec3Color); + ADD_PROPERTY_TO_MAP(PROP_COLOR_FINISH, ColorFinish, colorFinish, vec3Color); ADD_PROPERTY_TO_MAP(PROP_ALPHA, Alpha, alpha, float); ADD_PROPERTY_TO_MAP(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float); ADD_PROPERTY_TO_MAP(PROP_ALPHA_START, AlphaStart, alphaStart, float); @@ -1999,8 +2010,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_EMITTER_SHOULD_TRAIL, EmitterShouldTrail, emitterShouldTrail, bool); ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString); ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); - ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, vec3); + ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, vec3); ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float); ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, Collisionless, collisionless, bool); ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, unused, ignoreForCollisions, unused); // legacy support @@ -2019,24 +2030,24 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner); ADD_PROPERTY_TO_MAP(PROP_TEXT, Text, text, QString); ADD_PROPERTY_TO_MAP(PROP_LINE_HEIGHT, LineHeight, lineHeight, float); - ADD_PROPERTY_TO_MAP(PROP_TEXT_COLOR, TextColor, textColor, xColor); - ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor); + ADD_PROPERTY_TO_MAP(PROP_TEXT_COLOR, TextColor, textColor, u8vec3Color); + ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, u8vec3Color); ADD_PROPERTY_TO_MAP(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType); ADD_PROPERTY_TO_MAP(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); ADD_PROPERTY_TO_MAP(PROP_LIFESPAN, Lifespan, lifespan, float); ADD_PROPERTY_TO_MAP(PROP_EMITTING_PARTICLES, IsEmitting, isEmitting, bool); ADD_PROPERTY_TO_MAP(PROP_EMIT_RATE, EmitRate, emitRate, float); - ADD_PROPERTY_TO_MAP(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat); - ADD_PROPERTY_TO_MAP(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, vec3); + ADD_PROPERTY_TO_MAP(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, vec3); + ADD_PROPERTY_TO_MAP(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, quat); + ADD_PROPERTY_TO_MAP(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, vec3); ADD_PROPERTY_TO_MAP(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float); ADD_PROPERTY_TO_MAP(PROP_POLAR_START, EmitPolarStart, polarStart, float); ADD_PROPERTY_TO_MAP(PROP_POLAR_FINISH, EmitPolarFinish, polarFinish, float); ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_START, EmitAzimuthStart, azimuthStart, float); ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_FINISH, EmitAzimuthFinish, azimuthFinish, float); - ADD_PROPERTY_TO_MAP(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, vec3); + ADD_PROPERTY_TO_MAP(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, vec3); ADD_PROPERTY_TO_MAP(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); ADD_PROPERTY_TO_MAP(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); ADD_PROPERTY_TO_MAP(PROP_RADIUS_START, RadiusStart, radiusStart, float); @@ -2072,24 +2083,24 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString); ADD_PROPERTY_TO_MAP(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32); - ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); + ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, u8vec3Color); ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float); - ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLightDirection, keyLightDirection, vec3); ADD_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLightCastShadows, keyLightCastShadows, bool); - ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, vec3); ADD_PROPERTY_TO_MAP(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray); ADD_PROPERTY_TO_MAP(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t); ADD_PROPERTY_TO_MAP(PROP_NAME, Name, name, QString); ADD_PROPERTY_TO_MAP(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString); ADD_PROPERTY_TO_MAP(PROP_LINE_WIDTH, LineWidth, lineWidth, float); - ADD_PROPERTY_TO_MAP(PROP_LINE_POINTS, LinePoints, linePoints, QVector); + ADD_PROPERTY_TO_MAP(PROP_LINE_POINTS, LinePoints, linePoints, QVector); ADD_PROPERTY_TO_MAP(PROP_HREF, Href, href, QString); ADD_PROPERTY_TO_MAP(PROP_DESCRIPTION, Description, description, QString); ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool); ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray); - ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector); - ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector); + ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector); + ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector); ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector); ADD_PROPERTY_TO_MAP(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, QVector); ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString); @@ -2105,16 +2116,16 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_PARENT_ID, ParentID, parentID, QUuid); ADD_PROPERTY_TO_MAP(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, uint16_t); - ADD_PROPERTY_TO_MAP(PROP_LOCAL_POSITION, LocalPosition, localPosition, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat); - ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3); - ADD_PROPERTY_TO_MAP(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_POSITION, LocalPosition, localPosition, vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, quat); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, vec3); + ADD_PROPERTY_TO_MAP(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, vec3); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); - ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); + ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector); - ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector); + ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector); ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool); ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString); @@ -2172,6 +2183,26 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_CLONE_AVATAR_ENTITY, CloneAvatarEntity, cloneAvatarEntity, bool); ADD_PROPERTY_TO_MAP(PROP_CLONE_ORIGIN_ID, CloneOriginID, cloneOriginID, QUuid); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_TRIGGERABLE, Grab, grab, Triggerable, triggerable); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE, Grab, grab, Equippable, equippable); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, + EquippableLeftPosition, equippableLeftPosition); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, + EquippableLeftRotation, equippableLeftRotation); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, + EquippableRightPosition, equippableRightPosition); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, + EquippableRightRotation, equippableRightRotation); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab, + EquippableIndicatorURL, equippableIndicatorURL); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab, + EquippableIndicatorScale, equippableIndicatorScale); + ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab, + EquippableIndicatorOffset, equippableIndicatorOffset); + // FIXME - these are not yet handled //ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64); @@ -2224,7 +2255,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy // Always include the root octcode. This is only because the OctreeEditPacketSender will check these octcodes // to determine which server to send the changes to in the case of multiple jurisdictions. The root will be sent // to all servers. - glm::vec3 rootPosition(0); + vec3 rootPosition(0); float rootScale = 0.5f; unsigned char* octcode = pointToOctalCode(rootPosition.x, rootPosition.y, rootPosition.z, rootScale); @@ -2309,7 +2340,6 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_SCRIPT, properties.getScript()); APPEND_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, properties.getScriptTimestamp()); APPEND_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, properties.getServerScripts()); - APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, properties.getRegistrationPoint()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, properties.getAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping()); @@ -2344,6 +2374,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType())); + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); _staticAnimation.setProperties(properties); _staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); @@ -2356,8 +2387,8 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy } if (properties.getType() == EntityTypes::Light) { - APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, properties.getIsSpotlight()); APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); + APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, properties.getIsSpotlight()); APPEND_ENTITY_PROPERTY(PROP_INTENSITY, properties.getIntensity()); APPEND_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, properties.getFalloffRadius()); APPEND_ENTITY_PROPERTY(PROP_EXPONENT, properties.getExponent()); @@ -2385,6 +2416,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, properties.getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, properties.getRadiusFinish()); + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, properties.getColorSpread()); APPEND_ENTITY_PROPERTY(PROP_COLOR_START, properties.getColorStart()); APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, properties.getColorFinish()); @@ -2445,11 +2477,13 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy } if (properties.getType() == EntityTypes::Line) { + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth()); APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints()); } if (properties.getType() == EntityTypes::PolyLine) { + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth()); APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints()); APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getPackedNormals()); @@ -2464,6 +2498,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy properties.getType() == EntityTypes::Box || properties.getType() == EntityTypes::Sphere) { APPEND_ENTITY_PROPERTY(PROP_SHAPE, properties.getShape()); + APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor()); } // Materials @@ -2501,6 +2536,10 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, properties.getCloneLimit()); APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, properties.getCloneDynamic()); APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, properties.getCloneAvatarEntity()); + + _staticGrab.setProperties(properties); + _staticGrab.appendToEditPacket(packetData, requestedProperties, propertyFlags, + propertiesDidntFit, propertyCount, appendState); } if (propertyCount > 0) { @@ -2562,7 +2601,7 @@ QByteArray EntityItemProperties::getPackedNormals() const { return packNormals(getNormals()); } -QByteArray EntityItemProperties::packNormals(const QVector& normals) const { +QByteArray EntityItemProperties::packNormals(const QVector& normals) const { int normalsSize = normals.size(); QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0'); // add size of the array @@ -2579,7 +2618,7 @@ QByteArray EntityItemProperties::packNormals(const QVector& normals) QByteArray EntityItemProperties::getPackedStrokeColors() const { return packStrokeColors(getStrokeColors()); } -QByteArray EntityItemProperties::packStrokeColors(const QVector& strokeColors) const { +QByteArray EntityItemProperties::packStrokeColors(const QVector& strokeColors) const { int strokeColorsSize = strokeColors.size(); QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0'); @@ -2589,9 +2628,9 @@ QByteArray EntityItemProperties::packStrokeColors(const QVector& stro for (int i = 0; i < strokeColorsSize; i++) { // add the color to the QByteArray - packedStrokeColors[i * 3 + 1] = strokeColors[i].r * 255; - packedStrokeColors[i * 3 + 2] = strokeColors[i].g * 255; - packedStrokeColors[i * 3 + 3] = strokeColors[i].b * 255; + packedStrokeColors[i * 3 + 1] = strokeColors[i].x * 255; + packedStrokeColors[i * 3 + 2] = strokeColors[i].y * 255; + packedStrokeColors[i * 3 + 3] = strokeColors[i].z * 255; } return packedStrokeColors; } @@ -2680,13 +2719,13 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int processedBytes += propertyFlags.getEncodedLength(); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATION_OWNER, QByteArray, setSimulationOwner); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POSITION, glm::vec3, setPosition); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DIMENSIONS, glm::vec3, setDimensions); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ROTATION, glm::quat, setRotation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POSITION, vec3, setPosition); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DIMENSIONS, vec3, setDimensions); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ROTATION, quat, setRotation); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DENSITY, float, setDensity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY, glm::vec3, setVelocity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GRAVITY, glm::vec3, setGravity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION, glm::vec3, setAcceleration); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY, vec3, setVelocity); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GRAVITY, vec3, setGravity); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION, vec3, setAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DAMPING, float, setDamping); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RESTITUTION, float, setRestitution); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FRICTION, float, setFriction); @@ -2694,9 +2733,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCRIPT, QString, setScript); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SERVER_SCRIPTS, QString, setServerScripts); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, xColor, setColor); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_REGISTRATION_POINT, glm::vec3, setRegistrationPoint); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, glm::vec3, setAngularVelocity); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_REGISTRATION_POINT, vec3, setRegistrationPoint); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, vec3, setAngularVelocity); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow); @@ -2719,8 +2757,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int if (properties.getType() == EntityTypes::Text) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT, QString, setText); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_HEIGHT, float, setLineHeight); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_COLOR, xColor, setTextColor); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_COLOR, xColor, setBackgroundColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_COLOR, u8vec3Color, setTextColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_COLOR, u8vec3Color, setBackgroundColor); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FACE_CAMERA, bool, setFaceCamera); } @@ -2729,19 +2767,20 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS_SET, QVector, setJointRotationsSet); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector, setJointRotations); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector, setJointRotations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector, setJointTranslationsSet); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector, setJointTranslations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints); } if (properties.getType() == EntityTypes::Light) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FALLOFF_RADIUS, float, setFalloffRadius); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EXPONENT, float, setExponent); @@ -2756,22 +2795,23 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, quat, setEmitOrientation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_DIMENSIONS, vec3, setEmitDimensions); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_START, float, setPolarStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_FINISH, float, setPolarFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_START, float, setAzimuthStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, vec3, setEmitAcceleration); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_FINISH, float, setRadiusFinish); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_SPREAD, xColor, setColorSpread); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_START, vec3, setColorStart); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_FINISH, vec3, setColorFinish); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_SPREAD, u8vec3Color, setColorSpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_START, vec3Color, setColorStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_FINISH, vec3Color, setColorFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); @@ -2794,7 +2834,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FILTER_URL, QString, setFilterURL); - + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HAZE_MODE, uint32_t, setHazeMode); properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); @@ -2807,7 +2847,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::PolyVox) { - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, vec3, setVoxelVolumeSize); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_DATA, QByteArray, setVoxelData); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_SURFACE_STYLE, uint16_t, setVoxelSurfaceStyle); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_X_TEXTURE_URL, QString, setXTextureURL); @@ -2822,14 +2862,16 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::Line) { + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); } if (properties.getType() == EntityTypes::PolyLine) { + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector, setLinePoints); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QByteArray, setPackedNormals); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_COLORS, QByteArray, setPackedStrokeColors); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector, setStrokeWidths); @@ -2843,6 +2885,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int properties.getType() == EntityTypes::Box || properties.getType() == EntityTypes::Sphere) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE, QString, setShape); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor); } // Materials @@ -2881,6 +2924,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_DYNAMIC, bool, setCloneDynamic); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity); + properties.getGrab().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + return valid; } @@ -2888,14 +2933,14 @@ void EntityItemProperties::setPackedNormals(const QByteArray& value) { setNormals(unpackNormals(value)); } -QVector EntityItemProperties::unpackNormals(const QByteArray& normals) { +QVector EntityItemProperties::unpackNormals(const QByteArray& normals) { // the size of the vector is packed first - QVector unpackedNormals = QVector((int)normals[0]); + QVector unpackedNormals = QVector((int)normals[0]); if ((int)normals[0] == normals.size() / 6) { int j = 0; for (int i = 1; i < normals.size();) { - glm::vec3 aux = glm::vec3(); + vec3 aux = vec3(); i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15); unpackedNormals[j] = aux; j++; @@ -2911,9 +2956,9 @@ void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) { setStrokeColors(unpackStrokeColors(value)); } -QVector EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) { +QVector EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) { // the size of the vector is packed first - QVector unpackedStrokeColors = QVector((int)strokeColors[0]); + QVector unpackedStrokeColors = QVector((int)strokeColors[0]); if ((int)strokeColors[0] == strokeColors.size() / 3) { int j = 0; @@ -3120,6 +3165,7 @@ void EntityItemProperties::markAllChanged() { _skybox.markAllChanged(); _haze.markAllChanged(); _bloom.markAllChanged(); + _grab.markAllChanged(); _sourceUrlChanged = true; _voxelVolumeSizeChanged = true; @@ -3185,10 +3231,10 @@ void EntityItemProperties::markAllChanged() { AABox EntityItemProperties::getAABox() const { // _position represents the position of the registration point. - glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; + vec3 registrationRemainder = vec3(1.0f) - _registrationPoint; - glm::vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint); - glm::vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder; + vec3 unrotatedMinRelativeToEntity = - (_dimensions * _registrationPoint); + vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(_rotation); @@ -3654,6 +3700,7 @@ QList EntityItemProperties::listChangedProperties() { getSkybox().listChangedProperties(out); getHaze().listChangedProperties(out); getBloom().listChangedProperties(out); + getGrab().listChangedProperties(out); return out; } diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 338ec5e071..8527b471c3 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -58,6 +58,9 @@ const std::array COMPONENT_MODES = { { ComponentPair { COMPONENT_MODE_ENABLED, { "enabled" } } } }; +using vec3Color = glm::vec3; +using u8vec3Color = glm::u8vec3; + /// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an /// entity and a JavaScript style hash/QScriptValue storing a set of properties. Used in scripting to set/get the complete /// set of entity item properties via JavaScript hashes/QScriptValues @@ -137,10 +140,10 @@ public: DEFINE_PROPERTY_REF(PROP_SCRIPT, Script, script, QString, ENTITY_ITEM_DEFAULT_SCRIPT); DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP); DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL); - DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor, ParticleEffectEntityItem::DEFAULT_XCOLOR); - DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor, ParticleEffectEntityItem::DEFAULT_XCOLOR_SPREAD); - DEFINE_PROPERTY_REF(PROP_COLOR_START, ColorStart, colorStart, vec3, particle::DEFAULT_COLOR_UNINITIALIZED); - DEFINE_PROPERTY_REF(PROP_COLOR_FINISH, ColorFinish, colorFinish, vec3, particle::DEFAULT_COLOR_UNINITIALIZED); + DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, u8vec3Color, particle::DEFAULT_COLOR); + DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, u8vec3Color, particle::DEFAULT_COLOR_SPREAD); + DEFINE_PROPERTY_REF(PROP_COLOR_START, ColorStart, colorStart, glm::vec3, particle::DEFAULT_COLOR_UNINITIALIZED); + DEFINE_PROPERTY_REF(PROP_COLOR_FINISH, ColorFinish, colorFinish, glm::vec3, particle::DEFAULT_COLOR_UNINITIALIZED); DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float, particle::DEFAULT_ALPHA); DEFINE_PROPERTY(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float, particle::DEFAULT_ALPHA_SPREAD); DEFINE_PROPERTY(PROP_ALPHA_START, AlphaStart, alphaStart, float, particle::DEFAULT_ALPHA_START); @@ -164,8 +167,8 @@ public: DEFINE_PROPERTY_REF(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner, SimulationOwner()); DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString, TextEntityItem::DEFAULT_TEXT); DEFINE_PROPERTY(PROP_LINE_HEIGHT, LineHeight, lineHeight, float, TextEntityItem::DEFAULT_LINE_HEIGHT); - DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, xColor, TextEntityItem::DEFAULT_TEXT_COLOR); - DEFINE_PROPERTY_REF(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, xColor, TextEntityItem::DEFAULT_BACKGROUND_COLOR); + DEFINE_PROPERTY_REF(PROP_TEXT_COLOR, TextColor, textColor, u8vec3Color, TextEntityItem::DEFAULT_TEXT_COLOR); + DEFINE_PROPERTY_REF(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, u8vec3Color, TextEntityItem::DEFAULT_BACKGROUND_COLOR); DEFINE_PROPERTY_REF_ENUM(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType, SHAPE_TYPE_NONE); DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32, particle::DEFAULT_MAX_PARTICLES); DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float, particle::DEFAULT_LIFESPAN); @@ -206,7 +209,7 @@ public: DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup); DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, ""); DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH); - DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector, QVector()); + DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC); DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString, ""); DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, ""); DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA); @@ -233,8 +236,8 @@ public: DEFINE_PROPERTY_REF_ENUM(PROP_MATERIAL_MAPPING_MODE, MaterialMappingMode, materialMappingMode, MaterialMappingMode, UV); DEFINE_PROPERTY_REF(PROP_MATERIAL_PRIORITY, Priority, priority, quint16, 0); DEFINE_PROPERTY_REF(PROP_PARENT_MATERIAL_NAME, ParentMaterialName, parentMaterialName, QString, "0"); - DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_POS, MaterialMappingPos, materialMappingPos, vec2, glm::vec2(0, 0)); - DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, vec2, glm::vec2(1, 1)); + DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_POS, MaterialMappingPos, materialMappingPos, glm::vec2, glm::vec2(0.0f)); + DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, glm::vec2, glm::vec2(1.0f)); DEFINE_PROPERTY_REF(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float, 0); DEFINE_PROPERTY_REF(PROP_MATERIAL_DATA, MaterialData, materialData, QString, ""); @@ -260,16 +263,16 @@ public: DEFINE_PROPERTY_REF(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32, ENTITY_ITEM_DEFAULT_STATIC_CERTIFICATE_VERSION); // these are used when bouncing location data into and out of scripts - DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, vec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glm::vec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, quat, ENTITY_ITEM_DEFAULT_ROTATION); - DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, vec3, ENTITY_ITEM_ZERO_VEC3); - DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, vec3, ENTITY_ITEM_ZERO_VEC3); - DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, vec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3, ENTITY_ITEM_ZERO_VEC3); + DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector, QVector()); - DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector, QVector()); + DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC); DEFINE_PROPERTY(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool, ZoneEntityItem::DEFAULT_FLYING_ALLOWED); DEFINE_PROPERTY(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool, ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED); @@ -292,6 +295,8 @@ public: DEFINE_PROPERTY(PROP_CLONE_AVATAR_ENTITY, CloneAvatarEntity, cloneAvatarEntity, bool, ENTITY_ITEM_DEFAULT_CLONE_AVATAR_ENTITY); DEFINE_PROPERTY_REF(PROP_CLONE_ORIGIN_ID, CloneOriginID, cloneOriginID, QUuid, ENTITY_ITEM_DEFAULT_CLONE_ORIGIN_ID); + DEFINE_PROPERTY_GROUP(Grab, grab, GrabPropertyGroup); + static QString getComponentModeString(uint32_t mode); static QString getComponentModeAsString(uint32_t mode); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index ff4fb39354..d3a2dc6cec 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -101,8 +101,11 @@ changedProperties += P; \ } -inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::vec2& v) { return vec2toScriptValue(e, v); } -inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::vec3& v) { return vec3toScriptValue(e, v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::vec2& v) { return vec2ToScriptValue(e, v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::vec3& v) { return vec3ToScriptValue(e, v); } +inline QScriptValue vec3Color_convertScriptValue(QScriptEngine* e, const glm::vec3& v) { return vec3ColorToScriptValue(e, v); } +inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::u8vec3& v) { return u8vec3ToScriptValue(e, v); } +inline QScriptValue u8vec3Color_convertScriptValue(QScriptEngine* e, const glm::u8vec3& v) { return u8vec3ColorToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, float v) { return QScriptValue(v); } inline QScriptValue convertScriptValue(QScriptEngine* e, int v) { return QScriptValue(v); } inline QScriptValue convertScriptValue(QScriptEngine* e, bool v) { return QScriptValue(v); } @@ -111,10 +114,10 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, quint32 v) { return QSc inline QScriptValue convertScriptValue(QScriptEngine* e, quint64 v) { return QScriptValue((qsreal)v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QString& v) { return QScriptValue(v); } -inline QScriptValue convertScriptValue(QScriptEngine* e, const xColor& v) { return xColorToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const glm::quat& v) { return quatToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QScriptValue& v) { return v; } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorVec3ToScriptValue(e, v); } +inline QScriptValue qVectorVec3Color_convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorVec3ColorToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorQuatToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) {return qVectorBoolToScriptValue(e, v); } inline QScriptValue convertScriptValue(QScriptEngine* e, const QVector& v) { return qVectorFloatToScriptValue(e, v); } @@ -128,8 +131,6 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { return aaCubeToScriptValue(e, v); } - - #define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(X,G,g,P,p) \ if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ @@ -142,6 +143,18 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu properties.setProperty(#g, groupProperties); \ } +#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(X,G,g,P,p,T) \ + if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ + (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ + QScriptValue groupProperties = properties.property(#g); \ + if (!groupProperties.isValid()) { \ + groupProperties = engine->newObject(); \ + } \ + QScriptValue V = T##_convertScriptValue(engine, get##P()); \ + groupProperties.setProperty(#p, V); \ + properties.setProperty(#g, groupProperties); \ + } + #define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(X,G,g,P,p,M) \ if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ @@ -161,6 +174,13 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu properties.setProperty(#P, V); \ } +#define COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(p,P,T) \ + if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \ + (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ + QScriptValue V = T##_convertScriptValue(engine, _##P); \ + properties.setProperty(#P, V); \ + } + #define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(P, G) \ properties.setProperty(#P, G); @@ -171,6 +191,13 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { retu properties.setProperty(#P, V); \ } +#define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_TYPED(p, P, G, T) \ + if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \ + (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ + QScriptValue V = T##_convertScriptValue(engine, G); \ + properties.setProperty(#P, V); \ + } + // same as COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER but uses #X instead of #P in the setProperty() step #define COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, X, G) \ if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ @@ -205,7 +232,6 @@ inline QUuid QUuid_convertFromScriptValue(const QScriptValue& v, bool& isValid) inline EntityItemID EntityItemID_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toUuid(); } - inline QDateTime QDateTime_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; auto result = QDateTime::fromString(v.toVariant().toString().trimmed(), Qt::ISODate); @@ -213,8 +239,6 @@ inline QDateTime QDateTime_convertFromScriptValue(const QScriptValue& v, bool& i return result; } - - inline QByteArray QByteArray_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; QString b64 = v.toVariant().toString().trimmed(); @@ -222,49 +246,31 @@ inline QByteArray QByteArray_convertFromScriptValue(const QScriptValue& v, bool& } inline glm::vec2 vec2_convertFromScriptValue(const QScriptValue& v, bool& isValid) { - isValid = false; /// assume it can't be converted - QScriptValue x = v.property("x"); - QScriptValue y = v.property("y"); - if (x.isValid() && y.isValid()) { - glm::vec4 newValue(0); - newValue.x = x.toVariant().toFloat(); - newValue.y = y.toVariant().toFloat(); - isValid = !glm::isnan(newValue.x) && - !glm::isnan(newValue.y); - if (isValid) { - return newValue; - } - } - return glm::vec2(0); + isValid = true; + glm::vec2 vec2; + vec2FromScriptValue(v, vec2); + return vec2; } inline glm::vec3 vec3_convertFromScriptValue(const QScriptValue& v, bool& isValid) { - isValid = false; /// assume it can't be converted - QScriptValue x = v.property("x"); - QScriptValue y = v.property("y"); - QScriptValue z = v.property("z"); - if (!x.isValid()) { - x = v.property("red"); - } - if (!y.isValid()) { - y = v.property("green"); - } - if (!z.isValid()) { - z = v.property("blue"); - } - if (x.isValid() && y.isValid() && z.isValid()) { - glm::vec3 newValue(0); - newValue.x = x.toVariant().toFloat(); - newValue.y = y.toVariant().toFloat(); - newValue.z = z.toVariant().toFloat(); - isValid = !glm::isnan(newValue.x) && - !glm::isnan(newValue.y) && - !glm::isnan(newValue.z); - if (isValid) { - return newValue; - } - } - return glm::vec3(0); + isValid = true; + glm::vec3 vec3; + vec3FromScriptValue(v, vec3); + return vec3; +} + +inline glm::vec3 vec3Color_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + isValid = true; + glm::vec3 vec3; + vec3FromScriptValue(v, vec3); + return vec3; +} + +inline glm::u8vec3 u8vec3Color_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + isValid = true; + glm::u8vec3 vec3; + u8vec3FromScriptValue(v, vec3); + return vec3; } inline AACube AACube_convertFromScriptValue(const QScriptValue& v, bool& isValid) { @@ -317,31 +323,6 @@ inline glm::quat quat_convertFromScriptValue(const QScriptValue& v, bool& isVali return glm::quat(); } -inline xColor xColor_convertFromScriptValue(const QScriptValue& v, bool& isValid) { - xColor newValue { 255, 255, 255 }; - isValid = false; /// assume it can't be converted - QScriptValue r = v.property("red"); - QScriptValue g = v.property("green"); - QScriptValue b = v.property("blue"); - if (!r.isValid()) { - r = v.property("x"); - } - if (!g.isValid()) { - g = v.property("y"); - } - if (!b.isValid()) { - b = v.property("z"); - } - if (r.isValid() && g.isValid() && b.isValid()) { - newValue.red = r.toVariant().toInt(); - newValue.green = g.toVariant().toInt(); - newValue.blue = b.toVariant().toInt(); - isValid = true; - } - return newValue; -} - - #define COPY_PROPERTY_IF_CHANGED(P) \ { \ if (other._##P##Changed) { \ diff --git a/libraries/entities/src/EntityPropertyFlags.cpp b/libraries/entities/src/EntityPropertyFlags.cpp new file mode 100644 index 0000000000..c077b153b8 --- /dev/null +++ b/libraries/entities/src/EntityPropertyFlags.cpp @@ -0,0 +1,207 @@ + +#include "EntityPropertyFlags.h" + + +QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f) { + QString result = "[ "; + + result = f.getHasProperty(PROP_PAGED_PROPERTY) ? result + "pagedProperty " : result; + result = f.getHasProperty(PROP_CUSTOM_PROPERTIES_INCLUDED) ? result + "customPropertiesIncluded " : result; + result = f.getHasProperty(PROP_VISIBLE) ? result + "visible " : result; + result = f.getHasProperty(PROP_CAN_CAST_SHADOW) ? result + "canCastShadow " : result; + result = f.getHasProperty(PROP_POSITION) ? result + "position " : result; + result = f.getHasProperty(PROP_DIMENSIONS) ? result + "dimensions " : result; + result = f.getHasProperty(PROP_ROTATION) ? result + "rotation " : result; + result = f.getHasProperty(PROP_DENSITY) ? result + "density " : result; + result = f.getHasProperty(PROP_VELOCITY) ? result + "velocity " : result; + result = f.getHasProperty(PROP_GRAVITY) ? result + "gravity " : result; + result = f.getHasProperty(PROP_DAMPING) ? result + "damping " : result; + result = f.getHasProperty(PROP_LIFETIME) ? result + "lifetime " : result; + result = f.getHasProperty(PROP_SCRIPT) ? result + "script " : result; + result = f.getHasProperty(PROP_COLOR) ? result + "color " : result; + result = f.getHasProperty(PROP_MODEL_URL) ? result + "modelUrl " : result; + result = f.getHasProperty(PROP_ANIMATION_URL) ? result + "animationUrl " : result; + result = f.getHasProperty(PROP_ANIMATION_FPS) ? result + "animationFps " : result; + result = f.getHasProperty(PROP_ANIMATION_FRAME_INDEX) ? result + "animationFrameIndex " : result; + result = f.getHasProperty(PROP_ANIMATION_PLAYING) ? result + "animationPlaying " : result; + result = f.getHasProperty(PROP_ANIMATION_ALLOW_TRANSLATION) ? result + "animationAllowTranslation " : result; + result = f.getHasProperty(PROP_RELAY_PARENT_JOINTS) ? result + "relayParentJoints " : result; + result = f.getHasProperty(PROP_REGISTRATION_POINT) ? result + "registrationPoint " : result; + result = f.getHasProperty(PROP_ANGULAR_VELOCITY) ? result + "angularVelocity " : result; + result = f.getHasProperty(PROP_ANGULAR_DAMPING) ? result + "angularDamping " : result; + result = f.getHasProperty(PROP_COLLISIONLESS) ? result + "collisionless " : result; + result = f.getHasProperty(PROP_DYNAMIC) ? result + "dynamic " : result; + result = f.getHasProperty(PROP_IS_SPOTLIGHT) ? result + "isSpotlight " : result; + result = f.getHasProperty(PROP_DIFFUSE_COLOR) ? result + "diffuseColor " : result; + result = f.getHasProperty(PROP_AMBIENT_COLOR_UNUSED) ? result + "ambientColorUnused " : result; + result = f.getHasProperty(PROP_SPECULAR_COLOR_UNUSED) ? result + "specularColorUnused " : result; + result = f.getHasProperty(PROP_INTENSITY) ? result + "intensity " : result; + result = f.getHasProperty(PROP_LINEAR_ATTENUATION_UNUSED) ? result + "linearAttenuationUnused " : result; + result = f.getHasProperty(PROP_QUADRATIC_ATTENUATION_UNUSED) ? result + "quadraticAttenuationUnused " : result; + result = f.getHasProperty(PROP_EXPONENT) ? result + "exponent " : result; + result = f.getHasProperty(PROP_CUTOFF) ? result + "cutoff " : result; + result = f.getHasProperty(PROP_LOCKED) ? result + "locked " : result; + result = f.getHasProperty(PROP_TEXTURES) ? result + "textures " : result; + result = f.getHasProperty(PROP_ANIMATION_SETTINGS_UNUSED) ? result + "animationSettingsUnused " : result; + result = f.getHasProperty(PROP_USER_DATA) ? result + "userData " : result; + result = f.getHasProperty(PROP_SHAPE_TYPE) ? result + "shapeType " : result; + result = f.getHasProperty(PROP_MAX_PARTICLES) ? result + "maxParticles " : result; + result = f.getHasProperty(PROP_LIFESPAN) ? result + "lifespan " : result; + result = f.getHasProperty(PROP_EMIT_RATE) ? result + "emitRate " : result; + result = f.getHasProperty(PROP_EMIT_SPEED) ? result + "emitSpeed " : result; + result = f.getHasProperty(PROP_EMIT_STRENGTH) ? result + "emitStrength " : result; + result = f.getHasProperty(PROP_EMIT_ACCELERATION) ? result + "emitAcceleration " : result; + result = f.getHasProperty(PROP_PARTICLE_RADIUS) ? result + "particleRadius " : result; + result = f.getHasProperty(PROP_COMPOUND_SHAPE_URL) ? result + "compoundShapeUrl " : result; + result = f.getHasProperty(PROP_MARKETPLACE_ID) ? result + "marketplaceID " : result; + result = f.getHasProperty(PROP_ACCELERATION) ? result + "acceleration " : result; + result = f.getHasProperty(PROP_SIMULATION_OWNER) ? result + "simulationOwner " : result; + result = f.getHasProperty(PROP_NAME) ? result + "name " : result; + result = f.getHasProperty(PROP_COLLISION_SOUND_URL) ? result + "collisionSoundUrl " : result; + result = f.getHasProperty(PROP_RESTITUTION) ? result + "restitution " : result; + result = f.getHasProperty(PROP_FRICTION) ? result + "friction " : result; + result = f.getHasProperty(PROP_VOXEL_VOLUME_SIZE) ? result + "voxelVolumeSize " : result; + result = f.getHasProperty(PROP_VOXEL_DATA) ? result + "voxelData " : result; + result = f.getHasProperty(PROP_VOXEL_SURFACE_STYLE) ? result + "voxelSurfaceStyle " : result; + result = f.getHasProperty(PROP_LINE_WIDTH) ? result + "lineWidth " : result; + result = f.getHasProperty(PROP_LINE_POINTS) ? result + "linePoints " : result; + result = f.getHasProperty(PROP_HREF) ? result + "href " : result; + result = f.getHasProperty(PROP_DESCRIPTION) ? result + "description " : result; + result = f.getHasProperty(PROP_FACE_CAMERA) ? result + "faceCamera " : result; + result = f.getHasProperty(PROP_SCRIPT_TIMESTAMP) ? result + "scriptTimestamp " : result; + result = f.getHasProperty(PROP_ACTION_DATA) ? result + "actionData " : result; + result = f.getHasProperty(PROP_X_TEXTURE_URL) ? result + "xTextureUrl " : result; + result = f.getHasProperty(PROP_Y_TEXTURE_URL) ? result + "yTextureUrl " : result; + result = f.getHasProperty(PROP_Z_TEXTURE_URL) ? result + "zTextureUrl " : result; + result = f.getHasProperty(PROP_NORMALS) ? result + "normals " : result; + result = f.getHasProperty(PROP_STROKE_COLORS) ? result + "strokeColors " : result; + result = f.getHasProperty(PROP_STROKE_WIDTHS) ? result + "strokeWidths " : result; + result = f.getHasProperty(PROP_IS_UV_MODE_STRETCH) ? result + "isUvModeStretch " : result; + result = f.getHasProperty(PROP_SPEED_SPREAD) ? result + "speedSpread " : result; + result = f.getHasProperty(PROP_ACCELERATION_SPREAD) ? result + "accelerationSpread " : result; + result = f.getHasProperty(PROP_X_N_NEIGHBOR_ID) ? result + "xNNeighborID " : result; + result = f.getHasProperty(PROP_Y_N_NEIGHBOR_ID) ? result + "yNNeighborID " : result; + result = f.getHasProperty(PROP_Z_N_NEIGHBOR_ID) ? result + "zNNeighborID " : result; + result = f.getHasProperty(PROP_X_P_NEIGHBOR_ID) ? result + "xPNeighborID " : result; + result = f.getHasProperty(PROP_Y_P_NEIGHBOR_ID) ? result + "yPNeighborID " : result; + result = f.getHasProperty(PROP_Z_P_NEIGHBOR_ID) ? result + "zPNeighborID " : result; + result = f.getHasProperty(PROP_RADIUS_SPREAD) ? result + "radiusSpread " : result; + result = f.getHasProperty(PROP_RADIUS_START) ? result + "radiusStart " : result; + result = f.getHasProperty(PROP_RADIUS_FINISH) ? result + "radiusFinish " : result; + result = f.getHasProperty(PROP_ALPHA) ? result + "alpha " : result; + result = f.getHasProperty(PROP_COLOR_SPREAD) ? result + "colorSpread " : result; + result = f.getHasProperty(PROP_COLOR_START) ? result + "colorStart " : result; + result = f.getHasProperty(PROP_COLOR_FINISH) ? result + "colorFinish " : result; + result = f.getHasProperty(PROP_ALPHA_SPREAD) ? result + "alphaSpread " : result; + result = f.getHasProperty(PROP_ALPHA_START) ? result + "alphaStart " : result; + result = f.getHasProperty(PROP_ALPHA_FINISH) ? result + "alphaFinish " : result; + result = f.getHasProperty(PROP_EMIT_ORIENTATION) ? result + "emitOrientation " : result; + result = f.getHasProperty(PROP_EMIT_DIMENSIONS) ? result + "emitDimensions " : result; + result = f.getHasProperty(PROP_EMIT_RADIUS_START) ? result + "emitRadiusStart " : result; + result = f.getHasProperty(PROP_POLAR_START) ? result + "polarStart " : result; + result = f.getHasProperty(PROP_POLAR_FINISH) ? result + "polarFinish " : result; + result = f.getHasProperty(PROP_AZIMUTH_START) ? result + "azimuthStart " : result; + result = f.getHasProperty(PROP_AZIMUTH_FINISH) ? result + "azimuthFinish " : result; + result = f.getHasProperty(PROP_ANIMATION_LOOP) ? result + "animationLoop " : result; + result = f.getHasProperty(PROP_ANIMATION_FIRST_FRAME) ? result + "animationFirstFrame " : result; + result = f.getHasProperty(PROP_ANIMATION_LAST_FRAME) ? result + "animationLastFrame " : result; + result = f.getHasProperty(PROP_ANIMATION_HOLD) ? result + "animationHold " : result; + result = f.getHasProperty(PROP_ANIMATION_START_AUTOMATICALLY) ? result + "animationStartAutomatically " : result; + result = f.getHasProperty(PROP_EMITTER_SHOULD_TRAIL) ? result + "emitterShouldTrail " : result; + result = f.getHasProperty(PROP_PARENT_ID) ? result + "parentID " : result; + result = f.getHasProperty(PROP_PARENT_JOINT_INDEX) ? result + "parentJointIndex " : result; + result = f.getHasProperty(PROP_LOCAL_POSITION) ? result + "localPosition " : result; + result = f.getHasProperty(PROP_LOCAL_ROTATION) ? result + "localRotation " : result; + result = f.getHasProperty(PROP_QUERY_AA_CUBE) ? result + "queryAaCube " : result; + result = f.getHasProperty(PROP_JOINT_ROTATIONS_SET) ? result + "jointRotationsSet " : result; + result = f.getHasProperty(PROP_JOINT_ROTATIONS) ? result + "jointRotations " : result; + result = f.getHasProperty(PROP_JOINT_TRANSLATIONS_SET) ? result + "jointTranslationsSet " : result; + result = f.getHasProperty(PROP_JOINT_TRANSLATIONS) ? result + "jointTranslations " : result; + result = f.getHasProperty(PROP_COLLISION_MASK) ? result + "collisionMask " : result; + result = f.getHasProperty(PROP_FALLOFF_RADIUS) ? result + "falloffRadius " : result; + result = f.getHasProperty(PROP_FLYING_ALLOWED) ? result + "flyingAllowed " : result; + result = f.getHasProperty(PROP_GHOSTING_ALLOWED) ? result + "ghostingAllowed " : result; + result = f.getHasProperty(PROP_CLIENT_ONLY) ? result + "clientOnly " : result; + result = f.getHasProperty(PROP_OWNING_AVATAR_ID) ? result + "owningAvatarID " : result; + result = f.getHasProperty(PROP_SHAPE) ? result + "shape " : result; + result = f.getHasProperty(PROP_DPI) ? result + "dpi " : result; + result = f.getHasProperty(PROP_LOCAL_VELOCITY) ? result + "localVelocity " : result; + result = f.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ? result + "localAngularVelocity " : result; + result = f.getHasProperty(PROP_LAST_EDITED_BY) ? result + "lastEditedBy " : result; + result = f.getHasProperty(PROP_SERVER_SCRIPTS) ? result + "serverScripts " : result; + result = f.getHasProperty(PROP_FILTER_URL) ? result + "filterUrl " : result; + result = f.getHasProperty(PROP_ITEM_NAME) ? result + "itemName " : result; + result = f.getHasProperty(PROP_ITEM_DESCRIPTION) ? result + "itemDescription " : result; + result = f.getHasProperty(PROP_ITEM_CATEGORIES) ? result + "itemCategories " : result; + result = f.getHasProperty(PROP_ITEM_ARTIST) ? result + "itemArtist " : result; + result = f.getHasProperty(PROP_ITEM_LICENSE) ? result + "itemLicense " : result; + result = f.getHasProperty(PROP_LIMITED_RUN) ? result + "limitedRun " : result; + result = f.getHasProperty(PROP_EDITION_NUMBER) ? result + "editionNumber " : result; + result = f.getHasProperty(PROP_ENTITY_INSTANCE_NUMBER) ? result + "entityInstanceNumber " : result; + result = f.getHasProperty(PROP_CERTIFICATE_ID) ? result + "certificateID " : result; + result = f.getHasProperty(PROP_STATIC_CERTIFICATE_VERSION) ? result + "staticCertificateVersion " : result; + result = f.getHasProperty(PROP_CLONEABLE) ? result + "cloneable " : result; + result = f.getHasProperty(PROP_CLONE_LIFETIME) ? result + "cloneLifetime " : result; + result = f.getHasProperty(PROP_CLONE_LIMIT) ? result + "cloneLimit " : result; + result = f.getHasProperty(PROP_CLONE_DYNAMIC) ? result + "cloneDynamic " : result; + result = f.getHasProperty(PROP_CLONE_AVATAR_ENTITY) ? result + "cloneAvatarEntity " : result; + result = f.getHasProperty(PROP_CLONE_ORIGIN_ID) ? result + "cloneOriginID " : result; + result = f.getHasProperty(PROP_HAZE_MODE) ? result + "hazeMode " : result; + result = f.getHasProperty(PROP_KEYLIGHT_COLOR) ? result + "keylightColor " : result; + result = f.getHasProperty(PROP_KEYLIGHT_INTENSITY) ? result + "keylightIntensity " : result; + result = f.getHasProperty(PROP_KEYLIGHT_DIRECTION) ? result + "keylightDirection " : result; + result = f.getHasProperty(PROP_KEYLIGHT_CAST_SHADOW) ? result + "keylightCastShadow " : result; + result = f.getHasProperty(PROP_HAZE_RANGE) ? result + "hazeRange " : result; + result = f.getHasProperty(PROP_HAZE_COLOR) ? result + "hazeColor " : result; + result = f.getHasProperty(PROP_HAZE_GLARE_COLOR) ? result + "hazeGlareColor " : result; + result = f.getHasProperty(PROP_HAZE_ENABLE_GLARE) ? result + "hazeEnableGlare " : result; + result = f.getHasProperty(PROP_HAZE_GLARE_ANGLE) ? result + "hazeGlareAngle " : result; + result = f.getHasProperty(PROP_HAZE_ALTITUDE_EFFECT) ? result + "hazeAltitudeEffect " : result; + result = f.getHasProperty(PROP_HAZE_CEILING) ? result + "hazeCeiling " : result; + result = f.getHasProperty(PROP_HAZE_BASE_REF) ? result + "hazeBaseRef " : result; + result = f.getHasProperty(PROP_HAZE_BACKGROUND_BLEND) ? result + "hazeBackgroundBlend " : result; + result = f.getHasProperty(PROP_HAZE_ATTENUATE_KEYLIGHT) ? result + "hazeAttenuateKeylight " : result; + result = f.getHasProperty(PROP_HAZE_KEYLIGHT_RANGE) ? result + "hazeKeylightRange " : result; + result = f.getHasProperty(PROP_HAZE_KEYLIGHT_ALTITUDE) ? result + "hazeKeylightAltitude " : result; + result = f.getHasProperty(PROP_KEY_LIGHT_MODE) ? result + "keyLightMode " : result; + result = f.getHasProperty(PROP_AMBIENT_LIGHT_MODE) ? result + "ambientLightMode " : result; + result = f.getHasProperty(PROP_SKYBOX_MODE) ? result + "skyboxMode " : result; + result = f.getHasProperty(PROP_LOCAL_DIMENSIONS) ? result + "localDimensions " : result; + result = f.getHasProperty(PROP_MATERIAL_URL) ? result + "materialUrl " : result; + result = f.getHasProperty(PROP_MATERIAL_MAPPING_MODE) ? result + "materialMappingMode " : result; + result = f.getHasProperty(PROP_MATERIAL_PRIORITY) ? result + "materialPriority " : result; + result = f.getHasProperty(PROP_PARENT_MATERIAL_NAME) ? result + "parentMaterialName " : result; + result = f.getHasProperty(PROP_MATERIAL_MAPPING_POS) ? result + "materialMappingPos " : result; + result = f.getHasProperty(PROP_MATERIAL_MAPPING_SCALE) ? result + "materialMappingScale " : result; + result = f.getHasProperty(PROP_MATERIAL_MAPPING_ROT) ? result + "materialMappingRot " : result; + result = f.getHasProperty(PROP_MATERIAL_DATA) ? result + "materialData " : result; + result = f.getHasProperty(PROP_VISIBLE_IN_SECONDARY_CAMERA) ? result + "visibleInSecondaryCamera " : result; + result = f.getHasProperty(PROP_PARTICLE_SPIN) ? result + "particleSpin " : result; + result = f.getHasProperty(PROP_SPIN_START) ? result + "spinStart " : result; + result = f.getHasProperty(PROP_SPIN_FINISH) ? result + "spinFinish " : result; + result = f.getHasProperty(PROP_SPIN_SPREAD) ? result + "spinSpread " : result; + result = f.getHasProperty(PROP_PARTICLE_ROTATE_WITH_ENTITY) ? result + "particleRotateWithEntity " : result; + result = f.getHasProperty(PROP_BLOOM_INTENSITY) ? result + "bloomIntensity " : result; + result = f.getHasProperty(PROP_BLOOM_THRESHOLD) ? result + "bloomThreshold " : result; + result = f.getHasProperty(PROP_BLOOM_SIZE) ? result + "bloomSize " : result; + result = f.getHasProperty(PROP_GRAB_GRABBABLE) ? result + "grab.Grabbable " : result; + result = f.getHasProperty(PROP_GRAB_KINEMATIC) ? result + "grab.Kinematic " : result; + result = f.getHasProperty(PROP_GRAB_FOLLOWS_CONTROLLER) ? result + "grab.FollowsController " : result; + result = f.getHasProperty(PROP_GRAB_TRIGGERABLE) ? result + "grab.Triggerable " : result; + result = f.getHasProperty(PROP_GRAB_EQUIPPABLE) ? result + "grab.Equippable " : result; + result = + f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.LeftEquippablePositionOffset " : result; + result = + f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.LeftEquippableRotationOffset " : result; + result = + f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.RightEquippablePositionOffset " : result; + result = + f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.RightEquippableRotationOffset " : result; + result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_URL) ? result + "grab.EquippableIndicatorURL " : result; + result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE) ? result + "grab.EquippableIndicatorScale " : result; + result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET) ? result + "grab.EquippableIndicatorOffset " : result; + + result += "]"; + dbg.nospace() << result; + return dbg; +} diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 3932730661..d2f687fbd3 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -262,6 +262,19 @@ enum EntityPropertyList { PROP_BLOOM_THRESHOLD, PROP_BLOOM_SIZE, + PROP_GRAB_GRABBABLE, + PROP_GRAB_KINEMATIC, + PROP_GRAB_FOLLOWS_CONTROLLER, + PROP_GRAB_TRIGGERABLE, + PROP_GRAB_EQUIPPABLE, + PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, + PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, + PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, + PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, + PROP_GRAB_EQUIPPABLE_INDICATOR_URL, + PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, + PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, @@ -304,5 +317,10 @@ typedef PropertyFlags EntityPropertyFlags; // one greater than the last item property due to the enum's auto-incrementing. extern EntityPropertyList PROP_LAST_ITEM; +QString EntityPropertyFlagsToString(EntityPropertyFlags propertiesFlags); + + +QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f); + #endif // hifi_EntityPropertyFlags_h diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 3ecec89573..a8fce0d5fb 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1192,9 +1192,9 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c obj.setProperty("distance", value.distance); obj.setProperty("face", boxFaceToString(value.face)); - QScriptValue intersection = vec3toScriptValue(engine, value.intersection); + QScriptValue intersection = vec3ToScriptValue(engine, value.intersection); obj.setProperty("intersection", intersection); - QScriptValue surfaceNormal = vec3toScriptValue(engine, value.surfaceNormal); + QScriptValue surfaceNormal = vec3ToScriptValue(engine, value.surfaceNormal); obj.setProperty("surfaceNormal", surfaceNormal); obj.setProperty("extraInfo", engine->toScriptValue(value.extraInfo)); return obj; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a7c88ddc7d..0b3b8abba2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -668,7 +668,7 @@ void EntityTree::unhookChildAvatar(const EntityItemID entityID) { void EntityTree::cleanupCloneIDs(const EntityItemID& entityID) { EntityItemPointer entity = findEntityByEntityItemID(entityID); if (entity) { - // remove clone ID from it's clone origin's clone ID list if clone origin exists + // remove clone ID from its clone origin's clone ID list if clone origin exists const QUuid& cloneOriginID = entity->getCloneOriginID(); if (!cloneOriginID.isNull()) { EntityItemPointer cloneOrigin = findEntityByID(cloneOriginID); @@ -1933,6 +1933,14 @@ void EntityTree::fixupNeedsParentFixups() { } }); entity->locationChanged(true); + + // Update our parent's bounding box + bool success = false; + auto parent = entity->getParentPointer(success); + if (success && parent) { + parent->updateQueryAACube(); + } + entity->postParentFixup(); } else if (getIsServer() || _avatarIDs.contains(entity->getParentID())) { // this is a child of an avatar, which the entity server will never have @@ -2558,7 +2566,7 @@ bool EntityTree::readFromMap(QVariantMap& map) { if (needsConversion && (properties.getType() == EntityTypes::EntityType::Zone)) { // The legacy version had no keylight mode - this is set to on properties.setKeyLightMode(COMPONENT_MODE_ENABLED); - + // The ambient URL has been moved from "keyLight" to "ambientLight" if (entityMap.contains("keyLight")) { QVariantMap keyLightObject = entityMap["keyLight"].toMap(); @@ -2629,6 +2637,108 @@ bool EntityTree::readFromMap(QVariantMap& map) { } } + // convert old grab-related userData to new grab properties + if (contentVersion < (int)EntityVersion::GrabProperties) { + QJsonObject userData = QJsonDocument::fromJson(properties.getUserData().toUtf8()).object(); + QJsonObject grabbableKey = userData["grabbableKey"].toObject(); + QJsonValue wantsTrigger = grabbableKey["wantsTrigger"]; + + GrabPropertyGroup& grabProperties = properties.getGrab(); + + if (wantsTrigger.isBool()) { + grabProperties.setTriggerable(wantsTrigger.toBool()); + } + QJsonValue triggerable = grabbableKey["triggerable"]; + if (triggerable.isBool()) { + grabProperties.setTriggerable(triggerable.toBool()); + } + QJsonValue grabbable = grabbableKey["grabbable"]; + if (grabbable.isBool()) { + grabProperties.setGrabbable(grabbable.toBool()); + } + QJsonValue ignoreIK = grabbableKey["ignoreIK"]; + if (ignoreIK.isBool()) { + grabProperties.setGrabFollowsController(ignoreIK.toBool()); + } + QJsonValue kinematic = grabbableKey["kinematic"]; + if (kinematic.isBool()) { + grabProperties.setGrabKinematic(kinematic.toBool()); + } + + if (grabbableKey["spatialKey"].isObject()) { + QJsonObject spatialKey = grabbableKey["spatialKey"].toObject(); + grabProperties.setEquippable(true); + if (spatialKey["leftRelativePosition"].isObject()) { + grabProperties.setEquippableLeftPosition(qMapToVec3(spatialKey["leftRelativePosition"].toVariant())); + } + if (spatialKey["rightRelativePosition"].isObject()) { + grabProperties.setEquippableRightPosition(qMapToVec3(spatialKey["rightRelativePosition"].toVariant())); + } + if (spatialKey["relativeRotation"].isObject()) { + grabProperties.setEquippableLeftRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant())); + grabProperties.setEquippableRightRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant())); + } + } + + QJsonObject wearable = userData["wearable"].toObject(); + QJsonObject joints = wearable["joints"].toObject(); + if (joints["LeftHand"].isArray()) { + QJsonArray leftHand = joints["LeftHand"].toArray(); + if (leftHand.size() == 2) { + grabProperties.setEquippable(true); + grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant())); + grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant())); + } + } + if (joints["RightHand"].isArray()) { + QJsonArray rightHand = joints["RightHand"].toArray(); + if (rightHand.size() == 2) { + grabProperties.setEquippable(true); + grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant())); + grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant())); + } + } + + if (userData["equipHotspots"].isArray()) { + QJsonArray equipHotspots = userData["equipHotspots"].toArray(); + if (equipHotspots.size() > 0) { + // just take the first one + QJsonObject firstHotSpot = equipHotspots[0].toObject(); + QJsonObject joints = firstHotSpot["joints"].toObject(); + if (joints["LeftHand"].isArray()) { + QJsonArray leftHand = joints["LeftHand"].toArray(); + if (leftHand.size() == 2) { + grabProperties.setEquippable(true); + grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant())); + grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant())); + } + } + if (joints["RightHand"].isArray()) { + QJsonArray rightHand = joints["RightHand"].toArray(); + if (rightHand.size() == 2) { + grabProperties.setEquippable(true); + grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant())); + grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant())); + } + } + QJsonValue indicatorURL = firstHotSpot["modelURL"]; + if (indicatorURL.isString()) { + grabProperties.setEquippableIndicatorURL(indicatorURL.toString()); + } + QJsonValue indicatorScale = firstHotSpot["modelScale"]; + if (indicatorScale.isDouble()) { + grabProperties.setEquippableIndicatorScale(glm::vec3((float)indicatorScale.toDouble())); + } else if (indicatorScale.isObject()) { + grabProperties.setEquippableIndicatorScale(qMapToVec3(indicatorScale.toVariant())); + } + QJsonValue indicatorOffset = firstHotSpot["position"]; + if (indicatorOffset.isObject()) { + grabProperties.setEquippableIndicatorOffset(qMapToVec3(indicatorOffset.toVariant())); + } + } + } + } + // Zero out the spread values that were fixed in version ParticleEntityFix so they behave the same as before if (contentVersion < (int)EntityVersion::ParticleEntityFix) { properties.setRadiusSpread(0.0f); diff --git a/libraries/entities/src/GrabPropertyGroup.cpp b/libraries/entities/src/GrabPropertyGroup.cpp new file mode 100644 index 0000000000..c433043e31 --- /dev/null +++ b/libraries/entities/src/GrabPropertyGroup.cpp @@ -0,0 +1,303 @@ +// +// GrabPropertyGroup.h +// libraries/entities/src +// +// Created by Seth Alves on 2018-8-8. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "GrabPropertyGroup.h" + +#include + +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +void GrabPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, + QScriptEngine* engine, bool skipDefaults, + EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_TRIGGERABLE, Grab, grab, Triggerable, triggerable); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE, Grab, grab, Equippable, equippable); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, + EquippableLeftPosition, equippableLeftPosition); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, + EquippableLeftRotation, equippableLeftRotation); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, + EquippableRightPosition, equippableRightPosition); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, + EquippableRightRotation, equippableRightRotation); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab, + EquippableIndicatorURL, equippableIndicatorURL); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab, + EquippableIndicatorScale, equippableIndicatorScale); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab, + EquippableIndicatorOffset, equippableIndicatorOffset); + +} + +void GrabPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabbable, bool, setGrabbable); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabKinematic, bool, setGrabKinematic); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabFollowsController, bool, setGrabFollowsController); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, triggerable, bool, setTriggerable); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippable, bool, setEquippable); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableLeftPosition, vec3, setEquippableLeftPosition); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableLeftRotation, quat, setEquippableLeftRotation); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightPosition, vec3, setEquippableRightPosition); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightRotation, quat, setEquippableRightRotation); +} + +void GrabPropertyGroup::merge(const GrabPropertyGroup& other) { + COPY_PROPERTY_IF_CHANGED(grabbable); + COPY_PROPERTY_IF_CHANGED(grabKinematic); + COPY_PROPERTY_IF_CHANGED(grabFollowsController); + COPY_PROPERTY_IF_CHANGED(triggerable); + COPY_PROPERTY_IF_CHANGED(equippable); + COPY_PROPERTY_IF_CHANGED(equippableLeftPosition); + COPY_PROPERTY_IF_CHANGED(equippableLeftRotation); + COPY_PROPERTY_IF_CHANGED(equippableRightPosition); + COPY_PROPERTY_IF_CHANGED(equippableRightRotation); +} + +void GrabPropertyGroup::debugDump() const { + qCDebug(entities) << " GrabPropertyGroup: ---------------------------------------------"; + + qCDebug(entities) << " _grabbable:" << _grabbable; + qCDebug(entities) << " _grabKinematic:" << _grabKinematic; + qCDebug(entities) << " _grabFollowsController:" << _grabFollowsController; + qCDebug(entities) << " _triggerable:" << _triggerable; + qCDebug(entities) << " _equippable:" << _equippable; + qCDebug(entities) << " _equippableLeftPosition:" << _equippableLeftPosition; + qCDebug(entities) << " _equippableLeftRotation:" << _equippableLeftRotation; + qCDebug(entities) << " _equippableRightPosition:" << _equippableRightPosition; + qCDebug(entities) << " _equippableRightRotation:" << _equippableRightRotation; +} + +void GrabPropertyGroup::listChangedProperties(QList& out) { + if (grabbableChanged()) { + out << "grab-grabbable"; + } + if (grabKinematicChanged()) { + out << "grab-grabKinematic"; + } + if (grabFollowsControllerChanged()) { + out << "grab-followsController"; + } + if (triggerableChanged()) { + out << "grab-triggerable"; + } + if (equippableChanged()) { + out << "grab-equippable"; + } + if (equippableLeftPositionChanged()) { + out << "grab-equippableLeftPosition"; + } + if (equippableLeftRotationChanged()) { + out << "grab-equippableLeftRotation"; + } + if (equippableRightPositionChanged()) { + out << "grab-equippableRightPosition"; + } + if (equippableRightRotationChanged()) { + out << "grab-equippableRightRotation"; + } +} + +bool GrabPropertyGroup::appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, getGrabbable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, getGrabKinematic()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, getGrabFollowsController()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, getTriggerable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, getEquippable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, getEquippableLeftPosition()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, getEquippableLeftRotation()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, getEquippableRightPosition()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, getEquippableRightRotation()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, getEquippableIndicatorURL()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, getEquippableIndicatorScale()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, getEquippableIndicatorOffset()); + + return true; +} + +bool GrabPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, + const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + bool somethingChanged = false; + + READ_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, bool, setGrabbable); + READ_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, bool, setGrabKinematic); + READ_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, bool, setGrabFollowsController); + READ_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, bool, setTriggerable); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, bool, setEquippable); + READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableLeftPosition); + READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableLeftRotation); + READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableRightPosition); + READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableRightRotation); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, QString, setEquippableIndicatorURL); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, glm::vec3, setEquippableIndicatorScale); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, glm::vec3, setEquippableIndicatorOffset); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_GRABBABLE, Grabbable); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_KINEMATIC, GrabKinematic); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_FOLLOWS_CONTROLLER, GrabFollowsController); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_TRIGGERABLE, Triggerable); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE, Equippable); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, EquippableLeftPosition); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, EquippableLeftRotation); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, EquippableRightPosition); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, EquippableRightRotation); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, EquippableIndicatorURL); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, EquippableIndicatorScale); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, EquippableIndicatorOffset); + + processedBytes += bytesRead; + + Q_UNUSED(somethingChanged); + + return true; +} + +void GrabPropertyGroup::markAllChanged() { + _grabbableChanged = true; + _grabKinematicChanged = true; + _grabFollowsControllerChanged = true; + _triggerableChanged = true; + _equippableChanged = true; + _equippableLeftPositionChanged = true; + _equippableLeftRotationChanged = true; + _equippableRightPositionChanged = true; + _equippableRightRotationChanged = true; +} + +EntityPropertyFlags GrabPropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_GRAB_GRABBABLE, grabbable); + CHECK_PROPERTY_CHANGE(PROP_GRAB_KINEMATIC, grabKinematic); + CHECK_PROPERTY_CHANGE(PROP_GRAB_FOLLOWS_CONTROLLER, grabFollowsController); + CHECK_PROPERTY_CHANGE(PROP_GRAB_TRIGGERABLE, triggerable); + CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE, equippable); + CHECK_PROPERTY_CHANGE(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, equippableLeftPosition); + CHECK_PROPERTY_CHANGE(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, equippableLeftRotation); + CHECK_PROPERTY_CHANGE(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, equippableRightPosition); + CHECK_PROPERTY_CHANGE(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, equippableRightRotation); + CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, equippableIndicatorURL); + CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, equippableIndicatorScale); + CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, equippableIndicatorOffset); + + return changedProperties; +} + +void GrabPropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Grabbable, getGrabbable); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, GrabKinematic, getGrabKinematic); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, GrabFollowsController, getGrabFollowsController); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Triggerable, getTriggerable); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Equippable, getEquippable); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableLeftPosition, getEquippableLeftPosition); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableLeftRotation, getEquippableLeftRotation); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightPosition, getEquippableRightPosition); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightRotation, getEquippableRightRotation); +} + +bool GrabPropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Grabbable, grabbable, setGrabbable); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, GrabKinematic, grabKinematic, setGrabKinematic); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, GrabFollowsController, grabFollowsController, setGrabFollowsController); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Triggerable, triggerable, setTriggerable); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Equippable, equippable, setEquippable); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableLeftPosition, equippableLeftPosition, setEquippableLeftPosition); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableLeftRotation, equippableLeftRotation, setEquippableLeftRotation); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableRightPosition, equippableRightPosition, + setEquippableRightPosition); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableRightRotation, equippableRightRotation, + setEquippableRightRotation); + + return somethingChanged; +} + +EntityPropertyFlags GrabPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_GRAB_GRABBABLE; + requestedProperties += PROP_GRAB_KINEMATIC; + requestedProperties += PROP_GRAB_FOLLOWS_CONTROLLER; + requestedProperties += PROP_GRAB_TRIGGERABLE; + requestedProperties += PROP_GRAB_EQUIPPABLE; + requestedProperties += PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET; + requestedProperties += PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET; + requestedProperties += PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET; + requestedProperties += PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET; + requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_URL; + requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE; + requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET; + + return requestedProperties; +} + +void GrabPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, getGrabbable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, getGrabKinematic()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, getGrabFollowsController()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, getTriggerable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, getEquippable()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, getEquippableLeftPosition()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, getEquippableLeftRotation()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, getEquippableRightPosition()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, getEquippableRightRotation()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, getEquippableIndicatorURL()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, getEquippableIndicatorScale()); + APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, getEquippableIndicatorOffset()); +} + +int GrabPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, bool, setGrabbable); + READ_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, bool, setGrabKinematic); + READ_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, bool, setGrabFollowsController); + READ_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, bool, setTriggerable); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, bool, setEquippable); + READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableLeftPosition); + READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableLeftRotation); + READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableRightPosition); + READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableRightRotation); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, QString, setEquippableIndicatorURL); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, glm::vec3, setEquippableIndicatorScale); + READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, glm::vec3, setEquippableIndicatorOffset); + + return bytesRead; +} diff --git a/libraries/entities/src/GrabPropertyGroup.h b/libraries/entities/src/GrabPropertyGroup.h new file mode 100644 index 0000000000..37b157de06 --- /dev/null +++ b/libraries/entities/src/GrabPropertyGroup.h @@ -0,0 +1,141 @@ +// +// GrabPropertyGroup.h +// libraries/entities/src +// +// Created by Seth Alves on 2018-8-8. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_GrabPropertyGroup_h +#define hifi_GrabPropertyGroup_h + +#include + +#include + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class ReadBitstreamToTreeParams; + +static const bool INITIAL_GRABBABLE { true }; +static const bool INITIAL_KINEMATIC { true }; +static const bool INITIAL_FOLLOWS_CONTROLLER { true }; +static const bool INITIAL_TRIGGERABLE { false }; +static const bool INITIAL_EQUIPPABLE { false }; +static const glm::vec3 INITIAL_LEFT_EQUIPPABLE_POSITION { glm::vec3(0.0f) }; +static const glm::quat INITIAL_LEFT_EQUIPPABLE_ROTATION { glm::quat() }; +static const glm::vec3 INITIAL_RIGHT_EQUIPPABLE_POSITION { glm::vec3(0.0f) }; +static const glm::quat INITIAL_RIGHT_EQUIPPABLE_ROTATION { glm::quat() }; +static const glm::vec3 INITIAL_EQUIPPABLE_INDICATOR_SCALE { glm::vec3(1.0f) }; +static const glm::vec3 INITIAL_EQUIPPABLE_INDICATOR_OFFSET { glm::vec3(0.0f) }; + + +/**jsdoc + * Grab is defined by the following properties. + * @typedef {object} Entities.Grab + * + * @property {boolean} grabbable=true - If true the entity can be grabbed. + * @property {boolean} grabKinematic=true - If true the entity is updated in a kinematic manner. + * If false it will be grabbed using a tractor action. A kinematic grab will make the item appear more + * tightly held, but will cause it to behave poorly when interacting with dynamic entities. + * @property {boolean} grabFollowsController=true - If true the entity will follow the motions of the + * hand-controller even if the avatar's hand can't get to the implied position. This should be true + * for tools, pens, etc and false for things meant to decorate the hand. + * + * @property {boolean} triggerable=false - If true the entity will receive calls to trigger + * {@link Controller|Controller entity methods}. + * + * @property {boolean} equippable=true - If true the entity can be equipped. + * @property {Vec3} equippableLeftPosition=0,0,0 - Positional offset from the left hand, when equipped. + * @property {Quat} equippableLeftRotation=0,0,0,1 - Rotational offset from the left hand, when equipped. + * @property {Vec3} equippableRightPosition=0,0,0 - Positional offset from the right hand, when equipped. + * @property {Quat} equippableRightRotation=0,0,0,1 - Rotational offset from the right hand, when equipped. + * + * @property {string} equippableIndicatorURL="" - If non-empty, this model will be used to indicate that an + * entity is equippable, rather than the default. + * @property {Vec3} equippableIndicatorScale=1,1,1 - If equippableIndicatorURL is non-empty, this controls the + scale of the displayed overlay. + * @property {Vec3} equippableIndicatorOffset=0,0,0 - If equippableIndicatorURL is non-empty, this controls the + relative offset of the displayed overlay from the equippable entity. + */ + + +class GrabPropertyGroup : public PropertyGroup { +public: + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, + QScriptEngine* engine, bool skipDefaults, + EntityItemProperties& defaultEntityProperties) const override; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override; + + void merge(const GrabPropertyGroup& other); + + virtual void debugDump() const override; + virtual void listChangedProperties(QList& out) override; + + virtual bool appendToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, + const unsigned char*& dataAt, int& processedBytes) override; + virtual void markAllChanged() override; + virtual EntityPropertyFlags getChangedProperties() const override; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const override; + + // returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties) override; + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const override; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) override; + + // grab properties + DEFINE_PROPERTY(PROP_GRAB_GRABBABLE, Grabbable, grabbable, bool, INITIAL_GRABBABLE); + DEFINE_PROPERTY(PROP_GRAB_KINEMATIC, GrabKinematic, grabKinematic, bool, INITIAL_KINEMATIC); + DEFINE_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, GrabFollowsController, grabFollowsController, bool, + INITIAL_FOLLOWS_CONTROLLER); + DEFINE_PROPERTY(PROP_GRAB_TRIGGERABLE, Triggerable, triggerable, bool, INITIAL_TRIGGERABLE); + DEFINE_PROPERTY(PROP_GRAB_EQUIPPABLE, Equippable, equippable, bool, INITIAL_EQUIPPABLE); + DEFINE_PROPERTY_REF(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, EquippableLeftPosition, equippableLeftPosition, + glm::vec3, INITIAL_LEFT_EQUIPPABLE_POSITION); + DEFINE_PROPERTY_REF(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, EquippableLeftRotation, equippableLeftRotation, + glm::quat, INITIAL_LEFT_EQUIPPABLE_ROTATION); + DEFINE_PROPERTY_REF(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, EquippableRightPosition, equippableRightPosition, + glm::vec3, INITIAL_RIGHT_EQUIPPABLE_POSITION); + DEFINE_PROPERTY_REF(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, EquippableRightRotation, equippableRightRotation, + glm::quat, INITIAL_RIGHT_EQUIPPABLE_ROTATION); + DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, EquippableIndicatorURL, equippableIndicatorURL, QString, ""); + DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, EquippableIndicatorScale, equippableIndicatorScale, + glm::vec3, INITIAL_EQUIPPABLE_INDICATOR_SCALE); + DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, EquippableIndicatorOffset, equippableIndicatorOffset, + glm::vec3, INITIAL_EQUIPPABLE_INDICATOR_OFFSET); +}; + +#endif // hifi_GrabPropertyGroup_h diff --git a/libraries/entities/src/HazePropertyGroup.cpp b/libraries/entities/src/HazePropertyGroup.cpp index c15b28707c..632f73ced6 100644 --- a/libraries/entities/src/HazePropertyGroup.cpp +++ b/libraries/entities/src/HazePropertyGroup.cpp @@ -18,8 +18,8 @@ void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor, u8vec3Color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor, u8vec3Color); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle); @@ -36,8 +36,8 @@ void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProp void HazePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeRange, float, setHazeRange); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeColor, xColor, setHazeColor); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareColor, xColor, setHazeGlareColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeColor, u8vec3Color, setHazeColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareColor, u8vec3Color, setHazeGlareColor); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeEnableGlare, bool, setHazeEnableGlare); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareAngle, float, setHazeGlareAngle); @@ -167,8 +167,8 @@ bool HazePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, bool somethingChanged = false; READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange); - READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor); - READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor); + READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, u8vec3Color, setHazeColor); + READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, u8vec3Color, setHazeGlareColor); READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare); READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle); @@ -343,8 +343,8 @@ int HazePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* dat const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange); - READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor); - READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor); + READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, u8vec3Color, setHazeColor); + READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, u8vec3Color, setHazeGlareColor); READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare); READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle); diff --git a/libraries/entities/src/HazePropertyGroup.h b/libraries/entities/src/HazePropertyGroup.h index e992aefbf3..595dbeaf51 100644 --- a/libraries/entities/src/HazePropertyGroup.h +++ b/libraries/entities/src/HazePropertyGroup.h @@ -28,8 +28,8 @@ class EntityTreeElementExtraEncodeData; class ReadBitstreamToTreeParams; static const float INITIAL_HAZE_RANGE{ 1000.0f }; -static const xColor initialHazeGlareColorXcolor{ 255, 229, 179 }; -static const xColor initialHazeColorXcolor{ 128, 154, 179 }; +static const glm::u8vec3 initialHazeGlareColor { 255, 229, 179 }; +static const glm::u8vec3 initialHazeColor { 128, 154, 179 }; static const float INITIAL_HAZE_GLARE_ANGLE{ 20.0f }; static const float INITIAL_HAZE_BASE_REFERENCE{ 0.0f }; @@ -118,8 +118,8 @@ public: // Range only parameters DEFINE_PROPERTY(PROP_HAZE_RANGE, HazeRange, hazeRange, float, INITIAL_HAZE_RANGE); - DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, xColor, initialHazeColorXcolor); - DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, xColor, initialHazeGlareColorXcolor); + DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, glm::u8vec3, initialHazeColor); + DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, glm::u8vec3, initialHazeGlareColor); DEFINE_PROPERTY(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare, hazeEnableGlare, bool, false); DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle, hazeGlareAngle, float, INITIAL_HAZE_GLARE_ANGLE); diff --git a/libraries/entities/src/KeyLightPropertyGroup.cpp b/libraries/entities/src/KeyLightPropertyGroup.cpp index 67e6f05921..f0ad2965ce 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.cpp +++ b/libraries/entities/src/KeyLightPropertyGroup.cpp @@ -17,7 +17,7 @@ #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" -const xColor KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 }; +const glm::u8vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR = { 255, 255, 255 }; const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY = 1.0f; const float KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY = 0.5f; const glm::vec3 KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f }; @@ -26,20 +26,20 @@ const bool KeyLightPropertyGroup::DEFAULT_KEYLIGHT_CAST_SHADOWS { false }; void KeyLightPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color, u8vec3Color); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_DIRECTION, KeyLight, keyLight, Direction, direction); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows); } void KeyLightPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, color, xColor, setColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, color, u8vec3Color, setColor); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, intensity, float, setIntensity); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, direction, vec3, setDirection); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(keyLight, castShadows, bool, setCastShadows); // legacy property support - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, xColor, setColor, getColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightColor, u8vec3Color, setColor, getColor); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightIntensity, float, setIntensity, getIntensity); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightDirection, vec3, setDirection, getDirection); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(keyLightCastShadows, bool, setCastShadows, getCastShadows); @@ -99,7 +99,7 @@ bool KeyLightPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFl bool overwriteLocalData = true; bool somethingChanged = false; - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows); @@ -187,7 +187,7 @@ int KeyLightPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_KEYLIGHT_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setDirection); READ_ENTITY_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, bool, setCastShadows); diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index b966b78fc7..d7fa75a32e 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -84,13 +84,13 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - static const xColor DEFAULT_KEYLIGHT_COLOR; + static const glm::u8vec3 DEFAULT_KEYLIGHT_COLOR; static const float DEFAULT_KEYLIGHT_INTENSITY; static const float DEFAULT_KEYLIGHT_AMBIENT_INTENSITY; static const glm::vec3 DEFAULT_KEYLIGHT_DIRECTION; static const bool DEFAULT_KEYLIGHT_CAST_SHADOWS; - DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, xColor, DEFAULT_KEYLIGHT_COLOR); + DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, Color, color, glm::u8vec3, DEFAULT_KEYLIGHT_COLOR); DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, Intensity, intensity, float, DEFAULT_KEYLIGHT_INTENSITY); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_DIRECTION, Direction, direction, glm::vec3, DEFAULT_KEYLIGHT_DIRECTION); DEFINE_PROPERTY(PROP_KEYLIGHT_CAST_SHADOW, CastShadows, castShadows, bool, DEFAULT_KEYLIGHT_CAST_SHADOWS); diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 57a83a4173..e3de5f66f8 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -38,7 +38,6 @@ EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const E // our non-pure virtual subclass for now... LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) { _type = EntityTypes::Light; - _color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0; } void LightEntityItem::setUnscaledDimensions(const glm::vec3& value) { @@ -73,7 +72,7 @@ EntityItemProperties LightEntityItem::getProperties(const EntityPropertyFlags& d EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(isSpotlight, getIsSpotlight); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(intensity, getIntensity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(exponent, getExponent); COPY_ENTITY_PROPERTY_TO_PROPERTIES(cutoff, getCutoff); @@ -176,7 +175,7 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor); READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity); READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent); READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff); @@ -214,26 +213,15 @@ void LightEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, getFalloffRadius()); } -const rgbColor& LightEntityItem::getColor() const { - return _color; -} - -xColor LightEntityItem::getXColor() const { - xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; -} - -void LightEntityItem::setColor(const rgbColor& value) { - withWriteLock([&] { - memcpy(_color, value, sizeof(_color)); - _lightPropertiesChanged = true; +glm::u8vec3 LightEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; }); } -void LightEntityItem::setColor(const xColor& value) { +void LightEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { - _color[RED_INDEX] = value.red; - _color[GREEN_INDEX] = value.green; - _color[BLUE_INDEX] = value.blue; + _color = value; _lightPropertiesChanged = true; }); } diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index f56b5ce624..813333d534 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -52,18 +52,12 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - const rgbColor& getColor() const; - xColor getXColor() const; - - void setColor(const rgbColor& value); - void setColor(const xColor& value); + glm::u8vec3 getColor() const; + void setColor(const glm::u8vec3& value); bool getIsSpotlight() const; void setIsSpotlight(bool value); - void setIgnoredColor(const rgbColor& value) { } - void setIgnoredAttenuation(float value) { } - float getIntensity() const; void setIntensity(float value); float getFalloffRadius() const; @@ -96,7 +90,7 @@ public: private: // properties of a light - rgbColor _color; + glm::u8vec3 _color; bool _isSpotlight { DEFAULT_IS_SPOTLIGHT }; float _intensity { DEFAULT_INTENSITY }; float _falloffRadius { DEFAULT_FALLOFF_RADIUS }; diff --git a/libraries/entities/src/LineEntityItem.cpp b/libraries/entities/src/LineEntityItem.cpp index 1b20922b7d..4957c30112 100644 --- a/libraries/entities/src/LineEntityItem.cpp +++ b/libraries/entities/src/LineEntityItem.cpp @@ -41,13 +41,8 @@ EntityItemProperties LineEntityItem::getProperties(const EntityPropertyFlags& de EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class - - properties._color = getXColor(); - properties._colorChanged = false; - - + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); return properties; @@ -56,12 +51,11 @@ EntityItemProperties LineEntityItem::getProperties(const EntityPropertyFlags& de bool LineEntityItem::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class - + SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth); SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints); - if (somethingChanged) { bool wantDebug = false; if (wantDebug) { @@ -120,7 +114,7 @@ int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor); READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); @@ -154,36 +148,21 @@ void LineEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits void LineEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------"; - qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; + qCDebug(entities) << " color:" << _color; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); } - -const rgbColor& LineEntityItem::getColor() const { - return _color; -} - -xColor LineEntityItem::getXColor() const { - xColor result; - withReadLock([&] { - result = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; - }); - return result; -} - -void LineEntityItem::setColor(const rgbColor& value) { - withWriteLock([&] { - memcpy(_color, value, sizeof(_color)); +glm::u8vec3 LineEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; }); } -void LineEntityItem::setColor(const xColor& value) { +void LineEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { - _color[RED_INDEX] = value.red; - _color[GREEN_INDEX] = value.green; - _color[BLUE_INDEX] = value.blue; + _color = value; }); } diff --git a/libraries/entities/src/LineEntityItem.h b/libraries/entities/src/LineEntityItem.h index 06f7830e06..1ebb248d23 100644 --- a/libraries/entities/src/LineEntityItem.h +++ b/libraries/entities/src/LineEntityItem.h @@ -41,11 +41,8 @@ class LineEntityItem : public EntityItem { EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - const rgbColor& getColor() const; - xColor getXColor() const; - - void setColor(const rgbColor& value); - void setColor(const xColor& value); + glm::u8vec3 getColor() const; + void setColor(const glm::u8vec3& value); void setLineWidth(float lineWidth); float getLineWidth() const; @@ -76,7 +73,7 @@ class LineEntityItem : public EntityItem { static const int MAX_POINTS_PER_LINE; private: - rgbColor _color; + glm::u8vec3 _color; float _lineWidth { DEFAULT_LINE_WIDTH }; QVector _points; bool _pointsChanged { true }; diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 06afda4283..825dd83348 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -290,9 +290,9 @@ void MaterialEntityItem::applyMaterial() { return; } Transform textureTransform; - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); - textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); + textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); material->setTextureTransforms(textureTransform); graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, getPriority()); @@ -314,8 +314,25 @@ void MaterialEntityItem::applyMaterial() { _retryApply = true; } +AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { + AACube aaCube = EntityItem::calculateInitialQueryAACube(success); + // A Material entity's queryAACube contains its parent's queryAACube + auto parent = getParentPointer(success); + if (success && parent) { + success = false; + AACube parentQueryAACube = parent->calculateInitialQueryAACube(success); + if (success) { + aaCube += parentQueryAACube.getMinimumPoint(); + aaCube += parentQueryAACube.getMaximumPoint(); + } + } + return aaCube; +} + void MaterialEntityItem::postParentFixup() { removeMaterial(); + _queryAACubeSet = false; // force an update so we contain our parent + updateQueryAACube(); applyMaterial(); } diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index 7177aaf718..8aaa833db9 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -85,6 +85,8 @@ public: void postParentFixup() override; + AACube calculateInitialQueryAACube(bool& success) override; + private: // URL for this material. Currently, only JSON format is supported. Set to "materialData" to use the material data to live edit a material. // The following fields are supported in the JSON: diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index e3fca680f3..72192c8702 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -39,7 +39,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem( // set the last animated when interface (re)starts _type = EntityTypes::Model; _lastKnownCurrentFrame = -1; - _color[0] = _color[1] = _color[2] = 0; _visuallyReady = false; } @@ -56,7 +55,7 @@ void ModelEntityItem::setTextures(const QString& textures) { EntityItemProperties ModelEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class - COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); @@ -117,7 +116,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, const unsigned char* dataAt = data; bool animationPropertiesChanged = false; - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor); READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); @@ -154,6 +153,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& params) const { EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); + requestedProperties += PROP_COLOR; requestedProperties += PROP_MODEL_URL; requestedProperties += PROP_COMPOUND_SHAPE_URL; requestedProperties += PROP_TEXTURES; @@ -520,9 +520,6 @@ QVector ModelEntityItem::getJointTranslationsSet() const { } -xColor ModelEntityItem::getXColor() const { - xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; -} bool ModelEntityItem::hasModel() const { return resultWithReadLock([&] { return !_modelURL.isEmpty(); @@ -554,17 +551,19 @@ QString ModelEntityItem::getCompoundShapeURL() const { return _compoundShapeURL.get(); } -void ModelEntityItem::setColor(const rgbColor& value) { +QString ModelEntityItem::getCollisionShapeURL() const { + return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); +} + +void ModelEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { - memcpy(_color, value, sizeof(_color)); + _color = value; }); } -void ModelEntityItem::setColor(const xColor& value) { - withWriteLock([&] { - _color[RED_INDEX] = value.red; - _color[GREEN_INDEX] = value.green; - _color[BLUE_INDEX] = value.blue; +glm::u8vec3 ModelEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; }); } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 8d34664a09..91d2d81b88 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -55,12 +55,11 @@ public: void setShapeType(ShapeType type) override; virtual ShapeType getShapeType() const override; - // TODO: Move these to subclasses, or other appropriate abstraction // getters/setters applicable to models and particles + glm::u8vec3 getColor() const; + void setColor(const glm::u8vec3& value); - const rgbColor& getColor() const { return _color; } - xColor getXColor() const; bool hasModel() const; virtual bool hasCompoundShapeURL() const; @@ -70,8 +69,8 @@ public: static const QString DEFAULT_COMPOUND_SHAPE_URL; QString getCompoundShapeURL() const; - void setColor(const rgbColor& value); - void setColor(const xColor& value); + // Returns the URL used for the collision shape + QString getCollisionShapeURL() const; // model related properties virtual void setModelURL(const QString& url); @@ -157,7 +156,7 @@ protected: QVector _localJointData; int _lastKnownCurrentFrame{-1}; - rgbColor _color; + glm::u8vec3 _color; QString _modelURL; bool _relayParentJoints; diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index cea3e94ef0..46dcd1b006 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -151,9 +151,6 @@ uint64_t Properties::emitIntervalUsecs() const { return 0; } -const xColor ParticleEffectEntityItem::DEFAULT_XCOLOR = xColor(static_cast(DEFAULT_COLOR.r), static_cast(DEFAULT_COLOR.g), static_cast(DEFAULT_COLOR.b)); -const xColor ParticleEffectEntityItem::DEFAULT_XCOLOR_SPREAD = xColor(static_cast(DEFAULT_COLOR_SPREAD.r), static_cast(DEFAULT_COLOR_SPREAD.g), static_cast(DEFAULT_COLOR_SPREAD.b)); - EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity(new ParticleEffectEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); entity->setProperties(properties); @@ -165,7 +162,6 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte EntityItem(entityItemID) { _type = EntityTypes::ParticleEffect; - setColor(DEFAULT_COLOR); _visuallyReady = false; } @@ -412,7 +408,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() { EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class - COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); // FIXME - this doesn't appear to get used COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles); @@ -503,28 +499,12 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert return somethingChanged; } -void ParticleEffectEntityItem::setColor(const vec3& value) { +void ParticleEffectEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { _particleProperties.color.gradient.target = value; }); } -void ParticleEffectEntityItem::setColor(const xColor& value) { - withWriteLock([&] { - _particleProperties.color.gradient.target.r = value.red; - _particleProperties.color.gradient.target.g = value.green; - _particleProperties.color.gradient.target.b = value.blue; - }); -} - -xColor ParticleEffectEntityItem::getXColor() const { - xColor color; - color.red = _particleProperties.color.gradient.target.r; - color.green = _particleProperties.color.gradient.target.g; - color.blue = _particleProperties.color.gradient.target.b; - return color; -} - int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, @@ -533,15 +513,15 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting); READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType); READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); - READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, vec3, setEmitAcceleration); - READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, vec3, setAccelerationSpread); + READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); + READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); @@ -549,9 +529,9 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); - READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread); - READ_ENTITY_PROPERTY(PROP_COLOR_START, vec3, setColorStart); - READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, vec3, setColorFinish); + READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, u8vec3Color, setColorSpread); + READ_ENTITY_PROPERTY(PROP_COLOR_START, vec3Color, setColorStart); + READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, vec3Color, setColorFinish); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); @@ -560,7 +540,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, quat, setEmitOrientation); - READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, vec3, setEmitDimensions); + READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart); READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish); @@ -629,7 +609,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; - APPEND_ENTITY_PROPERTY(PROP_COLOR, getXColor()); + APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, getIsEmitting()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); @@ -713,22 +693,12 @@ void ParticleEffectEntityItem::setColorFinish(const vec3& colorFinish) { }); } -void ParticleEffectEntityItem::setColorSpread(const xColor& value) { +void ParticleEffectEntityItem::setColorSpread(const glm::u8vec3& value) { withWriteLock([&] { - _particleProperties.color.gradient.spread.r = value.red; - _particleProperties.color.gradient.spread.g = value.green; - _particleProperties.color.gradient.spread.b = value.blue; + _particleProperties.color.gradient.spread = value; }); } -xColor ParticleEffectEntityItem::getColorSpread() const { - xColor color; - color.red = _particleProperties.color.gradient.spread.r; - color.green = _particleProperties.color.gradient.spread.g; - color.blue = _particleProperties.color.gradient.spread.b; - return color; -} - void ParticleEffectEntityItem::setEmitterShouldTrail(bool emitterShouldTrail) { withWriteLock([&] { _particleProperties.emission.shouldTrail = emitterShouldTrail; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index a8e133942e..a89d7afc06 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -20,9 +20,9 @@ namespace particle { static const float SCRIPT_MAXIMUM_PI = 3.1416f; // Round up so that reasonable property values work static const float UNINITIALIZED = NAN; - static const vec3 DEFAULT_COLOR = { 255, 255, 255 }; + static const u8vec3 DEFAULT_COLOR = { 255, 255, 255 }; static const vec3 DEFAULT_COLOR_UNINITIALIZED = { UNINITIALIZED, UNINITIALIZED, UNINITIALIZED }; - static const vec3 DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; + static const u8vec3 DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; static const float DEFAULT_ALPHA = 1.0f; static const float DEFAULT_ALPHA_SPREAD = 0.0f; static const float DEFAULT_ALPHA_START = UNINITIALIZED; @@ -42,8 +42,8 @@ namespace particle { static const float MINIMUM_EMIT_SPEED = -1000.0f; static const float MAXIMUM_EMIT_SPEED = 1000.0f; // Approx mach 3 static const float DEFAULT_SPEED_SPREAD = 1.0f; - static const glm::quat DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_X); // Vertical - static const glm::vec3 DEFAULT_EMIT_DIMENSIONS = Vectors::ZERO; // Emit from point + static const quat DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_X); // Vertical + static const vec3 DEFAULT_EMIT_DIMENSIONS = Vectors::ZERO; // Emit from point static const float MINIMUM_EMIT_DIMENSION = 0.0f; static const float MAXIMUM_EMIT_DIMENSION = (float)TREE_SCALE; static const float DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitDimensions > 0) @@ -57,10 +57,10 @@ namespace particle { static const float MAXIMUM_AZIMUTH = SCRIPT_MAXIMUM_PI; static const float DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) static const float DEFAULT_AZIMUTH_FINISH = PI; // "" - static const glm::vec3 DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); + static const vec3 DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); static const float MINIMUM_EMIT_ACCELERATION = -100.0f; // ~ 10g static const float MAXIMUM_EMIT_ACCELERATION = 100.0f; - static const glm::vec3 DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); + static const vec3 DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); static const float MINIMUM_ACCELERATION_SPREAD = 0.0f; static const float MAXIMUM_ACCELERATION_SPREAD = 100.0f; static const float DEFAULT_PARTICLE_RADIUS = 0.025f; @@ -189,10 +189,10 @@ namespace particle { return *this; } - vec4 getColorStart() const { return vec4(ColorUtils::sRGBToLinearVec3(color.range.start / 255.0f), alpha.range.start); } - vec4 getColorMiddle() const { return vec4(ColorUtils::sRGBToLinearVec3(color.gradient.target / 255.0f), alpha.gradient.target); } - vec4 getColorFinish() const { return vec4(ColorUtils::sRGBToLinearVec3(color.range.finish / 255.0f), alpha.range.finish); } - vec4 getColorSpread() const { return vec4(ColorUtils::sRGBToLinearVec3(color.gradient.spread / 255.0f), alpha.gradient.spread); } + vec4 getColorStart() const { return vec4(ColorUtils::sRGBToLinearVec3(toGlm(color.range.start)), alpha.range.start); } + vec4 getColorMiddle() const { return vec4(ColorUtils::sRGBToLinearVec3(toGlm(color.gradient.target)), alpha.gradient.target); } + vec4 getColorFinish() const { return vec4(ColorUtils::sRGBToLinearVec3(toGlm(color.range.finish)), alpha.range.finish); } + vec4 getColorSpread() const { return vec4(ColorUtils::sRGBToLinearVec3(toGlm(color.gradient.spread)), alpha.gradient.spread); } }; } // namespace particles @@ -228,11 +228,8 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - xColor getXColor() const; - vec3 getColor() const { return _particleProperties.color.gradient.target; } - - void setColor(const vec3& value); - void setColor(const xColor& value); + void setColor(const glm::u8vec3& value); + glm::u8vec3 getColor() const { return _particleProperties.color.gradient.target; } void setColorStart(const vec3& colorStart); vec3 getColorStart() const { return _particleProperties.color.range.start; } @@ -240,8 +237,8 @@ public: void setColorFinish(const vec3& colorFinish); vec3 getColorFinish() const { return _particleProperties.color.range.finish; } - void setColorSpread(const xColor& colorSpread); - xColor getColorSpread() const; + void setColorSpread(const glm::u8vec3& colorSpread); + glm::u8vec3 getColorSpread() const { return _particleProperties.color.gradient.spread; } void setAlpha(float alpha); float getAlpha() const { return _particleProperties.alpha.gradient.target; } @@ -344,9 +341,6 @@ public: particle::Properties getParticleProperties() const; - static const xColor DEFAULT_XCOLOR; - static const xColor DEFAULT_XCOLOR_SPREAD; - protected: particle::Properties _particleProperties; bool _isEmitting { true }; diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index 2d0689b56a..c72256822d 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -39,12 +39,8 @@ PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : Entit EntityItemProperties PolyLineEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { QWriteLocker lock(&_quadReadWriteLock); EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class - - - properties._color = getXColor(); - properties._colorChanged = false; - + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth); COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints); COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals); @@ -204,7 +200,7 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor); READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals); @@ -253,7 +249,7 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode void PolyLineEntityItem::debugDump() const { quint64 now = usecTimestampNow(); qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; - qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; + qCDebug(entities) << " color:" << _color; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); @@ -261,7 +257,7 @@ void PolyLineEntityItem::debugDump() const { -QVector PolyLineEntityItem::getLinePoints() const { +QVector PolyLineEntityItem::getLinePoints() const { QVector result; withReadLock([&] { result = _points; @@ -269,7 +265,7 @@ QVector PolyLineEntityItem::getLinePoints() const { return result; } -QVector PolyLineEntityItem::getNormals() const { +QVector PolyLineEntityItem::getNormals() const { QVector result; withReadLock([&] { result = _normals; @@ -309,3 +305,16 @@ void PolyLineEntityItem::setTextures(const QString& textures) { } }); } + +void PolyLineEntityItem::setColor(const glm::u8vec3& value) { + withWriteLock([&] { + _strokeColorsChanged = true; + _color = value; + }); +} + +glm::u8vec3 PolyLineEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; + }); +} diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index 94b46ac5e2..f640bd7a9e 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -41,19 +41,8 @@ class PolyLineEntityItem : public EntityItem { EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - const rgbColor& getColor() const { return _color; } - xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } - - void setColor(const rgbColor& value) { - _strokeColorsChanged = true; - memcpy(_color, value, sizeof(_color)); - } - void setColor(const xColor& value) { - _strokeColorsChanged = true; - _color[RED_INDEX] = value.red; - _color[GREEN_INDEX] = value.green; - _color[BLUE_INDEX] = value.blue; - } + glm::u8vec3 getColor() const; + void setColor(const glm::u8vec3& value); void setLineWidth(float lineWidth){ _lineWidth = lineWidth; } float getLineWidth() const{ return _lineWidth; } @@ -109,7 +98,7 @@ private: void calculateScaleAndRegistrationPoint(); protected: - rgbColor _color; + glm::u8vec3 _color; float _lineWidth { DEFAULT_LINE_WIDTH }; bool _pointsChanged { true }; bool _normalsChanged { true }; diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 484a6110c3..e65742b36c 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -70,7 +70,7 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID) : EntityI _type = EntityTypes::PolyVox; } -void PolyVoxEntityItem::setVoxelVolumeSize(const vec3& voxelVolumeSize) { +void PolyVoxEntityItem::setVoxelVolumeSize(const glm::vec3& voxelVolumeSize) { withWriteLock([&] { assert(!glm::any(glm::isnan(voxelVolumeSize))); diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index ba238ab24f..dd05ce67b1 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -54,7 +54,7 @@ class PolyVoxEntityItem : public EntityItem { virtual void debugDump() const override; - virtual void setVoxelVolumeSize(const vec3& voxelVolumeSize); + virtual void setVoxelVolumeSize(const glm::vec3& voxelVolumeSize); virtual glm::vec3 getVoxelVolumeSize() const; virtual void setVoxelData(const QByteArray& voxelData); diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index a5e4e25e67..f67134da0a 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -73,7 +73,7 @@ namespace entity { return Shape::Sphere; } - ::QString stringFromShape(Shape shape) { + QString stringFromShape(Shape shape) { return shapeStrings[shape]; } } @@ -117,8 +117,10 @@ ShapeEntityItem::ShapeEntityItem(const EntityItemID& entityItemID) : EntityItem( EntityItemProperties ShapeEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class + properties.setShape(entity::stringFromShape(getShape())); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + properties._shapeChanged = false; + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); return properties; @@ -182,7 +184,7 @@ int ShapeEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_SHAPE, QString, setShape); - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_COLOR, glm::u8vec3, setColor); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); return bytesRead; @@ -210,32 +212,24 @@ void ShapeEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); } -void ShapeEntityItem::setColor(const rgbColor& value) { - memcpy(_color, value, sizeof(rgbColor)); - _material->setAlbedo(glm::vec3(_color[0], _color[1], _color[2]) / 255.0f); +void ShapeEntityItem::setColor(const glm::u8vec3& value) { + withWriteLock([&] { + _color = value; + _material->setAlbedo(toGlm(_color)); + }); } -xColor ShapeEntityItem::getXColor() const { - return xColor { _color[0], _color[1], _color[2] }; -} - -void ShapeEntityItem::setColor(const xColor& value) { - setColor(rgbColor { value.red, value.green, value.blue }); -} - -QColor ShapeEntityItem::getQColor() const { - auto& color = getColor(); - return QColor(color[0], color[1], color[2], (int)(getAlpha() * 255)); -} - -void ShapeEntityItem::setColor(const QColor& value) { - setColor(rgbColor { (uint8_t)value.red(), (uint8_t)value.green(), (uint8_t)value.blue() }); - setAlpha(value.alpha()); +glm::u8vec3 ShapeEntityItem::getColor() const { + return resultWithReadLock([&] { + return _color; + }); } void ShapeEntityItem::setAlpha(float alpha) { - _alpha = alpha; - _material->setOpacity(alpha); + withWriteLock([&] { + _alpha = alpha; + _material->setOpacity(alpha); + }); } void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) { @@ -313,7 +307,7 @@ void ShapeEntityItem::debugDump() const { qCDebug(entities) << " name:" << _name; qCDebug(entities) << " shape:" << stringFromShape(_shape) << " (EnumId: " << _shape << " )"; qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType()); - qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; + qCDebug(entities) << " color:" << _color; qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions()); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); @@ -419,5 +413,4 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { // This value specifies how the shape should be treated by physics calculations. ShapeType ShapeEntityItem::getShapeType() const { return _collisionShapeType; -} - +} \ No newline at end of file diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index d0326a3794..c89a8934f8 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -31,7 +31,7 @@ namespace entity { }; Shape shapeFromString(const ::QString& shapeString); - ::QString stringFromShape(Shape shape); + QString stringFromShape(Shape shape); } class ShapeEntityItem : public EntityItem { @@ -77,17 +77,11 @@ public: float getAlpha() const { return _alpha; }; void setAlpha(float alpha); - const rgbColor& getColor() const { return _color; } - void setColor(const rgbColor& value); + glm::u8vec3 getColor() const; + void setColor(const glm::u8vec3& value); void setUnscaledDimensions(const glm::vec3& value) override; - xColor getXColor() const; - void setColor(const xColor& value); - - QColor getQColor() const; - void setColor(const QColor& value); - bool shouldBePhysical() const override { return !isDead(); } bool supportsDetailedIntersection() const override; @@ -110,7 +104,7 @@ public: protected: float _alpha { 1.0f }; - rgbColor _color; + glm::u8vec3 _color; entity::Shape _shape { entity::Shape::Sphere }; //! This is SHAPE_TYPE_ELLIPSOID rather than SHAPE_TYPE_NONE to maintain diff --git a/libraries/entities/src/SkyboxPropertyGroup.cpp b/libraries/entities/src/SkyboxPropertyGroup.cpp index ba40c3fa6f..89ffa95dbe 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.cpp +++ b/libraries/entities/src/SkyboxPropertyGroup.cpp @@ -16,15 +16,15 @@ #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" -const xColor SkyboxPropertyGroup::DEFAULT_COLOR = { 0, 0, 0 }; +const glm::u8vec3 SkyboxPropertyGroup::DEFAULT_COLOR = { 0, 0, 0 }; void SkyboxPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color, u8vec3Color); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_SKYBOX_URL, Skybox, skybox, URL, url); } void SkyboxPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(skybox, color, xColor, setColor); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(skybox, color, u8vec3Color, setColor); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(skybox, url, QString, setURL); } @@ -71,7 +71,7 @@ bool SkyboxPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlag bool overwriteLocalData = true; bool somethingChanged = false; - READ_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY(PROP_SKYBOX_URL, QString, setURL); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_SKYBOX_COLOR, Color); @@ -143,7 +143,7 @@ int SkyboxPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* d int bytesRead = 0; const unsigned char* dataAt = data; - READ_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, xColor, setColor); + READ_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, u8vec3Color, setColor); READ_ENTITY_PROPERTY(PROP_SKYBOX_URL, QString, setURL); return bytesRead; diff --git a/libraries/entities/src/SkyboxPropertyGroup.h b/libraries/entities/src/SkyboxPropertyGroup.h index a94365d24d..c3f9b421f4 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.h +++ b/libraries/entities/src/SkyboxPropertyGroup.h @@ -32,7 +32,7 @@ class ReadBitstreamToTreeParams; /**jsdoc * A skybox is defined by the following properties. * @typedef {object} Entities.Skybox - * @property {Color} color=0,0,0 - Sets the color of the sky if url is "", otherwise modifies the + * @property {Color} color=0,0,0 - Sets the color of the sky if url is "", otherwise modifies the * color of the cube map image. * @property {string} url="" - A cube map image that is used to render the sky. */ @@ -83,16 +83,8 @@ public: EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) override; - glm::vec3 getColorVec3() const { - const quint8 MAX_COLOR = 255; - glm::vec3 color = { (float)_color.red / (float)MAX_COLOR, - (float)_color.green / (float)MAX_COLOR, - (float)_color.blue / (float)MAX_COLOR }; - return color; - } - - static const xColor DEFAULT_COLOR; - DEFINE_PROPERTY_REF(PROP_SKYBOX_COLOR, Color, color, xColor, DEFAULT_COLOR); + static const glm::u8vec3 DEFAULT_COLOR; + DEFINE_PROPERTY_REF(PROP_SKYBOX_COLOR, Color, color, glm::u8vec3, DEFAULT_COLOR); DEFINE_PROPERTY_REF(PROP_SKYBOX_URL, URL, url, QString, ""); }; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index da843256a0..8dd4877ce2 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -25,8 +25,8 @@ const QString TextEntityItem::DEFAULT_TEXT(""); const float TextEntityItem::DEFAULT_LINE_HEIGHT = 0.1f; -const xColor TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 }; -const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0}; +const glm::u8vec3 TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 }; +const glm::u8vec3 TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0}; const bool TextEntityItem::DEFAULT_FACE_CAMERA = false; EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { @@ -51,8 +51,8 @@ EntityItemProperties TextEntityItem::getProperties(const EntityPropertyFlags& de COPY_ENTITY_PROPERTY_TO_PROPERTIES(text, getText); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineHeight, getLineHeight); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(textColor, getTextColorX); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundColor, getBackgroundColorX); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(textColor, getTextColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundColor, getBackgroundColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(faceCamera, getFaceCamera); return properties; } @@ -91,8 +91,8 @@ int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_TEXT, QString, setText); READ_ENTITY_PROPERTY(PROP_LINE_HEIGHT, float, setLineHeight); - READ_ENTITY_PROPERTY(PROP_TEXT_COLOR, rgbColor, setTextColor); - READ_ENTITY_PROPERTY(PROP_BACKGROUND_COLOR, rgbColor, setBackgroundColor); + READ_ENTITY_PROPERTY(PROP_TEXT_COLOR, glm::u8vec3, setTextColor); + READ_ENTITY_PROPERTY(PROP_BACKGROUND_COLOR, glm::u8vec3, setBackgroundColor); READ_ENTITY_PROPERTY(PROP_FACE_CAMERA, bool, setFaceCamera); return bytesRead; @@ -206,55 +206,27 @@ float TextEntityItem::getLineHeight() const { return result; } -const rgbColor& TextEntityItem::getTextColor() const { - return _textColor; -} - -const rgbColor& TextEntityItem::getBackgroundColor() const { - return _backgroundColor; -} - -xColor TextEntityItem::getTextColorX() const { - xColor result; - withReadLock([&] { - result = { _textColor[RED_INDEX], _textColor[GREEN_INDEX], _textColor[BLUE_INDEX] }; - }); - return result; -} - -void TextEntityItem::setTextColor(const rgbColor& value) { +void TextEntityItem::setTextColor(const glm::u8vec3& value) { withWriteLock([&] { - memcpy(_textColor, value, sizeof(_textColor)); + _textColor = value; }); } -void TextEntityItem::setTextColor(const xColor& value) { +glm::u8vec3 TextEntityItem::getTextColor() const { + return resultWithReadLock([&] { + return _textColor; + }); +} + +void TextEntityItem::setBackgroundColor(const glm::u8vec3& value) { withWriteLock([&] { - _textColor[RED_INDEX] = value.red; - _textColor[GREEN_INDEX] = value.green; - _textColor[BLUE_INDEX] = value.blue; + _backgroundColor = value; }); } -xColor TextEntityItem::getBackgroundColorX() const { - xColor result; - withReadLock([&] { - result = { _backgroundColor[RED_INDEX], _backgroundColor[GREEN_INDEX], _backgroundColor[BLUE_INDEX] }; - }); - return result; -} - -void TextEntityItem::setBackgroundColor(const rgbColor& value) { - withWriteLock([&] { - memcpy(_backgroundColor, value, sizeof(_backgroundColor)); - }); -} - -void TextEntityItem::setBackgroundColor(const xColor& value) { - withWriteLock([&] { - _backgroundColor[RED_INDEX] = value.red; - _backgroundColor[GREEN_INDEX] = value.green; - _backgroundColor[BLUE_INDEX] = value.blue; +glm::u8vec3 TextEntityItem::getBackgroundColor() const { + return resultWithReadLock([&] { + return _backgroundColor; }); } diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index cbddf87fda..357697fdec 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -63,21 +63,13 @@ public: void setLineHeight(float value); float getLineHeight() const; - static const xColor DEFAULT_TEXT_COLOR; - // FIXME should not return a reference because of thread safety, but can't return an array - const rgbColor& getTextColor() const; - xColor getTextColorX() const; + static const glm::u8vec3 DEFAULT_TEXT_COLOR; + glm::u8vec3 getTextColor() const; + void setTextColor(const glm::u8vec3& value); - void setTextColor(const rgbColor& value); - void setTextColor(const xColor& value); - - static const xColor DEFAULT_BACKGROUND_COLOR; - // FIXME should not return a reference because of thread safety, but can't return an array - const rgbColor& getBackgroundColor() const; - xColor getBackgroundColorX() const; - - void setBackgroundColor(const rgbColor& value); - void setBackgroundColor(const xColor& value); + static const glm::u8vec3 DEFAULT_BACKGROUND_COLOR; + glm::u8vec3 getBackgroundColor() const; + void setBackgroundColor(const glm::u8vec3& value); static const bool DEFAULT_FACE_CAMERA; bool getFaceCamera() const; @@ -86,8 +78,8 @@ public: private: QString _text; float _lineHeight; - rgbColor _textColor; - rgbColor _backgroundColor; + glm::u8vec3 _textColor; + glm::u8vec3 _backgroundColor; bool _faceCamera; }; diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index f2afc1e7d4..67f79db6b7 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -367,8 +367,8 @@ namespace scriptable { obj.setProperty("metallic", material.metallic); obj.setProperty("scattering", material.scattering); obj.setProperty("unlit", material.unlit); - obj.setProperty("emissive", vec3toScriptValue(engine, material.emissive)); - obj.setProperty("albedo", vec3toScriptValue(engine, material.albedo)); + obj.setProperty("emissive", vec3ColorToScriptValue(engine, material.emissive)); + obj.setProperty("albedo", vec3ColorToScriptValue(engine, material.albedo)); obj.setProperty("emissiveMap", material.emissiveMap); obj.setProperty("albedoMap", material.albedoMap); obj.setProperty("opacityMap", material.opacityMap); diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp index 823602d939..e6e3b0e812 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.cpp +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -113,11 +113,11 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * @typedef {object} Material * @property {string} name="" - A name for the material. * @property {string} model="hifi_pbr" - Currently not used. - * @property {Vec3Color|RGBS} emissive - The emissive color, i.e., the color that the material emits. A {@link Vec3Color} value + * @property {Color|RGBS} emissive - The emissive color, i.e., the color that the material emits. A {@link Color} value * is treated as sRGB. A {@link RGBS} value can be either RGB or sRGB. * @property {number} opacity=1.0 - The opacity, 0.01.0. * @property {boolean} unlit=false - If true, the material is not lit. - * @property {Vec3Color|RGBS} albedo - The albedo color. A {@link Vec3Color} value is treated as sRGB. A {@link RGBS} value can + * @property {Color|RGBS} albedo - The albedo color. A {@link Color} value is treated as sRGB. A {@link RGBS} value can * be either RGB or sRGB. * @property {number} roughness - The roughness, 0.01.0. * @property {number} metallic - The metallicness, 0.01.0. diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index c914ad91af..3933e3ae56 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -75,8 +75,6 @@ protected: void makeLocalRequest(); Q_INVOKABLE void handleLocalRequestCompleted(); - virtual bool isCacheable() const override { return _loaded; } - Q_INVOKABLE virtual void downloadFinished(const QByteArray& data) override; bool handleFailedRequest(ResourceRequest::Result result) override; diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index aed9f3b0e5..076db44ea6 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -27,28 +27,35 @@ #include "NetworkLogging.h" #include "NodeList.h" - -#define clamp(x, min, max) (((x) < (min)) ? (min) :\ - (((x) > (max)) ? (max) :\ - (x))) - -void ResourceCacheSharedItems::appendActiveRequest(QWeakPointer resource) { +bool ResourceCacheSharedItems::appendRequest(QWeakPointer resource) { Lock lock(_mutex); - _loadingRequests.append(resource); + if ((uint32_t)_loadingRequests.size() < _requestLimit) { + _loadingRequests.append(resource); + return true; + } else { + _pendingRequests.append(resource); + return false; + } } -void ResourceCacheSharedItems::appendPendingRequest(QWeakPointer resource) { +void ResourceCacheSharedItems::setRequestLimit(uint32_t limit) { Lock lock(_mutex); - _pendingRequests.append(resource); + _requestLimit = limit; } -QList> ResourceCacheSharedItems::getPendingRequests() { +uint32_t ResourceCacheSharedItems::getRequestLimit() const { + Lock lock(_mutex); + return _requestLimit; +} + +QList> ResourceCacheSharedItems::getPendingRequests() const { QList> result; Lock lock(_mutex); - foreach(QSharedPointer resource, _pendingRequests) { - if (resource) { - result.append(resource); + foreach (QWeakPointer resource, _pendingRequests) { + auto locked = resource.lock(); + if (locked) { + result.append(locked); } } @@ -60,16 +67,12 @@ uint32_t ResourceCacheSharedItems::getPendingRequestsCount() const { return _pendingRequests.size(); } -QList> ResourceCacheSharedItems::getLoadingRequests() { +QList> ResourceCacheSharedItems::getLoadingRequests() const { QList> result; - Lock lock(_mutex); - - foreach(QSharedPointer resource, _loadingRequests) { - if (resource) { - result.append(resource); - } + { + Lock lock(_mutex); + result = _loadingRequests; } - return result; } @@ -131,6 +134,11 @@ QSharedPointer ResourceCacheSharedItems::getHighestPendingRequest() { return highestResource; } +void ResourceCacheSharedItems::clear() { + Lock lock(_mutex); + _pendingRequests.clear(); + _loadingRequests.clear(); +} ScriptableResourceCache::ScriptableResourceCache(QSharedPointer resourceCache) { _resourceCache = resourceCache; @@ -244,9 +252,7 @@ ResourceCache::ResourceCache(QObject* parent) : QObject(parent) { } } -ResourceCache::~ResourceCache() { - clearUnusedResources(); -} +ResourceCache::~ResourceCache() {} void ResourceCache::clearATPAssets() { { @@ -260,6 +266,7 @@ void ResourceCache::clearATPAssets() { if (auto strongRef = resource.lock()) { // Make sure the resource won't reinsert itself strongRef->setCache(nullptr); + _totalResourcesSize -= strongRef->getBytes(); } } } @@ -269,28 +276,18 @@ void ResourceCache::clearATPAssets() { for (auto& resource : _unusedResources.values()) { if (resource->getURL().scheme() == URL_SCHEME_ATP) { _unusedResources.remove(resource->getLRUKey()); - } - } - } - { - QWriteLocker locker(&_resourcesToBeGottenLock); - auto it = _resourcesToBeGotten.begin(); - while (it != _resourcesToBeGotten.end()) { - if (it->scheme() == URL_SCHEME_ATP) { - it = _resourcesToBeGotten.erase(it); - } else { - ++it; + _unusedResourcesSize -= resource->getBytes(); } } } - + resetResourceCounters(); } void ResourceCache::refreshAll() { // Clear all unused resources so we don't have to reload them clearUnusedResources(); - resetResourceCounters(); + resetUnusedResourceCounter(); QHash> resources; { @@ -306,21 +303,6 @@ void ResourceCache::refreshAll() { } } -void ResourceCache::refresh(const QUrl& url) { - QSharedPointer resource; - { - QReadLocker locker(&_resourcesLock); - resource = _resources.value(url).lock(); - } - - if (resource) { - resource->refresh(); - } else { - removeResource(url); - resetResourceCounters(); - } -} - QVariantList ResourceCache::getResourceList() { QVariantList list; if (QThread::currentThread() != thread()) { @@ -338,12 +320,13 @@ QVariantList ResourceCache::getResourceList() { return list; } -void ResourceCache::setRequestLimit(int limit) { - _requestLimit = limit; +void ResourceCache::setRequestLimit(uint32_t limit) { + auto sharedItems = DependencyManager::get(); + sharedItems->setRequestLimit(limit); // Now go fill any new request spots - while (attemptHighestPriorityRequest()) { - // just keep looping until we reach the new limit or no more pending requests + while (sharedItems->getLoadingRequestsCount() < limit && sharedItems->getPendingRequestsCount() > 0) { + attemptHighestPriorityRequest(); } } @@ -381,9 +364,9 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& } void ResourceCache::setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize) { - _unusedResourcesMaxSize = clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE); + _unusedResourcesMaxSize = glm::clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE); reserveUnusedResource(0); - resetResourceCounters(); + resetUnusedResourceCounter(); } void ResourceCache::addUnusedResource(const QSharedPointer& resource) { @@ -391,18 +374,20 @@ void ResourceCache::addUnusedResource(const QSharedPointer& resource) if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) { resource->setCache(nullptr); removeResource(resource->getURL(), resource->getBytes()); - resetResourceCounters(); + resetTotalResourceCounter(); return; } reserveUnusedResource(resource->getBytes()); resource->setLRUKey(++_lastLRUKey); - _unusedResourcesSize += resource->getBytes(); - resetResourceCounters(); + { + QWriteLocker locker(&_unusedResourcesLock); + _unusedResources.insert(resource->getLRUKey(), resource); + _unusedResourcesSize += resource->getBytes(); + } - QWriteLocker locker(&_unusedResourcesLock); - _unusedResources.insert(resource->getLRUKey(), resource); + resetUnusedResourceCounter(); } void ResourceCache::removeUnusedResource(const QSharedPointer& resource) { @@ -412,7 +397,7 @@ void ResourceCache::removeUnusedResource(const QSharedPointer& resourc _unusedResourcesSize -= resource->getBytes(); locker.unlock(); - resetResourceCounters(); + resetUnusedResourceCounter(); } } @@ -445,14 +430,19 @@ void ResourceCache::clearUnusedResources() { } _unusedResources.clear(); } + _unusedResourcesSize = 0; } -void ResourceCache::resetResourceCounters() { +void ResourceCache::resetTotalResourceCounter() { { QReadLocker locker(&_resourcesLock); _numTotalResources = _resources.size(); } + emit dirty(); +} + +void ResourceCache::resetUnusedResourceCounter() { { QReadLocker locker(&_unusedResourcesLock); _numUnusedResources = _unusedResources.size(); @@ -461,6 +451,13 @@ void ResourceCache::resetResourceCounters() { emit dirty(); } +void ResourceCache::resetResourceCounters() { + resetTotalResourceCounter(); + resetUnusedResourceCounter(); + + emit dirty(); +} + void ResourceCache::removeResource(const QUrl& url, qint64 size) { QWriteLocker locker(&_resourcesLock); _resources.remove(url); @@ -481,38 +478,34 @@ QList> ResourceCache::getLoadingRequests() { return DependencyManager::get()->getLoadingRequests(); } -int ResourceCache::getPendingRequestCount() { +uint32_t ResourceCache::getPendingRequestCount() { return DependencyManager::get()->getPendingRequestsCount(); } -int ResourceCache::getLoadingRequestCount() { +uint32_t ResourceCache::getLoadingRequestCount() { return DependencyManager::get()->getLoadingRequestsCount(); } bool ResourceCache::attemptRequest(QSharedPointer resource) { Q_ASSERT(!resource.isNull()); - auto sharedItems = DependencyManager::get(); - if (_requestsActive >= _requestLimit) { - // wait until a slot becomes available - sharedItems->appendPendingRequest(resource); - return false; + if (sharedItems->appendRequest(resource)) { + resource->makeRequest(); + return true; } - - ++_requestsActive; - sharedItems->appendActiveRequest(resource); - resource->makeRequest(); - return true; + return false; } void ResourceCache::requestCompleted(QWeakPointer resource) { auto sharedItems = DependencyManager::get(); sharedItems->removeRequest(resource); - --_requestsActive; - attemptHighestPriorityRequest(); + // Now go fill any new request spots + while (sharedItems->getLoadingRequestsCount() < sharedItems->getRequestLimit() && sharedItems->getPendingRequestsCount() > 0) { + attemptHighestPriorityRequest(); + } } bool ResourceCache::attemptHighestPriorityRequest() { @@ -521,10 +514,6 @@ bool ResourceCache::attemptHighestPriorityRequest() { return (resource && attemptRequest(resource)); } -const int DEFAULT_REQUEST_LIMIT = 10; -int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT; -int ResourceCache::_requestsActive = 0; - static int requestID = 0; Resource::Resource(const QUrl& url) : @@ -550,7 +539,7 @@ void Resource::ensureLoading() { } void Resource::setLoadPriority(const QPointer& owner, float priority) { - if (!(_failedToLoad)) { + if (!_failedToLoad) { _loadPriorities.insert(owner, priority); } } @@ -566,7 +555,7 @@ void Resource::setLoadPriorities(const QHash, float>& prioriti } void Resource::clearLoadPriority(const QPointer& owner) { - if (!(_failedToLoad)) { + if (!_failedToLoad) { _loadPriorities.remove(owner); } } @@ -592,6 +581,7 @@ void Resource::refresh() { if (_request && !(_loaded || _failedToLoad)) { return; } + if (_request) { _request->disconnect(this); _request->deleteLater(); @@ -613,7 +603,7 @@ void Resource::allReferencesCleared() { if (_cache && isCacheable()) { // create and reinsert new shared pointer - QSharedPointer self(this, &Resource::allReferencesCleared); + QSharedPointer self(this, &Resource::deleter); setSelf(self); reinsert(); @@ -623,7 +613,7 @@ void Resource::allReferencesCleared() { if (_cache) { // remove from the cache _cache->removeResource(getURL(), getBytes()); - _cache->resetResourceCounters(); + _cache->resetTotalResourceCounter(); } deleteLater(); @@ -732,6 +722,7 @@ void Resource::handleReplyFinished() { { "from_cache", false }, { "size_mb", _bytesTotal / 1000000.0 } }); + ResourceCache::requestCompleted(_self); return; } diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 2c0baad3f7..33490301d7 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -66,21 +66,25 @@ class ResourceCacheSharedItems : public Dependency { using Lock = std::unique_lock; public: - void appendPendingRequest(QWeakPointer newRequest); - void appendActiveRequest(QWeakPointer newRequest); + bool appendRequest(QWeakPointer newRequest); void removeRequest(QWeakPointer doneRequest); - QList> getPendingRequests(); - uint32_t getPendingRequestsCount() const; - QList> getLoadingRequests(); + void setRequestLimit(uint32_t limit); + uint32_t getRequestLimit() const; + QList> getPendingRequests() const; QSharedPointer getHighestPendingRequest(); + uint32_t getPendingRequestsCount() const; + QList> getLoadingRequests() const; uint32_t getLoadingRequestsCount() const; + void clear(); private: ResourceCacheSharedItems() = default; mutable Mutex _mutex; QList> _pendingRequests; - QList> _loadingRequests; + QList> _loadingRequests; + const uint32_t DEFAULT_REQUEST_LIMIT = 10; + uint32_t _requestLimit { DEFAULT_REQUEST_LIMIT }; }; /// Wrapper to expose resources to JS/QML @@ -200,25 +204,20 @@ public: Q_INVOKABLE QVariantList getResourceList(); - static void setRequestLimit(int limit); - static int getRequestLimit() { return _requestLimit; } - - static int getRequestsActive() { return _requestsActive; } + static void setRequestLimit(uint32_t limit); + static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize); qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; } static QList> getLoadingRequests(); - - static int getPendingRequestCount(); - - static int getLoadingRequestCount(); + static uint32_t getPendingRequestCount(); + static uint32_t getLoadingRequestCount(); ResourceCache(QObject* parent = nullptr); virtual ~ResourceCache(); void refreshAll(); - void refresh(const QUrl& url); void clearUnusedResources(); signals: @@ -272,11 +271,11 @@ private: friend class ScriptableResourceCache; void reserveUnusedResource(qint64 resourceSize); - void resetResourceCounters(); void removeResource(const QUrl& url, qint64 size = 0); - static int _requestLimit; - static int _requestsActive; + void resetTotalResourceCounter(); + void resetUnusedResourceCounter(); + void resetResourceCounters(); // Resources QHash> _resources; @@ -293,10 +292,6 @@ private: std::atomic _numUnusedResources { 0 }; std::atomic _unusedResourcesSize { 0 }; - - // Pending resources - QQueue _resourcesToBeGotten; - QReadWriteLock _resourcesToBeGottenLock { QReadWriteLock::Recursive }; }; /// Wrapper to expose resource caches to JS/QML @@ -455,7 +450,7 @@ protected: virtual void makeRequest(); /// Checks whether the resource is cacheable. - virtual bool isCacheable() const { return true; } + virtual bool isCacheable() const { return _loaded; } /// Called when the download has finished. /// This should be overridden by subclasses that need to process the data once it is downloaded. diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 8cb7c9aaa4..7cd2330753 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -33,14 +33,14 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: case PacketType::EntityPhysics: - return static_cast(EntityVersion::BloomEffect); + return static_cast(EntityVersion::ScriptGlmVectors); case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::ConicalFrustums); case PacketType::AvatarIdentity: case PacketType::AvatarData: case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::MigrateAvatarEntitiesToTraits); + return static_cast(AvatarMixerPacketVersion::FarGrabJointsRedux); case PacketType::MessagesData: return static_cast(MessageDataVersion::TextOrBinaryData); // ICE packets diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 84a93ac939..c40ee69c08 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -242,7 +242,9 @@ enum class EntityVersion : PacketVersion { YieldSimulationOwnership, ParticleEntityFix, ParticleSpin, - BloomEffect + BloomEffect, + GrabProperties, + ScriptGlmVectors }; enum class EntityScriptCallMethodVersion : PacketVersion { @@ -293,7 +295,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { ProceduralFaceMovementFlagsAndBlendshapes, FarGrabJoints, MigrateSkeletonURLToTraits, - MigrateAvatarEntitiesToTraits + MigrateAvatarEntitiesToTraits, + FarGrabJointsRedux }; enum class DomainConnectRequestVersion : PacketVersion { diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index b938850684..88e83c01c8 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -198,17 +198,17 @@ const unsigned char* OctreePacketData::getFinalizedData() { int OctreePacketData::getFinalizedSize() { if (!_enableCompression) { - return _bytesInUse; + return _bytesInUse; } if (_dirty) { if (_debug) { qCDebug(octree, "getFinalizedSize() _compressedBytes=%d _bytesInUse=%d",_compressedBytes, _bytesInUse); } - compressContent(); + compressContent(); } - return _compressedBytes; + return _compressedBytes; } @@ -297,14 +297,6 @@ bool OctreePacketData::appendValue(const nodeColor& color) { return appendColor(color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX]); } -bool OctreePacketData::appendValue(const xColor& color) { - return appendColor(color.red, color.green, color.blue); -} - -bool OctreePacketData::appendValue(const rgbColor& color) { - return appendColor(color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX]); -} - bool OctreePacketData::appendColor(colorPart red, colorPart green, colorPart blue) { // eventually we can make this use a dictionary... bool success = false; @@ -371,7 +363,6 @@ bool OctreePacketData::appendValue(quint64 value) { } bool OctreePacketData::appendValue(float value) { - const unsigned char* data = (const unsigned char*)&value; int length = sizeof(value); bool success = append(data, length); @@ -384,7 +375,7 @@ bool OctreePacketData::appendValue(float value) { bool OctreePacketData::appendValue(const glm::vec2& value) { const unsigned char* data = (const unsigned char*)&value; - int length = sizeof(value); + int length = sizeof(glm::vec2); bool success = append(data, length); if (success) { _bytesOfValues += length; @@ -395,7 +386,7 @@ bool OctreePacketData::appendValue(const glm::vec2& value) { bool OctreePacketData::appendValue(const glm::vec3& value) { const unsigned char* data = (const unsigned char*)&value; - int length = sizeof(value); + int length = sizeof(glm::vec3); bool success = append(data, length); if (success) { _bytesOfValues += length; @@ -404,6 +395,10 @@ bool OctreePacketData::appendValue(const glm::vec3& value) { return success; } +bool OctreePacketData::appendValue(const glm::u8vec3& color) { + return appendColor(color.x, color.y, color.z); +} + bool OctreePacketData::appendValue(const QVector& value) { uint16_t qVecSize = value.size(); bool success = appendValue(qVecSize); @@ -604,6 +599,9 @@ bool OctreePacketData::compressContent() { memcpy(_compressed, compressedData.constData(), _compressedBytes); _dirty = false; success = true; + } else { + qCWarning(octree) << "OctreePacketData::compressContent -- compressedData.size >= MAX_OCTREE_PACKET_DATA_SIZE"; + assert(false); } return success; } @@ -623,11 +621,16 @@ void OctreePacketData::loadFinalizedContent(const unsigned char* data, int lengt memcpy(compressedData.data(), data, _compressedBytes); QByteArray uncompressedData = qUncompress(compressedData); - if (uncompressedData.size() <= _bytesAvailable) { - _bytesInUse = uncompressedData.size(); - _bytesAvailable -= uncompressedData.size(); - memcpy(_uncompressed, uncompressedData.constData(), _bytesInUse); + if (uncompressedData.size() > _bytesAvailable) { + int moreNeeded = uncompressedData.size() - _bytesAvailable; + _uncompressedByteArray.resize(_uncompressedByteArray.size() + moreNeeded); + _uncompressed = (unsigned char*)_uncompressedByteArray.data(); + _bytesAvailable += moreNeeded; } + + _bytesInUse = uncompressedData.size(); + _bytesAvailable -= uncompressedData.size(); + memcpy(_uncompressed, uncompressedData.constData(), _bytesInUse); } else { memcpy(_uncompressed, data, length); memcpy(_compressed, data, length); @@ -673,6 +676,21 @@ void OctreePacketData::debugBytes() { qCDebug(octree) << " _bytesReserved=" << _bytesReserved; } +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result) { + memcpy(&result, dataBytes, sizeof(result)); + return sizeof(result); +} + +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result) { + memcpy(&result, dataBytes, sizeof(result)); + return sizeof(result); +} + +int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result) { + memcpy(&result, dataBytes, sizeof(result)); + return sizeof(result); +} + int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QString& result) { uint16_t length; memcpy(&length, dataBytes, sizeof(length)); @@ -695,14 +713,6 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QUuid& return sizeof(length) + length; } -int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, xColor& result) { - result.red = dataBytes[RED_INDEX]; - result.green = dataBytes[GREEN_INDEX]; - result.blue = dataBytes[BLUE_INDEX]; - return sizeof(rgbColor); -} - - int OctreePacketData::unpackDataFromBytes(const unsigned char *dataBytes, QVector& result) { uint16_t length; memcpy(&length, dataBytes, sizeof(uint16_t)); diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 8d8f599fea..46726d83a6 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -143,12 +143,6 @@ public: /// appends a color to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const nodeColor& color); - /// appends a color to the end of the stream, may fail if new data stream is too long to fit in packet - bool appendValue(const xColor& color); - - /// appends a color to the end of the stream, may fail if new data stream is too long to fit in packet - bool appendValue(const rgbColor& color); - /// appends a unsigned 8 bit int to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(uint8_t value); @@ -170,6 +164,9 @@ public: /// appends a non-position vector to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const glm::vec3& value); + /// appends a color to the end of the stream, may fail if new data stream is too long to fit in packet + bool appendValue(const glm::u8vec3& value); + /// appends a QVector of vec3s to the end of the stream, may fail if new data stream is too long to fit in packet bool appendValue(const QVector& value); @@ -253,20 +250,19 @@ public: static quint64 getTotalBytesOfColor() { return _totalBytesOfColor; } /// total bytes of color static int unpackDataFromBytes(const unsigned char* dataBytes, float& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } - static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } - static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, bool& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, quint64& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, uint32_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, uint16_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, uint8_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } - static int unpackDataFromBytes(const unsigned char* dataBytes, rgbColor& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, glm::quat& result) { int bytes = unpackOrientationQuatFromBytes(dataBytes, result); return bytes; } static int unpackDataFromBytes(const unsigned char* dataBytes, ShapeType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, MaterialMappingMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } + static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result); + static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result); + static int unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QString& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result); - static int unpackDataFromBytes(const unsigned char* dataBytes, xColor& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); static int unpackDataFromBytes(const unsigned char* dataBytes, QVector& result); diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index b716d5c0d1..626184d1dc 100755 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -701,7 +701,7 @@ void CharacterController::updateState() { const btScalar GROUND_TO_FLY_THRESHOLD = 0.8f * _radius + _halfHeight; const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 250 * MSECS_PER_SECOND; const btScalar MIN_HOVER_HEIGHT = _scaleFactor * DEFAULT_AVATAR_MIN_HOVER_HEIGHT; - const quint64 JUMP_TO_HOVER_PERIOD = 1100 * MSECS_PER_SECOND; + const quint64 JUMP_TO_HOVER_PERIOD = _scaleFactor < 1.0f ? _scaleFactor * 1100 * MSECS_PER_SECOND : 1100 * MSECS_PER_SECOND; // scan for distant floor // rayStart is at center of bottom sphere diff --git a/libraries/render-utils/src/BackgroundStage.cpp b/libraries/render-utils/src/BackgroundStage.cpp index d9115c7943..ca643b9f14 100644 --- a/libraries/render-utils/src/BackgroundStage.cpp +++ b/libraries/render-utils/src/BackgroundStage.cpp @@ -55,85 +55,46 @@ BackgroundStage::BackgroundPointer BackgroundStage::removeBackground(Index index void DrawBackgroundStage::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { - const auto& lightingModel = inputs; + const auto& lightingModel = inputs.get0(); if (!lightingModel->isBackgroundEnabled()) { return; } // Background rendering decision - auto backgroundStage = renderContext->_scene->getStage(); - assert(backgroundStage); - - graphics::SunSkyStagePointer background; + const auto& backgroundStage = renderContext->_scene->getStage(); + const auto& backgroundFrame = inputs.get1(); graphics::SkyboxPointer skybox; - if (backgroundStage->_currentFrame._backgrounds.size()) { - auto backgroundId = backgroundStage->_currentFrame._backgrounds.front(); - auto background = backgroundStage->getBackground(backgroundId); + if (backgroundStage && backgroundFrame->_backgrounds.size()) { + const auto& background = backgroundStage->getBackground(backgroundFrame->_backgrounds.front()); if (background) { skybox = background->getSkybox(); } } - /* auto backgroundMode = skyStage->getBackgroundMode(); - switch (backgroundMode) { - case graphics::SunSkyStage::SKY_DEFAULT: { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - - scene->setSunModelEnable(false); - sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR)); - sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY); - sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); - sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION); - // fall through: render a skybox (if available), or the defaults (if requested) - } - - case graphics::SunSkyStage::SKY_BOX: {*/ if (skybox && !skybox->empty()) { - PerformanceTimer perfTimer("skybox"); - auto args = renderContext->args; + PerformanceTimer perfTimer("skybox"); + auto args = renderContext->args; - gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) { - args->_batch = &batch; + gpu::doInBatch("DrawBackgroundStage::run", args->_context, [&](gpu::Batch& batch) { + args->_batch = &batch; - batch.enableSkybox(true); + batch.enableSkybox(true); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->getViewFrustum().evalProjectionMatrix(projMat); - args->getViewFrustum().evalViewTransform(viewMat); + glm::mat4 projMat; + Transform viewMat; + args->getViewFrustum().evalProjectionMatrix(projMat); + args->getViewFrustum().evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); - skybox->render(batch, args->getViewFrustum()); - }); - args->_batch = nullptr; - - // break; - } - // fall through: render defaults (if requested) -// } -/* - case graphics::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { - if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { - auto scene = DependencyManager::get()->getStage(); - auto sceneKeyLight = scene->getKeyLight(); - auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); - if (defaultSkyboxAmbientTexture) { - sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); - sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); - } - // fall through: render defaults skybox - } else { - break; - } + skybox->render(batch, args->getViewFrustum()); + }); + args->_batch = nullptr; } - */ - } BackgroundStageSetup::BackgroundStageSetup() { diff --git a/libraries/render-utils/src/BackgroundStage.h b/libraries/render-utils/src/BackgroundStage.h index db876b1993..61ca576ca8 100644 --- a/libraries/render-utils/src/BackgroundStage.h +++ b/libraries/render-utils/src/BackgroundStage.h @@ -65,6 +65,7 @@ public: BackgroundStage::BackgroundIndices _backgrounds; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -76,18 +77,16 @@ public: BackgroundStageSetup(); void run(const render::RenderContextPointer& renderContext); - -protected: }; class DrawBackgroundStage { public: - using Inputs = LightingModelPointer; + using Inputs = render::VaryingSet2; using JobModel = render::Job::ModelI; - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); + DrawBackgroundStage() {} -protected: + void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); }; #endif diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index e6217eb825..db86480eea 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -35,7 +35,16 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons const auto frameTransform = inputs.get0(); const auto inputFrameBuffer = inputs.get1(); - const auto bloom = inputs.get2(); + const auto bloomFrame = inputs.get2(); + const auto& bloomStage = renderContext->_scene->getStage(); + graphics::BloomPointer bloom; + if (bloomStage && bloomFrame->_blooms.size()) { + bloom = bloomStage->getBloom(bloomFrame->_blooms.front()); + } + if (!bloom) { + renderContext->taskFlow.abortTask(); + return; + } assert(inputFrameBuffer->hasColor()); @@ -65,11 +74,6 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y }; - if (!bloom) { - renderContext->taskFlow.abortTask(); - return; - } - _parameters.edit()._threshold = bloom->getBloomThreshold(); gpu::doInBatch("BloomThreshold::run", args->_context, [&](gpu::Batch& batch) { @@ -89,6 +93,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons outputs.edit0() = _outputBuffer; outputs.edit1() = 0.5f + bloom->getBloomSize() * 3.5f; + outputs.edit2() = bloom; } BloomApply::BloomApply() { @@ -296,9 +301,9 @@ void BloomEffect::build(JobModel& task, const render::Varying& inputs, render::V const auto blurFB2 = task.addJob("BloomBlur2", blurInput2); const auto& frameBuffer = inputs.getN(1); - const auto& bloom = inputs.getN(2); // Mix all blur levels at quarter resolution + const auto bloom = bloomOutputs.getN(2); const auto applyInput = BloomApply::Inputs(blurInputBuffer, blurFB0, blurFB1, blurFB2, bloom).asVarying(); task.addJob("BloomApply", applyInput); // And then blend result in additive manner on top of final color buffer diff --git a/libraries/render-utils/src/BloomEffect.h b/libraries/render-utils/src/BloomEffect.h index 12c94bb929..07ae2887c9 100644 --- a/libraries/render-utils/src/BloomEffect.h +++ b/libraries/render-utils/src/BloomEffect.h @@ -14,7 +14,7 @@ #include -#include "graphics/Bloom.h" +#include "BloomStage.h" #include "DeferredFrameTransform.h" @@ -28,8 +28,8 @@ class BloomThresholdConfig : public render::Job::Config { class BloomThreshold { public: - using Inputs = render::VaryingSet3; - using Outputs = render::VaryingSet2; + using Inputs = render::VaryingSet3; + using Outputs = render::VaryingSet3; using Config = BloomThresholdConfig; using JobModel = render::Job::ModelIO; @@ -127,7 +127,7 @@ private: class BloomEffect { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet3; using Config = BloomConfig; using JobModel = render::Task::ModelI; diff --git a/libraries/render-utils/src/BloomStage.cpp b/libraries/render-utils/src/BloomStage.cpp index 904e27f5da..b3ba5f9565 100644 --- a/libraries/render-utils/src/BloomStage.cpp +++ b/libraries/render-utils/src/BloomStage.cpp @@ -16,16 +16,6 @@ std::string BloomStage::_stageName { "BLOOM_STAGE"}; const BloomStage::Index BloomStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; -FetchBloomStage::FetchBloomStage() { - _bloom = std::make_shared(); -} - -void FetchBloomStage::configure(const Config& config) { - _bloom->setBloomIntensity(config.bloomIntensity); - _bloom->setBloomThreshold(config.bloomThreshold); - _bloom->setBloomSize(config.bloomSize); -} - BloomStage::Index BloomStage::findBloom(const BloomPointer& bloom) const { auto found = _bloomMap.find(bloom); if (found != _bloomMap.end()) { @@ -66,14 +56,3 @@ void BloomStageSetup::run(const render::RenderContextPointer& renderContext) { renderContext->_scene->resetStage(BloomStage::getName(), std::make_shared()); } } - -void FetchBloomStage::run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom) { - auto bloomStage = renderContext->_scene->getStage(); - assert(bloomStage); - - bloom = nullptr; - if (bloomStage->_currentFrame._blooms.size() != 0) { - auto bloomId = bloomStage->_currentFrame._blooms.front(); - bloom = bloomStage->getBloom(bloomId); - } -} diff --git a/libraries/render-utils/src/BloomStage.h b/libraries/render-utils/src/BloomStage.h index 27bd97dcab..7ba7e56035 100644 --- a/libraries/render-utils/src/BloomStage.h +++ b/libraries/render-utils/src/BloomStage.h @@ -65,6 +65,7 @@ public: BloomStage::BloomIndices _blooms; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -102,17 +103,4 @@ signals: void dirty(); }; -class FetchBloomStage { -public: - using Config = FetchBloomConfig; - using JobModel = render::Job::ModelO; - - FetchBloomStage(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::BloomPointer& bloom); - -private: - graphics::BloomPointer _bloom; -}; #endif diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 0e61b36280..be9e75a9a5 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -405,6 +405,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto& ambientOcclusionFramebuffer = inputs.get3(); auto& velocityFramebuffer = inputs.get4(); auto& frameTransform = inputs.get5(); + auto& lightFrame = inputs.get6(); gpu::doInBatch("DebugDeferredBuffer::run", args->_context, [&](gpu::Batch& batch) { batch.enableStereo(false); @@ -443,7 +444,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame); const auto& globalShadow = lightAndShadow.second; if (globalShadow) { batch.setResourceTexture(Textures::Shadow, globalShadow->map); diff --git a/libraries/render-utils/src/DebugDeferredBuffer.h b/libraries/render-utils/src/DebugDeferredBuffer.h index 9daa8fd530..dba3ff8532 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.h +++ b/libraries/render-utils/src/DebugDeferredBuffer.h @@ -21,6 +21,8 @@ #include "AmbientOcclusionEffect.h" #include "VelocityBufferPass.h" +#include "LightStage.h" + class DebugDeferredBufferConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled) @@ -39,12 +41,13 @@ signals: class DebugDeferredBuffer { public: - using Inputs = render::VaryingSet6; + DeferredFrameTransformPointer, + LightStage::FramePointer>; using Config = DebugDeferredBufferConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 3b23711a64..a10949e0e6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -70,17 +70,22 @@ void DeferredLightingEffect::init() { loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations); } +// FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch) { + setupKeyLightBatch(args, batch, args->_scene->getStage()->_currentFrame); +} + +void DeferredLightingEffect::setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame) { PerformanceTimer perfTimer("DLE->setupBatch()"); graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { - keySunLight = lightStage->getCurrentKeyLight(); + keySunLight = lightStage->getCurrentKeyLight(lightFrame); } graphics::LightPointer keyAmbiLight; if (lightStage) { - keyAmbiLight = lightStage->getCurrentAmbientLight(); + keyAmbiLight = lightStage->getCurrentAmbientLight(lightFrame); } if (keySunLight) { @@ -361,12 +366,6 @@ void PrepareDeferred::run(const RenderContextPointer& renderContext, const Input // For the rest of the rendering, bind the lighting model batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); }); - - - // Prepare a fresh Light Frame - auto lightStage = renderContext->_scene->getStage(); - assert(lightStage); - lightStage->_currentFrame.clear(); } @@ -374,7 +373,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const graphics::HazePointer& haze, + const LightStage::FramePointer& lightFrame, + const HazeStage::FramePointer& hazeFrame, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, @@ -434,7 +434,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(*lightFrame); const auto& globalShadow = lightAndShadow.second; // Bind the shadow buffers @@ -448,8 +448,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto keyLight = lightAndShadow.first; graphics::LightPointer ambientLight; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - ambientLight = lightStage->getLight(lightStage->_currentFrame._ambientLights.front()); + if (lightStage && lightFrame->_ambientLights.size()) { + ambientLight = lightStage->getLight(lightFrame->_ambientLights.front()); } bool hasAmbientMap = (ambientLight != nullptr); @@ -458,8 +458,8 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, // Check if keylight casts shadows bool keyLightCastShadows { false }; - if (renderShadows && lightStage && lightStage->_currentFrame._sunLights.size()) { - graphics::LightPointer keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front()); + if (renderShadows && lightStage && lightFrame->_sunLights.size()) { + graphics::LightPointer keyLight = lightStage->getLight(lightFrame->_sunLights.front()); if (keyLight) { keyLightCastShadows = keyLight->getCastShadows(); } @@ -496,13 +496,17 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, } // Setup the global lighting - deferredLightingEffect->setupKeyLightBatch(args, batch); + deferredLightingEffect->setupKeyLightBatch(args, batch, *lightFrame); // Haze - if (haze) { - batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); + const auto& hazeStage = args->_scene->getStage(); + if (hazeStage && hazeFrame->_hazes.size() > 0) { + const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); + if (hazePointer) { + batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); + } } - + batch.draw(gpu::TRIANGLE_STRIP, 4); deferredLightingEffect->unsetKeyLightBatch(batch); @@ -617,7 +621,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs auto lightClusters = inputs.get6(); auto args = renderContext->args; - const auto haze = inputs.get7(); + const auto& lightFrame = inputs.get7(); + const auto& hazeFrame = inputs.get8(); if (!_gpuTimer) { _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); @@ -626,10 +631,10 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs auto previousBatch = args->_batch; gpu::doInBatch(nullptr, args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; - _gpuTimer->begin(batch); + _gpuTimer->begin(batch); + + setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, lightFrame, hazeFrame, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); - setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, haze, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource, _renderShadows); - lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); cleanupJob.run(renderContext); @@ -647,19 +652,18 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { if (!_defaultLight || !_defaultBackground) { - if (!_defaultSkyboxTexture) { - auto textureCache = DependencyManager::get(); - { - PROFILE_RANGE(render, "Process Default Skybox"); - QFileSelector fileSelector; - fileSelector.setExtraSelectors(FileUtils::getFileSelectors()); - auto skyboxUrl = fileSelector.select(PathUtils::resourcesPath() + "images/Default-Sky-9-cubemap.ktx"); + if (!_defaultSkyboxNetworkTexture) { + PROFILE_RANGE(render, "Process Default Skybox"); + _defaultSkyboxNetworkTexture = DependencyManager::get()->getTexture( + PathUtils::resourcesUrl() + "images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json", image::TextureUsage::CUBE_TEXTURE); + } - _defaultSkyboxTexture = gpu::Texture::unserialize(skyboxUrl.toStdString()); - _defaultSkyboxAmbientTexture = _defaultSkyboxTexture; - - _defaultSkybox->setCubemap(_defaultSkyboxTexture); - } + if (_defaultSkyboxNetworkTexture && _defaultSkyboxNetworkTexture->isLoaded() && _defaultSkyboxNetworkTexture->getGPUTexture()) { + _defaultSkyboxAmbientTexture = _defaultSkyboxNetworkTexture->getGPUTexture(); + _defaultSkybox->setCubemap(_defaultSkyboxAmbientTexture); + } else { + // Don't do anything until the skybox has loaded + return; } auto lightStage = renderContext->_scene->getStage(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 70bfb65f38..a838d0c4d6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -49,6 +49,7 @@ public: void init(); static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch); + static void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, const LightStage::Frame& lightFrame); static void unsetKeyLightBatch(gpu::Batch& batch); static void setupLocalLightsBatch(gpu::Batch& batch, const LightClustersPointer& lightClusters); @@ -139,13 +140,13 @@ public: class RenderDeferredSetup { public: - // using JobModel = render::Job::ModelI; - + void run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const graphics::HazePointer& haze, + const LightStage::FramePointer& lightFrame, + const HazeStage::FramePointer& hazeFrame, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource, @@ -181,9 +182,9 @@ using RenderDeferredConfig = render::GPUJobConfig; class RenderDeferred { public: - using Inputs = render::VaryingSet8 < + using Inputs = render::VaryingSet9< DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, - AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, graphics::HazePointer>; + AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, LightStage::FramePointer, HazeStage::FramePointer>; using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; @@ -220,7 +221,7 @@ protected: graphics::HazePointer _defaultHaze{ nullptr }; HazeStage::Index _defaultHazeID{ HazeStage::INVALID_INDEX }; graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() }; - gpu::TexturePointer _defaultSkyboxTexture; + NetworkTexturePointer _defaultSkyboxNetworkTexture; gpu::TexturePointer _defaultSkyboxAmbientTexture; }; diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp index 538a916a06..db80cbecae 100644 --- a/libraries/render-utils/src/DrawHaze.cpp +++ b/libraries/render-utils/src/DrawHaze.cpp @@ -19,7 +19,6 @@ #include "StencilMaskPass.h" #include "FramebufferCache.h" -#include "HazeStage.h" #include "LightStage.h" namespace ru { @@ -32,98 +31,15 @@ namespace gr { using graphics::slot::buffer::Buffer; } -void HazeConfig::setHazeColor(const glm::vec3 value) { - hazeColor = value; -} - -void HazeConfig::setHazeGlareAngle(const float value) { - hazeGlareAngle = value; -} - -void HazeConfig::setHazeGlareColor(const glm::vec3 value) { - hazeGlareColor = value; -} - -void HazeConfig::setHazeBaseReference(const float value) { - hazeBaseReference = value; -} - -void HazeConfig::setHazeActive(const bool active) { - isHazeActive = active; -} - -void HazeConfig::setAltitudeBased(const bool active) { - isAltitudeBased = active; -} - -void HazeConfig::setHazeAttenuateKeyLight(const bool active) { - isHazeAttenuateKeyLight = active; -} - -void HazeConfig::setModulateColorActive(const bool active) { - isModulateColorActive = active; -} - -void HazeConfig::setHazeEnableGlare(const bool active) { - isHazeEnableGlare = active; -} - -void HazeConfig::setHazeRange(const float value) { - hazeRange = value; -} - -void HazeConfig::setHazeAltitude(const float value) { - hazeHeight = value; -} - -void HazeConfig::setHazeKeyLightRange(const float value) { - hazeKeyLightRange = value; -} - -void HazeConfig::setHazeKeyLightAltitude(const float value) { - hazeKeyLightAltitude = value; -} - -void HazeConfig::setHazeBackgroundBlend(const float value) { - hazeBackgroundBlend = value; -} - -MakeHaze::MakeHaze() { - _haze = std::make_shared(); -} - -void MakeHaze::configure(const Config& config) { - _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); - - _haze->setHazeGlareColor(config.hazeGlareColor); - _haze->setHazeBaseReference(config.hazeBaseReference); - - _haze->setHazeActive(config.isHazeActive); - _haze->setAltitudeBased(config.isAltitudeBased); - _haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight); - _haze->setModulateColorActive(config.isModulateColorActive); - _haze->setHazeEnableGlare(config.isHazeEnableGlare); - - _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - - _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); - - _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); -} - -void MakeHaze::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { - haze = _haze; -} - -void DrawHaze::configure(const Config& config) { -} - void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) { - const auto haze = inputs.get0(); - if (haze == nullptr) { + const auto hazeFrame = inputs.get0(); + const auto& hazeStage = renderContext->args->_scene->getStage(); + graphics::HazePointer haze; + if (hazeStage && hazeFrame->_hazes.size() > 0) { + haze = hazeStage->getHaze(hazeFrame->_hazes.front()); + } + + if (!haze) { return; } @@ -131,6 +47,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu const auto framebuffer = inputs.get2(); const auto transformBuffer = inputs.get3(); const auto lightingModel = inputs.get4(); + const auto lightFrame = inputs.get5(); auto depthBuffer = framebuffer->getLinearDepthTexture(); @@ -161,17 +78,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(outputFramebufferSize, args->_viewport)); batch.setPipeline(_hazePipeline); - - auto hazeStage = args->_scene->getStage(); - if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); - if (hazePointer) { - batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); - } else { - // Something is wrong, so just quit Haze - return; - } - } + batch.setUniformBuffer(ru::Buffer::HazeParams, haze->getHazeParametersBuffer()); batch.setUniformBuffer(ru::Buffer::DeferredFrameTransform, transformBuffer->getFrameTransformBuffer()); batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); @@ -179,13 +86,12 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu auto lightStage = args->_scene->getStage(); if (lightStage) { graphics::LightPointer keyLight; - keyLight = lightStage->getCurrentKeyLight(); + keyLight = lightStage->getCurrentKeyLight(*lightFrame); if (keyLight) { batch.setUniformBuffer(gr::Buffer::KeyLight, keyLight->getLightSchemaBuffer()); } } - batch.draw(gpu::TRIANGLE_STRIP, 4); }); } diff --git a/libraries/render-utils/src/DrawHaze.h b/libraries/render-utils/src/DrawHaze.h index e30ce26dd4..9236543068 100644 --- a/libraries/render-utils/src/DrawHaze.h +++ b/libraries/render-utils/src/DrawHaze.h @@ -19,152 +19,20 @@ #include #include #include -#include #include "SurfaceGeometryPass.h" #include "LightingModel.h" +#include "HazeStage.h" +#include "LightStage.h" + using LinearDepthFramebufferPointer = std::shared_ptr; -class MakeHazeConfig : public render::Job::Config { - Q_OBJECT - - Q_PROPERTY(glm::vec3 hazeColor MEMBER hazeColor WRITE setHazeColor NOTIFY dirty); - Q_PROPERTY(float hazeGlareAngle MEMBER hazeGlareAngle WRITE setHazeGlareAngle NOTIFY dirty); - - Q_PROPERTY(glm::vec3 hazeGlareColor MEMBER hazeGlareColor WRITE setHazeGlareColor NOTIFY dirty); - Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty); - - Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty); - Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty); - Q_PROPERTY(bool isHazeAttenuateKeyLight MEMBER isHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight NOTIFY dirty); - Q_PROPERTY(bool isModulateColorActive MEMBER isModulateColorActive WRITE setModulateColorActive NOTIFY dirty); - Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty); - - Q_PROPERTY(float hazeRange MEMBER hazeRange WRITE setHazeRange NOTIFY dirty); - Q_PROPERTY(float hazeHeight MEMBER hazeHeight WRITE setHazeAltitude NOTIFY dirty); - - Q_PROPERTY(float hazeKeyLightRange MEMBER hazeKeyLightRange WRITE setHazeKeyLightRange NOTIFY dirty); - Q_PROPERTY(float hazeKeyLightAltitude MEMBER hazeKeyLightAltitude WRITE setHazeKeyLightAltitude NOTIFY dirty); - - Q_PROPERTY(float hazeBackgroundBlend MEMBER hazeBackgroundBlend WRITE setHazeBackgroundBlend NOTIFY dirty); - -public: - MakeHazeConfig() : render::Job::Config() {} - - glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - - glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; - - bool isHazeActive{ false }; - bool isAltitudeBased{ false }; - bool isHazeAttenuateKeyLight{ false }; - bool isModulateColorActive{ false }; - bool isHazeEnableGlare{ false }; - - float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - - float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - - float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; - -public slots: - void setHazeColor(const glm::vec3 value) { hazeColor = value; emit dirty(); } - void setHazeGlareAngle(const float value) { hazeGlareAngle = value; emit dirty(); } - - void setHazeGlareColor(const glm::vec3 value) { hazeGlareColor = value; emit dirty(); } - void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); } - - void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); } - void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); } - void setHazeAttenuateKeyLight(const bool active) { isHazeAttenuateKeyLight = active; emit dirty(); } - void setModulateColorActive(const bool active) { isModulateColorActive = active; emit dirty(); } - void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); } - - void setHazeRange(const float value) { hazeRange = value; emit dirty(); } - void setHazeAltitude(const float value) { hazeHeight = value; emit dirty(); } - - void setHazeKeyLightRange(const float value) { hazeKeyLightRange = value; emit dirty(); } - void setHazeKeyLightAltitude(const float value) { hazeKeyLightAltitude = value; emit dirty(); } - - void setHazeBackgroundBlend(const float value) { hazeBackgroundBlend = value; ; emit dirty(); } - -signals: - void dirty(); -}; - -class MakeHaze { -public: - using Config = MakeHazeConfig; - using JobModel = render::Job::ModelO; - - MakeHaze(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); - -private: - graphics::HazePointer _haze; -}; - -class HazeConfig : public render::Job::Config { -public: - HazeConfig() : render::Job::Config(true) {} - - // attributes - glm::vec3 hazeColor{ graphics::Haze::INITIAL_HAZE_COLOR }; - float hazeGlareAngle{ graphics::Haze::INITIAL_HAZE_GLARE_ANGLE }; - - glm::vec3 hazeGlareColor{ graphics::Haze::INITIAL_HAZE_GLARE_COLOR }; - float hazeBaseReference{ graphics::Haze::INITIAL_HAZE_BASE_REFERENCE }; - - bool isHazeActive{ false }; // Setting this to true will set haze to on - bool isAltitudeBased{ false }; - bool isHazeAttenuateKeyLight{ false }; - bool isModulateColorActive{ false }; - bool isHazeEnableGlare{ false }; - - float hazeRange{ graphics::Haze::INITIAL_HAZE_RANGE }; - float hazeHeight{ graphics::Haze::INITIAL_HAZE_HEIGHT }; - - float hazeKeyLightRange{ graphics::Haze::INITIAL_KEY_LIGHT_RANGE }; - float hazeKeyLightAltitude{ graphics::Haze::INITIAL_KEY_LIGHT_ALTITUDE }; - - float hazeBackgroundBlend{ graphics::Haze::INITIAL_HAZE_BACKGROUND_BLEND }; - - // methods - void setHazeColor(const glm::vec3 value); - void setHazeGlareAngle(const float value); - - void setHazeGlareColor(const glm::vec3 value); - void setHazeBaseReference(const float value); - - void setHazeActive(const bool active); - void setAltitudeBased(const bool active); - void setHazeAttenuateKeyLight(const bool active); - void setModulateColorActive(const bool active); - void setHazeEnableGlare(const bool active); - - void setHazeRange(const float value); - void setHazeAltitude(const float value); - - void setHazeKeyLightRange(const float value); - void setHazeKeyLightAltitude(const float value); - - void setHazeBackgroundBlend(const float value); -}; - class DrawHaze { public: - using Inputs = render::VaryingSet5; - using Config = HazeConfig; - using JobModel = render::Job::ModelI; + using Inputs = render::VaryingSet6; + using JobModel = render::Job::ModelI; - void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const Inputs& inputs); private: diff --git a/libraries/render-utils/src/HazeStage.cpp b/libraries/render-utils/src/HazeStage.cpp index e56b715b8c..c850828be5 100644 --- a/libraries/render-utils/src/HazeStage.cpp +++ b/libraries/render-utils/src/HazeStage.cpp @@ -16,32 +16,6 @@ std::string HazeStage::_stageName { "HAZE_STAGE"}; const HazeStage::Index HazeStage::INVALID_INDEX { render::indexed_container::INVALID_INDEX }; -FetchHazeStage::FetchHazeStage() { - _haze = std::make_shared(); -} - -void FetchHazeStage::configure(const Config& config) { - _haze->setHazeColor(config.hazeColor); - _haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(config.hazeGlareAngle)); - - _haze->setHazeGlareColor(config.hazeGlareColor); - _haze->setHazeBaseReference(config.hazeBaseReference); - - _haze->setHazeActive(config.isHazeActive); - _haze->setAltitudeBased(config.isAltitudeBased); - _haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight); - _haze->setModulateColorActive(config.isModulateColorActive); - _haze->setHazeEnableGlare(config.isHazeEnableGlare); - - _haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeRange)); - _haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeHeight)); - - _haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange)); - _haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude)); - - _haze->setHazeBackgroundBlend(config.hazeBackgroundBlend); -} - HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const { auto found = _hazeMap.find(haze); if (found != _hazeMap.end()) { @@ -84,15 +58,4 @@ void HazeStageSetup::run(const render::RenderContextPointer& renderContext) { if (!stage) { renderContext->_scene->resetStage(HazeStage::getName(), std::make_shared()); } -} - -void FetchHazeStage::run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze) { - auto hazeStage = renderContext->_scene->getStage(); - assert(hazeStage); - - haze = nullptr; - if (hazeStage->_currentFrame._hazes.size() != 0) { - auto hazeId = hazeStage->_currentFrame._hazes.front(); - haze = hazeStage->getHaze(hazeId); - } -} +} \ No newline at end of file diff --git a/libraries/render-utils/src/HazeStage.h b/libraries/render-utils/src/HazeStage.h index b48168e376..b1c7d0384c 100644 --- a/libraries/render-utils/src/HazeStage.h +++ b/libraries/render-utils/src/HazeStage.h @@ -65,6 +65,7 @@ public: HazeStage::HazeIndices _hazes; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; }; @@ -150,18 +151,4 @@ public slots: signals: void dirty(); }; - -class FetchHazeStage { -public: - using Config = FetchHazeConfig; - using JobModel = render::Job::ModelO; - - FetchHazeStage(); - - void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, graphics::HazePointer& haze); - -private: - graphics::HazePointer _haze; -}; #endif diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp index ae484f868f..252416ea9d 100644 --- a/libraries/render-utils/src/LightClusters.cpp +++ b/libraries/render-utils/src/LightClusters.cpp @@ -175,15 +175,15 @@ void LightClusters::updateLightStage(const LightStagePointer& lightStage) { } -void LightClusters::updateLightFrame(const LightStage::Frame& lightFrame, bool points, bool spots) { +void LightClusters::updateLightFrame(const LightStage::FramePointer& lightFrame, bool points, bool spots) { // start fresh _visibleLightIndices.clear(); // Now gather the lights // gather lights - auto& srcPointLights = lightFrame._pointLights; - auto& srcSpotLights = lightFrame._spotLights; + auto& srcPointLights = lightFrame->_pointLights; + auto& srcSpotLights = lightFrame->_spotLights; int numPointLights = (int)srcPointLights.size(); int numSpotLights = (int)srcSpotLights.size(); @@ -548,7 +548,8 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext, auto deferredTransform = inputs.get0(); auto lightingModel = inputs.get1(); - auto surfaceGeometryFramebuffer = inputs.get2(); + auto lightFrame = inputs.get2(); + auto surfaceGeometryFramebuffer = inputs.get3(); // first update the Grid with the new frustum if (!_freeze) { @@ -559,7 +560,7 @@ void LightClusteringPass::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); _lightClusters->updateLightStage(lightStage); - _lightClusters->updateLightFrame(lightStage->_currentFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); + _lightClusters->updateLightFrame(lightFrame, lightingModel->isPointLightEnabled(), lightingModel->isSpotLightEnabled()); auto clusteringStats = _lightClusters->updateClusters(); diff --git a/libraries/render-utils/src/LightClusters.h b/libraries/render-utils/src/LightClusters.h index fa054c304a..e109e43aaa 100644 --- a/libraries/render-utils/src/LightClusters.h +++ b/libraries/render-utils/src/LightClusters.h @@ -79,7 +79,7 @@ public: void updateLightStage(const LightStagePointer& lightStage); - void updateLightFrame(const LightStage::Frame& lightFrame, bool points = true, bool spots = true); + void updateLightFrame(const LightStage::FramePointer& lightFrame, bool points = true, bool spots = true); glm::ivec3 updateClusters(); @@ -167,7 +167,7 @@ protected: class LightClusteringPass { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet4; using Outputs = LightClustersPointer; using Config = LightClusteringPassConfig; using JobModel = render::Job::ModelIO; diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index 369c62c197..ccedb0cd7b 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -372,36 +372,36 @@ LightStage::LightPointer LightStage::removeLight(Index index) { return removedLight; } -LightStage::LightPointer LightStage::getCurrentKeyLight() const { - Index keyLightId{ _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); +LightStage::LightPointer LightStage::getCurrentKeyLight(const LightStage::Frame& frame) const { + Index keyLightId { _defaultLightId }; + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } return _lights.get(keyLightId); } -LightStage::LightPointer LightStage::getCurrentAmbientLight() const { +LightStage::LightPointer LightStage::getCurrentAmbientLight(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._ambientLights.empty()) { - keyLightId = _currentFrame._ambientLights.front(); + if (!frame._ambientLights.empty()) { + keyLightId = frame._ambientLights.front(); } return _lights.get(keyLightId); } -LightStage::ShadowPointer LightStage::getCurrentKeyShadow() const { +LightStage::ShadowPointer LightStage::getCurrentKeyShadow(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } auto shadow = getShadow(keyLightId); assert(shadow == nullptr || shadow->getLight() == getLight(keyLightId)); return shadow; } -LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow() const { +LightStage::LightAndShadow LightStage::getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const { Index keyLightId { _defaultLightId }; - if (!_currentFrame._sunLights.empty()) { - keyLightId = _currentFrame._sunLights.front(); + if (!frame._sunLights.empty()) { + keyLightId = frame._sunLights.front(); } auto shadow = getShadow(keyLightId); auto light = getLight(keyLightId); diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index b8a49d81bb..5e5b6cf4fa 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -151,11 +151,6 @@ public: return LightAndShadow(light, shadow); } - LightPointer getCurrentKeyLight() const; - LightPointer getCurrentAmbientLight() const; - ShadowPointer getCurrentKeyShadow() const; - LightAndShadow getCurrentKeyLightAndShadow() const; - LightStage(); gpu::BufferPointer getLightArrayBuffer() const { return _lightArrayBuffer; } @@ -185,6 +180,7 @@ public: LightStage::LightIndices _sunLights; LightStage::LightIndices _ambientLights; }; + using FramePointer = std::shared_ptr; Frame _currentFrame; @@ -193,6 +189,11 @@ public: Index getSpotOffLight() { return _spotOffLightId; } Index getSunOffLight() { return _sunOffLightId; } + LightPointer getCurrentKeyLight(const LightStage::Frame& frame) const; + LightPointer getCurrentAmbientLight(const LightStage::Frame& frame) const; + ShadowPointer getCurrentKeyShadow(const LightStage::Frame& frame) const; + LightAndShadow getCurrentKeyLightAndShadow(const LightStage::Frame& frame) const; + protected: struct Desc { diff --git a/libraries/render-utils/src/RenderCommonTask.cpp b/libraries/render-utils/src/RenderCommonTask.cpp index 9aee0e57a4..4422d15d5c 100644 --- a/libraries/render-utils/src/RenderCommonTask.cpp +++ b/libraries/render-utils/src/RenderCommonTask.cpp @@ -197,12 +197,14 @@ void Blit::run(const RenderContextPointer& renderContext, const gpu::Framebuffer }); } -void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) { +void ExtractFrustums::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output) { assert(renderContext->args); assert(renderContext->args->_context); RenderArgs* args = renderContext->args; + const auto& lightFrame = inputs; + // Return view frustum auto& viewFrustum = output[VIEW_FRUSTUM].edit(); if (!viewFrustum) { @@ -216,7 +218,7 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) { auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit(); if (lightStage) { - auto globalShadow = lightStage->getCurrentKeyShadow(); + auto globalShadow = lightStage->getCurrentKeyShadow(*lightFrame); if (globalShadow && i<(int)globalShadow->getCascadeCount()) { auto& cascade = globalShadow->getCascade(i); @@ -229,3 +231,21 @@ void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Out } } } + +void FetchCurrentFrames::run(const render::RenderContextPointer& renderContext, Outputs& outputs) { + auto lightStage = renderContext->_scene->getStage(); + assert(lightStage); + outputs.edit0() = std::make_shared(lightStage->_currentFrame); + + auto backgroundStage = renderContext->_scene->getStage(); + assert(backgroundStage); + outputs.edit1() = std::make_shared(backgroundStage->_currentFrame); + + auto hazeStage = renderContext->_scene->getStage(); + assert(hazeStage); + outputs.edit2() = std::make_shared(hazeStage->_currentFrame); + + auto bloomStage = renderContext->_scene->getStage(); + assert(bloomStage); + outputs.edit3() = std::make_shared(bloomStage->_currentFrame); +} diff --git a/libraries/render-utils/src/RenderCommonTask.h b/libraries/render-utils/src/RenderCommonTask.h index 65f8cdfbfc..9b611bc38d 100644 --- a/libraries/render-utils/src/RenderCommonTask.h +++ b/libraries/render-utils/src/RenderCommonTask.h @@ -13,6 +13,11 @@ #include #include "LightingModel.h" +#include "LightStage.h" +#include "BackgroundStage.h" +#include "HazeStage.h" +#include "BloomStage.h" + class BeginGPURangeTimer { public: using JobModel = render::Job::ModelO; @@ -106,10 +111,22 @@ public: FRUSTUM_COUNT }; - using Output = render::VaryingArray; - using JobModel = render::Job::ModelO; + using Inputs = LightStage::FramePointer; + using Outputs = render::VaryingArray; + using JobModel = render::Job::ModelIO; - void run(const render::RenderContextPointer& renderContext, Output& output); + void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& output); +}; + + +class FetchCurrentFrames { +public: + using Outputs = render::VaryingSet4; + using JobModel = render::Job::ModelO; + + FetchCurrentFrames() {} + + void run(const render::RenderContextPointer& renderContext, Outputs& outputs); }; #endif // hifi_RenderDeferredTask_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 57f5c3ec34..4052b6bd5a 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -180,29 +180,32 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now. task.addJob("DrawLight", lights); + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + const auto backgroundFrame = currentFrames.getN(1); + const auto hazeFrame = currentFrames.getN(2); + const auto bloomFrame = currentFrames.getN(3); + // Light Clustering // Create the cluster grid of lights, cpu job for now - const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).asVarying(); + const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, lightFrame, linearDepthTarget).asVarying(); const auto lightClusters = task.addJob("LightClustering", lightClusteringPassInputs); - - // Add haze model - const auto hazeModel = task.addJob("HazeModel"); // DeferredBuffer is complete, now let's shade it into the LightingBuffer const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, - surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying(); - + surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, lightFrame, hazeFrame).asVarying(); task.addJob("RenderDeferred", deferredLightingInputs, renderShadows); - // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job - task.addJob("DrawBackgroundDeferred", lightingModel); + const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); + task.addJob("DrawBackgroundDeferred", backgroundInputs); - const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeModel, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel)); + const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeFrame, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingModel, lightFrame)); task.addJob("DrawHazeDeferred", drawHazeInputs); // Render transparent objects forward in LightingBuffer - const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters, jitter).asVarying(); + const auto transparentsInputs = DrawDeferred::Inputs(transparents, hazeFrame, lightFrame, lightingModel, lightClusters, jitter).asVarying(); task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); // Light Cluster Grid Debuging job @@ -246,8 +249,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("Antialiasing", antialiasingInputs); // Add bloom - const auto bloomModel = task.addJob("BloomModel"); - const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomModel).asVarying(); + const auto bloomInputs = BloomEffect::Inputs(deferredFrameTransform, lightingFramebuffer, bloomFrame).asVarying(); task.addJob("Bloom", bloomInputs); // Lighting Buffer ready for tone mapping @@ -261,11 +263,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawLightBounds", lights); task.addJob("DrawZones", zones); - const auto frustums = task.addJob("ExtractFrustums"); - const auto viewFrustum = frustums.getN(ExtractFrustums::VIEW_FRUSTUM); + const auto frustums = task.addJob("ExtractFrustums", lightFrame); + const auto viewFrustum = frustums.getN(ExtractFrustums::VIEW_FRUSTUM); task.addJob("DrawViewFrustum", viewFrustum, glm::vec3(0.0f, 1.0f, 0.0f)); for (auto i = 0; i < ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT; i++) { - const auto shadowFrustum = frustums.getN(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i); + const auto shadowFrustum = frustums.getN(ExtractFrustums::SHADOW_CASCADE0_FRUSTUM + i); float tint = 1.0f - i / float(ExtractFrustums::SHADOW_CASCADE_FRUSTUM_COUNT - 1); char jobName[64]; sprintf(jobName, "DrawShadowFrustum%d", i); @@ -290,7 +292,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // Debugging stages { // Debugging Deferred buffer job - const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform)); + const auto debugFramebuffers = render::Varying(DebugDeferredBuffer::Inputs(deferredFramebuffer, linearDepthTarget, surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, velocityBuffer, deferredFrameTransform, lightFrame)); task.addJob("DebugDeferredBuffer", debugFramebuffers); const auto debugSubsurfaceScatteringInputs = DebugSubsurfaceScattering::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, @@ -315,7 +317,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawStatus", drawStatusInputs, DrawStatus(statusIconMap)); } - task.addJob("DrawZoneStack", deferredFrameTransform); + const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying(); + task.addJob("DrawZoneStack", debugZoneInputs); } // Upscale to finale resolution @@ -351,9 +354,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& auto config = std::static_pointer_cast(renderContext->jobConfig); const auto& inItems = inputs.get0(); - const auto& lightingModel = inputs.get1(); - const auto& lightClusters = inputs.get2(); - const auto jitter = inputs.get3(); + const auto& hazeFrame = inputs.get1(); + const auto& lightFrame = inputs.get2(); + const auto& lightingModel = inputs.get3(); + const auto& lightClusters = inputs.get4(); + const auto jitter = inputs.get5(); auto deferredLightingEffect = DependencyManager::get(); RenderArgs* args = renderContext->args; @@ -378,13 +383,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& batch.setUniformBuffer(ru::Buffer::LightModel, lightingModel->getParametersBuffer()); // Set the light - deferredLightingEffect->setupKeyLightBatch(args, batch); + deferredLightingEffect->setupKeyLightBatch(args, batch, *lightFrame); deferredLightingEffect->setupLocalLightsBatch(batch, lightClusters); // Setup haze if current zone has haze - auto hazeStage = args->_scene->getStage(); - if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { - graphics::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); + const auto& hazeStage = args->_scene->getStage(); + if (hazeStage && hazeFrame->_hazes.size() > 0) { + const auto& hazePointer = hazeStage->getHaze(hazeFrame->_hazes.front()); if (hazePointer) { batch.setUniformBuffer(ru::Buffer::HazeParams, hazePointer->getHazeParametersBuffer()); } diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 161a14c943..c18daa6d3d 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -17,6 +17,7 @@ #include "LightingModel.h" #include "LightClusters.h" #include "RenderShadowTask.h" +#include "HazeStage.h" class DrawDeferredConfig : public render::Job::Config { Q_OBJECT @@ -42,7 +43,7 @@ protected: class DrawDeferred { public: - using Inputs = render::VaryingSet4; + using Inputs = render::VaryingSet6; using Config = DrawDeferredConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 9ab60786b5..53f89aaec3 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -32,7 +32,6 @@ #include "FramebufferCache.h" #include "TextureCache.h" #include "RenderCommonTask.h" -#include "LightStage.h" namespace ru { using render_utils::slot::texture::Texture; @@ -59,13 +58,13 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Extract opaques / transparents / lights / metas / overlays / background const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE]; const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE]; - // const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; + //const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT]; const auto& metas = items.get0()[RenderFetchCullSortTask::META]; const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE]; const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE]; //const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND]; - // const auto& spatialSelection = items[1]; + //const auto& spatialSelection = items[1]; fadeEffect->build(task, opaques); @@ -76,10 +75,17 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Filter zones from the general metas bucket const auto zones = task.addJob("ZoneRenderer", metas); + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + const auto backgroundFrame = currentFrames.getN(1); + //const auto hazeFrame = currentFrames.getN(2); + //const auto bloomFrame = currentFrames.getN(3); + // GPU jobs: Start preparing the main framebuffer const auto framebuffer = task.addJob("PrepareFramebuffer"); - task.addJob("PrepareForward", lightingModel); + task.addJob("PrepareForward", lightFrame); // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", framebuffer); @@ -101,7 +107,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("DrawOpaques", opaqueInputs, shapePlumber); // Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job - task.addJob("DrawBackgroundDeferred", lightingModel); + const auto backgroundInputs = DrawBackgroundStage::Inputs(lightingModel, backgroundFrame).asVarying(); + task.addJob("DrawBackgroundForward", backgroundInputs); // Draw transparent objects forward const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); @@ -114,8 +121,8 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend task.addJob("DrawTransparentBounds", transparents); task.addJob("DrawZones", zones); - task.addJob("DrawZoneStack", deferredFrameTransform); - + const auto debugZoneInputs = DebugZoneLighting::Inputs(deferredFrameTransform, lightFrame, backgroundFrame).asVarying(); + task.addJob("DrawZoneStack", debugZoneInputs); } // Lighting Buffer ready for tone mapping @@ -180,12 +187,12 @@ void PrepareForward::run(const RenderContextPointer& renderContext, const Inputs graphics::LightPointer keySunLight; auto lightStage = args->_scene->getStage(); if (lightStage) { - keySunLight = lightStage->getCurrentKeyLight(); + keySunLight = lightStage->getCurrentKeyLight(*inputs); } graphics::LightPointer keyAmbiLight; if (lightStage) { - keyAmbiLight = lightStage->getCurrentAmbientLight(); + keyAmbiLight = lightStage->getCurrentAmbientLight(*inputs); } if (keySunLight) { diff --git a/libraries/render-utils/src/RenderForwardTask.h b/libraries/render-utils/src/RenderForwardTask.h index 22e75d4bdc..54341d1ded 100755 --- a/libraries/render-utils/src/RenderForwardTask.h +++ b/libraries/render-utils/src/RenderForwardTask.h @@ -15,6 +15,7 @@ #include #include #include "LightingModel.h" +#include "LightStage.h" class RenderForwardTask { public: @@ -40,7 +41,7 @@ private: class PrepareForward { public: - using Inputs = LightingModelPointer; + using Inputs = LightStage::FramePointer; using JobModel = render::Job::ModelI; void run(const render::RenderContextPointer& renderContext, diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index 7c24c08c27..c4fa297965 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -24,6 +24,8 @@ #include "RenderUtilsLogging.h" +#include "RenderCommonTask.h" + // These values are used for culling the objects rendered in the shadow map // but are readjusted afterwards #define SHADOW_FRUSTUM_NEAR 1.0f @@ -40,10 +42,6 @@ void RenderShadowTask::configure(const Config& configuration) { } void RenderShadowTask::build(JobModel& task, const render::Varying& input, render::Varying& output, render::CullFunctor cameraCullFunctor, uint8_t tagBits, uint8_t tagMask) { - ::CullFunctor shadowCullFunctor = [this](const RenderArgs* args, const AABox& bounds) { - return _cullFunctor(args, bounds); - }; - // Prepare the ShapePipeline ShapePlumberPointer shapePlumber = std::make_shared(); { @@ -54,7 +52,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende initZPassPipelines(*shapePlumber, state); } - const auto setupOutput = task.addJob("ShadowSetup"); + // FIXME: calling this here before the zones/lights are drawn during the deferred/forward passes means we're actually using the frames from the previous draw + // Fetch the current frame stacks from all the stages + const auto currentFrames = task.addJob("FetchCurrentFrames"); + const auto lightFrame = currentFrames.getN(0); + + const auto setupOutput = task.addJob("ShadowSetup", lightFrame); const auto queryResolution = setupOutput.getN(1); // Fetch and cull the items from the scene @@ -89,7 +92,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { char jobName[64]; sprintf(jobName, "ShadowCascadeSetup%d", i); - const auto cascadeSetupOutput = task.addJob(jobName, i, _cullFunctor, tagBits, tagMask); + const auto cascadeSetupOutput = task.addJob(jobName, lightFrame, i, tagBits, tagMask); const auto shadowFilter = cascadeSetupOutput.getN(0); auto antiFrustum = render::Varying(ViewFrustumPointer()); cascadeFrustums[i] = cascadeSetupOutput.getN(1); @@ -97,14 +100,15 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende antiFrustum = cascadeFrustums[i - 2]; } - // CPU jobs: finer grained culling - const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum).asVarying(); + const auto cullInputs = CullShadowBounds::Inputs(sortedShapes, shadowFilter, antiFrustum, lightFrame, cascadeSetupOutput.getN(2)).asVarying(); sprintf(jobName, "CullShadowCascade%d", i); - const auto culledShadowItemsAndBounds = task.addJob(jobName, cullInputs, shadowCullFunctor); + const auto culledShadowItemsAndBounds = task.addJob(jobName, cullInputs); // GPU jobs: Render to shadow map sprintf(jobName, "RenderShadowMap%d", i); - task.addJob(jobName, culledShadowItemsAndBounds, shapePlumber, i); + const auto shadowInputs = RenderShadowMap::Inputs(culledShadowItemsAndBounds.getN(0), + culledShadowItemsAndBounds.getN(1), lightFrame).asVarying(); + task.addJob(jobName, shadowInputs, shapePlumber, i); sprintf(jobName, "ShadowCascadeTeardown%d", i); task.addJob(jobName, shadowFilter); @@ -204,11 +208,12 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, con const auto& inShapes = inputs.get0(); const auto& inShapeBounds = inputs.get1(); + const auto& lightFrame = inputs.get2(); auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - auto shadow = lightStage->getCurrentKeyShadow(); + auto shadow = lightStage->getCurrentKeyShadow(*lightFrame); if (!shadow || _cascadeIndex >= shadow->getCascadeCount()) { return; } @@ -328,11 +333,12 @@ void RenderShadowSetup::setSlopeBias(int cascadeIndex, float value) { _bias[cascadeIndex]._slope = value * value * value * 0.01f; } -void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { +void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) { // Abort all jobs if not casting shadows auto lightStage = renderContext->_scene->getStage(); + auto lightFrame = *input; assert(lightStage); - if (!lightStage->getCurrentKeyLight() || !lightStage->getCurrentKeyLight()->getCastShadows()) { + if (!lightStage->getCurrentKeyLight(lightFrame) || !lightStage->getCurrentKeyLight(lightFrame)->getCastShadows()) { renderContext->taskFlow.abortTask(); return; } @@ -346,7 +352,7 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O *_cameraFrustum = args->getViewFrustum(); output.edit2() = _cameraFrustum; - const auto globalShadow = lightStage->getCurrentKeyShadow(); + const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); if (globalShadow) { globalShadow->setKeylightFrustum(args->getViewFrustum(), SHADOW_FRUSTUM_NEAR, SHADOW_FRUSTUM_FAR); @@ -413,15 +419,18 @@ void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, O } } -void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, Outputs& output) { +void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output) { auto lightStage = renderContext->_scene->getStage(); + const auto& lightFrame = *input; assert(lightStage); // Cache old render args RenderArgs* args = renderContext->args; - const auto globalShadow = lightStage->getCurrentKeyShadow(); - if (globalShadow && _cascadeIndexgetCascadeCount()) { + RenderShadowTask::CullFunctor cullFunctor; + + const auto globalShadow = lightStage->getCurrentKeyShadow(lightFrame); + if (globalShadow && _cascadeIndex < globalShadow->getCascadeCount()) { // Second item filter is to filter items to keep in shadow frustum computation (here we need to keep shadow receivers) output.edit0() = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(_tagBits, _tagMask); @@ -434,13 +443,14 @@ void RenderShadowCascadeSetup::run(const render::RenderContextPointer& renderCon const auto minTexelCount = 24.0f; // TODO : maybe adapt that with LOD management system? texelSize *= minTexelCount; - _cullFunctor._minSquareSize = texelSize * texelSize; + cullFunctor._minSquareSize = texelSize * texelSize; output.edit1() = cascadeFrustum; } else { output.edit0() = ItemFilter::Builder::nothing(); output.edit1() = ViewFrustumPointer(); } + output.edit2() = cullFunctor; } void RenderShadowCascadeTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) { @@ -498,13 +508,20 @@ void CullShadowBounds::run(const render::RenderContextPointer& renderContext, co outShapes.clear(); outBounds = AABox(); + const auto& lightFrame = *inputs.get3(); + auto cullFunctor = inputs.get4(); + + render::CullFunctor shadowCullFunctor = [cullFunctor](const RenderArgs* args, const AABox& bounds) { + return cullFunctor(args, bounds); + }; + if (!filter.selectsNothing()) { auto& details = args->_details.edit(RenderDetails::SHADOW); - render::CullTest test(_cullFunctor, args, details, antiFrustum); + render::CullTest test(shadowCullFunctor, args, details, antiFrustum); auto scene = args->_scene; auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - const auto globalLightDir = lightStage->getCurrentKeyLight()->getDirection(); + const auto globalLightDir = lightStage->getCurrentKeyLight(lightFrame)->getDirection(); auto castersFilter = render::ItemFilter::Builder(filter).withShadowCaster().build(); const auto& receiversFilter = filter; diff --git a/libraries/render-utils/src/RenderShadowTask.h b/libraries/render-utils/src/RenderShadowTask.h index 77892305fb..8aaf554514 100644 --- a/libraries/render-utils/src/RenderShadowTask.h +++ b/libraries/render-utils/src/RenderShadowTask.h @@ -19,11 +19,13 @@ #include "Shadows_shared.slh" +#include "LightStage.h" + class ViewFrustum; class RenderShadowMap { public: - using Inputs = render::VaryingSet2; + using Inputs = render::VaryingSet3; using JobModel = render::Job::ModelI; RenderShadowMap(render::ShapePlumberPointer shapePlumber, unsigned int cascadeIndex) : _shapePlumber{ shapePlumber }, _cascadeIndex{ cascadeIndex } {} @@ -98,13 +100,14 @@ signals: class RenderShadowSetup { public: + using Inputs = LightStage::FramePointer; using Outputs = render::VaryingSet3; using Config = RenderShadowSetupConfig; - using JobModel = render::Job::ModelO; + using JobModel = render::Job::ModelIO; RenderShadowSetup(); void configure(const Config& configuration); - void run(const render::RenderContextPointer& renderContext, Outputs& output); + void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output); private: @@ -121,19 +124,19 @@ private: class RenderShadowCascadeSetup { public: - using Outputs = render::VaryingSet2; - using JobModel = render::Job::ModelO; + using Inputs = LightStage::FramePointer; + using Outputs = render::VaryingSet3; + using JobModel = render::Job::ModelIO; - RenderShadowCascadeSetup(unsigned int cascadeIndex, RenderShadowTask::CullFunctor& cullFunctor, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : - _cascadeIndex{ cascadeIndex }, _cullFunctor{ cullFunctor }, _tagBits(tagBits), _tagMask(tagMask) {} - void run(const render::RenderContextPointer& renderContext, Outputs& output); + RenderShadowCascadeSetup(unsigned int cascadeIndex, uint8_t tagBits = 0x00, uint8_t tagMask = 0x00) : + _cascadeIndex(cascadeIndex), _tagBits(tagBits), _tagMask(tagMask) {} + + void run(const render::RenderContextPointer& renderContext, const Inputs& input, Outputs& output); private: - unsigned int _cascadeIndex; - RenderShadowTask::CullFunctor& _cullFunctor; - uint8_t _tagBits{ 0x00 }; - uint8_t _tagMask{ 0x00 }; + uint8_t _tagBits { 0x00 }; + uint8_t _tagMask { 0x00 }; }; class RenderShadowCascadeTeardown { @@ -152,20 +155,11 @@ public: class CullShadowBounds { public: - using Inputs = render::VaryingSet3; + using Inputs = render::VaryingSet5; using Outputs = render::VaryingSet2; using JobModel = render::Job::ModelIO; - CullShadowBounds(render::CullFunctor cullFunctor) : - _cullFunctor{ cullFunctor } { - } - void run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs); - -private: - - render::CullFunctor _cullFunctor; - }; #endif // hifi_RenderShadowTask_h diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index 1a1b3706f9..4ffc8730a7 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -39,28 +39,16 @@ namespace gr { using namespace render; -class SetupZones { -public: - using Inputs = render::ItemBounds; - using JobModel = render::Job::ModelI; - - SetupZones() {} - - void run(const RenderContextPointer& context, const Inputs& inputs); - -protected: -}; - const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" }; -void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& ouput) { +void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) { // Filter out the sorted list of zones const auto zoneItems = task.addJob("FilterZones", input, ZONES_SELECTION.c_str()); // just setup the current zone env task.addJob("SetupZones", zoneItems); - ouput = zoneItems; + output = zoneItems; } void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs) { @@ -130,27 +118,29 @@ const gpu::PipelinePointer& DebugZoneLighting::getBackgroundPipeline() { void DebugZoneLighting::run(const render::RenderContextPointer& context, const Inputs& inputs) { RenderArgs* args = context->args; - auto deferredTransform = inputs; + auto deferredTransform = inputs.get0(); + auto lightFrame = inputs.get1(); + auto backgroundFrame = inputs.get2(); auto lightStage = context->_scene->getStage(LightStage::getName()); std::vector keyLightStack; - if (lightStage && lightStage->_currentFrame._sunLights.size()) { - for (auto index : lightStage->_currentFrame._sunLights) { + if (lightStage && lightFrame->_sunLights.size()) { + for (auto index : lightFrame->_sunLights) { keyLightStack.push_back(lightStage->getLight(index)); } } std::vector ambientLightStack; - if (lightStage && lightStage->_currentFrame._ambientLights.size()) { - for (auto index : lightStage->_currentFrame._ambientLights) { + if (lightStage && lightFrame->_ambientLights.size()) { + for (auto index : lightFrame->_ambientLights) { ambientLightStack.push_back(lightStage->getLight(index)); } } auto backgroundStage = context->_scene->getStage(BackgroundStage::getName()); std::vector skyboxStack; - if (backgroundStage && backgroundStage->_currentFrame._backgrounds.size()) { - for (auto index : backgroundStage->_currentFrame._backgrounds) { + if (backgroundStage && backgroundFrame->_backgrounds.size()) { + for (auto index : backgroundFrame->_backgrounds) { auto background = backgroundStage->getBackground(index); if (background) { skyboxStack.push_back(background->getSkybox()); @@ -158,7 +148,6 @@ void DebugZoneLighting::run(const render::RenderContextPointer& context, const I } } - gpu::doInBatch("DebugZoneLighting::run", args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); diff --git a/libraries/render-utils/src/ZoneRenderer.h b/libraries/render-utils/src/ZoneRenderer.h index 6e85243d1a..1646c5977d 100644 --- a/libraries/render-utils/src/ZoneRenderer.h +++ b/libraries/render-utils/src/ZoneRenderer.h @@ -16,6 +16,19 @@ #include "DeferredFrameTransform.h" +#include "LightStage.h" +#include "BackgroundStage.h" + +class SetupZones { +public: + using Inputs = render::ItemBounds; + using JobModel = render::Job::ModelI; + + SetupZones() {} + + void run(const render::RenderContextPointer& context, const Inputs& inputs); +}; + class ZoneRendererConfig : public render::Task::Config { Q_OBJECT Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty) @@ -44,7 +57,7 @@ public: ZoneRendererTask() {} - void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs); + void build(JobModel& task, const render::Varying& inputs, render::Varying& output); void configure(const Config& config) { _maxDrawn = config.maxDrawn; } @@ -59,7 +72,7 @@ public: Config(bool enabled = false) : JobConfig(enabled) {} }; - using Inputs = DeferredFrameTransformPointer; + using Inputs = render::VaryingSet3; using JobModel = render::Job::ModelI; DebugZoneLighting() {} diff --git a/libraries/script-engine/src/ModelScriptingInterface.cpp b/libraries/script-engine/src/ModelScriptingInterface.cpp index c693083ebf..1716ea72ff 100644 --- a/libraries/script-engine/src/ModelScriptingInterface.cpp +++ b/libraries/script-engine/src/ModelScriptingInterface.cpp @@ -192,7 +192,7 @@ QScriptValue ModelScriptingInterface::getVertex(MeshProxy* meshProxy, int vertex } glm::vec3 pos = vertexBufferView.get(vertexIndex); - return vec3toScriptValue(_modelScriptEngine, pos); + return vec3ToScriptValue(_modelScriptEngine, pos); } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 8cfd2b75cf..be1a9c20ef 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -679,9 +679,9 @@ void ScriptEngine::init() { qScriptRegisterSequenceMetaType>(this); qScriptRegisterSequenceMetaType>(this); - qScriptRegisterSequenceMetaType >(this); - qScriptRegisterSequenceMetaType >(this); - qScriptRegisterSequenceMetaType >(this); + qScriptRegisterSequenceMetaType>(this); + qScriptRegisterSequenceMetaType>(this); + qScriptRegisterSequenceMetaType>(this); QScriptValue xmlHttpRequestConstructorValue = newFunction(XMLHttpRequestClass::constructor); globalObject().setProperty("XMLHttpRequest", xmlHttpRequestConstructorValue); diff --git a/libraries/script-engine/src/SpatialEvent.cpp b/libraries/script-engine/src/SpatialEvent.cpp index d06cc556d3..8520c0c485 100644 --- a/libraries/script-engine/src/SpatialEvent.cpp +++ b/libraries/script-engine/src/SpatialEvent.cpp @@ -33,9 +33,9 @@ SpatialEvent::SpatialEvent(const SpatialEvent& event) { QScriptValue SpatialEvent::toScriptValue(QScriptEngine* engine, const SpatialEvent& event) { QScriptValue obj = engine->newObject(); - obj.setProperty("locTranslation", vec3toScriptValue(engine, event.locTranslation) ); + obj.setProperty("locTranslation", vec3ToScriptValue(engine, event.locTranslation) ); obj.setProperty("locRotation", quatToScriptValue(engine, event.locRotation) ); - obj.setProperty("absTranslation", vec3toScriptValue(engine, event.absTranslation) ); + obj.setProperty("absTranslation", vec3ToScriptValue(engine, event.absTranslation) ); obj.setProperty("absRotation", quatToScriptValue(engine, event.absRotation) ); return obj; diff --git a/libraries/script-engine/src/TouchEvent.cpp b/libraries/script-engine/src/TouchEvent.cpp index 6ff591decf..58ac9ec8c1 100644 --- a/libraries/script-engine/src/TouchEvent.cpp +++ b/libraries/script-engine/src/TouchEvent.cpp @@ -14,9 +14,10 @@ #include #include -#include #include +#include "RegisteredMetaTypes.h" + TouchEvent::TouchEvent() : x(0.0f), y(0.0f), @@ -220,7 +221,7 @@ QScriptValue TouchEvent::toScriptValue(QScriptEngine* engine, const TouchEvent& QScriptValue pointsObj = engine->newArray(); int index = 0; foreach (glm::vec2 point, event.points) { - QScriptValue thisPoint = vec2toScriptValue(engine, point); + QScriptValue thisPoint = vec2ToScriptValue(engine, point); pointsObj.setProperty(index, thisPoint); index++; } diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 696981d1b4..fe903c07e2 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -21,24 +21,6 @@ #include "GLMHelpers.h" -/**jsdoc - * A 3-dimensional vector. See also the {@link Vec3(0)|Vec3} object. - * - * @typedef {object} Vec3 - * @property {number} x - X-coordinate of the vector. - * @property {number} y - Y-coordinate of the vector. - * @property {number} z - Z-coordinate of the vector. - */ - -/**jsdoc - * A color vector. See also the {@link Vec3(0)|Vec3} object. - * - * @typedef {object} Vec3Color - * @property {number} x - Red component value. Integer in the range 0 - 255. - * @property {number} y - Green component value. Integer in the range 0 - 255. - * @property {number} z - Blue component value. Integer in the range 0 - 255. - */ - /**jsdoc * The Vec3 API facilities for generating and manipulating 3-dimensional vectors. High Fidelity uses a right-handed * Cartesian coordinate system where the y-axis is the "up" and the negative z-axis is the "front" direction. diff --git a/libraries/shared/src/BufferParser.h b/libraries/shared/src/BufferParser.h index 74b47cb72f..c73356558e 100644 --- a/libraries/shared/src/BufferParser.h +++ b/libraries/shared/src/BufferParser.h @@ -94,13 +94,6 @@ inline void BufferParser::readValue(QUuid& result) { readUuid(result); } -template<> -inline void BufferParser::readValue(xColor& result) { - readValue(result.red); - readValue(result.blue); - readValue(result.green); -} - template<> inline void BufferParser::readValue(QVector& result) { uint16_t length; readValue(length); diff --git a/libraries/shared/src/ColorUtils.h b/libraries/shared/src/ColorUtils.h index e113449db3..dd9fd8dcd6 100644 --- a/libraries/shared/src/ColorUtils.h +++ b/libraries/shared/src/ColorUtils.h @@ -22,7 +22,7 @@ extern const float srgbToLinearLookupTable[256]; class ColorUtils { public: - inline static glm::vec3 toVec3(const xColor& color); + inline static glm::vec3 toVec3(const glm::u8vec3& color); // Convert to gamma 2.2 space from linear inline static glm::vec3 toGamma22Vec3(const glm::vec3& linear); @@ -40,9 +40,9 @@ public: inline static float tosRGBFloat(const float& linear); }; -inline glm::vec3 ColorUtils::toVec3(const xColor& color) { +inline glm::vec3 ColorUtils::toVec3(const glm::u8vec3& color) { const float ONE_OVER_255 = 1.0f / 255.0f; - return glm::vec3(color.red * ONE_OVER_255, color.green * ONE_OVER_255, color.blue * ONE_OVER_255); + return glm::vec3(color.x * ONE_OVER_255, color.y * ONE_OVER_255, color.z * ONE_OVER_255); } inline glm::vec3 ColorUtils::toGamma22Vec3(const glm::vec3& linear) { diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index d324e5af10..1a62227c31 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -448,17 +448,16 @@ glm::vec2 toGlm(const QPointF& pt) { return glm::vec2(pt.x(), pt.y()); } -glm::vec3 toGlm(const xColor& color) { +glm::vec3 toGlm(const glm::u8vec3& color) { static const float MAX_COLOR = 255.0f; - return glm::vec3(color.red, color.green, color.blue) / MAX_COLOR; + return glm::vec3(color) / MAX_COLOR; } -xColor xColorFromGlm(const glm::vec3 & color) { +vec4 toGlm(const glm::u8vec3& color, float alpha) { static const float MAX_COLOR = 255.0f; - return { (uint8_t)(color.x * MAX_COLOR), (uint8_t)(color.y * MAX_COLOR), (uint8_t)(color.z * MAX_COLOR) }; + return vec4(glm::vec3(color) / MAX_COLOR, alpha); } - glm::vec4 toGlm(const QColor& color) { return glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()); } @@ -475,10 +474,6 @@ QSize fromGlm(const glm::ivec2 & v) { return QSize(v.x, v.y); } -vec4 toGlm(const xColor& color, float alpha) { - return vec4((float)color.red / 255.0f, (float)color.green / 255.0f, (float)color.blue / 255.0f, alpha); -} - QRectF glmToRect(const glm::vec2 & pos, const glm::vec2 & size) { QRectF result(pos.x, pos.y, size.x, size.y); return result; diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 96219ea48c..e7aaace1ae 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -24,6 +24,7 @@ using glm::ivec2; using glm::ivec3; using glm::ivec4; using glm::uvec2; +using glm::u8vec3; using glm::uvec3; using glm::uvec4; using glm::mat3; @@ -174,12 +175,10 @@ bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, f uvec2 toGlm(const QSize& size); ivec2 toGlm(const QPoint& pt); vec2 toGlm(const QPointF& pt); -vec3 toGlm(const xColor& color); +vec3 toGlm(const glm::u8vec3& color); vec4 toGlm(const QColor& color); ivec4 toGlm(const QRect& rect); -vec4 toGlm(const xColor& color, float alpha); - -xColor xColorFromGlm(const glm::vec3 & c); +vec4 toGlm(const glm::u8vec3& color, float alpha); QSize fromGlm(const glm::ivec2 & v); QMatrix4x4 fromGlm(const glm::mat4 & m); diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index e66121f159..60b426e46d 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -132,8 +132,6 @@ QUrl PathUtils::expandToLocalDataAbsolutePath(const QUrl& fileUrl) { return expandedURL; } - QUrl::fromLocalFile(resourcesPath()).toString(); - return fileUrl; } diff --git a/libraries/shared/src/QVariantGLM.cpp b/libraries/shared/src/QVariantGLM.cpp index f7fd7fbc8a..12c4628fbd 100644 --- a/libraries/shared/src/QVariantGLM.cpp +++ b/libraries/shared/src/QVariantGLM.cpp @@ -20,10 +20,6 @@ QVariantList quatToQList(const glm::quat& g) { return QVariantList() << g.x << g.y << g.z << g.w; } -QVariantList rgbColorToQList(const rgbColor& v) { - return QVariantList() << (int)(v[0]) << (int)(v[1]) << (int)(v[2]); -} - QVariantMap vec3ToQMap(const glm::vec3& glmVector) { QVariantMap vectorAsVariantMap; vectorAsVariantMap["x"] = glmVector.x; @@ -56,14 +52,6 @@ glm::quat qListToQuat(const QVariant& q) { return glm::quat(w, x, y, z); } -void qListToRgbColor(const QVariant& q, rgbColor& returnValue) { - QVariantList qList = q.toList(); - returnValue[RED_INDEX] = qList[RED_INDEX].toInt(); - returnValue[GREEN_INDEX] = qList[GREEN_INDEX].toInt(); - returnValue[BLUE_INDEX] = qList[BLUE_INDEX].toInt(); -} - - glm::vec3 qMapToVec3(const QVariant& q) { QVariantMap qMap = q.toMap(); if (qMap.contains("x") && qMap.contains("y") && qMap.contains("z")) { diff --git a/libraries/shared/src/QVariantGLM.h b/libraries/shared/src/QVariantGLM.h index a8f8b531c0..d61f64312a 100644 --- a/libraries/shared/src/QVariantGLM.h +++ b/libraries/shared/src/QVariantGLM.h @@ -19,14 +19,12 @@ QVariantList vec3ToQList(const glm::vec3& g); QVariantList quatToQList(const glm::quat& g); -QVariantList rgbColorToQList(const rgbColor& v); QVariantMap vec3ToQMap(const glm::vec3& glmVector); QVariantMap quatToQMap(const glm::quat& glmQuat); glm::vec3 qListToVec3(const QVariant& q); glm::quat qListToQuat(const QVariant& q); -void qListToRgbColor(const QVariant& q, rgbColor& returnValue); glm::vec3 qMapToVec3(const QVariant& q); glm::quat qMapToQuat(const QVariant& q); diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 0c8f4f0466..dc84afff93 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -25,14 +25,14 @@ #include #include -int vec4MetaTypeId = qRegisterMetaType(); +int vec2MetaTypeId = qRegisterMetaType(); +int u8vec3MetaTypeId = qRegisterMetaType(); int vec3MetaTypeId = qRegisterMetaType(); +int vec4MetaTypeId = qRegisterMetaType(); int qVectorVec3MetaTypeId = qRegisterMetaType>(); int qVectorQuatMetaTypeId = qRegisterMetaType>(); int qVectorBoolMetaTypeId = qRegisterMetaType>(); -int vec2MetaTypeId = qRegisterMetaType(); int quatMetaTypeId = qRegisterMetaType(); -int xColorMetaTypeId = qRegisterMetaType(); int pickRayMetaTypeId = qRegisterMetaType(); int collisionMetaTypeId = qRegisterMetaType(); int qMapURLStringMetaTypeId = qRegisterMetaType>(); @@ -41,27 +41,560 @@ int voidLambdaType = qRegisterMetaType>(); int variantLambdaType = qRegisterMetaType>(); void registerMetaTypes(QScriptEngine* engine) { - qScriptRegisterMetaType(engine, mat4toScriptValue, mat4FromScriptValue); + qScriptRegisterMetaType(engine, vec2ToScriptValue, vec2FromScriptValue); + qScriptRegisterMetaType(engine, vec3ToScriptValue, vec3FromScriptValue); + qScriptRegisterMetaType(engine, u8vec3ToScriptValue, u8vec3FromScriptValue); qScriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue); - qScriptRegisterMetaType(engine, vec3toScriptValue, vec3FromScriptValue); + qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue); + qScriptRegisterMetaType(engine, mat4toScriptValue, mat4FromScriptValue); + qScriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue); qScriptRegisterMetaType(engine, qVectorQuatToScriptValue, qVectorQuatFromScriptValue); qScriptRegisterMetaType(engine, qVectorBoolToScriptValue, qVectorBoolFromScriptValue); qScriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue); qScriptRegisterMetaType(engine, qVectorIntToScriptValue, qVectorIntFromScriptValue); - qScriptRegisterMetaType(engine, vec2toScriptValue, vec2FromScriptValue); - qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue); + + qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); qScriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue); - qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue); - qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue); qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue); + qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue); + qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue); qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); - qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); qScriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue); } +QScriptValue vec2ToScriptValue(QScriptEngine* engine, const glm::vec2& vec2) { + auto prototype = engine->globalObject().property("__hifi_vec2__"); + if (!prototype.property("defined").toBool()) { + prototype = engine->evaluate( + "__hifi_vec2__ = Object.defineProperties({}, { " + "defined: { value: true }," + "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "u: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "v: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }" + "})" + ); + } + QScriptValue value = engine->newObject(); + value.setProperty("x", vec2.x); + value.setProperty("y", vec2.y); + value.setPrototype(prototype); + return value; +} + +void vec2FromScriptValue(const QScriptValue& object, glm::vec2& vec2) { + if (object.isNumber()) { + vec2 = glm::vec2(object.toVariant().toFloat()); + } else if (object.isArray()) { + QVariantList list = object.toVariant().toList(); + if (list.length() == 2) { + vec2.x = list[0].toFloat(); + vec2.y = list[1].toFloat(); + } + } else { + QScriptValue x = object.property("x"); + if (!x.isValid()) { + x = object.property("u"); + } + + QScriptValue y = object.property("y"); + if (!y.isValid()) { + y = object.property("v"); + } + + vec2.x = x.toVariant().toFloat(); + vec2.y = y.toVariant().toFloat(); + } +} + +QVariant vec2ToVariant(const glm::vec2 &vec2) { + if (vec2.x != vec2.x || vec2.y != vec2.y) { + // if vec2 contains a NaN don't try to convert it + return QVariant(); + } + QVariantMap result; + result["x"] = vec2.x; + result["y"] = vec2.y; + return result; +} + +glm::vec2 vec2FromVariant(const QVariant &object, bool& isValid) { + isValid = false; + glm::vec2 result; + if (object.canConvert()) { + result = glm::vec2(object.toFloat()); + isValid = true; + } else if (object.canConvert()) { + auto qvec2 = qvariant_cast(object); + result.x = qvec2.x(); + result.y = qvec2.y(); + isValid = true; + } else { + auto map = object.toMap(); + auto x = map["x"]; + if (!x.isValid()) { + x = map["u"]; + } + + auto y = map["y"]; + if (!y.isValid()) { + y = map["v"]; + } + + if (x.isValid() && y.isValid()) { + result.x = x.toFloat(&isValid); + if (isValid) { + result.y = y.toFloat(&isValid); + } + } + } + return result; +} + +glm::vec2 vec2FromVariant(const QVariant &object) { + bool valid; + return vec2FromVariant(object, valid); +} + +QScriptValue vec3ToScriptValue(QScriptEngine* engine, const glm::vec3& vec3) { + auto prototype = engine->globalObject().property("__hifi_vec3__"); + if (!prototype.property("defined").toBool()) { + prototype = engine->evaluate( + "__hifi_vec3__ = Object.defineProperties({}, { " + "defined: { value: true }," + "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," + "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," + "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" + "})" + ); + } + QScriptValue value = engine->newObject(); + value.setProperty("x", vec3.x); + value.setProperty("y", vec3.y); + value.setProperty("z", vec3.z); + value.setPrototype(prototype); + return value; +} + +QScriptValue vec3ColorToScriptValue(QScriptEngine* engine, const glm::vec3& vec3) { + auto prototype = engine->globalObject().property("__hifi_vec3_color__"); + if (!prototype.property("defined").toBool()) { + prototype = engine->evaluate( + "__hifi_vec3_color__ = Object.defineProperties({}, { " + "defined: { value: true }," + "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," + "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," + "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" + "})" + ); + } + QScriptValue value = engine->newObject(); + value.setProperty("red", vec3.x); + value.setProperty("green", vec3.y); + value.setProperty("blue", vec3.z); + value.setPrototype(prototype); + return value; +} + +void vec3FromScriptValue(const QScriptValue& object, glm::vec3& vec3) { + if (object.isNumber()) { + vec3 = glm::vec3(object.toVariant().toFloat()); + } else if (object.isString()) { + QColor qColor(object.toString()); + if (qColor.isValid()) { + vec3.x = qColor.red(); + vec3.y = qColor.green(); + vec3.z = qColor.blue(); + } + } else if (object.isArray()) { + QVariantList list = object.toVariant().toList(); + if (list.length() == 3) { + vec3.x = list[0].toFloat(); + vec3.y = list[1].toFloat(); + vec3.z = list[2].toFloat(); + } + } else { + QScriptValue x = object.property("x"); + if (!x.isValid()) { + x = object.property("r"); + } + if (!x.isValid()) { + x = object.property("red"); + } + + QScriptValue y = object.property("y"); + if (!y.isValid()) { + y = object.property("g"); + } + if (!y.isValid()) { + y = object.property("green"); + } + + QScriptValue z = object.property("z"); + if (!z.isValid()) { + z = object.property("b"); + } + if (!z.isValid()) { + z = object.property("blue"); + } + + vec3.x = x.toVariant().toFloat(); + vec3.y = y.toVariant().toFloat(); + vec3.z = z.toVariant().toFloat(); + } +} + +QScriptValue u8vec3ToScriptValue(QScriptEngine* engine, const glm::u8vec3& vec3) { + auto prototype = engine->globalObject().property("__hifi_u8vec3__"); + if (!prototype.property("defined").toBool()) { + prototype = engine->evaluate( + "__hifi_u8vec3__ = Object.defineProperties({}, { " + "defined: { value: true }," + "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," + "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," + "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," + "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," + "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" + "})" + ); + } + QScriptValue value = engine->newObject(); + value.setProperty("x", vec3.x); + value.setProperty("y", vec3.y); + value.setProperty("z", vec3.z); + value.setPrototype(prototype); + return value; +} + +QScriptValue u8vec3ColorToScriptValue(QScriptEngine* engine, const glm::u8vec3& vec3) { + auto prototype = engine->globalObject().property("__hifi_u8vec3_color__"); + if (!prototype.property("defined").toBool()) { + prototype = engine->evaluate( + "__hifi_u8vec3_color__ = Object.defineProperties({}, { " + "defined: { value: true }," + "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," + "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," + "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," + "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," + "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" + "})" + ); + } + QScriptValue value = engine->newObject(); + value.setProperty("red", vec3.x); + value.setProperty("green", vec3.y); + value.setProperty("blue", vec3.z); + value.setPrototype(prototype); + return value; +} + +void u8vec3FromScriptValue(const QScriptValue& object, glm::u8vec3& vec3) { + if (object.isNumber()) { + vec3 = glm::vec3(object.toVariant().toUInt()); + } else if (object.isString()) { + QColor qColor(object.toString()); + if (qColor.isValid()) { + vec3.x = (uint8_t)qColor.red(); + vec3.y = (uint8_t)qColor.green(); + vec3.z = (uint8_t)qColor.blue(); + } + } else if (object.isArray()) { + QVariantList list = object.toVariant().toList(); + if (list.length() == 3) { + vec3.x = list[0].toUInt(); + vec3.y = list[1].toUInt(); + vec3.z = list[2].toUInt(); + } + } else { + QScriptValue x = object.property("x"); + if (!x.isValid()) { + x = object.property("r"); + } + if (!x.isValid()) { + x = object.property("red"); + } + + QScriptValue y = object.property("y"); + if (!y.isValid()) { + y = object.property("g"); + } + if (!y.isValid()) { + y = object.property("green"); + } + + QScriptValue z = object.property("z"); + if (!z.isValid()) { + z = object.property("b"); + } + if (!z.isValid()) { + z = object.property("blue"); + } + + vec3.x = x.toVariant().toUInt(); + vec3.y = y.toVariant().toUInt(); + vec3.z = z.toVariant().toUInt(); + } +} + +QVariant vec3toVariant(const glm::vec3& vec3) { + if (vec3.x != vec3.x || vec3.y != vec3.y || vec3.z != vec3.z) { + // if vec3 contains a NaN don't try to convert it + return QVariant(); + } + QVariantMap result; + result["x"] = vec3.x; + result["y"] = vec3.y; + result["z"] = vec3.z; + return result; +} + +glm::vec3 vec3FromVariant(const QVariant& object, bool& valid) { + glm::vec3 v; + valid = false; + if (!object.isValid() || object.isNull()) { + return v; + } else if (object.canConvert()) { + v = glm::vec3(object.toFloat()); + valid = true; + } else if (object.canConvert()) { + auto qvec3 = qvariant_cast(object); + v.x = qvec3.x(); + v.y = qvec3.y(); + v.z = qvec3.z(); + valid = true; + } else if (object.canConvert()) { + QColor qColor(object.toString()); + if (qColor.isValid()) { + v.x = (uint8_t)qColor.red(); + v.y = (uint8_t)qColor.green(); + v.z = (uint8_t)qColor.blue(); + valid = true; + } + } else if (object.canConvert()) { + QColor qColor = qvariant_cast(object); + if (qColor.isValid()) { + v.x = (uint8_t)qColor.red(); + v.y = (uint8_t)qColor.green(); + v.z = (uint8_t)qColor.blue(); + valid = true; + } + } else { + auto map = object.toMap(); + auto x = map["x"]; + if (!x.isValid()) { + x = map["r"]; + } + if (!x.isValid()) { + x = map["red"]; + } + + auto y = map["y"]; + if (!y.isValid()) { + y = map["g"]; + } + if (!y.isValid()) { + y = map["green"]; + } + + auto z = map["z"]; + if (!z.isValid()) { + z = map["b"]; + } + if (!z.isValid()) { + z = map["blue"]; + } + + if (x.canConvert() && y.canConvert() && z.canConvert()) { + v.x = x.toFloat(); + v.y = y.toFloat(); + v.z = z.toFloat(); + valid = true; + } + } + return v; +} + +glm::vec3 vec3FromVariant(const QVariant& object) { + bool valid = false; + return vec3FromVariant(object, valid); +} + +QVariant u8vec3toVariant(const glm::u8vec3& vec3) { + QVariantMap result; + result["x"] = vec3.x; + result["y"] = vec3.y; + result["z"] = vec3.z; + return result; +} + +QVariant u8vec3ColortoVariant(const glm::u8vec3& vec3) { + QVariantMap result; + result["red"] = vec3.x; + result["green"] = vec3.y; + result["blue"] = vec3.z; + return result; +} + +glm::u8vec3 u8vec3FromVariant(const QVariant& object, bool& valid) { + glm::u8vec3 v; + valid = false; + if (!object.isValid() || object.isNull()) { + return v; + } else if (object.canConvert()) { + v = glm::vec3(object.toUInt()); + valid = true; + } else if (object.canConvert()) { + auto qvec3 = qvariant_cast(object); + v.x = (uint8_t)qvec3.x(); + v.y = (uint8_t)qvec3.y(); + v.z = (uint8_t)qvec3.z(); + valid = true; + } else if (object.canConvert()) { + QColor qColor(object.toString()); + if (qColor.isValid()) { + v.x = (uint8_t)qColor.red(); + v.y = (uint8_t)qColor.green(); + v.z = (uint8_t)qColor.blue(); + valid = true; + } + } else if (object.canConvert()) { + QColor qColor = qvariant_cast(object); + if (qColor.isValid()) { + v.x = (uint8_t)qColor.red(); + v.y = (uint8_t)qColor.green(); + v.z = (uint8_t)qColor.blue(); + valid = true; + } + } else { + auto map = object.toMap(); + auto x = map["x"]; + if (!x.isValid()) { + x = map["r"]; + } + if (!x.isValid()) { + x = map["red"]; + } + + auto y = map["y"]; + if (!y.isValid()) { + y = map["g"]; + } + if (!y.isValid()) { + y = map["green"]; + } + + auto z = map["z"]; + if (!z.isValid()) { + z = map["b"]; + } + if (!z.isValid()) { + z = map["blue"]; + } + + if (x.canConvert() && y.canConvert() && z.canConvert()) { + v.x = x.toUInt(); + v.y = y.toUInt(); + v.z = z.toUInt(); + valid = true; + } + } + return v; +} + +glm::u8vec3 u8vec3FromVariant(const QVariant& object) { + bool valid = false; + return u8vec3FromVariant(object, valid); +} + +QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) { + QScriptValue obj = engine->newObject(); + obj.setProperty("x", vec4.x); + obj.setProperty("y", vec4.y); + obj.setProperty("z", vec4.z); + obj.setProperty("w", vec4.w); + return obj; +} + +void vec4FromScriptValue(const QScriptValue& object, glm::vec4& vec4) { + vec4.x = object.property("x").toVariant().toFloat(); + vec4.y = object.property("y").toVariant().toFloat(); + vec4.z = object.property("z").toVariant().toFloat(); + vec4.w = object.property("w").toVariant().toFloat(); +} + +QVariant vec4toVariant(const glm::vec4& vec4) { + if (isNaN(vec4.x) || isNaN(vec4.y) || isNaN(vec4.z) || isNaN(vec4.w)) { + // if vec4 contains a NaN don't try to convert it + return QVariant(); + } + QVariantMap result; + result["x"] = vec4.x; + result["y"] = vec4.y; + result["z"] = vec4.z; + result["w"] = vec4.w; + return result; +} + +glm::vec4 vec4FromVariant(const QVariant& object, bool& valid) { + glm::vec4 v; + valid = false; + if (!object.isValid() || object.isNull()) { + return v; + } else if (object.canConvert()) { + v = glm::vec4(object.toFloat()); + valid = true; + } else if (object.canConvert()) { + auto qvec4 = qvariant_cast(object); + v.x = qvec4.x(); + v.y = qvec4.y(); + v.z = qvec4.z(); + v.w = qvec4.w(); + valid = true; + } else { + auto map = object.toMap(); + auto x = map["x"]; + auto y = map["y"]; + auto z = map["z"]; + auto w = map["w"]; + if (x.canConvert() && y.canConvert() && z.canConvert() && w.canConvert()) { + v.x = x.toFloat(); + v.y = y.toFloat(); + v.z = z.toFloat(); + v.w = w.toFloat(); + valid = true; + } + } + return v; +} + +glm::vec4 vec4FromVariant(const QVariant& object) { + bool valid = false; + return vec4FromVariant(object, valid); +} + QScriptValue mat4toScriptValue(QScriptEngine* engine, const glm::mat4& mat4) { QScriptValue obj = engine->newObject(); obj.setProperty("r0c0", mat4[0][0]); @@ -102,168 +635,42 @@ void mat4FromScriptValue(const QScriptValue& object, glm::mat4& mat4) { mat4[3][3] = object.property("r3c3").toVariant().toFloat(); } -QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) { - QScriptValue obj = engine->newObject(); - obj.setProperty("x", vec4.x); - obj.setProperty("y", vec4.y); - obj.setProperty("z", vec4.z); - obj.setProperty("w", vec4.w); - return obj; -} - -void vec4FromScriptValue(const QScriptValue& object, glm::vec4& vec4) { - vec4.x = object.property("x").toVariant().toFloat(); - vec4.y = object.property("y").toVariant().toFloat(); - vec4.z = object.property("z").toVariant().toFloat(); - vec4.w = object.property("w").toVariant().toFloat(); -} - -QScriptValue vec3toScriptValue(QScriptEngine* engine, const glm::vec3 &vec3) { - QScriptValue obj = engine->newObject(); - if (vec3.x != vec3.x || vec3.y != vec3.y || vec3.z != vec3.z) { - // if vec3 contains a NaN don't try to convert it - return obj; +QScriptValue qVectorVec3ColorToScriptValue(QScriptEngine* engine, const QVector& vector) { + QScriptValue array = engine->newArray(); + for (int i = 0; i < vector.size(); i++) { + array.setProperty(i, vec3ColorToScriptValue(engine, vector.at(i))); } - obj.setProperty("x", vec3.x); - obj.setProperty("y", vec3.y); - obj.setProperty("z", vec3.z); - obj.setProperty("red", vec3.x); - obj.setProperty("green", vec3.y); - obj.setProperty("blue", vec3.z); - return obj; -} - -void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3) { - auto x = object.property("x").toVariant(); - if (!x.isValid()) { - x = object.property("red").toVariant(); - } - auto y = object.property("y").toVariant(); - if (!y.isValid()) { - y = object.property("green").toVariant(); - } - auto z = object.property("z").toVariant(); - if (!z.isValid()) { - z = object.property("blue").toVariant(); - } - vec3.x = x.toFloat(); - vec3.y = y.toFloat(); - vec3.z = z.toFloat(); -} - -QVariant vec3toVariant(const glm::vec3& vec3) { - if (vec3.x != vec3.x || vec3.y != vec3.y || vec3.z != vec3.z) { - // if vec3 contains a NaN don't try to convert it - return QVariant(); - } - QVariantMap result; - result["x"] = vec3.x; - result["y"] = vec3.y; - result["z"] = vec3.z; - return result; -} - -QVariant vec4toVariant(const glm::vec4& vec4) { - if (isNaN(vec4.x) || isNaN(vec4.y) || isNaN(vec4.z) || isNaN(vec4.w)) { - // if vec4 contains a NaN don't try to convert it - return QVariant(); - } - QVariantMap result; - result["x"] = vec4.x; - result["y"] = vec4.y; - result["z"] = vec4.z; - result["w"] = vec4.w; - return result; + return array; } QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector& vector) { QScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { - array.setProperty(i, vec3toScriptValue(engine, vector.at(i))); + array.setProperty(i, vec3ToScriptValue(engine, vector.at(i))); } return array; } +QVector qVectorVec3FromScriptValue(const QScriptValue& array) { + QVector newVector; + int length = array.property("length").toInteger(); -glm::vec3 vec3FromVariant(const QVariant& object, bool& valid) { - glm::vec3 v; - valid = false; - if (!object.isValid() || object.isNull()) { - return v; - } else if (object.canConvert()) { - v = glm::vec3(object.toFloat()); - valid = true; - } else if (object.canConvert()) { - auto qvec3 = qvariant_cast(object); - v.x = qvec3.x(); - v.y = qvec3.y(); - v.z = qvec3.z(); - valid = true; - } else { - auto map = object.toMap(); - auto x = map["x"]; - auto y = map["y"]; - auto z = map["z"]; - if (!x.isValid()) { - x = map["width"]; - } - if (!y.isValid()) { - y = map["height"]; - } - if (!y.isValid()) { - z = map["depth"]; - } - - if (x.canConvert() && y.canConvert() && z.canConvert()) { - v.x = x.toFloat(); - v.y = y.toFloat(); - v.z = z.toFloat(); - valid = true; - } + for (int i = 0; i < length; i++) { + glm::vec3 newVec3 = glm::vec3(); + vec3FromScriptValue(array.property(i), newVec3); + newVector << newVec3; } - return v; + return newVector; } -glm::vec3 vec3FromVariant(const QVariant& object) { - bool valid = false; - return vec3FromVariant(object, valid); -} +void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& vector) { + int length = array.property("length").toInteger(); -glm::vec4 vec4FromVariant(const QVariant& object, bool& valid) { - glm::vec4 v; - valid = false; - if (!object.isValid() || object.isNull()) { - return v; - } else if (object.canConvert()) { - v = glm::vec4(object.toFloat()); - valid = true; - } else if (object.canConvert()) { - auto qvec4 = qvariant_cast(object); - v.x = qvec4.x(); - v.y = qvec4.y(); - v.z = qvec4.z(); - v.w = qvec4.w(); - valid = true; - } else { - auto map = object.toMap(); - auto x = map["x"]; - auto y = map["y"]; - auto z = map["z"]; - auto w = map["w"]; - if (x.canConvert() && y.canConvert() && z.canConvert() && w.canConvert()) { - v.x = x.toFloat(); - v.y = y.toFloat(); - v.z = z.toFloat(); - v.w = w.toFloat(); - valid = true; - } + for (int i = 0; i < length; i++) { + glm::vec3 newVec3 = glm::vec3(); + vec3FromScriptValue(array.property(i), newVec3); + vector << newVec3; } - return v; -} - -glm::vec4 vec4FromVariant(const QVariant& object) { - bool valid = false; - return vec4FromVariant(object, valid); } QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat) { @@ -297,11 +704,11 @@ void quatFromScriptValue(const QScriptValue& object, glm::quat &quat) { glm::quat quatFromVariant(const QVariant &object, bool& isValid) { glm::quat q; if (object.canConvert()) { - auto qvec3 = qvariant_cast(object); - q.x = qvec3.x(); - q.y = qvec3.y(); - q.z = qvec3.z(); - q.w = qvec3.scalar(); + auto qquat = qvariant_cast(object); + q.x = qquat.x(); + q.y = qquat.y(); + q.z = qquat.z(); + q.w = qquat.scalar(); // enforce normalized quaternion float length = glm::length(q); @@ -340,7 +747,7 @@ glm::quat quatFromVariant(const QVariant& object) { QVariant quatToVariant(const glm::quat& quat) { if (quat.x != quat.x || quat.y != quat.y || quat.z != quat.z) { - // if vec3 contains a NaN don't try to convert it + // if quat contains a NaN don't try to convert it return QVariant(); } QVariantMap result; @@ -432,29 +839,6 @@ void qVectorIntFromScriptValue(const QScriptValue& array, QVector& vec } } -// -QVector qVectorVec3FromScriptValue(const QScriptValue& array){ - QVector newVector; - int length = array.property("length").toInteger(); - - for (int i = 0; i < length; i++) { - glm::vec3 newVec3 = glm::vec3(); - vec3FromScriptValue(array.property(i), newVec3); - newVector << newVec3; - } - return newVector; -} - -void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& vector ) { - int length = array.property("length").toInteger(); - - for (int i = 0; i < length; i++) { - glm::vec3 newVec3 = glm::vec3(); - vec3FromScriptValue(array.property(i), newVec3); - vector << newVec3; - } -} - QVector qVectorQuatFromScriptValue(const QScriptValue& array){ QVector newVector; int length = array.property("length").toInteger(); @@ -495,71 +879,6 @@ void qVectorBoolFromScriptValue(const QScriptValue& array, QVector& vector } } -QScriptValue vec2toScriptValue(QScriptEngine* engine, const glm::vec2 &vec2) { - QScriptValue obj = engine->newObject(); - obj.setProperty("x", vec2.x); - obj.setProperty("y", vec2.y); - return obj; -} - -void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2) { - vec2.x = object.property("x").toVariant().toFloat(); - vec2.y = object.property("y").toVariant().toFloat(); -} - -QVariant vec2toVariant(const glm::vec2 &vec2) { - if (vec2.x != vec2.x || vec2.y != vec2.y) { - // if vec2 contains a NaN don't try to convert it - return QVariant(); - } - QVariantMap result; - result["x"] = vec2.x; - result["y"] = vec2.y; - return result; -} - -glm::vec2 vec2FromVariant(const QVariant &object, bool& isValid) { - isValid = false; - glm::vec2 result; - if (object.canConvert()) { - result = glm::vec2(object.toFloat()); - } else if (object.canConvert()) { - auto qvec2 = qvariant_cast(object); - result.x = qvec2.x(); - result.y = qvec2.y(); - } else { - auto map = object.toMap(); - auto x = map["x"]; - if (!x.isValid()) { - x = map["width"]; - } - auto y = map["y"]; - if (!y.isValid()) { - y = map["height"]; - } - if (x.isValid() && y.isValid()) { - result.x = x.toFloat(&isValid); - if (isValid) { - result.y = y.toFloat(&isValid); - } - } - } - return result; -} - -glm::vec2 vec2FromVariant(const QVariant &object) { - bool valid; - return vec2FromVariant(object, valid); -} - -/**jsdoc - * Defines a rectangular portion of an image or screen, or similar. - * @typedef {object} Rect - * @property {number} x - Left, x-coordinate value. - * @property {number} y - Top, y-coordinate value. - * @property {number} width - Width of the rectangle. - * @property {number} height - Height of the rectangle. - */ QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect) { QScriptValue obj = engine->newObject(); obj.setProperty("x", rect.x()); @@ -654,94 +973,6 @@ QRectF qRectFFromVariant(const QVariant& object) { return qRectFFromVariant(object, valid); } - -QScriptValue xColorToScriptValue(QScriptEngine *engine, const xColor& color) { - QScriptValue obj = engine->newObject(); - obj.setProperty("red", color.red); - obj.setProperty("green", color.green); - obj.setProperty("blue", color.blue); - return obj; -} - -void xColorFromScriptValue(const QScriptValue &object, xColor& color) { - if (!object.isValid()) { - return; - } - if (object.isNumber()) { - color.red = color.green = color.blue = (uint8_t)object.toUInt32(); - } else if (object.isString()) { - QColor qcolor(object.toString()); - if (qcolor.isValid()) { - color.red = (uint8_t)qcolor.red(); - color.blue = (uint8_t)qcolor.blue(); - color.green = (uint8_t)qcolor.green(); - } - } else { - color.red = object.property("red").toVariant().toInt(); - color.green = object.property("green").toVariant().toInt(); - color.blue = object.property("blue").toVariant().toInt(); - } -} - -/**jsdoc - * An RGB color value. - * @typedef {object} Color - * @property {number} red - Red component value. Integer in the range 0 - 255. - * @property {number} green - Green component value. Integer in the range 0 - 255. - * @property {number} blue - Blue component value. Integer in the range 0 - 255. - */ -QVariant xColorToVariant(const xColor& color) { - QVariantMap obj; - obj["red"] = color.red; - obj["green"] = color.green; - obj["blue"] = color.blue; - return obj; -} - -xColor xColorFromVariant(const QVariant &object, bool& isValid) { - isValid = false; - xColor color { 0, 0, 0 }; - if (!object.isValid()) { - return color; - } - if (object.canConvert()) { - isValid = true; - color.red = color.green = color.blue = (uint8_t)object.toInt(); - } else if (object.canConvert()) { - QColor qcolor(object.toString()); - if (qcolor.isValid()) { - isValid = true; - color.red = (uint8_t)qcolor.red(); - color.blue = (uint8_t)qcolor.blue(); - color.green = (uint8_t)qcolor.green(); - } - } else if (object.canConvert()) { - QColor qcolor = qvariant_cast(object); - if (qcolor.isValid()) { - isValid = true; - color.red = (uint8_t)qcolor.red(); - color.blue = (uint8_t)qcolor.blue(); - color.green = (uint8_t)qcolor.green(); - } - } else { - QVariantMap map = object.toMap(); - color.red = map["red"].toInt(&isValid); - if (isValid) { - color.green = map["green"].toInt(&isValid); - } - if (isValid) { - color.blue = map["blue"].toInt(&isValid); - } - } - return color; -} - -xColor xColorFromVariant(const QVariant &object) { - bool valid; - return xColorFromVariant(object, valid); -} - - QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color) { QScriptValue object = engine->newObject(); object.setProperty("red", color.red()); @@ -804,9 +1035,9 @@ void qURLFromScriptValue(const QScriptValue& object, QUrl& url) { QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) { QScriptValue obj = engine->newObject(); - QScriptValue origin = vec3toScriptValue(engine, pickRay.origin); + QScriptValue origin = vec3ToScriptValue(engine, pickRay.origin); obj.setProperty("origin", origin); - QScriptValue direction = vec3toScriptValue(engine, pickRay.direction); + QScriptValue direction = vec3ToScriptValue(engine, pickRay.direction); obj.setProperty("direction", direction); return obj; } @@ -850,9 +1081,9 @@ QScriptValue collisionToScriptValue(QScriptEngine* engine, const Collision& coll obj.setProperty("type", collision.type); obj.setProperty("idA", quuidToScriptValue(engine, collision.idA)); obj.setProperty("idB", quuidToScriptValue(engine, collision.idB)); - obj.setProperty("penetration", vec3toScriptValue(engine, collision.penetration)); - obj.setProperty("contactPoint", vec3toScriptValue(engine, collision.contactPoint)); - obj.setProperty("velocityChange", vec3toScriptValue(engine, collision.velocityChange)); + obj.setProperty("penetration", vec3ToScriptValue(engine, collision.penetration)); + obj.setProperty("contactPoint", vec3ToScriptValue(engine, collision.contactPoint)); + obj.setProperty("velocityChange", vec3ToScriptValue(engine, collision.velocityChange)); return obj; } diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 9379269d13..64a874f63d 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -29,13 +29,12 @@ class QColor; class QUrl; -Q_DECLARE_METATYPE(glm::vec4) -Q_DECLARE_METATYPE(glm::vec3) Q_DECLARE_METATYPE(glm::vec2) +Q_DECLARE_METATYPE(glm::u8vec3) +Q_DECLARE_METATYPE(glm::vec3) +Q_DECLARE_METATYPE(glm::vec4) Q_DECLARE_METATYPE(glm::quat) Q_DECLARE_METATYPE(glm::mat4) -Q_DECLARE_METATYPE(xColor) -Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(AACube) Q_DECLARE_METATYPE(std::function); @@ -47,6 +46,101 @@ void registerMetaTypes(QScriptEngine* engine); QScriptValue mat4toScriptValue(QScriptEngine* engine, const glm::mat4& mat4); void mat4FromScriptValue(const QScriptValue& object, glm::mat4& mat4); +/**jsdoc +* A 2-dimensional vector. +* +* @typedef {object} Vec2 +* @property {number} x - X-coordinate of the vector. Synonyms: u. +* @property {number} y - Y-coordinate of the vector. Synonyms: v. +* @example Vec2s can be set in multiple ways and modified with their aliases, but still stringify in the same way +* Entities.editEntity(, { materialMappingPos: { x: 0.1, y: 0.2 }}); // { x: 0.1, y: 0.2 } +* Entities.editEntity(, { materialMappingPos: { u: 0.3, v: 0.4 }}); // { x: 0.3, y: 0.4 } +* Entities.editEntity(, { materialMappingPos: [0.5, 0.6] }); // { x: 0.5, y: 0.6 } +* Entities.editEntity(, { materialMappingPos: 0.7 }); // { x: 0.7, y: 0.7 } +* var color = Entities.getEntityProperties().materialMappingPos; // { x: 0.7, y: 0.7 } +* color.v = 0.8; // { x: 0.7, y: 0.8 } +*/ +QScriptValue vec2ToScriptValue(QScriptEngine* engine, const glm::vec2& vec2); +void vec2FromScriptValue(const QScriptValue& object, glm::vec2& vec2); + +QVariant vec2ToVariant(const glm::vec2& vec2); +glm::vec2 vec2FromVariant(const QVariant& object, bool& valid); +glm::vec2 vec2FromVariant(const QVariant& object); + +/**jsdoc +* A 3-dimensional vector. See also the {@link Vec3(0)|Vec3} object. +* +* @typedef {object} Vec3 +* @property {number} x - X-coordinate of the vector. Synonyms: r, red. +* @property {number} y - Y-coordinate of the vector. Synonyms: g, green. +* @property {number} z - Z-coordinate of the vector. Synonyms: b, blue. +* @example Vec3s can be set in multiple ways and modified with their aliases, but still stringify in the same way +* Entities.editEntity(, { position: { x: 1, y: 2, z: 3 }}); // { x: 1, y: 2, z: 3 } +* Entities.editEntity(, { position: { r: 4, g: 5, b: 6 }}); // { x: 4, y: 5, z: 6 } +* Entities.editEntity(, { position: { red: 7, green: 8, blue: 9 }}); // { x: 7, y: 8, z: 9 } +* Entities.editEntity(, { position: [10, 11, 12] }); // { x: 10, y: 11, z: 12 } +* Entities.editEntity(, { position: 13 }); // { x: 13, y: 13, z: 13 } +* var position = Entities.getEntityProperties().position; // { x: 13, y: 13, z: 13 } +* position.g = 14; // { x: 13, y: 14, z: 13 } +* position.blue = 15; // { x: 13, y: 14, z: 15 } +* Entities.editEntity(, { position: "red"}); // { x: 255, y: 0, z: 0 } +* Entities.editEntity(, { position: "#00FF00"}); // { x: 0, y: 255, z: 0 } +*/ +QScriptValue vec3ToScriptValue(QScriptEngine* engine, const glm::vec3& vec3); +QScriptValue vec3ColorToScriptValue(QScriptEngine* engine, const glm::vec3& vec3); +void vec3FromScriptValue(const QScriptValue& object, glm::vec3& vec3); + +QVariant vec3toVariant(const glm::vec3& vec3); +glm::vec3 vec3FromVariant(const QVariant &object, bool& valid); +glm::vec3 vec3FromVariant(const QVariant &object); + +/**jsdoc +* A color vector. See also the {@link Vec3(0)|Vec3} object. +* +* @typedef {object} Color +* @property {number} red - Red component value. Integer in the range 0 - 255. Synonyms: r, x. +* @property {number} green - Green component value. Integer in the range 0 - 255. Synonyms: g, y. +* @property {number} blue - Blue component value. Integer in the range 0 - 255. Synonyms: b, z. +* @example Colors can be set in multiple ways and modified with their aliases, but still stringify in the same way +* Entities.editEntity(, { color: { x: 1, y: 2, z: 3 }}); // { red: 1, green: 2, blue: 3 } +* Entities.editEntity(, { color: { r: 4, g: 5, b: 6 }}); // { red: 4, green: 5, blue: 6 } +* Entities.editEntity(, { color: { red: 7, green: 8, blue: 9 }}); // { red: 7, green: 8, blue: 9 } +* Entities.editEntity(, { color: [10, 11, 12] }); // { red: 10, green: 11, blue: 12 } +* Entities.editEntity(, { color: 13 }); // { red: 13, green: 13, blue: 13 } +* var color = Entities.getEntityProperties().color; // { red: 13, green: 13, blue: 13 } +* color.g = 14; // { red: 13, green: 14, blue: 13 } +* color.blue = 15; // { red: 13, green: 14, blue: 15 } +* Entities.editEntity(, { color: "red"}); // { red: 255, green: 0, blue: 0 } +* Entities.editEntity(, { color: "#00FF00"}); // { red: 0, green: 255, blue: 0 } +*/ +/**jsdoc +* A color vector. See also the {@link Vec3(0)|Vec3} object. +* +* @typedef {object} ColorFloat +* @property {number} red - Red component value. Real in the range 0 - 255. Synonyms: r, x. +* @property {number} green - Green component value. Real in the range 0 - 255. Synonyms: g, y. +* @property {number} blue - Blue component value. Real in the range 0 - 255. Synonyms: b, z. +* @example ColorFloats can be set in multiple ways and modified with their aliases, but still stringify in the same way +* Entities.editEntity(, { color: { x: 1, y: 2, z: 3 }}); // { red: 1, green: 2, blue: 3 } +* Entities.editEntity(, { color: { r: 4, g: 5, b: 6 }}); // { red: 4, green: 5, blue: 6 } +* Entities.editEntity(, { color: { red: 7, green: 8, blue: 9 }}); // { red: 7, green: 8, blue: 9 } +* Entities.editEntity(, { color: [10, 11, 12] }); // { red: 10, green: 11, blue: 12 } +* Entities.editEntity(, { color: 13 }); // { red: 13, green: 13, blue: 13 } +* var color = Entities.getEntityProperties().color; // { red: 13, green: 13, blue: 13 } +* color.g = 14; // { red: 13, green: 14, blue: 13 } +* color.blue = 15; // { red: 13, green: 14, blue: 15 } +* Entities.editEntity(, { color: "red"}); // { red: 255, green: 0, blue: 0 } +* Entities.editEntity(, { color: "#00FF00"}); // { red: 0, green: 255, blue: 0 } +*/ +QScriptValue u8vec3ToScriptValue(QScriptEngine* engine, const glm::u8vec3& vec3); +QScriptValue u8vec3ColorToScriptValue(QScriptEngine* engine, const glm::u8vec3& vec3); +void u8vec3FromScriptValue(const QScriptValue& object, glm::u8vec3& vec3); + +QVariant u8vec3toVariant(const glm::u8vec3& vec3); +QVariant u8vec3ColortoVariant(const glm::u8vec3& vec3); +glm::u8vec3 u8vec3FromVariant(const QVariant &object, bool& valid); +glm::u8vec3 u8vec3FromVariant(const QVariant &object); + /**jsdoc * A 4-dimensional vector. * @@ -56,36 +150,12 @@ void mat4FromScriptValue(const QScriptValue& object, glm::mat4& mat4); * @property {number} z - Z-coordinate of the vector. * @property {number} w - W-coordinate of the vector. */ -// Vec4 QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4); void vec4FromScriptValue(const QScriptValue& object, glm::vec4& vec4); QVariant vec4toVariant(const glm::vec4& vec4); glm::vec4 vec4FromVariant(const QVariant &object, bool& valid); glm::vec4 vec4FromVariant(const QVariant &object); -// Vec3 -QScriptValue vec3toScriptValue(QScriptEngine* engine, const glm::vec3 &vec3); -void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3); - -QVariant vec3toVariant(const glm::vec3& vec3); -glm::vec3 vec3FromVariant(const QVariant &object, bool& valid); -glm::vec3 vec3FromVariant(const QVariant &object); - -/**jsdoc - * A 2-dimensional vector. - * - * @typedef {object} Vec2 - * @property {number} x - X-coordinate of the vector. - * @property {number} y - Y-coordinate of the vector. - */ -// Vec2 -QScriptValue vec2toScriptValue(QScriptEngine* engine, const glm::vec2 &vec2); -void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2); - -QVariant vec2toVariant(const glm::vec2 &vec2); -glm::vec2 vec2FromVariant(const QVariant &object, bool& valid); -glm::vec2 vec2FromVariant(const QVariant &object); - // Quaternions QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat); void quatFromScriptValue(const QScriptValue &object, glm::quat& quat); @@ -94,25 +164,26 @@ QVariant quatToVariant(const glm::quat& quat); glm::quat quatFromVariant(const QVariant &object, bool& isValid); glm::quat quatFromVariant(const QVariant &object); -// Rect +/**jsdoc + * Defines a rectangular portion of an image or screen, or similar. + * @typedef {object} Rect + * @property {number} x - Left, x-coordinate value. + * @property {number} y - Top, y-coordinate value. + * @property {number} width - Width of the rectangle. + * @property {number} height - Height of the rectangle. + */ QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect); void qRectFromScriptValue(const QScriptValue& object, QRect& rect); QRect qRectFromVariant(const QVariant& object, bool& isValid); QRect qRectFromVariant(const QVariant& object); QVariant qRectToVariant(const QRect& rect); + QScriptValue qRectFToScriptValue(QScriptEngine* engine, const QRectF& rect); void qRectFFromScriptValue(const QScriptValue& object, QRectF& rect); QRectF qRectFFromVariant(const QVariant& object, bool& isValid); QRectF qRectFFromVariant(const QVariant& object); QVariant qRectFToVariant(const QRectF& rect); -// xColor -QScriptValue xColorToScriptValue(QScriptEngine* engine, const xColor& color); -void xColorFromScriptValue(const QScriptValue &object, xColor& color); - -QVariant xColorToVariant(const xColor& color); -xColor xColorFromVariant(const QVariant &object, bool& isValid); - // QColor QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color); void qColorFromScriptValue(const QScriptValue& object, QColor& color); @@ -121,11 +192,14 @@ QScriptValue qURLToScriptValue(QScriptEngine* engine, const QUrl& url); void qURLFromScriptValue(const QScriptValue& object, QUrl& url); // vector +Q_DECLARE_METATYPE(QVector) QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector& vector); +QScriptValue qVectorVec3ColorToScriptValue(QScriptEngine* engine, const QVector& vector); void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& vector); QVector qVectorVec3FromScriptValue(const QScriptValue& array); // vector +Q_DECLARE_METATYPE(QVector) QScriptValue qVectorQuatToScriptValue(QScriptEngine* engine, const QVector& vector); void qVectorQuatFromScriptValue(const QScriptValue& array, QVector& vector); QVector qVectorQuatFromScriptValue(const QScriptValue& array); diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 012e7aa1f5..39def1cab9 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -24,7 +24,6 @@ #include - #ifdef Q_OS_WIN #include #include "CPUIdent.h" @@ -348,7 +347,7 @@ unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, } auto voxelSizeInBytes = bytesRequiredForCodeLength(voxelSizeInOctets); // (voxelSizeInBits/8)+1; - auto voxelBufferSize = voxelSizeInBytes + sizeof(rgbColor); // 3 for color + auto voxelBufferSize = voxelSizeInBytes + sizeof(glm::u8vec3); // 3 for color // allocate our resulting buffer unsigned char* voxelOut = new unsigned char[voxelBufferSize]; diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 3b24110f18..f36574bed6 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -80,43 +80,6 @@ const int BYTES_PER_COLOR = 3; const int BYTES_PER_FLAGS = 1; typedef unsigned char colorPart; typedef unsigned char nodeColor[BYTES_PER_COLOR + BYTES_PER_FLAGS]; -typedef unsigned char rgbColor[BYTES_PER_COLOR]; - -inline QDebug& operator<<(QDebug& dbg, const rgbColor& c) { - dbg.nospace() << "{type='rgbColor'" - ", red=" << c[0] << - ", green=" << c[1] << - ", blue=" << c[2] << - "}"; - return dbg; -} - -struct xColor { - xColor() {} - xColor(unsigned char r, unsigned char g, unsigned char b) : red(r), green(g), blue(b) {} - unsigned char red; - unsigned char green; - unsigned char blue; -}; - -inline QDebug& operator<<(QDebug& dbg, const xColor& c) { - dbg.nospace() << "{type='xColor'" - ", red=" << c.red << - ", green=" << c.green << - ", blue=" << c.blue << - "}"; - 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); -} // Use a custom User-Agent to avoid ModSecurity filtering, e.g. by hosting providers. const QByteArray HIGH_FIDELITY_USER_AGENT = "Mozilla/5.0 (HighFidelityInterface)"; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 4b8768704a..fd2ff6e790 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -75,7 +75,10 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) { }); bool success = false; - getParentPointer(success); + auto parent = getParentPointer(success); + if (success && parent) { + parent->updateQueryAACube(); + } } Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const { @@ -155,12 +158,14 @@ void SpatiallyNestable::beParentOfChild(SpatiallyNestablePointer newChild) const _childrenLock.withWriteLock([&] { _children[newChild->getID()] = newChild; }); + // Our QueryAACube will automatically be updated to include our new child } void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { _childrenLock.withWriteLock([&] { _children.remove(newChild->getID()); }); + _queryAACubeSet = false; // We need to reset our queryAACube when we lose a child } void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { @@ -1092,7 +1097,23 @@ AACube SpatiallyNestable::getMaximumAACube(bool& success) const { return AACube(getWorldPosition(success) - glm::vec3(defaultAACubeSize / 2.0f), defaultAACubeSize); } -const float PARENTED_EXPANSION_FACTOR = 3.0f; +AACube SpatiallyNestable::calculateInitialQueryAACube(bool& success) { + success = false; + AACube maxAACube = getMaximumAACube(success); + if (!success) { + return AACube(); + } + + success = true; + if (shouldPuffQueryAACube()) { + // make an expanded AACube centered on the object + const float PARENTED_EXPANSION_FACTOR = 3.0f; + float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); + return AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); + } else { + return maxAACube; + } +} bool SpatiallyNestable::updateQueryAACube() { if (!queryAACubeNeedsUpdate()) { @@ -1100,20 +1121,12 @@ bool SpatiallyNestable::updateQueryAACube() { } bool success; - AACube maxAACube = getMaximumAACube(success); + AACube initialQueryAACube = calculateInitialQueryAACube(success); if (!success) { return false; } - - if (shouldPuffQueryAACube()) { - // make an expanded AACube centered on the object - float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); - _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); - _queryAACubeIsPuffed = true; - } else { - _queryAACube = maxAACube; - _queryAACubeIsPuffed = false; - } + _queryAACube = initialQueryAACube; + _queryAACubeIsPuffed = shouldPuffQueryAACube(); forEachDescendant([&](const SpatiallyNestablePointer& descendant) { bool childSuccess; @@ -1128,6 +1141,12 @@ bool SpatiallyNestable::updateQueryAACube() { }); _queryAACubeSet = true; + + auto parent = getParentPointer(success); + if (success && parent) { + parent->updateQueryAACube(); + } + return true; } @@ -1158,7 +1177,7 @@ bool SpatiallyNestable::queryAACubeNeedsUpdate() const { // make sure children are still in their boxes, also. bool childNeedsUpdate = false; forEachDescendantTest([&](const SpatiallyNestablePointer& descendant) { - if (!childNeedsUpdate && descendant->queryAACubeNeedsUpdate()) { + if (descendant->queryAACubeNeedsUpdate() || !_queryAACube.contains(descendant->getQueryAACube())) { childNeedsUpdate = true; // Don't recurse further return false; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index a50e687a9b..03ed97afbd 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -19,7 +19,6 @@ #include "SpatialParentFinder.h" #include "shared/ReadWriteLockable.h" - class SpatiallyNestable; using SpatiallyNestableWeakPointer = std::weak_ptr; using SpatiallyNestableWeakConstPointer = std::weak_ptr; @@ -112,6 +111,7 @@ public: virtual glm::vec3 getParentAngularVelocity(bool& success) const; virtual AACube getMaximumAACube(bool& success) const; + virtual AACube calculateInitialQueryAACube(bool& success); virtual void setQueryAACube(const AACube& queryAACube); virtual bool queryAACubeNeedsUpdate() const; diff --git a/libraries/shared/src/StreamUtils.cpp b/libraries/shared/src/StreamUtils.cpp index 9ed0e24593..abacb012e5 100644 --- a/libraries/shared/src/StreamUtils.cpp +++ b/libraries/shared/src/StreamUtils.cpp @@ -78,6 +78,11 @@ QDebug& operator<<(QDebug& dbg, const glm::vec3& v) { return dbg; } +QDebug& operator<<(QDebug& dbg, const glm::u8vec3& v) { + dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ')'; + return dbg; +} + QDebug& operator<<(QDebug& dbg, const glm::vec4& v) { dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ')'; return dbg; diff --git a/libraries/shared/src/StreamUtils.h b/libraries/shared/src/StreamUtils.h index caf7b565f4..b6d6c522c5 100644 --- a/libraries/shared/src/StreamUtils.h +++ b/libraries/shared/src/StreamUtils.h @@ -42,6 +42,7 @@ class QDebug; // Add support for writing these to qDebug(). QDebug& operator<<(QDebug& s, const glm::vec2& v); QDebug& operator<<(QDebug& s, const glm::vec3& v); +QDebug& operator<<(QDebug& s, const glm::u8vec3& v); QDebug& operator<<(QDebug& s, const glm::vec4& v); QDebug& operator<<(QDebug& s, const glm::quat& q); QDebug& operator<<(QDebug& s, const glm::mat4& m); diff --git a/libraries/shared/src/shared/JSONHelpers.cpp b/libraries/shared/src/shared/JSONHelpers.cpp index c7cbf0e724..298a1ea85d 100644 --- a/libraries/shared/src/shared/JSONHelpers.cpp +++ b/libraries/shared/src/shared/JSONHelpers.cpp @@ -68,6 +68,20 @@ vec4 vec4FromJsonValue(const QJsonValue& v) { return glmFromJson(v); } +QJsonValue toJsonValueHelper(const QVariant& variant, int type) { + // User-registered types need explicit conversion + if (type == qMetaTypeId()) { + return toJsonValue(variant.value()); + } else if (type == qMetaTypeId()) { + return toJsonValue(variant.value()); + } else if (type == qMetaTypeId()) { + return toJsonValue(variant.value()); + } else { + // Qt types are converted automatically + return QJsonValue::fromVariant(variant); + } +} + QJsonValue toJsonValue(const QObject& o) { QJsonObject json{}; @@ -76,20 +90,8 @@ QJsonValue toJsonValue(const QObject& o) { for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) { QString name = QString::fromLatin1(meta->property(i).name()); auto type = meta->property(i).userType(); - QVariant variant{ meta->property(i).read(&o) }; - QJsonValue value; - - // User-registered types need explicit conversion - if (type == qMetaTypeId()) { - value = toJsonValue(variant.value()); - } else if (type == qMetaTypeId()) { - value = toJsonValue(variant.value()); - } else if (type == qMetaTypeId()) { - value = toJsonValue(variant.value()); - } else { - // Qt types are converted automatically - value = QJsonValue::fromVariant(variant); - } + QVariant variant { meta->property(i).read(&o) }; + QJsonValue value = toJsonValueHelper(variant, type); json.insert(name, value); } @@ -106,6 +108,24 @@ QJsonValue toJsonValue(const QObject& o) { return json; } +QJsonValue toJsonValue(const QObject& o, const std::vector& props) { + QJsonObject json {}; + + const auto& meta = o.metaObject(); + // Only add the properties in props + for (auto& prop : props) { + int i = meta->indexOfProperty(prop.toStdString().c_str()); + QString name = QString::fromLatin1(meta->property(i).name()); + auto type = meta->property(i).userType(); + QVariant variant { meta->property(i).read(&o) }; + QJsonValue value = toJsonValueHelper(variant, type); + + json.insert(name, value); + } + + return json; +} + void qObjectFromJsonValue(const QJsonValue& j, QObject& o) { const QJsonObject object = j.toObject(); for (auto it = object.begin(); it != object.end(); it++) { diff --git a/libraries/shared/src/shared/JSONHelpers.h b/libraries/shared/src/shared/JSONHelpers.h index 735d33b5a5..a7e7077904 100644 --- a/libraries/shared/src/shared/JSONHelpers.h +++ b/libraries/shared/src/shared/JSONHelpers.h @@ -15,7 +15,9 @@ QJsonValue toJsonValue(const quat& q); QJsonValue toJsonValue(const vec3& v); QJsonValue toJsonValue(const vec4& v); +QJsonValue toJsonValueHelper(const QVariant& variant, int type); QJsonValue toJsonValue(const QObject& o); +QJsonValue toJsonValue(const QObject& o, const std::vector& props); quat quatFromJsonValue(const QJsonValue& q); vec3 vec3FromJsonValue(const QJsonValue& v); diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 3878c5719b..ee5483d5cb 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -418,6 +418,7 @@ protected: template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7; \ template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8; \ + template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8 > using VaryingSet9 = task::VaryingSet9; \ template < class T, int NUM > using VaryingArray = task::VaryingArray; diff --git a/libraries/task/src/task/Varying.h b/libraries/task/src/task/Varying.h index 7b7b9907fb..9536db2799 100644 --- a/libraries/task/src/task/Varying.h +++ b/libraries/task/src/task/Varying.h @@ -328,6 +328,45 @@ public: Varying asVarying() const { return Varying((*this)); } }; +template +class VaryingSet9 : public std::tuple { +public: + using Parent = std::tuple; + + VaryingSet9() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7()), Varying(T8())) {} + VaryingSet9(const VaryingSet9& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src), std::get<8>(src)) {} + VaryingSet9(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth, const Varying& nine) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth, nine) {} + + const T0& get0() const { return std::get<0>((*this)).template get(); } + T0& edit0() { return std::get<0>((*this)).template edit(); } + + const T1& get1() const { return std::get<1>((*this)).template get(); } + T1& edit1() { return std::get<1>((*this)).template edit(); } + + const T2& get2() const { return std::get<2>((*this)).template get(); } + T2& edit2() { return std::get<2>((*this)).template edit(); } + + const T3& get3() const { return std::get<3>((*this)).template get(); } + T3& edit3() { return std::get<3>((*this)).template edit(); } + + const T4& get4() const { return std::get<4>((*this)).template get(); } + T4& edit4() { return std::get<4>((*this)).template edit(); } + + const T5& get5() const { return std::get<5>((*this)).template get(); } + T5& edit5() { return std::get<5>((*this)).template edit(); } + + const T6& get6() const { return std::get<6>((*this)).template get(); } + T6& edit6() { return std::get<6>((*this)).template edit(); } + + const T7& get7() const { return std::get<7>((*this)).template get(); } + T7& edit7() { return std::get<7>((*this)).template edit(); } + + const T8& get8() const { return std::get<8>((*this)).template get(); } + T8& edit8() { return std::get<8>((*this)).template edit(); } + + Varying asVarying() const { return Varying((*this)); } +}; + template < class T, int NUM > class VaryingArray : public std::array { public: diff --git a/scripts/developer/tests/ambientSoundTest.js b/scripts/developer/tests/ambientSoundTest.js index d048d5f73d..98dbf8bba0 100644 --- a/scripts/developer/tests/ambientSoundTest.js +++ b/scripts/developer/tests/ambientSoundTest.js @@ -10,7 +10,7 @@ var uuid = Entities.addEntity({ maxVolume: 0.1, range: 25, disabled: true, - grabbableKey: { wantsTrigger: true }, + grab: { triggerable: true } }), lifetime: 600, }); diff --git a/scripts/developer/tests/controllerTableTest.js b/scripts/developer/tests/controllerTableTest.js index 239c7fd0ce..517ff0ab1a 100644 --- a/scripts/developer/tests/controllerTableTest.js +++ b/scripts/developer/tests/controllerTableTest.js @@ -1,7 +1,7 @@ "use strict"; /* jslint bitwise: true */ -/* global Script, Entities, MyAvatar, Vec3, Quat, Mat4 */ +/* global Script, Entities, MyAvatar, Vec3, Quat, Mat4, Overlays */ (function() { // BEGIN LOCAL_SCOPE @@ -19,7 +19,7 @@ var sectionCenterB = 0; var sectionCenterSign = 0; var yFlip = 0; - + var objects = []; var overlays = []; @@ -35,41 +35,41 @@ createPropsCube(index, false, false, true, true); createPropsModel(index, false, false, true, true); createSign(index, "Clone Dynamic Entity"); - }; + } function createCloneEntity(index) { createPropsCube(index, false, false, true, false); createPropsModel(index, false, false, true, false); createSign(index, "Clone Non-Dynamic Entity"); - }; + } function createNearGrabOverlay(index) { createPropsCubeOverlay(index, false, false, true, true); createPropsModelOverlay(index, false, false, true, true); createSign(index, "Near Grab Overlay"); - }; + } function createNearGrabEntity(index) { createPropsCube(index, false, false, false, false); createPropsModel(index, false, false, false, false); createSign(index, "Near Grab Entity"); - }; + } function createFarGrabEntity(index) { createPropsCube(index, true, false, false, false); createPropsModel(index, true, false, false, false); createSign(index, "Far Grab Entity"); - }; + } function createPropsModel(i, dynamic, collisionless, clone, cloneDynamic) { var propsModel = { name: "controller-tests model object " + i, type: "Model", modelURL: "http://headache.hungry.com/~seth/hifi/controller-tests/color-cube.obj", - + position: sectionCenterA, rotation: sectionRotation, - + gravity: (dynamic && !collisionless) ? { x: 0, y: -1, z: 0 } : { x: 0, y: 0, z: 0 }, dimensions: { x: 0.2, y: 0.2, z: 0.2 }, userData: JSON.stringify({ @@ -270,8 +270,8 @@ Entities.deleteEntity(nearbyID); } - for (var i = 0; i < overlays.length; i++) { - var overlayID = overlays[i]; + for (var j = 0; j < overlays.length; j++) { + var overlayID = overlays[j]; Overlays.deleteOverlay(overlayID); } }); diff --git a/scripts/system/avatarapp.js b/scripts/system/avatarapp.js index 10ccb66d96..ece35acce7 100644 --- a/scripts/system/avatarapp.js +++ b/scripts/system/avatarapp.js @@ -329,36 +329,18 @@ function isGrabbable(entityID) { return false; } - var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'userData']); + var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'grab.grabbable']); if (properties.clientOnly) { - var userData; - try { - userData = JSON.parse(properties.userData); - } catch (e) { - userData = {}; - } - - return userData.grabbableKey && userData.grabbableKey.grabbable; + return properties.grab.grabbable; } return false; } function setGrabbable(entityID, grabbable) { - var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'userData']); + var properties = Entities.getEntityProperties(entityID, ['clientOnly']); if (properties.clientOnly) { - var userData; - try { - userData = JSON.parse(properties.userData); - } catch (e) { - userData = {}; - } - - if (userData.grabbableKey === undefined) { - userData.grabbableKey = {}; - } - userData.grabbableKey.grabbable = grabbable; - Entities.editEntity(entityID, {userData: JSON.stringify(userData)}); + Entities.editEntity(entityID, { grab: { grabbable: grabbable }}); } } diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index f5bf0f8e4c..b866d04f18 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -10,9 +10,8 @@ /* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation, controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true, LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES, - getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, COLORS_GRAB_SEARCHING_HALF_SQUEEZE - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager, print getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, + PointerManager, getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, PointerManager, print, Selection, DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE */ @@ -34,6 +33,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var PROFILE = false; var DEBUG = false; + var SHOW_GRAB_SPHERE = false; + if (typeof Test !== "undefined") { PROFILE = true; @@ -51,6 +52,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.tabletID = null; this.blacklist = []; this.pointerManager = new PointerManager(); + this.grabSphereOverlays = [null, null]; // a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are // not set to false (not in use), a module cannot start. When a module is using a slot, that module's name @@ -251,7 +253,28 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); for (h = LEFT_HAND; h <= RIGHT_HAND; h++) { if (controllerLocations[h].valid) { var controllerPosition = controllerLocations[h].position; - var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_MAX_RADIUS * sensorScaleFactor); + var findRadius = NEAR_MAX_RADIUS * sensorScaleFactor; + + if (SHOW_GRAB_SPHERE) { + if (this.grabSphereOverlays[h]) { + Overlays.editOverlay(this.grabSphereOverlays[h], { position: controllerLocations[h].position }); + } else { + var grabSphereSize = findRadius * 2; + this.grabSphereOverlays[h] = Overlays.addOverlay("sphere", { + position: controllerLocations[h].position, + dimensions: { x: grabSphereSize, y: grabSphereSize, z: grabSphereSize }, + color: { red: 30, green: 30, blue: 255 }, + alpha: 0.3, + solid: true, + visible: true, + // lineWidth: 2.0, + drawInFront: false, + grabbable: false + }); + } + } + + var nearbyEntityIDs = Entities.findEntities(controllerPosition, findRadius); for (var j = 0; j < nearbyEntityIDs.length; j++) { var entityID = nearbyEntityIDs[j]; var props = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); diff --git a/scripts/system/controllers/controllerDisplay.js b/scripts/system/controllers/controllerDisplay.js index 8aa0393357..e40b761307 100644 --- a/scripts/system/controllers/controllerDisplay.js +++ b/scripts/system/controllers/controllerDisplay.js @@ -7,7 +7,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* globals createControllerDisplay:true deleteControllerDisplay:true */ +/* globals createControllerDisplay:true, deleteControllerDisplay:true, Controller, Overlays, Vec3, MyAvatar, Quat */ function clamp(value, min, max) { if (value < min) { @@ -188,7 +188,7 @@ createControllerDisplay = function(config) { for (var partName in controller.parts) { var part = controller.parts[partName]; var localPosition = Vec3.subtract(part.naturalPosition, controller.naturalPosition); - var localRotation = { x: 0, y: 0, z: 0, w: 1 } + var localRotation = { x: 0, y: 0, z: 0, w: 1 }; controllerDisplay.parts[partName] = controller.parts[partName]; @@ -203,7 +203,7 @@ createControllerDisplay = function(config) { if (part.defaultTextureLayer) { var textures = {}; textures[part.textureName] = part.textureLayers[part.defaultTextureLayer].defaultTextureURL; - properties['textures'] = textures; + properties.textures = textures; } var overlayID = Overlays.addOverlay("model", properties); diff --git a/scripts/system/controllers/controllerDisplayManager.js b/scripts/system/controllers/controllerDisplayManager.js index e3fd74e05b..f93f8b1624 100644 --- a/scripts/system/controllers/controllerDisplayManager.js +++ b/scripts/system/controllers/controllerDisplayManager.js @@ -7,8 +7,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* globals ControllerDisplayManager:true createControllerDisplay deleteControllerDisplay - VIVE_CONTROLLER_CONFIGURATION_LEFT VIVE_CONTROLLER_CONFIGURATION_RIGHT */ +/* globals ControllerDisplayManager:true, createControllerDisplay, deleteControllerDisplay, + VIVE_CONTROLLER_CONFIGURATION_LEFT, VIVE_CONTROLLER_CONFIGURATION_RIGHT, Script, HMD, Controller, + MyAvatar, Overlays, TOUCH_CONTROLLER_CONFIGURATION_LEFT, TOUCH_CONTROLLER_CONFIGURATION_RIGHT, Messages */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function () { @@ -93,7 +94,7 @@ ControllerDisplayManager = function() { if (controllerRight) { controllerRight.resize(sensorScaleFactor); } - }; + } var handleMessages = function(channel, message, sender) { var i, data, name, visible; diff --git a/scripts/system/controllers/controllerModules/disableOtherModule.js b/scripts/system/controllers/controllerModules/disableOtherModule.js index 0928b29d5d..7636c56f65 100644 --- a/scripts/system/controllers/controllerModules/disableOtherModule.js +++ b/scripts/system/controllers/controllerModules/disableOtherModule.js @@ -58,18 +58,16 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); if (channel === 'Hifi-Hand-Disabler') { if (message === 'left') { leftDisableModules.disableModules = true; - } - if (message === 'right') { + } else if (message === 'right') { rightDisableModules.disableModules = true; - } - if (message === 'both' || message === 'none') { - if (message === 'both') { - leftDisableModules.disableModules = true; - rightDisableModules.disableModules = true; - } else if (message === 'none') { - leftDisableModules.disableModules = false; - rightDisableModules.disableModules = false; - } + } else if (message === 'both') { + leftDisableModules.disableModules = true; + rightDisableModules.disableModules = true; + } else if (message === 'none') { + leftDisableModules.disableModules = false; + rightDisableModules.disableModules = false; + } else { + print("disableOtherModule -- unknown command: " + message); } } } diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 91c8d89daf..f4d9c731b7 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -6,11 +6,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, Camera, +/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, Camera, print, getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, entityIsFarGrabbedByOther, Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable, - cloneEntity, DISPATCHER_PROPERTIES, Uuid, unhighlightTargetEntity, isInEditMode + cloneEntity, DISPATCHER_PROPERTIES, Uuid, unhighlightTargetEntity, isInEditMode, getGrabbableData */ Script.include("/~/system/libraries/Xform.js"); @@ -66,12 +66,16 @@ EquipHotspotBuddy.prototype.updateHotspot = function(hotspot, timestamp) { overlays: [] }; - var diameter = hotspot.radius * 2; + var dimensions = hotspot.radius * 2 * EQUIP_SPHERE_SCALE_FACTOR; + + if (hotspot.indicatorURL) { + dimensions = hotspot.indicatorScale; + } // override default sphere with a user specified model, if it exists. overlayInfoSet.overlays.push(Overlays.addOverlay("model", { name: "hotspot overlay", - url: hotspot.modelURL ? hotspot.modelURL : DEFAULT_SPHERE_MODEL_URL, + url: hotspot.indicatorURL ? hotspot.indicatorURL : DEFAULT_SPHERE_MODEL_URL, position: hotspot.worldPosition, rotation: { x: 0, @@ -79,8 +83,7 @@ EquipHotspotBuddy.prototype.updateHotspot = function(hotspot, timestamp) { z: 0, w: 1 }, - dimensions: diameter * EQUIP_SPHERE_SCALE_FACTOR, - scale: hotspot.modelScale, + dimensions: dimensions, ignoreRayIntersection: true })); overlayInfoSet.type = "model"; @@ -137,8 +140,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var position = entityXform.xformPoint(overlayInfoSet.localPosition); var dimensions; - if (overlayInfoSet.type === "sphere") { - dimensions = (overlayInfoSet.hotspot.radius / 2) * overlayInfoSet.currentSize * EQUIP_SPHERE_SCALE_FACTOR; + if (overlayInfoSet.hotspot.indicatorURL) { + var ratio = overlayInfoSet.currentSize / overlayInfoSet.targetSize; + dimensions = { + x: overlayInfoSet.hotspot.dimensions.x * ratio, + y: overlayInfoSet.hotspot.dimensions.y * ratio, + z: overlayInfoSet.hotspot.dimensions.z * ratio + }; } else { dimensions = (overlayInfoSet.hotspot.radius / 2) * overlayInfoSet.currentSize; } @@ -158,12 +166,21 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } }; + +var alreadyWarned = {}; +function warnAboutUserData(props) { + if (alreadyWarned[props.id]) { + return; + } + print("Warning -- overriding grab properties with userData for " + props.id + " / " + props.name); + alreadyWarned[props.id] = true; +} + + (function() { var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints"; - var EQUIP_RADIUS = 1.0; // radius used for palm vs equip-hotspot for equipping. - var HAPTIC_PULSE_STRENGTH = 1.0; var HAPTIC_PULSE_DURATION = 13.0; var HAPTIC_TEXTURE_STRENGTH = 0.1; @@ -176,36 +193,86 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var TRIGGER_OFF_VALUE = 0.1; var TRIGGER_ON_VALUE = TRIGGER_OFF_VALUE + 0.05; // Squeezed just enough to activate search or near grab var BUMPER_ON_VALUE = 0.5; - + var EMPTY_PARENT_ID = "{00000000-0000-0000-0000-000000000000}"; - + var UNEQUIP_KEY = "u"; function getWearableData(props) { - var wearable = {}; - try { - if (!props.userDataParsed) { - props.userDataParsed = JSON.parse(props.userData); - } + if (props.grab.equippable) { + // if equippable is true, we know this was already converted from the old userData style to properties + return { + joints: { + LeftHand: [ props.grab.equippableLeftPosition, props.grab.equippableLeftRotation ], + RightHand: [ props.grab.equippableRightPosition, props.grab.equippableRightRotation ] + }, + indicatorURL: props.grab.equippableIndicatorURL, + indicatorScale: props.grab.equippableIndicatorScale, + indicatorOffset: props.grab.equippableIndicatorOffset + }; + } else { + // check for old userData equippability. The JSON reader will convert userData to properties + // in EntityTree.cpp, but this won't catch things created from scripts or some items in + // the market. Eventually we'll remove this section. + try { + if (!props.userDataParsed) { + props.userDataParsed = JSON.parse(props.userData); + } + var userDataParsed = props.userDataParsed; - wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {}; - } catch (err) { - // don't want to spam the logs - } - return wearable; - } - function getEquipHotspotsData(props) { - var equipHotspots = []; - try { - if (!props.userDataParsed) { - props.userDataParsed = JSON.parse(props.userData); - } + // userData: { wearable: { joints: { LeftHand: {...}, RightHand: {...} } } } + if (userDataParsed.wearable && userDataParsed.wearable.joints) { + warnAboutUserData(props); + userDataParsed.wearable.indicatorURL = ""; + userDataParsed.wearable.indicatorScale = { x: 1, y: 1, z: 1 }; + userDataParsed.wearable.indicatorOffset = { x: 0, y: 0, z: 0 }; + return userDataParsed.wearable; + } - equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : []; - } catch (err) { - // don't want to spam the logs + // userData: { equipHotspots: { joints: { LeftHand: {...}, RightHand: {...} } } } + // https://highfidelity.atlassian.net/wiki/spaces/HOME/pages/51085337/Authoring+Equippable+Entities + if (userDataParsed.equipHotspots && + userDataParsed.equipHotspots.length > 0 && + userDataParsed.equipHotspots[0].joints) { + warnAboutUserData(props); + var hotSpot = userDataParsed.equipHotspots[0]; + + var indicatorScale = { x: hotSpot.radius, y: hotSpot.radius, z: hotSpot.radius }; + if (hotSpot.modelURL && hotSpot.modelURL !== "") { + indicatorScale = hotSpot.modelScale; + } + + return { + joints: hotSpot.joints, + indicatorURL: hotSpot.modelURL, + indicatorScale: indicatorScale, + indicatorOffset: hotSpot.position, + }; + } + + // userData:{grabbableKey:{spatialKey:{leftRelativePosition:{...},rightRelativePosition:{...}}}} + if (userDataParsed.grabbableKey && + userDataParsed.grabbableKey.spatialKey) { + warnAboutUserData(props); + var joints = {}; + joints.LeftHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ]; + joints.RightHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ]; + if (userDataParsed.grabbableKey.spatialKey.leftRelativePosition) { + joints.LeftHand = [userDataParsed.grabbableKey.spatialKey.leftRelativePosition, + userDataParsed.grabbableKey.spatialKey.relativeRotation]; + } + if (userDataParsed.grabbableKey.spatialKey.rightRelativePosition) { + joints.RightHand = [userDataParsed.grabbableKey.spatialKey.rightRelativePosition, + userDataParsed.grabbableKey.spatialKey.relativeRotation]; + } + return { joints: joints }; + } + + } catch (err) { + // don't spam logs + } + return null; } - return equipHotspots; } function getAttachPointSettings() { @@ -275,7 +342,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.handHasBeenRightsideUp = false; this.parameters = makeDispatcherModuleParameters( - 300, + 115, this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip"] : ["leftHand", "leftHandEquip"], [], 100); @@ -299,51 +366,29 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa // * radius {number} radius of equip hotspot // * joints {Object} keys are joint names values are arrays of two elements: // offset position {Vec3} and offset rotation {Quat}, both are in the coordinate system of the joint. - // * modelURL {string} url for model to use instead of default sphere. - // * modelScale {Vec3} scale factor for model + // * indicatorURL {string} url for model to use instead of default sphere. + // * indicatorScale {Vec3} scale factor for model this.collectEquipHotspots = function(props) { var result = []; var entityID = props.id; var entityXform = new Xform(props.rotation, props.position); - var equipHotspotsProps = getEquipHotspotsData(props); - if (equipHotspotsProps && equipHotspotsProps.length > 0) { - var i, length = equipHotspotsProps.length; - for (i = 0; i < length; i++) { - var hotspot = equipHotspotsProps[i]; - if (hotspot.position && hotspot.radius && hotspot.joints) { - result.push({ - key: entityID.toString() + i.toString(), - entityID: entityID, - localPosition: hotspot.position, - worldPosition: entityXform.xformPoint(hotspot.position), - radius: hotspot.radius, - joints: hotspot.joints, - modelURL: hotspot.modelURL, - modelScale: hotspot.modelScale - }); - } - } - } else { - var wearableProps = getWearableData(props); - var sensorToScaleFactor = MyAvatar.sensorToWorldScale; - if (wearableProps && wearableProps.joints) { - - result.push({ - key: entityID.toString() + "0", - entityID: entityID, - localPosition: { - x: 0, - y: 0, - z: 0 - }, - worldPosition: entityXform.pos, - radius: EQUIP_RADIUS * sensorToScaleFactor, - joints: wearableProps.joints, - modelURL: null, - modelScale: null - }); - } + var wearableProps = getWearableData(props); + var sensorToScaleFactor = MyAvatar.sensorToWorldScale; + if (wearableProps && wearableProps.joints) { + result.push({ + key: entityID.toString() + "0", + entityID: entityID, + localPosition: wearableProps.indicatorOffset, + worldPosition: entityXform.pos, + radius: ((wearableProps.indicatorScale.x + + wearableProps.indicatorScale.y + + wearableProps.indicatorScale.z) / 3) * sensorToScaleFactor, + dimensions: wearableProps.indicatorScale, + joints: wearableProps.joints, + indicatorURL: wearableProps.indicatorURL, + indicatorScale: wearableProps.indicatorScale, + }); } return result; }; @@ -492,7 +537,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa }; Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message)); - var grabbedProperties = Entities.getEntityProperties(this.targetEntityID); + var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); + var grabData = getGrabbableData(grabbedProperties); // if an object is "equipped" and has a predefined offset, use it. if (this.grabbedHotspot) { @@ -510,7 +556,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } var handJointIndex; - if (this.ignoreIK) { + if (grabData.grabFollowsController) { handJointIndex = this.controllerJointIndex; } else { handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); @@ -796,7 +842,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (intersection.intersects) { var entityID = intersection.entityID; var entityProperties = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); - var hasEquipData = getWearableData(entityProperties).joints || getEquipHotspotsData(entityProperties).length > 0; + entityProperties.id = entityID; + var hasEquipData = getWearableData(entityProperties); if (hasEquipData && entityProperties.parentID === EMPTY_PARENT_ID && !entityIsFarGrabbedByOther(entityID)) { entityProperties.id = entityID; var rightHandPosition = MyAvatar.getJointPosition("RightHand"); @@ -804,7 +851,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var distanceToRightHand = Vec3.distance(entityProperties.position, rightHandPosition); var distanceToLeftHand = Vec3.distance(entityProperties.position, leftHandPosition); var leftHandAvailable = leftEquipEntity.targetEntityID === null; - var rightHandAvailable = rightEquipEntity.targetEntityID === null; + var rightHandAvailable = rightEquipEntity.targetEntityID === null; if (rightHandAvailable && (distanceToRightHand < distanceToLeftHand || !leftHandAvailable)) { // clear any existing grab actions on the entity now (their later removal could affect bootstrapping flags) clearGrabActions(entityID); @@ -817,7 +864,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } } }; - + var onKeyPress = function(event) { if (event.text.toLowerCase() === UNEQUIP_KEY) { if (rightEquipEntity.targetEntityID) { @@ -828,7 +875,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } } }; - + var deleteEntity = function(entityID) { if (rightEquipEntity.targetEntityID === entityID) { rightEquipEntity.endEquipEntity(); @@ -837,7 +884,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa leftEquipEntity.endEquipEntity(); } }; - + var clearEntities = function() { if (rightEquipEntity.targetEntityID) { rightEquipEntity.endEquipEntity(); @@ -846,7 +893,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa leftEquipEntity.endEquipEntity(); } }; - + Messages.subscribe('Hifi-Hand-Grab'); Messages.subscribe('Hifi-Hand-Drop'); Messages.messageReceived.connect(handleMessage); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index d9b63ad534..9ee1b954e2 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -8,38 +8,19 @@ /* jslint bitwise: true */ /* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, - getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, + getEnabledModuleByName, makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, entityIsGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, - PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, - getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI - Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, - worldPositionToRegistrationFrameMatrix + TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, + getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, + Picks, makeLaserLockInfo, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, + worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES, Uuid, Picks */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); -Script.include("/~/system/libraries/Xform.js"); (function() { - var GRABBABLE_PROPERTIES = [ - "position", - "registrationPoint", - "rotation", - "gravity", - "collidesWith", - "dynamic", - "collisionless", - "locked", - "name", - "shapeType", - "parentID", - "parentJointIndex", - "density", - "dimensions", - "userData" - ]; var MARGIN = 25; @@ -105,9 +86,9 @@ Script.include("/~/system/libraries/Xform.js"); this.locked = false; this.highlightedEntity = null; this.reticleMinX = MARGIN; - this.reticleMaxX; + this.reticleMaxX = null; this.reticleMinY = MARGIN; - this.reticleMaxY; + this.reticleMaxY = null; this.ignoredEntities = []; @@ -211,7 +192,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix()); var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition); - var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES); var now = Date.now(); var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds this.currentObjectTime = now; @@ -328,7 +309,7 @@ Script.include("/~/system/libraries/Xform.js"); this.notPointingAtEntity = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var entityProperty = Entities.getEntityProperties(intersection.objectID); + var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); var entityType = entityProperty.type; var hudRayPick = controllerData.hudRayPicks[this.hand]; var point2d = this.calculateNewReticlePosition(hudRayPick.intersection); @@ -372,7 +353,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldControllerPosition = controllerLocation.position; var worldControllerRotation = controllerLocation.orientation; - var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); this.currentObjectPosition = grabbedProperties.position; this.grabRadius = intersection.distance; @@ -394,7 +375,7 @@ Script.include("/~/system/libraries/Xform.js"); }; this.targetIsNull = function() { - var properties = Entities.getEntityProperties(this.grabbedThingID); + var properties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES); if (Object.keys(properties).length === 0 && this.distanceHolding) { return true; } @@ -459,8 +440,8 @@ Script.include("/~/system/libraries/Xform.js"); // if we are doing a distance grab and the object or tablet gets close enough to the controller, // stop the far-grab so the near-grab or equip can take over. for (var k = 0; k < nearGrabReadiness.length; k++) { - if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID - || HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) { + if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID || + HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) { this.endFarGrabAction(); this.restoreIgnoredEntities(); return makeRunningValues(false, [], []); @@ -486,12 +467,7 @@ Script.include("/~/system/libraries/Xform.js"); Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); this.highlightedEntity = null; - var targetProps = Entities.getEntityProperties(entityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href", - "collisionless" - ]); + var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); if (targetProps.href !== "") { AddressManager.handleLookupString(targetProps.href); this.restoreIgnoredEntities(); @@ -540,12 +516,7 @@ Script.include("/~/system/libraries/Xform.js"); if (this.highlightedEntity !== targetEntityID) { Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); - var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href", - "collisionless" - ]); + var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps); selectionTargetObject.parentProps = getEntityParents(selectionTargetProps); @@ -575,11 +546,12 @@ Script.include("/~/system/libraries/Xform.js"); if (!_this.entityWithContextOverlay && _this.contextOverlayTimer && _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { - var props = Entities.getEntityProperties(rayPickInfo.objectID); + var props = Entities.getEntityProperties(rayPickInfo.objectID, DISPATCHER_PROPERTIES); var pointerEvent = { type: "Move", id: _this.hand + 1, // 0 is reserved for hardware mouse - pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props), + pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, + rayPickInfo.intersection, props), pos3D: rayPickInfo.intersection, normal: rayPickInfo.surfaceNormal, direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js b/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js index 78abcb9b20..571b8feda3 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js @@ -11,32 +11,14 @@ makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, entityIsGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, - Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, - Uuid, worldPositionToRegistrationFrameMatrix + Picks, makeLaserLockInfo, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, + Uuid, worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); -Script.include("/~/system/libraries/Xform.js"); (function() { - var GRABBABLE_PROPERTIES = [ - "position", - "registrationPoint", - "rotation", - "gravity", - "collidesWith", - "dynamic", - "collisionless", - "locked", - "name", - "shapeType", - "parentID", - "parentJointIndex", - "density", - "dimensions", - "userData" - ]; var MARGIN = 25; @@ -45,7 +27,6 @@ Script.include("/~/system/libraries/Xform.js"); this.entityProps = entityProps; this.targetEntityID = null; this.targetEntityProps = null; - this.previousCollisionStatus = null; this.getTargetEntity = function() { var parentPropsLength = this.parentProps.length; @@ -74,7 +55,6 @@ Script.include("/~/system/libraries/Xform.js"); this.potentialEntityWithContextOverlay = false; this.entityWithContextOverlay = false; this.contextOverlayTimer = false; - this.previousCollisionStatus = false; this.locked = false; this.highlightedEntity = null; this.reticleMinX = MARGIN; @@ -182,7 +162,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix()); var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition); - var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES); var now = Date.now(); var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds this.currentObjectTime = now; @@ -284,7 +264,7 @@ Script.include("/~/system/libraries/Xform.js"); this.notPointingAtEntity = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var entityProperty = Entities.getEntityProperties(intersection.objectID); + var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); var entityType = entityProperty.type; var hudRayPick = controllerData.hudRayPicks[this.hand]; var point2d = this.calculateNewReticlePosition(hudRayPick.intersection); @@ -319,7 +299,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldControllerPosition = controllerLocation.position; var worldControllerRotation = controllerLocation.orientation; - var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); this.currentObjectPosition = grabbedProperties.position; this.grabRadius = intersection.distance; @@ -341,7 +321,7 @@ Script.include("/~/system/libraries/Xform.js"); }; this.targetIsNull = function() { - var properties = Entities.getEntityProperties(this.grabbedThingID); + var properties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES); if (Object.keys(properties).length === 0 && this.distanceHolding) { return true; } @@ -351,7 +331,7 @@ Script.include("/~/system/libraries/Xform.js"); this.getTargetProps = function (controllerData) { var targetEntityID = controllerData.rayPicks[this.hand].objectID; if (targetEntityID) { - return Entities.getEntityProperties(targetEntityID); + return Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); } return null; }; @@ -435,11 +415,7 @@ Script.include("/~/system/libraries/Xform.js"); Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); this.highlightedEntity = null; - var targetProps = Entities.getEntityProperties(entityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href" - ]); + var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); if (targetProps.href !== "") { AddressManager.handleLookupString(targetProps.href); return makeRunningValues(false, [], []); @@ -488,11 +464,7 @@ Script.include("/~/system/libraries/Xform.js"); if (this.highlightedEntity !== targetEntityID) { Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); - var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href" - ]); + var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps); selectionTargetObject.parentProps = getEntityParents(selectionTargetProps); @@ -522,7 +494,8 @@ Script.include("/~/system/libraries/Xform.js"); if (!_this.entityWithContextOverlay && _this.contextOverlayTimer && _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { - var pEvProps = Entities.getEntityProperties(rayPickInfo.objectID); + var pEvProps = Entities.getEntityProperties(rayPickInfo.objectID, + DISPATCHER_PROPERTIES); var pointerEvent = { type: "Move", id: _this.hand + 1, // 0 is reserved for hardware mouse diff --git a/scripts/system/controllers/controllerModules/farParentGrabEntity.js b/scripts/system/controllers/controllerModules/farParentGrabEntity.js index a9ec246a32..45fe606c0f 100644 --- a/scripts/system/controllers/controllerModules/farParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farParentGrabEntity.js @@ -10,34 +10,15 @@ /* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Quat, getEnabledModuleByName, makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, entityIsGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation, - projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager, + projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, unhighlightTargetEntity, Messages, Uuid, findGroupParent, - worldPositionToRegistrationFrameMatrix + worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES, findFarGrabJointChildEntities */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); -Script.include("/~/system/libraries/Xform.js"); (function() { - var GRABBABLE_PROPERTIES = [ - "position", - "registrationPoint", - "rotation", - "gravity", - "collidesWith", - "dynamic", - "collisionless", - "locked", - "name", - "shapeType", - "parentID", - "parentJointIndex", - "density", - "dimensions", - "userData" - ]; - var MARGIN = 25; function TargetObject(entityID, entityProps) { @@ -68,6 +49,7 @@ Script.include("/~/system/libraries/Xform.js"); this.hand = hand; this.targetEntityID = null; this.targetObject = null; + this.previouslyUnhooked = {}; this.previousParentID = {}; this.previousParentJointIndex = {}; this.potentialEntityWithContextOverlay = false; @@ -78,6 +60,7 @@ Script.include("/~/system/libraries/Xform.js"); this.reticleMaxX = 0; this.reticleMinY = MARGIN; this.reticleMaxY = 0; + this.lastUnexpectedChildrenCheckTime = 0; var FAR_GRAB_JOINTS = [65527, 65528]; // FARGRAB_LEFTHAND_INDEX, FARGRAB_RIGHTHAND_INDEX @@ -214,7 +197,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix()); var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition); - var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); var now = Date.now(); var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds this.currentObjectTime = now; @@ -275,7 +258,7 @@ Script.include("/~/system/libraries/Xform.js"); this.endFarParentGrab = function (controllerData) { this.hapticTargetID = null; // var endProps = controllerData.nearbyEntityPropertiesByID[this.targetEntityID]; - var endProps = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES); + var endProps = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); if (this.thisFarGrabJointIsParent(endProps)) { Entities.editEntity(this.targetEntityID, { parentID: this.previousParentID[this.targetEntityID], @@ -313,7 +296,7 @@ Script.include("/~/system/libraries/Xform.js"); this.notPointingAtEntity = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var entityProperty = Entities.getEntityProperties(intersection.objectID); + var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); var entityType = entityProperty.type; var hudRayPick = controllerData.hudRayPicks[this.hand]; var point2d = this.calculateNewReticlePosition(hudRayPick.intersection); @@ -348,7 +331,7 @@ Script.include("/~/system/libraries/Xform.js"); var worldControllerPosition = controllerLocation.position; var worldControllerRotation = controllerLocation.orientation; - var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES); + var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES); this.currentObjectPosition = grabbedProperties.position; this.grabRadius = intersection.distance; @@ -369,8 +352,51 @@ Script.include("/~/system/libraries/Xform.js"); } }; + this.checkForUnexpectedChildren = function (controllerData) { + // sometimes things can get parented to a hand and this script is unaware. Search for such entities and + // unhook them. + + var now = Date.now(); + var UNEXPECTED_CHILDREN_CHECK_TIME = 0.1; // seconds + if (now - this.lastUnexpectedChildrenCheckTime > MSECS_PER_SEC * UNEXPECTED_CHILDREN_CHECK_TIME) { + this.lastUnexpectedChildrenCheckTime = now; + + var children = findFarGrabJointChildEntities(this.hand); + var _this = this; + + children.forEach(function(childID) { + // we appear to be holding something and this script isn't in a state that would be holding something. + // unhook it. if we previously took note of this entity's parent, put it back where it was. This + // works around some problems that happen when more than one hand or avatar is passing something around. + if (_this.previousParentID[childID]) { + var previousParentID = _this.previousParentID[childID]; + var previousParentJointIndex = _this.previousParentJointIndex[childID]; + + // The main flaw with keeping track of previous parentage in individual scripts is: + // (1) A grabs something (2) B takes it from A (3) A takes it from B (4) A releases it + // now A and B will take turns passing it back to the other. Detect this and stop the loop here... + var UNHOOK_LOOP_DETECT_MS = 200; + if (_this.previouslyUnhooked[childID]) { + if (now - _this.previouslyUnhooked[childID] < UNHOOK_LOOP_DETECT_MS) { + previousParentID = Uuid.NULL; + previousParentJointIndex = -1; + } + } + _this.previouslyUnhooked[childID] = now; + + Entities.editEntity(childID, { + parentID: previousParentID, + parentJointIndex: previousParentJointIndex + }); + } else { + Entities.editEntity(childID, { parentID: Uuid.NULL }); + } + }); + } + }; + this.targetIsNull = function() { - var properties = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES); + var properties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES); if (Object.keys(properties).length === 0 && this.distanceHolding) { return true; } @@ -380,7 +406,7 @@ Script.include("/~/system/libraries/Xform.js"); this.getTargetProps = function (controllerData) { var targetEntity = controllerData.rayPicks[this.hand].objectID; if (targetEntity) { - var gtProps = Entities.getEntityProperties(targetEntity, GRABBABLE_PROPERTIES); + var gtProps = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES); if (entityIsGrabbable(gtProps)) { // give haptic feedback if (gtProps.id !== this.hapticTargetID) { @@ -416,6 +442,7 @@ Script.include("/~/system/libraries/Xform.js"); return makeRunningValues(true, [], []); } } else { + this.checkForUnexpectedChildren(controllerData); this.destroyContextOverlay(); return makeRunningValues(false, [], []); } @@ -480,11 +507,7 @@ Script.include("/~/system/libraries/Xform.js"); var entityID = rayPickInfo.objectID; Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); this.highlightedEntity = null; - var targetProps = Entities.getEntityProperties(entityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href" - ]); + var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES); if (targetProps.href !== "") { AddressManager.handleLookupString(targetProps.href); return makeRunningValues(false, [], []); @@ -533,11 +556,7 @@ Script.include("/~/system/libraries/Xform.js"); var targetEntityID = rayPickInfo.objectID; if (this.highlightedEntity !== targetEntityID) { Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity); - var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href" - ]); + var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps); selectionTargetObject.parentProps = getEntityParents(selectionTargetProps); @@ -567,7 +586,8 @@ Script.include("/~/system/libraries/Xform.js"); if (!_this.entityWithContextOverlay && _this.contextOverlayTimer && _this.potentialEntityWithContextOverlay === rayPickInfo.objectID) { - var cotProps = Entities.getEntityProperties(rayPickInfo.objectID); + var cotProps = Entities.getEntityProperties(rayPickInfo.objectID, + DISPATCHER_PROPERTIES); var pointerEvent = { type: "Move", id: _this.hand + 1, // 0 is reserved for hardware mouse diff --git a/scripts/system/controllers/controllerModules/farTrigger.js b/scripts/system/controllers/controllerModules/farTrigger.js index 25df17ee84..2b003e4732 100644 --- a/scripts/system/controllers/controllerModules/farTrigger.js +++ b/scripts/system/controllers/controllerModules/farTrigger.js @@ -6,19 +6,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, +/* global Script, RIGHT_HAND, LEFT_HAND, MyAvatar, makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, - PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams + getGrabbableData, makeLaserParams, DISPATCHER_PROPERTIES */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); (function() { - function entityWantsNearTrigger(props) { + function entityWantsFarTrigger(props) { var grabbableData = getGrabbableData(props); - return grabbableData.triggerable || grabbableData.wantsTrigger; + return grabbableData.triggerable; } function FarTriggerEntity(hand) { @@ -37,11 +36,10 @@ Script.include("/~/system/libraries/controllers.js"); makeLaserParams(this.hand, false)); this.getTargetProps = function (controllerData) { - // nearbyEntityProperties is already sorted by length from controller var targetEntity = controllerData.rayPicks[this.hand].objectID; if (targetEntity) { - var targetProperties = Entities.getEntityProperties(targetEntity); - if (entityWantsNearTrigger(targetProperties)) { + var targetProperties = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES); + if (entityWantsFarTrigger(targetProperties)) { return targetProperties; } } diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index bc09ebee7a..403b5d5149 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -8,11 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset, - makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, - PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable, Messages, print -*/ +/* global Script, MyAvatar, entityIsCloneable, Messages, print */ "use strict"; @@ -134,7 +130,7 @@ rightHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID); } } catch (e) { - print("Failed to parse message"); + print("highlightNearbyEntities -- Failed to parse message: " + JSON.stringify(message)); } } else if (channel === 'Hifi-unhighlight-all') { leftHighlightNearbyEntities.clearAll(); diff --git a/scripts/system/controllers/controllerModules/hudOverlayPointer.js b/scripts/system/controllers/controllerModules/hudOverlayPointer.js index 04a3911e0b..6181414084 100644 --- a/scripts/system/controllers/controllerModules/hudOverlayPointer.js +++ b/scripts/system/controllers/controllerModules/hudOverlayPointer.js @@ -10,16 +10,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, - getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, - enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, - makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, - PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, - getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI, - makeLaserParams - -*/ +/* global Script, Controller, RIGHT_HAND, LEFT_HAND, HMD, makeLaserParams */ (function() { Script.include("/~/system/libraries/controllers.js"); var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); @@ -72,7 +63,7 @@ this.processLaser = function(controllerData) { var controllerLocation = controllerData.controllerLocations[this.hand]; - var otherModuleRunning = this.getOtherModule().running; + // var otherModuleRunning = this.getOtherModule().running; if ((controllerData.triggerValues[this.hand] < ControllerDispatcherUtils.TRIGGER_ON_VALUE || !controllerLocation.valid) || this.pointingAtTablet(controllerData)) { return false; diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index 15da1537a1..4b6eb7e313 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -8,9 +8,8 @@ /* jslint bitwise: true */ /* global Script, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeRunningValues, - Messages, makeDispatcherModuleParameters, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, - getEnabledModuleByName, PICK_MAX_DISTANCE, isInEditMode, Picks, makeLaserParams, Entities + Messages, makeDispatcherModuleParameters, HMD, getEnabledModuleByName, TRIGGER_ON_VALUE, isInEditMode, Picks, + makeLaserParams */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -24,9 +23,9 @@ Script.include("/~/system/libraries/utils.js"); this.triggerClicked = false; this.selectedTarget = null; this.reticleMinX = MARGIN; - this.reticleMaxX; + this.reticleMaxX = null; this.reticleMinY = MARGIN; - this.reticleMaxY; + this.reticleMaxY = null; this.parameters = makeDispatcherModuleParameters( 160, @@ -49,8 +48,8 @@ Script.include("/~/system/libraries/utils.js"); }; this.pointingAtTablet = function(objectID) { - return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) - || (HMD.homeButtonID && objectID === HMD.homeButtonID); + return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || + (HMD.homeButtonID && objectID === HMD.homeButtonID); }; this.calculateNewReticlePosition = function(intersection) { diff --git a/scripts/system/controllers/controllerModules/inVREditMode.js b/scripts/system/controllers/controllerModules/inVREditMode.js index 7b78d5e1c4..ef02e41ef3 100644 --- a/scripts/system/controllers/controllerModules/inVREditMode.js +++ b/scripts/system/controllers/controllerModules/inVREditMode.js @@ -8,7 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, +/* global Script, HMD, Messages, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, makeRunningValues, getEnabledModuleByName, makeLaserParams */ @@ -22,17 +22,17 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var NO_HAND_LASER = -1; // Invalid hand parameter so that default laser is not displayed. this.parameters = makeDispatcherModuleParameters( 200, // Not too high otherwise the tablet laser doesn't work. - this.hand === RIGHT_HAND - ? ["rightHand", "rightHandEquip", "rightHandTrigger"] - : ["leftHand", "leftHandEquip", "leftHandTrigger"], + this.hand === RIGHT_HAND ? + ["rightHand", "rightHandEquip", "rightHandTrigger"] : + ["leftHand", "leftHandEquip", "leftHandTrigger"], [], 100, makeLaserParams(NO_HAND_LASER, false) ); this.pointingAtTablet = function (objectID) { - return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) - || (HMD.homeButtonID && objectID === HMD.homeButtonID); + return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || + (HMD.homeButtonID && objectID === HMD.homeButtonID); }; this.isReady = function (controllerData) { @@ -49,9 +49,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } // Tablet stylus. - var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightTabletStylusInput" - : "LeftTabletStylusInput"); + var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND ? + "RightTabletStylusInput" : + "LeftTabletStylusInput"); if (tabletStylusInput) { var tabletReady = tabletStylusInput.isReady(controllerData); if (tabletReady.active) { @@ -60,9 +60,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } // Tablet surface. - var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightWebSurfaceLaserInput" - : "LeftWebSurfaceLaserInput"); + var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ? + "RightWebSurfaceLaserInput" : + "LeftWebSurfaceLaserInput"); if (overlayLaser) { var overlayLaserReady = overlayLaser.isReady(controllerData); var target = controllerData.rayPicks[this.hand].objectID; @@ -72,9 +72,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } // Tablet grabbing. - var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightNearParentingGrabOverlay" - : "LeftNearParentingGrabOverlay"); + var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND ? + "RightNearParentingGrabOverlay" : + "LeftNearParentingGrabOverlay"); if (nearOverlay) { var nearOverlayReady = nearOverlay.isReady(controllerData); if (nearOverlayReady.active && HMD.tabletID && nearOverlay.grabbedThingID === HMD.tabletID) { @@ -83,9 +83,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } // Teleport. - var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightTeleporter" - : "LeftTeleporter"); + var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND ? + "RightTeleporter" : + "LeftTeleporter"); if (teleporter) { var teleporterReady = teleporter.isReady(controllerData); if (teleporterReady.active) { diff --git a/scripts/system/controllers/controllerModules/mouseHMD.js b/scripts/system/controllers/controllerModules/mouseHMD.js index 101a3502e1..27fe82ca19 100644 --- a/scripts/system/controllers/controllerModules/mouseHMD.js +++ b/scripts/system/controllers/controllerModules/mouseHMD.js @@ -10,6 +10,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/* global Script, HMD, Reticle, Vec3, Controller */ + (function() { var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); @@ -121,7 +123,7 @@ if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now) || !hmdActive) { if (!hmdActive) { Reticle.visible = true; - } else { + } else { Reticle.visible = false; } diff --git a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js index ac57c8691f..59a68d98a4 100644 --- a/scripts/system/controllers/controllerModules/mouseHighlightEntities.js +++ b/scripts/system/controllers/controllerModules/mouseHighlightEntities.js @@ -12,7 +12,7 @@ /* jslint bitwise: true */ -/* global Script, print, Entities, Picks, HMD, Controller, MyAvatar, isInEditMode*/ +/* global Script, print, Entities, Messages, Picks, HMD, MyAvatar, isInEditMode, DISPATCHER_PROPERTIES */ (function() { @@ -46,11 +46,7 @@ var targetEntityID = pickResult.objectID; if (this.highlightedEntity !== targetEntityID) { - var targetProps = Entities.getEntityProperties(targetEntityID, [ - "dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type", "href" - ]); + var targetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES); if (this.highlightedEntity) { dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity); diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index a8de76aebd..5ced6080a2 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -10,7 +10,8 @@ propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity, - HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity, Uuid + HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity, Uuid, + DISPATCHER_PROPERTIES */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -62,12 +63,12 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); var grabbableData = getGrabbableData(targetProps); - this.ignoreIK = grabbableData.ignoreIK; - this.kinematicGrab = grabbableData.kinematic; + this.grabFollowsController = grabbableData.grabFollowsController; + this.kinematicGrab = grabbableData.grabKinematic; var handRotation; var handPosition; - if (this.ignoreIK) { + if (this.grabFollowsController) { var controllerID = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var controllerLocation = getControllerWorldLocation(controllerID, false); @@ -99,7 +100,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); ttl: ACTION_TTL, kinematic: this.kinematicGrab, kinematicSetVelocity: true, - ignoreIK: this.ignoreIK + ignoreIK: this.grabFollowsController }); if (this.actionID === Uuid.NULL) { this.actionID = null; @@ -136,7 +137,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); ttl: ACTION_TTL, kinematic: this.kinematicGrab, kinematicSetVelocity: true, - ignoreIK: this.ignoreIK + ignoreIK: this.grabFollowsController }); if (success) { this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); @@ -238,7 +239,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); var targetCloneable = entityIsCloneable(targetProps); if (targetCloneable) { var cloneID = cloneEntity(targetProps); - var cloneProps = Entities.getEntityProperties(cloneID); + var cloneProps = Entities.getEntityProperties(cloneID, DISPATCHER_PROPERTIES); this.targetEntityID = cloneID; this.startNearGrabAction(controllerData, cloneProps); } else { diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index cc88371441..bbdcbaaa64 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -12,7 +12,7 @@ findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity, - distanceBetweenEntityLocalPositionAndBoundingBox, GRAB_POINT_SPHERE_OFFSET + distanceBetweenEntityLocalPositionAndBoundingBox, getGrabbableData, getGrabPointSphereOffset, DISPATCHER_PROPERTIES */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -28,16 +28,8 @@ Script.include("/~/system/libraries/controllers.js"); var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral function getGrabOffset(handController) { - var offset = GRAB_POINT_SPHERE_OFFSET; - if (handController === Controller.Standard.LeftHand) { - offset = { - x: -GRAB_POINT_SPHERE_OFFSET.x, - y: GRAB_POINT_SPHERE_OFFSET.y, - z: GRAB_POINT_SPHERE_OFFSET.z - }; - } - - offset.y = -GRAB_POINT_SPHERE_OFFSET.y; + var offset = getGrabPointSphereOffset(handController, true); + offset.y = -offset.y; return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); } @@ -101,6 +93,7 @@ Script.include("/~/system/libraries/controllers.js"); }; this.startNearParentingGrabEntity = function (controllerData, targetProps) { + var grabData = getGrabbableData(targetProps); Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); unhighlightTargetEntity(this.targetEntityID); this.highlightedEntity = null; @@ -111,12 +104,11 @@ Script.include("/~/system/libraries/controllers.js"); Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message)); var handJointIndex; - // if (this.ignoreIK) { - // handJointIndex = this.controllerJointIndex; - // } else { - // handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); - // } - handJointIndex = getControllerJointIndex(this.hand); + if (grabData.grabFollowsController) { + handJointIndex = getControllerJointIndex(this.hand); + } else { + handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"); + } var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(targetProps.id, "startNearGrab", args); @@ -368,7 +360,7 @@ Script.include("/~/system/libraries/controllers.js"); if (this.cloneAllowed) { var cloneID = cloneEntity(targetProps); if (cloneID !== null) { - var cloneProps = Entities.getEntityProperties(cloneID); + var cloneProps = Entities.getEntityProperties(cloneID, DISPATCHER_PROPERTIES); this.grabbing = true; this.targetEntityID = cloneID; this.startNearParentingGrabEntity(controllerData, cloneProps); diff --git a/scripts/system/controllers/controllerModules/nearTrigger.js b/scripts/system/controllers/controllerModules/nearTrigger.js index 6a9cd9fbcd..f4e39cfbb9 100644 --- a/scripts/system/controllers/controllerModules/nearTrigger.js +++ b/scripts/system/controllers/controllerModules/nearTrigger.js @@ -16,7 +16,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); function entityWantsNearTrigger(props) { var grabbableData = getGrabbableData(props); - return grabbableData.triggerable || grabbableData.wantsTrigger; + return grabbableData.triggerable; } function NearTriggerEntity(hand) { diff --git a/scripts/system/controllers/controllerModules/scaleEntity.js b/scripts/system/controllers/controllerModules/scaleEntity.js index 9d54eef98e..24c05a1394 100644 --- a/scripts/system/controllers/controllerModules/scaleEntity.js +++ b/scripts/system/controllers/controllerModules/scaleEntity.js @@ -7,7 +7,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Vec3, MyAvatar, RIGHT_HAND */ +/* global Script, Vec3, MyAvatar, Entities, RIGHT_HAND */ (function() { var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js"); diff --git a/scripts/system/controllers/controllerModules/stylusInput.js b/scripts/system/controllers/controllerModules/stylusInput.js index 0ca6cd1b04..1d36fb687f 100644 --- a/scripts/system/controllers/controllerModules/stylusInput.js +++ b/scripts/system/controllers/controllerModules/stylusInput.js @@ -5,11 +5,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, - enableDispatcherModule, disableDispatcherModule, makeRunningValues, - Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, - HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, - getEnabledModuleByName, Pointers, Picks, PickType +/* global Script, MyAvatar, Controller, Uuid, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeRunningValues, Vec3, makeDispatcherModuleParameters, Overlays, HMD, Settings, getEnabledModuleByName, Pointers, + Picks, PickType */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -200,7 +198,7 @@ Script.include("/~/system/libraries/controllers.js"); Overlays.hoverEnterOverlay.connect(mouseHoverEnter); Overlays.hoverLeaveOverlay.connect(mouseHoverLeave); - Overlays.mousePressOnOverlay.connect(mousePress); + Overlays.mousePressOnOverlay.connect(mousePress); this.cleanup = function () { leftTabletStylusInput.cleanup(); diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index bf5022cdaf..20a1e47bf2 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -10,7 +10,7 @@ /* jslint bitwise: true */ -/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, +/* global Script, Entities, MyAvatar, Controller, Quat, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3, HMD, Uuid, AvatarList, Picks, Pointers, PickType */ @@ -680,8 +680,8 @@ Script.include("/~/system/libraries/controllers.js"); this.teleportLocked = function () { // Lock teleport if in advanced movement mode and have just transitioned from pressing a direction button. - return Controller.getValue(Controller.Hardware.Application.AdvancedMovement) - && (_this.axisButtonStateX !== 0 || _this.axisButtonStateY !== 0); + return Controller.getValue(Controller.Hardware.Application.AdvancedMovement) && + (_this.axisButtonStateX !== 0 || _this.axisButtonStateY !== 0); }; this.buttonPress = function (value) { diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 2412e2fa1c..3d66e84d1f 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -5,11 +5,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, - makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, - INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, - TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams +/* global Script, Entities, enableDispatcherModule, disableDispatcherModule, makeRunningValues, + makeDispatcherModuleParameters, Overlays, HMD, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, + ContextOverlay, Picks, makeLaserParams, Settings, MyAvatar, RIGHT_HAND, LEFT_HAND, DISPATCHER_PROPERTIES */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -82,7 +80,7 @@ Script.include("/~/system/libraries/controllers.js"); return overlayType === "web3d" || triggerPressed; } } else if (intersection.type === Picks.INTERSECTED_ENTITY) { - var entityProperties = Entities.getEntityProperties(objectID); + var entityProperties = Entities.getEntityProperties(objectID, DISPATCHER_PROPERTIES); var entityType = entityProperties.type; var isLocked = entityProperties.locked; return entityType === "Web" && (!isLocked || triggerPressed); @@ -91,8 +89,9 @@ Script.include("/~/system/libraries/controllers.js"); }; this.deleteContextOverlay = function() { - var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"); + var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND ? + "RightFarActionGrabEntity" : + "LeftFarActionGrabEntity"); if (farGrabModule) { var entityWithContextOverlay = farGrabModule.entityWithContextOverlay; diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index 6899577de2..73938af0d3 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/* global Script, Menu */ + var CONTOLLER_SCRIPTS = [ "squeezeHands.js", "controllerDisplayManager.js", @@ -19,8 +21,8 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/nearParentGrabEntity.js", "controllerModules/nearParentGrabOverlay.js", "controllerModules/nearActionGrabEntity.js", - // "controllerModules/farActionGrabEntity.js", - // "controllerModules/farParentGrabEntity.js", + "controllerModules/farActionGrabEntityDynOnly.js", + "controllerModules/farParentGrabEntity.js", "controllerModules/stylusInput.js", "controllerModules/equipEntity.js", "controllerModules/nearTrigger.js", @@ -38,25 +40,22 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/mouseHighlightEntities.js" ]; -if (Settings.getValue("useFarGrabJoints", false)) { - CONTOLLER_SCRIPTS.push("controllerModules/farActionGrabEntityDynOnly.js"); - CONTOLLER_SCRIPTS.push("controllerModules/farParentGrabEntity.js"); -} else { - CONTOLLER_SCRIPTS.push("controllerModules/farActionGrabEntity.js"); -} - var DEBUG_MENU_ITEM = "Debug defaultScripts.js"; function runDefaultsTogether() { for (var j in CONTOLLER_SCRIPTS) { - Script.include(CONTOLLER_SCRIPTS[j]); + if (CONTOLLER_SCRIPTS.hasOwnProperty(j)) { + Script.include(CONTOLLER_SCRIPTS[j]); + } } } function runDefaultsSeparately() { for (var i in CONTOLLER_SCRIPTS) { - Script.load(CONTOLLER_SCRIPTS[i]); + if (CONTOLLER_SCRIPTS.hasOwnProperty(i)) { + Script.load(CONTOLLER_SCRIPTS[i]); + } } } diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 48229ac9d9..a78a2971e9 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -14,9 +14,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* global MyAvatar, Entities, Script, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller, - isInEditMode, HMD entityIsGrabbable, Picks, PickType, Pointers, unhighlightTargetEntity*/ - +/* global MyAvatar, Entities, Script, HMD, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller, + isInEditMode, entityIsGrabbable, Picks, PickType, Pointers, unhighlightTargetEntity, DISPATCHER_PROPERTIES, + entityIsGrabbable, entityIsEquipped, getMainTabletIDs +*/ +/* jslint bitwise: true */ (function() { // BEGIN LOCAL_SCOPE @@ -37,7 +39,6 @@ var IDENTITY_QUAT = { z: 0, w: 0 }; -var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with handControllerGrab.js var DEFAULT_GRABBABLE_DATA = { grabbable: true, @@ -339,16 +340,14 @@ Grabber.prototype.pressEvent = function(event) { return; } - var props = Entities.getEntityProperties(pickResults.objectID, ["dynamic", "userData", "locked", "type"]); + var props = Entities.getEntityProperties(pickResults.objectID, DISPATCHER_PROPERTIES); var isDynamic = props.dynamic; - var isGrabbable = props.grabbable; if (!entityIsGrabbable(props)) { // only grab grabbable objects return; } - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, pickResults.objectID, DEFAULT_GRABBABLE_DATA); - if (grabbableData.grabbable === false) { + if (!props.grab.grabbable) { return; } @@ -359,7 +358,7 @@ Grabber.prototype.pressEvent = function(event) { mouse.startDrag(event); var clickedEntity = pickResults.objectID; - var entityProperties = Entities.getEntityProperties(clickedEntity); + var entityProperties = Entities.getEntityProperties(clickedEntity, DISPATCHER_PROPERTIES); this.startPosition = entityProperties.position; this.lastRotation = entityProperties.rotation; this.madeDynamic = false; @@ -484,7 +483,7 @@ Grabber.prototype.moveEvent = function(event) { Grabber.prototype.moveEventProcess = function() { this.moveEventTimer = null; // see if something added/restored gravity - var entityProperties = Entities.getEntityProperties(this.entityID); + var entityProperties = Entities.getEntityProperties(this.entityID, DISPATCHER_PROPERTIES); if (!entityProperties || !entityProperties.gravity || HMD.active) { return; } diff --git a/scripts/system/controllers/handTouch.js b/scripts/system/controllers/handTouch.js index 97a24cb3f2..c706d054c1 100644 --- a/scripts/system/controllers/handTouch.js +++ b/scripts/system/controllers/handTouch.js @@ -11,7 +11,7 @@ /* jslint bitwise: true */ -/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities +/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities, RayPick */ (function () { @@ -22,8 +22,8 @@ var MSECONDS_AFTER_LOAD = 2000; var updateFingerWithIndex = 0; var untouchableEntities = []; - - // Keys to access finger data + + // Keys to access finger data var fingerKeys = ["pinky", "ring", "middle", "index", "thumb"]; // Additionally close the hands to achieve a grabbing effect @@ -47,7 +47,7 @@ left: new Palm(), right: new Palm() }; - + var handJointNames = {left: "LeftHand", right: "RightHand"}; // Store which fingers are touching - if all false restate the default poses diff --git a/scripts/system/controllers/squeezeHands.js b/scripts/system/controllers/squeezeHands.js index c9de473e28..69f44f46a9 100644 --- a/scripts/system/controllers/squeezeHands.js +++ b/scripts/system/controllers/squeezeHands.js @@ -11,6 +11,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/* global Script, MyAvatar, Messages, Controller */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ (function() { // BEGIN LOCAL_SCOPE @@ -20,7 +21,7 @@ var lastRightTrigger = 0; var leftHandOverlayAlpha = 0; var rightHandOverlayAlpha = 0; -var CONTROLLER_DEAD_SPOT = 0.25; +// var CONTROLLER_DEAD_SPOT = 0.25; var TRIGGER_SMOOTH_TIMESCALE = 0.1; var OVERLAY_RAMP_RATE = 8.0; @@ -42,9 +43,9 @@ function clamp(val, min, max) { return Math.min(Math.max(val, min), max); } -function normalizeControllerValue(val) { - return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1); -} +// function normalizeControllerValue(val) { +// return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1); +// } function lerp(a, b, alpha) { return a * (1 - alpha) + b * alpha; diff --git a/scripts/system/controllers/touchControllerConfiguration.js b/scripts/system/controllers/touchControllerConfiguration.js index f22252f646..991b77b8af 100644 --- a/scripts/system/controllers/touchControllerConfiguration.js +++ b/scripts/system/controllers/touchControllerConfiguration.js @@ -8,7 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* globals TOUCH_CONTROLLER_CONFIGURATION_LEFT:true TOUCH_CONTROLLER_CONFIGURATION_RIGHT:true */ +/* globals TOUCH_CONTROLLER_CONFIGURATION_LEFT:true, TOUCH_CONTROLLER_CONFIGURATION_RIGHT:true, + Quat, Vec3, Script, MyAvatar, Controller */ /* eslint camelcase: ["error", { "properties": "never" }] */ var leftBaseRotation = Quat.multiply( @@ -22,9 +23,9 @@ var rightBaseRotation = Quat.multiply( // keep these in sync with the values from OculusHelpers.cpp var CONTROLLER_LENGTH_OFFSET = 0.0762; -var CONTROLLER_LATERAL_OFFSET = 0.0381; -var CONTROLLER_VERTICAL_OFFSET = 0.0381; -var CONTROLLER_FORWARD_OFFSET = 0.1524; +// var CONTROLLER_LATERAL_OFFSET = 0.0381; +// var CONTROLLER_VERTICAL_OFFSET = 0.0381; +// var CONTROLLER_FORWARD_OFFSET = 0.1524; var leftBasePosition = Vec3.multiplyQbyV(leftBaseRotation, { x: -CONTROLLER_LENGTH_OFFSET / 2.0, diff --git a/scripts/system/controllers/viveControllerConfiguration.js b/scripts/system/controllers/viveControllerConfiguration.js index 60f0b6b88a..09fd8adacc 100644 --- a/scripts/system/controllers/viveControllerConfiguration.js +++ b/scripts/system/controllers/viveControllerConfiguration.js @@ -8,11 +8,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* globals VIVE_CONTROLLER_CONFIGURATION_LEFT:true VIVE_CONTROLLER_CONFIGURATION_RIGHT:true */ +/* globals VIVE_CONTROLLER_CONFIGURATION_LEFT:true, VIVE_CONTROLLER_CONFIGURATION_RIGHT:true, + MyAvatar, Quat, Script, Vec3, Controller */ /* eslint camelcase: ["error", { "properties": "never" }] */ -var LEFT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_LEFTHAND"); -var RIGHT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_RIGHTHAND"); +// var LEFT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_LEFTHAND"); +// var RIGHT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_RIGHTHAND"); var leftBaseRotation = Quat.multiply( Quat.fromPitchYawRollDegrees(0, 0, 45), @@ -58,10 +59,10 @@ var viveNaturalPosition = { }; var BASE_URL = Script.resourcesPath(); -var TIP_TEXTURE_BASE_URL = BASE_URL + "meshes/controller/vive_tips.fbm/"; +// var TIP_TEXTURE_BASE_URL = BASE_URL + "meshes/controller/vive_tips.fbm/"; var viveModelURL = BASE_URL + "meshes/controller/vive_body.fbx"; -var viveTipsModelURL = BASE_URL + "meshes/controller/vive_tips.fbx"; +// var viveTipsModelURL = BASE_URL + "meshes/controller/vive_tips.fbx"; var viveTriggerModelURL = "meshes/controller/vive_trigger.fbx"; VIVE_CONTROLLER_CONFIGURATION_LEFT = { @@ -340,4 +341,3 @@ VIVE_CONTROLLER_CONFIGURATION_RIGHT = { } ] }; - diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 27858722ec..b4684a0fd4 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -345,11 +345,15 @@ var toolBar = (function () { position = grid.snapToSurface(grid.snapToGrid(position, false, dimensions), dimensions); properties.position = position; + + if (!properties.grab) { + properties.grab = {}; + } if (Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE) && !(properties.type === "Zone" || properties.type === "Light" || properties.type === "ParticleEffect")) { - properties.userData = JSON.stringify({ grabbableKey: { grabbable: true } }); + properties.grab.grabbable = true; } else { - properties.userData = JSON.stringify({ grabbableKey: { grabbable: false } }); + properties.grab.grabbable = false; } SelectionManager.saveProperties(); diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 6c1931932a..8e7b3f1ad5 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -244,7 +244,7 @@ input.search:focus { height: 26px; margin-top: 1px; margin-bottom: 1px; - box-shadow: 0 0 0px 1px #00b4ef; + box-shadow: 0 0 0 1px #00b4ef; } input:disabled, textarea:disabled { @@ -455,11 +455,11 @@ input[type=checkbox]:checked + label:hover { #properties-list fieldset { position: relative; /* 0.1px on the top is to prevent margin collapsing between this and it's first child */ - margin: 21px -21px 0px -21px; - padding: 0.1px 21px 0px 21px; + margin: 21px -21px 0 -21px; + padding: 0.1px 21px 0 21px; border: none; border-top: 1px rgb(90,90,90) solid; - box-shadow: 0px -1px 0px rgb(37,37,37); + box-shadow: 0 -1px 0 rgb(37,37,37); } #properties-list fieldset.fstuple, #properties-list fieldset.fsrow { @@ -469,7 +469,7 @@ input[type=checkbox]:checked + label:hover { } #properties-list > fieldset[data-collapsed="true"] + fieldset { - margin-top: 0px; + margin-top: 0; } #properties-list > fieldset[data-collapsed="true"] > *:not(legend) { @@ -477,14 +477,14 @@ input[type=checkbox]:checked + label:hover { } #properties-list legend + fieldset { - margin-top: 0px; + margin-top: 0; border: none; box-shadow: none; } #properties-list > fieldset#properties-header { - margin-top: 0px; - padding-bottom: 0px; + margin-top: 0; + padding-bottom: 0; } @@ -940,8 +940,8 @@ tuple, .blue:focus, .tuple .z:focus, .tuple .roll:focus { #properties-list .two-column fieldset legend { display: table; width: 100%; - margin: 21px -21px 0px -21px; - padding: 0px 0px 0px 21px; + margin: 21px -21px 0 -21px; + padding: 0 0 0 21px; font-family: Raleway-Regular; font-size: 12px; color: #afafaf; @@ -973,6 +973,10 @@ fieldset .checkbox-sub-props .property:first-child { ::-webkit-scrollbar-track { background-color: #2e2e2e; } +#entity-table-scroll::-webkit-scrollbar-track { + border-bottom-right-radius: 7px; +} + ::-webkit-scrollbar-thumb { background-color: #696969; border: 2px solid #2e2e2e; @@ -1031,6 +1035,16 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { position: relative; /* New positioning context. */ } +#footer-text { + float: right; + padding-top: 12px; + padding-right: 22px; +} + +#entity-list-footer { + padding-top: 9px; +} + #search-area { padding-right: 168px; padding-bottom: 24px; @@ -1068,6 +1082,9 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { margin-top: 28px; border-left: 2px solid #575757; border-right: 2px solid #575757; + border-bottom: 2px solid #575757; + border-bottom-left-radius: 7px; + border-bottom-right-radius: 7px; background-color: #1c1c1c; } @@ -1084,8 +1101,7 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { background-color: #1c1c1c; } -#entity-table thead tr, #entity-table thead tr th, -#entity-table tfoot tr, #entity-table tfoot tr td { +#entity-table thead tr, #entity-table thead tr th { background: none; } @@ -1196,19 +1212,6 @@ th#entity-hasTransparent .sort-order { top: -1px; } -#entity-table tfoot { - box-sizing: border-box; - border: 2px solid #575757; - border-bottom-left-radius: 7px; - border-bottom-right-radius: 7px; - border-top: 1px solid #575757; - position: absolute; - bottom: -21px; - left: 0; - width: 100%; -} - - #col-type { width: 16%; } @@ -1788,4 +1791,13 @@ input#reset-to-natural-dimensions { .skybox-section { display: none; -} \ No newline at end of file +} + +input[type=button]#export { + height: 38px; + width: 180px; +} + +body#entity-list-body { + padding-bottom: 0; +} diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 7eed78ecf3..c62c785c99 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -1,4 +1,4 @@ -