diff --git a/interface/resources/meshes/tablet-with-home-button.fbx b/interface/resources/meshes/tablet-with-home-button.fbx
index 13ab8bab0c..70b8008bad 100644
Binary files a/interface/resources/meshes/tablet-with-home-button.fbx and b/interface/resources/meshes/tablet-with-home-button.fbx differ
diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
index 8d94e284ed..177dfed420 100644
--- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
+++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml
@@ -239,6 +239,25 @@ Rectangle {
}
}
}
+ }
+
+ HifiCommerceCommon.FirstUseTutorial {
+ id: firstUseTutorial;
+ z: 999;
+ visible: root.activeView === "firstUseTutorial";
+ anchors.fill: parent;
+
+ Connections {
+ onSendSignalToParent: {
+ switch (message.method) {
+ case 'tutorial_skipClicked':
+ case 'tutorial_finished':
+ Settings.setValue("isFirstUseOfPurchases", false);
+ root.activeView = "checkoutSuccess";
+ break;
+ }
+ }
+ }
}
//
@@ -611,6 +630,28 @@ Rectangle {
lightboxPopup.visible = true;
}
}
+ RalewaySemiBold {
+ id: explainRezText;
+ //visible: !root.isWearable;
+ text: 'What does "Rez" mean?'
+ // Text size
+ size: 16;
+ // Anchors
+ anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
+ anchors.topMargin: 6;
+ height: paintedHeight;
+ anchors.left: parent.left;
+ anchors.right: parent.right;
+ // Style
+ color: hifi.colors.redAccent;
+ wrapMode: Text.WordWrap;
+ // Alignment
+ horizontalAlignment: Text.AlignHCenter;
+ verticalAlignment: Text.AlignVCenter;
+ onLinkActivated: {
+ root.activeView = "firstUseTutorial";
+ }
+ }
RalewaySemiBold {
id: myPurchasesLink;
@@ -618,7 +659,7 @@ Rectangle {
// Text size
size: 20;
// Anchors
- anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
+ anchors.top: explainRezText.visible ? explainRezText.bottom : (noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom);
anchors.topMargin: 40;
height: paintedHeight;
anchors.left: parent.left;
diff --git a/interface/resources/qml/hifi/commerce/purchases/FirstUseTutorial.qml b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
similarity index 97%
rename from interface/resources/qml/hifi/commerce/purchases/FirstUseTutorial.qml
rename to interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
index 2e8ad6db65..0d3f67ef7a 100644
--- a/interface/resources/qml/hifi/commerce/purchases/FirstUseTutorial.qml
+++ b/interface/resources/qml/hifi/commerce/common/FirstUseTutorial.qml
@@ -25,7 +25,13 @@ Rectangle {
HifiConstants { id: hifi; }
id: root;
- property int activeView: 1;
+ property int activeView: 1;
+
+ onVisibleChanged: {
+ if (visible) {
+ root.activeView = 1;
+ }
+ }
Image {
anchors.fill: parent;
diff --git a/interface/resources/qml/hifi/commerce/purchases/images/Purchase-First-Run-1.jpg b/interface/resources/qml/hifi/commerce/common/images/Purchase-First-Run-1.jpg
similarity index 100%
rename from interface/resources/qml/hifi/commerce/purchases/images/Purchase-First-Run-1.jpg
rename to interface/resources/qml/hifi/commerce/common/images/Purchase-First-Run-1.jpg
diff --git a/interface/resources/qml/hifi/commerce/purchases/images/Purchase-First-Run-2.jpg b/interface/resources/qml/hifi/commerce/common/images/Purchase-First-Run-2.jpg
similarity index 100%
rename from interface/resources/qml/hifi/commerce/purchases/images/Purchase-First-Run-2.jpg
rename to interface/resources/qml/hifi/commerce/common/images/Purchase-First-Run-2.jpg
diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
index b5697f687d..d75fd6604b 100644
--- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
+++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml
@@ -241,7 +241,7 @@ Rectangle {
}
}
- FirstUseTutorial {
+ HifiCommerceCommon.FirstUseTutorial {
id: firstUseTutorial;
z: 999;
visible: root.activeView === "firstUseTutorial";
diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml
index 7cada5e914..0026bf6cdb 100644
--- a/interface/resources/qml/hifi/commerce/wallet/Help.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml
@@ -25,6 +25,7 @@ Item {
id: root;
property string keyFilePath;
+ property bool showDebugButtons: true;
Hifi.QmlCommerce {
id: commerce;
@@ -56,6 +57,7 @@ Item {
}
HifiControlsUit.Button {
id: clearCachedPassphraseButton;
+ visible: root.showDebugButtons;
color: hifi.buttons.black;
colorScheme: hifi.colorSchemes.dark;
anchors.top: parent.top;
@@ -71,6 +73,7 @@ Item {
}
HifiControlsUit.Button {
id: resetButton;
+ visible: root.showDebugButtons;
color: hifi.buttons.red;
colorScheme: hifi.colorSchemes.dark;
anchors.top: clearCachedPassphraseButton.top;
@@ -95,12 +98,12 @@ Item {
ListElement {
isExpanded: false;
question: "Where are my private keys stored?"
- answer: qsTr('By default, your private keys are only stored on your hard drive in High Fidelity Interface\'s AppData directory.
Tap here to open the file path of your hifikey in your file explorer.');
+ answer: qsTr('By default, your private keys are only stored on your hard drive in High Fidelity Interface\'s AppData directory.
Tap here to open the folder where your HifiKeys are stored on your main display.');
}
ListElement {
isExpanded: false;
question: "How can I backup my private keys?"
- answer: qsTr('You may backup the file containing your private keys by copying it to a USB flash drive, or to a service like Dropbox or Google Drive.
Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.
Tap here to open the file path of your hifikey in your file explorer.');
+ answer: qsTr('You may backup the file containing your private keys by copying it to a USB flash drive, or to a service like Dropbox or Google Drive.
Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.
Tap here to open the folder where your HifiKeys are stored on your main display.');
}
ListElement {
isExpanded: false;
diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml
index 8d5d9f97de..2243143906 100644
--- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml
@@ -25,7 +25,7 @@ Item {
HifiConstants { id: hifi; }
id: root;
- z: 998;
+ z: 997;
property bool keyboardRaised: false;
property string titleBarIcon: "";
property string titleBarText: "";
@@ -350,7 +350,7 @@ Item {
Item {
id: keyboardContainer;
- z: 999;
+ z: 998;
visible: keyboard.raised;
property bool punctuationMode: false;
anchors {
@@ -361,11 +361,13 @@ Item {
Image {
id: lowerKeyboardButton;
+ z: 999;
source: "images/lowerKeyboard.png";
- anchors.horizontalCenter: parent.horizontalCenter;
- anchors.bottom: keyboard.top;
- height: 30;
- width: 120;
+ anchors.right: keyboard.right;
+ anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
+ anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
+ height: 50;
+ width: 60;
MouseArea {
anchors.fill: parent;
diff --git a/interface/resources/qml/hifi/commerce/wallet/Security.qml b/interface/resources/qml/hifi/commerce/wallet/Security.qml
index 0f2edbe913..485b0ec086 100644
--- a/interface/resources/qml/hifi/commerce/wallet/Security.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/Security.qml
@@ -290,7 +290,17 @@ Item {
id: removeHmdContainer;
z: 998;
visible: false;
- color: hifi.colors.blueHighlight;
+
+ gradient: Gradient {
+ GradientStop {
+ position: 0.2;
+ color: hifi.colors.baseGrayHighlight;
+ }
+ GradientStop {
+ position: 1.0;
+ color: hifi.colors.baseGrayShadow;
+ }
+ }
anchors.fill: backupInstructionsButton;
radius: 5;
MouseArea {
diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
index 9beadd3361..472dd50b7d 100644
--- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml
@@ -165,7 +165,7 @@ Rectangle {
WalletSetup {
id: walletSetup;
visible: root.activeView === "walletSetup";
- z: 998;
+ z: 997;
anchors.fill: parent;
Connections {
@@ -192,7 +192,7 @@ Rectangle {
PassphraseChange {
id: passphraseChange;
visible: root.activeView === "passphraseChange";
- z: 998;
+ z: 997;
anchors.top: titleBarContainer.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
@@ -217,7 +217,7 @@ Rectangle {
SecurityImageChange {
id: securityImageChange;
visible: root.activeView === "securityImageChange";
- z: 998;
+ z: 997;
anchors.top: titleBarContainer.bottom;
anchors.left: parent.left;
anchors.right: parent.right;
@@ -653,7 +653,7 @@ Rectangle {
Item {
id: keyboardContainer;
- z: 999;
+ z: 998;
visible: keyboard.raised;
property bool punctuationMode: false;
anchors {
@@ -664,11 +664,13 @@ Rectangle {
Image {
id: lowerKeyboardButton;
+ z: 999;
source: "images/lowerKeyboard.png";
- anchors.horizontalCenter: parent.horizontalCenter;
- anchors.bottom: keyboard.top;
- height: 30;
- width: 120;
+ anchors.right: keyboard.right;
+ anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
+ anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
+ height: 50;
+ width: 60;
MouseArea {
anchors.fill: parent;
diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
index 50891deb60..280d49ceed 100644
--- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
+++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml
@@ -164,7 +164,7 @@ Item {
anchors.top: parent.top;
anchors.topMargin: 26;
anchors.left: parent.left;
- anchors.leftMargin: 30;
+ anchors.leftMargin: 20;
anchors.right: parent.right;
anchors.rightMargin: 30;
height: 30;
diff --git a/interface/resources/qml/hifi/commerce/wallet/images/lowerKeyboard.png b/interface/resources/qml/hifi/commerce/wallet/images/lowerKeyboard.png
index 9fc88262db..c14409d45c 100644
Binary files a/interface/resources/qml/hifi/commerce/wallet/images/lowerKeyboard.png and b/interface/resources/qml/hifi/commerce/wallet/images/lowerKeyboard.png differ
diff --git a/interface/resources/qml/hifi/toolbars/Toolbar.qml b/interface/resources/qml/hifi/toolbars/Toolbar.qml
index 9015c026b0..4710fa3256 100644
--- a/interface/resources/qml/hifi/toolbars/Toolbar.qml
+++ b/interface/resources/qml/hifi/toolbars/Toolbar.qml
@@ -19,6 +19,7 @@ Window {
shown: true
width: content.width
height: content.height
+ disableFade: true
// Disable this window from being able to call 'desktop.raise() and desktop.showDesktop'
activator: Item {}
property bool horizontal: true
diff --git a/interface/resources/qml/windows/Fadable.qml b/interface/resources/qml/windows/Fadable.qml
index 38cd4bf1f9..6bbd1edcac 100644
--- a/interface/resources/qml/windows/Fadable.qml
+++ b/interface/resources/qml/windows/Fadable.qml
@@ -26,6 +26,7 @@ FocusScope {
property var completionCallback;
// The target property to animate, usually scale or opacity
property alias fadeTargetProperty: root.opacity
+ property bool disableFade: false
// always start the property at 0 to enable fade in on creation
fadeTargetProperty: 0
// DO NOT set visible to false or when derived types override it it
@@ -35,6 +36,9 @@ FocusScope {
// Some dialogs should be destroyed when they become
// invisible, so handle that
onVisibleChanged: {
+ if (disableFade) {
+ return;
+ }
// If someone directly set the visibility to false
// toggle it back on and use the targetVisible flag to transition
// via fading.
@@ -62,7 +66,9 @@ FocusScope {
}
onFadeTargetPropertyChanged: {
- visible = (fadeTargetProperty != 0.0);
+ if (!disableFade) {
+ visible = (fadeTargetProperty != 0.0);
+ }
}
function fadeIn(callback) {
diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp
index 017f11c680..e4d7f6bbc9 100644
--- a/libraries/baking/src/FBXBaker.cpp
+++ b/libraries/baking/src/FBXBaker.cpp
@@ -594,6 +594,10 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() };
QFileInfo textureFileInfo { fbxTextureFileName.replace("\\", "/") };
+ if (hasErrors()) {
+ return;
+ }
+
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
// re-baking an FBX that already references baked textures is a fail
// so we add an error and return from here
@@ -602,6 +606,11 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
return;
}
+ if (!TextureBaker::getSupportedFormats().contains(textureFileInfo.suffix())) {
+ // this is a texture format we don't bake, skip it
+ handleWarning(fbxTextureFileName + " is not a bakeable texture format");
+ continue;
+ }
// make sure this texture points to something and isn't one we've already re-mapped
if (!textureFileInfo.filePath().isEmpty()) {
diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
index 8c1a6318f9..3fd1d024c1 100644
--- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp
@@ -96,6 +96,7 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
polylineFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, position));
polylineFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
polylineFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, uv));
+ polylineFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
});
PolyLineUniforms uniforms;
@@ -116,7 +117,8 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
entity->pointsChanged() ||
entity->strokeWidthsChanged() ||
entity->normalsChanged() ||
- entity->texturesChanged()
+ entity->texturesChanged() ||
+ entity->strokeColorsChanged()
);
}
@@ -129,9 +131,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
if (!textures.isEmpty()) {
entityTextures = QUrl(textures);
}
+ _texture = DependencyManager::get()->getTexture(entityTextures);
}
-
- if (!_texture || _texture->getURL() != entityTextures) {
+
+
+ if (!_texture) {
_texture = DependencyManager::get()->getTexture(entityTextures);
}
}
@@ -143,6 +147,10 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
auto pointsChanged = entity->pointsChanged();
auto strokeWidthsChanged = entity->strokeWidthsChanged();
auto normalsChanged = entity->normalsChanged();
+ auto strokeColorsChanged = entity->strokeColorsChanged();
+
+
+ bool isUVModeStretch = entity->getIsUVModeStretch();
entity->resetPolyLineChanged();
_polylineTransform = Transform();
@@ -158,10 +166,14 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
if (normalsChanged) {
_lastNormals = entity->getNormals();
}
- if (pointsChanged || strokeWidthsChanged || normalsChanged) {
+ if (strokeColorsChanged) {
+ _lastStrokeColors = entity->getStrokeColors();
+ _lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector({ toGlm(entity->getXColor()) });
+ }
+ if (pointsChanged || strokeWidthsChanged || normalsChanged || strokeColorsChanged) {
_empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2;
if (!_empty) {
- updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths));
+ updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths, _lastStrokeColors, isUVModeStretch, _textureAspectRatio));
}
}
}
@@ -175,7 +187,12 @@ void PolyLineEntityRenderer::updateGeometry(const std::vector& vertices)
_verticesBuffer->setSubData(0, vertices);
}
-std::vector PolyLineEntityRenderer::updateVertices(const QVector& points, const QVector& normals, const QVector& strokeWidths) {
+std::vector PolyLineEntityRenderer::updateVertices(const QVector& points,
+ const QVector& normals,
+ const QVector& strokeWidths,
+ const QVector& strokeColors,
+ const bool isUVModeStretch,
+ const float textureAspectRatio) {
// Calculate the minimum vector size out of normals, points, and stroke widths
int size = std::min(points.size(), std::min(normals.size(), strokeWidths.size()));
@@ -190,10 +207,52 @@ std::vector PolyLineEntityRenderer::updateVertic
float uCoord = 0.0f;
int finalIndex = size - 1;
glm::vec3 binormal;
+ float accumulatedDistance = 0.0f;
+ float distanceToLastPoint = 0.0f;
+ float accumulatedStrokeWidth = 0.0f;
+ float strokeWidth = 0.0f;
+ bool doesStrokeWidthVary = false;
+
+
+ for (int i = 1; i < strokeWidths.size(); i++) {
+ if (strokeWidths[i] != strokeWidths[i - 1]) {
+ doesStrokeWidthVary = true;
+ break;
+ }
+ }
+
for (int i = 0; i <= finalIndex; i++) {
const float& width = strokeWidths.at(i);
const auto& point = points.at(i);
const auto& normal = normals.at(i);
+ const auto& color = strokeColors.size() == normals.size() ? strokeColors.at(i) : strokeColors.at(0);
+ int vertexIndex = i * 2;
+
+
+ if (!isUVModeStretch && i >= 1) {
+ distanceToLastPoint = glm::distance(points.at(i), points.at(i - 1));
+ accumulatedDistance += distanceToLastPoint;
+ strokeWidth = 2 * strokeWidths[i];
+
+ if (doesStrokeWidthVary) {
+ //If the stroke varies along the line the texture will stretch more or less depending on the speed
+ //because it looks better than using the same method as below
+ accumulatedStrokeWidth += strokeWidth;
+ float increaseValue = 1;
+ if (accumulatedStrokeWidth != 0) {
+ float newUcoord = glm::ceil(((1.0f / textureAspectRatio) * accumulatedDistance) / (accumulatedStrokeWidth / i));
+ increaseValue = newUcoord - uCoord;
+ }
+
+ increaseValue = increaseValue > 0 ? increaseValue : 1;
+ uCoord += increaseValue;
+ } else {
+ //If the stroke width is constant then the textures should keep the aspect ratio along the line
+ uCoord = ((1.0f / textureAspectRatio) * accumulatedDistance) / strokeWidth;
+ }
+ } else if (vertexIndex >= 2) {
+ uCoord += uCoordInc;
+ }
// For last point we can assume binormals are the same since it represents the last two vertices of quad
if (i < finalIndex) {
@@ -206,11 +265,10 @@ std::vector PolyLineEntityRenderer::updateVertic
}
}
- const auto v1 = point + binormal;
- const auto v2 = point - binormal;
- vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f));
- vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f));
- uCoord += uCoordInc;
+ const auto v1 = points.at(i) + binormal;
+ const auto v2 = points.at(i) - binormal;
+ vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f), color);
+ vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f), color);
}
return vertices;
@@ -235,6 +293,12 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get()->getWhiteTexture());
}
+ float textureWidth = (float)_texture->getOriginalWidth();
+ float textureHeight = (float)_texture->getOriginalHeight();
+ if (textureWidth != 0 && textureHeight != 0) {
+ _textureAspectRatio = textureWidth / textureHeight;
+ }
+
batch.setInputFormat(polylineFormat);
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
@@ -247,4 +311,4 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
#endif
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
-}
+}
\ No newline at end of file
diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h
index 610ee53cf7..1e27ac9ae7 100644
--- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h
+++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h
@@ -27,7 +27,9 @@ public:
protected:
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
- virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
+ virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene,
+ Transaction& transaction,
+ const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual ItemKey getKey() override;
@@ -38,24 +40,37 @@ protected:
struct Vertex {
Vertex() {}
- Vertex(const vec3& position, const vec3& normal, const vec2& uv) : position(position), normal(normal), uv(uv) {}
+ Vertex(const vec3& position, const vec3& normal, const vec2& uv, const vec3& color) : position(position),
+ normal(normal),
+ uv(uv),
+ color(color) {}
vec3 position;
vec3 normal;
vec2 uv;
+ vec3 color;
};
void updateGeometry(const std::vector& vertices);
- static std::vector updateVertices(const QVector& points, const QVector& normals, const QVector& strokeWidths);
+ static std::vector updateVertices(const QVector& points,
+ const QVector& normals,
+ const QVector& strokeWidths,
+ const QVector& strokeColors,
+ const bool isUVModeStretch,
+ const float textureAspectRatio);
Transform _polylineTransform;
QVector _lastPoints;
QVector _lastNormals;
+ QVector _lastStrokeColors;
QVector _lastStrokeWidths;
gpu::BufferPointer _verticesBuffer;
gpu::BufferView _uniformBuffer;
+
uint32_t _numVertices { 0 };
bool _empty{ true };
NetworkTexturePointer _texture;
+ float _textureAspectRatio { 1.0f };
+
};
} } // namespace
diff --git a/libraries/entities-renderer/src/paintStroke.slf b/libraries/entities-renderer/src/paintStroke.slf
index ccf2057e09..738561eccc 100644
--- a/libraries/entities-renderer/src/paintStroke.slf
+++ b/libraries/entities-renderer/src/paintStroke.slf
@@ -40,7 +40,7 @@ void main(void) {
packDeferredFragmentTranslucent(
float(frontCondition) * interpolatedNormal,
texel.a * varColor.a,
- polyline.color * texel.rgb,
+ color * texel.rgb,
vec3(0.01, 0.01, 0.01),
10.0);
}
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index 7ad2f22144..32ac9823f6 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -345,7 +345,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
+ CHECK_PROPERTY_CHANGE(PROP_STROKE_COLORS, strokeColors);
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
+ CHECK_PROPERTY_CHANGE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
@@ -595,8 +597,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
}
if (!skipDefaults && !strictSemantics) {
@@ -761,7 +765,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
+ 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.
@@ -915,7 +922,9 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
COPY_PROPERTY_IF_CHANGED(faceCamera);
COPY_PROPERTY_IF_CHANGED(actionData);
COPY_PROPERTY_IF_CHANGED(normals);
+ COPY_PROPERTY_IF_CHANGED(strokeColors);
COPY_PROPERTY_IF_CHANGED(strokeWidths);
+ COPY_PROPERTY_IF_CHANGED(isUVModeStretch);
COPY_PROPERTY_IF_CHANGED(created);
_animation.merge(other._animation);
@@ -1102,7 +1111,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
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_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);
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
@@ -1448,9 +1459,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
if (properties.getType() == EntityTypes::PolyLine) {
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
- APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
+ APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getPackedNormals());
+ APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, properties.getPackedStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
+ APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, properties.getIsUVModeStretch());
}
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
@@ -1537,6 +1550,44 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
return success;
}
+QByteArray EntityItemProperties::getPackedNormals() const {
+ return packNormals(getNormals());
+}
+
+QByteArray EntityItemProperties::packNormals(const QVector& normals) const {
+ int normalsSize = normals.size();
+ QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0');
+ // add size of the array
+ packedNormals[0] = ((uint8_t)normalsSize);
+
+ int index = 1;
+ for (int i = 0; i < normalsSize; i++) {
+ int numBytes = packFloatVec3ToSignedTwoByteFixed((unsigned char*)packedNormals.data() + index, normals[i], 15);
+ index += numBytes;
+ }
+ return packedNormals;
+}
+
+QByteArray EntityItemProperties::getPackedStrokeColors() const {
+ return packStrokeColors(getStrokeColors());
+}
+QByteArray EntityItemProperties::packStrokeColors(const QVector& strokeColors) const {
+ int strokeColorsSize = strokeColors.size();
+ QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0');
+
+ // add size of the array
+ packedStrokeColors[0] = ((uint8_t)strokeColorsSize);
+
+
+ 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;
+ }
+ return packedStrokeColors;
+}
+
// TODO:
// how to handle lastEdited?
// how to handle lastUpdated?
@@ -1758,9 +1809,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
if (properties.getType() == EntityTypes::PolyLine) {
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_NORMALS, QVector, setNormals);
+ 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);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
}
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
@@ -1791,6 +1844,53 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
return valid;
}
+void EntityItemProperties::setPackedNormals(const QByteArray& value) {
+ setNormals(unpackNormals(value));
+}
+
+QVector EntityItemProperties::unpackNormals(const QByteArray& normals) {
+ // the size of the vector is packed first
+ 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();
+ i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15);
+ unpackedNormals[j] = aux;
+ j++;
+ }
+ } else {
+ qCDebug(entities) << "WARNING - Expected received size for normals does not match. Expected: " << (int)normals[0]
+ << " Received: " << (normals.size() / 6);
+ }
+ return unpackedNormals;
+}
+
+void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) {
+ setStrokeColors(unpackStrokeColors(value));
+}
+
+QVector EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) {
+ // the size of the vector is packed first
+ QVector unpackedStrokeColors = QVector((int)strokeColors[0]);
+
+ if ((int)strokeColors[0] == strokeColors.size() / 3) {
+ int j = 0;
+ for (int i = 1; i < strokeColors.size();) {
+
+ float r = (uint8_t)strokeColors[i++] / 255.0f;
+ float g = (uint8_t)strokeColors[i++] / 255.0f;
+ float b = (uint8_t)strokeColors[i++] / 255.0f;
+ unpackedStrokeColors[j++] = glmVec3(r, g, b);
+ }
+ } else {
+ qCDebug(entities) << "WARNING - Expected received size for stroke colors does not match. Expected: "
+ << (int)strokeColors[0] << " Received: " << (strokeColors.size() / 3);
+ }
+
+ return unpackedStrokeColors;
+}
// NOTE: This version will only encode the portion of the edit message immediately following the
// header it does not include the send times and sequence number because that is handled by the
@@ -1932,7 +2032,9 @@ void EntityItemProperties::markAllChanged() {
_actionDataChanged = true;
_normalsChanged = true;
+ _strokeColorsChanged = true;
_strokeWidthsChanged = true;
+ _isUVModeStretchChanged = true;
_xTextureURLChanged = true;
_yTextureURLChanged = true;
@@ -2347,6 +2449,14 @@ QList EntityItemProperties::listChangedProperties() {
out += "shape";
}
+ if (strokeColorsChanged()) {
+ out += "strokeColors";
+ }
+
+ if (isUVModeStretchChanged()) {
+ out += "isUVModeStretch";
+ }
+
getAnimation().listChangedProperties(out);
getKeyLight().listChangedProperties(out);
getSkybox().listChangedProperties(out);
diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h
index 654cd1a6af..6547026e5c 100644
--- a/libraries/entities/src/EntityItemProperties.h
+++ b/libraries/entities/src/EntityItemProperties.h
@@ -191,8 +191,10 @@ public:
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, "");
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
- DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector, QVector());
+ DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
+ DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector, QVector());
+ DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true);
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, "");
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, "");
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, "");
@@ -322,6 +324,17 @@ public:
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; }
+ void setPackedNormals(const QByteArray& value);
+ QVector unpackNormals(const QByteArray& normals);
+
+ void setPackedStrokeColors(const QByteArray& value);
+ QVector unpackStrokeColors(const QByteArray& strokeColors);
+
+ QByteArray getPackedNormals() const;
+ QByteArray packNormals(const QVector& normals) const;
+
+ QByteArray getPackedStrokeColors() const;
+ QByteArray packStrokeColors(const QVector& strokeColors) const;
protected:
QString getCollisionMaskAsString() const;
diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h
index ab5d1d8094..f4e8a18012 100644
--- a/libraries/entities/src/EntityItemPropertiesDefaults.h
+++ b/libraries/entities/src/EntityItemPropertiesDefaults.h
@@ -24,6 +24,8 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3 = glm::vec3(0.0f);
const glm::vec3 ENTITY_ITEM_ONE_VEC3 = glm::vec3(1.0f);
const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
+const QVector ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC = QVector();
+
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();
diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h
index 56ec4faa6d..c20b362b04 100644
--- a/libraries/entities/src/EntityPropertyFlags.h
+++ b/libraries/entities/src/EntityPropertyFlags.h
@@ -109,7 +109,9 @@ enum EntityPropertyList {
// Used by PolyLine entity
PROP_NORMALS,
+ PROP_STROKE_COLORS,
PROP_STROKE_WIDTHS,
+ PROP_IS_UV_MODE_STRETCH,
// used by particles
PROP_SPEED_SPREAD,
diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp
index a308a17c66..7cd70fdb21 100644
--- a/libraries/entities/src/PolyLineEntityItem.cpp
+++ b/libraries/entities/src/PolyLineEntityItem.cpp
@@ -22,7 +22,7 @@
#include "PolyLineEntityItem.h"
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
-const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
+const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 60;
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
@@ -31,6 +31,7 @@ EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, cons
return entity;
}
+
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
_type = EntityTypes::PolyLine;
}
@@ -42,12 +43,15 @@ EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desir
properties._color = getXColor();
properties._colorChanged = false;
+
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeColors, getStrokeColors);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(isUVModeStretch, getIsUVModeStretch);
return properties;
}
@@ -60,8 +64,10 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeColors, setStrokeColors);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(isUVModeStretch, setIsUVModeStretch);
if (somethingChanged) {
bool wantDebug = false;
@@ -108,6 +114,15 @@ bool PolyLineEntityItem::setNormals(const QVector& normals) {
return true;
}
+bool PolyLineEntityItem::setStrokeColors(const QVector& strokeColors) {
+ withWriteLock([&] {
+ _strokeColors = strokeColors;
+ _strokeColorsChanged = true;
+ });
+ return true;
+}
+
+
bool PolyLineEntityItem::setLinePoints(const QVector& points) {
if (points.size() > MAX_POINTS_PER_LINE) {
return false;
@@ -193,8 +208,10 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints);
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector, setNormals);
+ READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector, setStrokeColors);
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector, setStrokeWidths);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
+ READ_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
return bytesRead;
}
@@ -207,8 +224,10 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam
requestedProperties += PROP_LINE_WIDTH;
requestedProperties += PROP_LINE_POINTS;
requestedProperties += PROP_NORMALS;
+ requestedProperties += PROP_STROKE_COLORS;
requestedProperties += PROP_STROKE_WIDTHS;
requestedProperties += PROP_TEXTURES;
+ requestedProperties += PROP_IS_UV_MODE_STRETCH;
return requestedProperties;
}
@@ -227,8 +246,10 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
+ APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
+ APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, getIsUVModeStretch());
}
void PolyLineEntityItem::debugDump() const {
@@ -258,6 +279,14 @@ QVector PolyLineEntityItem::getNormals() const {
return result;
}
+QVector PolyLineEntityItem::getStrokeColors() const {
+ QVector result;
+ withReadLock([&] {
+ result = _strokeColors;
+ });
+ return result;
+}
+
QVector PolyLineEntityItem::getStrokeWidths() const {
QVector result;
withReadLock([&] {
diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h
index 2219229269..7e47ce3aa7 100644
--- a/libraries/entities/src/PolyLineEntityItem.h
+++ b/libraries/entities/src/PolyLineEntityItem.h
@@ -46,9 +46,11 @@ class PolyLineEntityItem : public EntityItem {
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;
@@ -64,9 +66,15 @@ class PolyLineEntityItem : public EntityItem {
bool setNormals(const QVector& normals);
QVector getNormals() const;
+ bool setStrokeColors(const QVector& strokeColors);
+ QVector getStrokeColors() const;
+
bool setStrokeWidths(const QVector& strokeWidths);
QVector getStrokeWidths() const;
+ void setIsUVModeStretch(bool isUVModeStretch){ _isUVModeStretch = isUVModeStretch; }
+ bool getIsUVModeStretch() const{ return _isUVModeStretch; }
+
QString getTextures() const;
void setTextures(const QString& textures);
@@ -76,10 +84,11 @@ class PolyLineEntityItem : public EntityItem {
bool pointsChanged() const { return _pointsChanged; }
bool normalsChanged() const { return _normalsChanged; }
+ bool strokeColorsChanged() const { return _strokeColorsChanged; }
bool strokeWidthsChanged() const { return _strokeWidthsChanged; }
bool texturesChanged() const { return _texturesChangedFlag; }
void resetTexturesChanged() { _texturesChangedFlag = false; }
- void resetPolyLineChanged() { _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
+ void resetPolyLineChanged() { _strokeColorsChanged = _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
// never have a ray intersection pick a PolyLineEntityItem.
@@ -103,11 +112,14 @@ private:
float _lineWidth { DEFAULT_LINE_WIDTH };
bool _pointsChanged { true };
bool _normalsChanged { true };
+ bool _strokeColorsChanged { true };
bool _strokeWidthsChanged { true };
QVector _points;
QVector _normals;
+ QVector _strokeColors;
QVector _strokeWidths;
QString _textures;
+ bool _isUVModeStretch;
bool _texturesChangedFlag { false };
mutable QReadWriteLock _quadReadWriteLock;
};
diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp
index a07d016078..efb38eede1 100644
--- a/libraries/networking/src/udt/PacketHeaders.cpp
+++ b/libraries/networking/src/udt/PacketHeaders.cpp
@@ -29,6 +29,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd:
case PacketType::EntityEdit:
case PacketType::EntityData:
+ return VERSION_ENTITIES_STROKE_COLOR_PROPERTY;
case PacketType::EntityPhysics:
return VERSION_ENTITIES_HAZE;
case PacketType::EntityQuery:
diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h
index 5d170f8d3f..ea65f8ac78 100644
--- a/libraries/networking/src/udt/PacketHeaders.h
+++ b/libraries/networking/src/udt/PacketHeaders.h
@@ -269,6 +269,9 @@ const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72;
const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73;
const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74;
const PacketVersion VERSION_ENTITIES_HAZE = 75;
+const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76;
+const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77;
+
enum class EntityQueryPacketVersion: PacketVersion {
JSONFilter = 18,
diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js
index f892a5ec78..61e520af21 100644
--- a/scripts/defaultScripts.js
+++ b/scripts/defaultScripts.js
@@ -32,7 +32,7 @@ var DEFAULT_SCRIPTS_COMBINED = [
"system/tablet-ui/tabletUI.js"
];
var DEFAULT_SCRIPTS_SEPARATE = [
- "system/controllers/controllerScripts.js",
+ "system/controllers/controllerScripts.js"
// "system/chat.js"
];
diff --git a/scripts/system/bubble.js b/scripts/system/bubble.js
index c3d240f9a5..4ea684ff06 100644
--- a/scripts/system/bubble.js
+++ b/scripts/system/bubble.js
@@ -25,10 +25,10 @@
// The bubble model itself
var bubbleOverlay = Overlays.addOverlay("model", {
url: Script.resolvePath("assets/models/Bubble-v14.fbx"), // If you'd like to change the model, modify this line (and the dimensions below)
- dimensions: { x: 1.0, y: 0.75, z: 1.0 },
+ dimensions: { x: MyAvatar.sensorToWorldScale, y: 0.75 * MyAvatar.sensorToWorldScale, z: MyAvatar.sensorToWorldScale },
position: { x: MyAvatar.position.x, y: -MyAvatar.scale * 2 + MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE, z: MyAvatar.position.z },
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
- scale: { x: 2 * MyAvatar.sensorToWorldScale, y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale, z: 2 * MyAvatar.sensorToWorldScale },
+ scale: { x: 2 , y: MyAvatar.scale * 0.5 + 0.5, z: 2 },
visible: false,
ignoreRayIntersection: true
});
@@ -62,6 +62,11 @@
}
Overlays.editOverlay(bubbleOverlay, {
+ dimensions: {
+ x: MyAvatar.sensorToWorldScale,
+ y: 0.75 * MyAvatar.sensorToWorldScale,
+ z: MyAvatar.sensorToWorldScale
+ },
position: {
x: MyAvatar.position.x,
y: -MyAvatar.scale * 2 + MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE,
@@ -69,9 +74,9 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
- x: 2 * MyAvatar.sensorToWorldScale,
- y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale,
- z: 2 * MyAvatar.sensorToWorldScale
+ x: 2 ,
+ y: MyAvatar.scale * 0.5 + 0.5 ,
+ z: 2
},
visible: true
});
@@ -107,6 +112,11 @@
if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) {
Overlays.editOverlay(bubbleOverlay, {
+ dimensions: {
+ x: MyAvatar.sensorToWorldScale,
+ y: 0.75 * MyAvatar.sensorToWorldScale,
+ z: MyAvatar.sensorToWorldScale
+ },
// Quickly raise the bubble from the ground up
position: {
x: MyAvatar.position.x,
@@ -115,14 +125,19 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
- x: 2 * MyAvatar.sensorToWorldScale,
- y: ((1 - ((BUBBLE_RAISE_ANIMATION_DURATION_MS - delay) / BUBBLE_RAISE_ANIMATION_DURATION_MS)) * MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale),
- z: 2 * MyAvatar.sensorToWorldScale
+ x: 2 ,
+ y: ((1 - ((BUBBLE_RAISE_ANIMATION_DURATION_MS - delay) / BUBBLE_RAISE_ANIMATION_DURATION_MS)) * MyAvatar.scale * 0.5 + 0.5),
+ z: 2
}
});
} else {
// Keep the bubble in place for a couple seconds
Overlays.editOverlay(bubbleOverlay, {
+ dimensions: {
+ x: MyAvatar.sensorToWorldScale,
+ y: 0.75 * MyAvatar.sensorToWorldScale,
+ z: MyAvatar.sensorToWorldScale
+ },
position: {
x: MyAvatar.position.x,
y: MyAvatar.position.y + MyAvatar.scale * BUBBLE_HEIGHT_SCALE,
@@ -130,9 +145,9 @@
},
rotation: Quat.multiply(MyAvatar.orientation, Quat.fromVec3Degrees({x: 0.0, y: 180.0, z: 0.0})),
scale: {
- x: 2 * MyAvatar.sensorToWorldScale,
- y: MyAvatar.scale * 0.5 + 0.2 * MyAvatar.sensorToWorldScale,
- z: 2 * MyAvatar.sensorToWorldScale
+ x: 2,
+ y: MyAvatar.scale * 0.5 + 0.5 ,
+ z: 2
}
});
}
diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js
index 1c6652dc50..ce6480f989 100644
--- a/scripts/system/controllers/controllerModules/teleport.js
+++ b/scripts/system/controllers/controllerModules/teleport.js
@@ -107,6 +107,7 @@ Script.include("/~/system/libraries/controllers.js");
ignoreRayIntersection: true
};
+
var teleportRenderStates = [{name: "cancel", path: cancelPath, end: cancelEnd},
{name: "teleport", path: teleportPath, end: teleportEnd},
{name: "seat", path: seatPath, end: seatEnd}];
@@ -117,6 +118,7 @@ Script.include("/~/system/libraries/controllers.js");
var coolInTimeout = null;
var ignoredEntities = [];
+
var TELEPORTER_STATES = {
IDLE: 'idle',
COOL_IN: 'cool_in',
diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js
index 01a3bc1e52..f808262e9e 100644
--- a/scripts/system/html/js/colpick.js
+++ b/scripts/system/html/js/colpick.js
@@ -68,6 +68,7 @@ For usage and examples: colpick.com/plugin
cal.data('colpick').color = col = hexToHsb(fixHex(this.value));
fillRGBFields(col, cal.get(0));
fillHSBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
} else if (this.parentNode.className.indexOf('_hsb') > 0) {
cal.data('colpick').color = col = fixHSB({
h: parseInt(cal.data('colpick').fields.eq(4).val(), 10),
@@ -76,6 +77,7 @@ For usage and examples: colpick.com/plugin
});
fillRGBFields(col, cal.get(0));
fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
} else {
cal.data('colpick').color = col = rgbToHsb(fixRGB({
r: parseInt(cal.data('colpick').fields.eq(1).val(), 10),
@@ -84,6 +86,7 @@ For usage and examples: colpick.com/plugin
}));
fillHexFields(col, cal.get(0));
fillHSBFields(col, cal.get(0));
+ fillRGBFields(col, cal.get(0));
}
setSelector(col, cal.get(0));
setHue(col, cal.get(0));
diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js
index 0f4fe58586..29bbb4576e 100644
--- a/scripts/system/html/js/marketplacesInject.js
+++ b/scripts/system/html/js/marketplacesInject.js
@@ -140,6 +140,10 @@
if (!$('body').hasClass("login-injected") && !userIsLoggedIn) {
$('body').addClass("login-injected");
var resultsElement = document.getElementById('results');
+ if (!resultsElement) { // If we're on the main page, this will evaluate to `true`
+ resultsElement = document.getElementById('item-show');
+ resultsElement.style = 'margin-top:0;';
+ }
var logInElement = document.createElement('div');
logInElement.classList.add("row");
logInElement.id = "logInDiv";