From aab63bf1098028a9be4c2b8dadf50d35facb1147 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 13 Sep 2017 14:32:22 +0200 Subject: [PATCH 01/79] Added support for R11G11B10F and RGB9E5 cubemaps. Weird colors though but it doesn't crash --- libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp | 23 +++ .../src/gpu/gl41/GL41BackendTexture.cpp | 2 + .../src/gpu/gl45/GL45BackendTexture.cpp | 2 + libraries/gpu/src/gpu/Format.cpp | 4 +- libraries/gpu/src/gpu/Format.h | 6 + libraries/gpu/src/gpu/Texture.cpp | 48 +++--- libraries/image/src/image/Image.cpp | 161 ++++++++++++++---- libraries/image/src/image/Image.h | 7 +- 8 files changed, 199 insertions(+), 54 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp index ef9b6c4297..8d4259e240 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp @@ -19,6 +19,7 @@ bool GLTexelFormat::isCompressed() const { case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: return true; default: return false; @@ -94,6 +95,11 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) { result = GL_R11F_G11F_B10F; break; + case gpu::RGB9E5: + // the type should be float + result = GL_RGB9_E5; + break; + case gpu::DEPTH: result = GL_DEPTH_COMPONENT32; switch (dstFormat.getType()) { @@ -244,6 +250,9 @@ GLenum GLTexelFormat::evalGLTexelFormatInternal(const gpu::Element& dstFormat) { case gpu::COMPRESSED_BC5_XY: result = GL_COMPRESSED_RG_RGTC2; break; + case gpu::COMPRESSED_BC6_RGB: + result = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + break; case gpu::COMPRESSED_BC7_SRGBA: result = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; @@ -396,6 +405,9 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::COMPRESSED_BC5_XY: texel.internalFormat = GL_COMPRESSED_RG_RGTC2; break; + case gpu::COMPRESSED_BC6_RGB: + texel.internalFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + break; case gpu::COMPRESSED_BC7_SRGBA: texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; @@ -495,10 +507,18 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::R11G11B10: texel.format = GL_RGB; + texel.type = GL_UNSIGNED_INT_10F_11F_11F_REV; // the type should be float texel.internalFormat = GL_R11F_G11F_B10F; break; + case gpu::RGB9E5: + texel.format = GL_RGB; + texel.type = GL_UNSIGNED_INT_5_9_9_9_REV; + // the type should be float + texel.internalFormat = GL_RGB9_E5; + break; + case gpu::DEPTH: texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it texel.internalFormat = GL_DEPTH_COMPONENT32; @@ -694,6 +714,9 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::COMPRESSED_BC5_XY: texel.internalFormat = GL_COMPRESSED_RG_RGTC2; break; + case gpu::COMPRESSED_BC6_RGB: + texel.internalFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + break; case gpu::COMPRESSED_BC7_SRGBA: texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; break; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 5998aebb33..cde4ff5f75 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -114,6 +114,7 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: glCompressedTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; @@ -131,6 +132,7 @@ Size GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: glCompressedTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index d8b3968ed8..795a630ccd 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -143,6 +143,7 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: glCompressedTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, internalFormat, static_cast(sourceSize), sourcePointer); break; @@ -158,6 +159,7 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: if (glCompressedTextureSubImage2DEXT) { auto target = GLTexture::CUBE_FACE_LAYOUT[face]; glCompressedTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, internalFormat, diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp index b15f8d929f..7efe4d3ed6 100644 --- a/libraries/gpu/src/gpu/Format.cpp +++ b/libraries/gpu/src/gpu/Format.cpp @@ -24,11 +24,13 @@ const Element Element::COLOR_COMPRESSED_SRGB { TILE4x4, COMPRESSED, COMPRESSED_B const Element Element::COLOR_COMPRESSED_SRGBA_MASK { TILE4x4, COMPRESSED, COMPRESSED_BC1_SRGBA }; const Element Element::COLOR_COMPRESSED_SRGBA { TILE4x4, COMPRESSED, COMPRESSED_BC3_SRGBA }; const Element Element::COLOR_COMPRESSED_XY { TILE4x4, COMPRESSED, COMPRESSED_BC5_XY }; -const Element Element::COLOR_COMPRESSED_SRGBA_HIGH { TILE4x4, COMPRESSED, COMPRESSED_BC7_SRGBA }; +const Element Element::COLOR_COMPRESSED_SRGBA_HIGH{ TILE4x4, COMPRESSED, COMPRESSED_BC7_SRGBA }; +const Element Element::COLOR_COMPRESSED_HDR_RGB{ TILE4x4, COMPRESSED, COMPRESSED_BC6_RGB }; const Element Element::VEC2NU8_XY{ VEC2, NUINT8, XY }; const Element Element::COLOR_R11G11B10{ SCALAR, FLOAT, R11G11B10 }; +const Element Element::COLOR_RGB9E5{ SCALAR, FLOAT, RGB9E5 }; const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA }; const Element Element::VEC2F_UV{ VEC2, FLOAT, UV }; const Element Element::VEC2F_XY{ VEC2, FLOAT, XY }; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index c4d88236da..0654b23581 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -187,11 +187,13 @@ enum Semantic : uint8_t { COMPRESSED_BC3_SRGBA, COMPRESSED_BC4_RED, COMPRESSED_BC5_XY, + COMPRESSED_BC6_RGB, COMPRESSED_BC7_SRGBA, _LAST_COMPRESSED, R11G11B10, + RGB9E5, UNIFORM, UNIFORM_BUFFER, @@ -240,11 +242,13 @@ static const int SEMANTIC_SIZE_FACTOR[NUM_SEMANTICS] = { 16, //COMPRESSED_BC3_SRGBA, 1 byte/pixel * 4x4 pixels = 16 bytes 8, //COMPRESSED_BC4_RED, 1/2 byte/pixel * 4x4 pixels = 8 bytes 16, //COMPRESSED_BC5_XY, 1 byte/pixel * 4x4 pixels = 16 bytes + 16, //COMPRESSED_BC6_RGB, 1 byte/pixel * 4x4 pixels = 16 bytes 16, //COMPRESSED_BC7_SRGBA, 1 byte/pixel * 4x4 pixels = 16 bytes 1, //_LAST_COMPRESSED, 1, //R11G11B10, + 1, //RGB9E5 1, //UNIFORM, 1, //UNIFORM_BUFFER, @@ -306,12 +310,14 @@ public: static const Element COLOR_BGRA_32; static const Element COLOR_SBGRA_32; static const Element COLOR_R11G11B10; + static const Element COLOR_RGB9E5; static const Element COLOR_COMPRESSED_RED; static const Element COLOR_COMPRESSED_SRGB; static const Element COLOR_COMPRESSED_SRGBA_MASK; static const Element COLOR_COMPRESSED_SRGBA; static const Element COLOR_COMPRESSED_XY; static const Element COLOR_COMPRESSED_SRGBA_HIGH; + static const Element COLOR_COMPRESSED_HDR_RGB; static const Element VEC2NU8_XY; static const Element VEC4F_COLOR_RGBA; static const Element VEC2F_UV; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 4b836512c4..d817d39883 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -683,6 +684,22 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< PROFILE_RANGE(render_gpu, "sphericalHarmonicsFromTexture"); + auto mipFormat = cubeTexture.getStoredMipFormat(); + std::function unpackFunc; + switch (mipFormat.getSemantic()) + { + case gpu::R11G11B10: + unpackFunc = glm::unpackF2x11_1x10; + break; + case gpu::RGB9E5: + unpackFunc = glm::unpackF3x9_E1x5; + break; + default: + assert(false); + break; + } + assert(mipFormat.getSemantic() == gpu::R11G11B10); + const uint sqOrder = order*order; // allocate memory for calculations @@ -716,17 +733,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { PROFILE_RANGE(render_gpu, "ProcessFace"); - auto mipFormat = cubeTexture.getStoredMipFormat(); - auto numComponents = mipFormat.getScalarCount(); - int roffset { 0 }; - int goffset { 1 }; - int boffset { 2 }; - if ((mipFormat.getSemantic() == gpu::BGRA) || (mipFormat.getSemantic() == gpu::SBGRA)) { - roffset = 2; - boffset = 0; - } - - auto data = cubeTexture.accessStoredMipFace(0, face)->readData(); + auto data = (const uint32*)cubeTexture.accessStoredMipFace(0, face)->readData(); if (data == nullptr) { continue; } @@ -806,29 +813,24 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< // index of texel in texture - // get color from texture and map to range [0, 1] - float red { 0.0f }; - float green { 0.0f }; - float blue { 0.0f }; + // get color from texture + glm::vec3 color{ 0.f, 0.f, 0.f }; for (int i = 0; i < stride; ++i) { for (int j = 0; j < stride; ++j) { - int k = (int)(x + i - halfStride + (y + j - halfStride) * width) * numComponents; - red += ColorUtils::sRGB8ToLinearFloat(data[k + roffset]); - green += ColorUtils::sRGB8ToLinearFloat(data[k + goffset]); - blue += ColorUtils::sRGB8ToLinearFloat(data[k + boffset]); + int k = (int)(x + i - halfStride + (y + j - halfStride) * width); + color += unpackFunc(data[k]); } } - glm::vec3 clr(red, green, blue); // scale color and add to previously accumulated coefficients // red - sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), clr.r * fDiffSolid); + sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), color.r * fDiffSolid); sphericalHarmonicsAdd(resultR.data(), order, resultR.data(), shBuffB.data()); // green - sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), clr.g * fDiffSolid); + sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), color.g * fDiffSolid); sphericalHarmonicsAdd(resultG.data(), order, resultG.data(), shBuffB.data()); // blue - sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), clr.b * fDiffSolid); + sphericalHarmonicsScale(shBuffB.data(), order, shBuff.data(), color.b * fDiffSolid); sphericalHarmonicsAdd(resultB.data(), order, resultB.data(), shBuffB.data()); } } diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index f274dc54f8..f51319fadf 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -12,6 +12,7 @@ #include "Image.h" #include +#include #include #include @@ -260,8 +261,6 @@ gpu::TexturePointer processImage(const QByteArray& content, const std::string& f return texture; } - - QImage processSourceImage(const QImage& srcImage, bool cubemap) { PROFILE_RANGE(resource_parse, "processSourceImage"); const glm::uvec2 srcImageSize = toGlm(srcImage.size()); @@ -331,10 +330,81 @@ struct MyErrorHandler : public nvtt::ErrorHandler { } }; -void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { -#if CPU_MIPMAPS - PROFILE_RANGE(resource_parse, "generateMips"); +void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { + assert(image.format() == QIMAGE_HDR_FORMAT); + const int width = image.width(), height = image.height(); + std::vector data; + std::vector::iterator dataIt; + + data.resize(width*height); + dataIt = data.begin(); + for (auto lineNb = 0; lineNb < height; lineNb++) { + const uint32* srcPixelIt = (const uint32*) image.constScanLine(lineNb); + const uint32* srcPixelEnd = srcPixelIt + width; + + while (srcPixelIt < srcPixelEnd) { + *dataIt = glm::vec4(glm::unpackF2x11_1x10(*srcPixelIt), 1.f); + ++srcPixelIt; + ++dataIt; + } + } + assert(dataIt == data.end()); + + nvtt::TextureType textureType = nvtt::TextureType_2D; + nvtt::InputFormat inputFormat = nvtt::InputFormat_RGBA_32F; + nvtt::WrapMode wrapMode = nvtt::WrapMode_Mirror; + nvtt::RoundMode roundMode = nvtt::RoundMode_None; + nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None; + + nvtt::CompressionOptions compressionOptions; + compressionOptions.setQuality(nvtt::Quality_Production); + + auto mipFormat = texture->getStoredMipFormat(); + if (mipFormat == gpu::Element::COLOR_COMPRESSED_HDR_RGB) { + compressionOptions.setFormat(nvtt::Format_BC6); + } + else if (mipFormat == gpu::Element::COLOR_RGB9E5) { + compressionOptions.setFormat(nvtt::Format_RGB); + compressionOptions.setPixelType(nvtt::PixelType_SharedExp); + compressionOptions.setPitchAlignment(4); + compressionOptions.setPixelFormat(9, 9, 9, 5); + } + else if (mipFormat == gpu::Element::COLOR_R11G11B10) { + // WARNING : With NVTT 2.1, using float 11/10 produces an assertion in the compressor + compressionOptions.setFormat(nvtt::Format_RGB); + compressionOptions.setPixelType(nvtt::PixelType_Float); + compressionOptions.setPitchAlignment(4); + compressionOptions.setPixelFormat(11, 11, 10, 0); + } + else { + qCWarning(imagelogging) << "Unknown mip format"; + Q_UNREACHABLE(); + return; + } + + nvtt::OutputOptions outputOptions; + outputOptions.setOutputHeader(false); + MyOutputHandler outputHandler(texture, face); + outputOptions.setOutputHandler(&outputHandler); + MyErrorHandler errorHandler; + outputOptions.setErrorHandler(&errorHandler); + nvtt::Context context; + int mipLevel = 0; + + nvtt::Surface surface; + surface.setImage(inputFormat, width, height, 1, &(*data.begin())); + surface.setAlphaMode(alphaMode); + surface.setWrapMode(wrapMode); + + context.compress(surface, face, mipLevel++, compressionOptions, outputOptions); + while (surface.canMakeNextMipmap()) { + surface.buildNextMipmap(nvtt::MipmapFilter_Box); + context.compress(surface, face, mipLevel++, compressionOptions, outputOptions); + } +} + +void generateLDRMips(gpu::Texture* texture, QImage& image, int face) { if (image.format() != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); } @@ -388,10 +458,10 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); compressionOptions.setPitchAlignment(4); compressionOptions.setPixelFormat(32, - 0x000000FF, - 0x0000FF00, - 0x00FF0000, - 0xFF000000); + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); inputGamma = 1.0f; outputGamma = 1.0f; } else if (mipFormat == gpu::Element::COLOR_BGRA_32) { @@ -399,10 +469,10 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); compressionOptions.setPitchAlignment(4); compressionOptions.setPixelFormat(32, - 0x00FF0000, - 0x0000FF00, - 0x000000FF, - 0xFF000000); + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); inputGamma = 1.0f; outputGamma = 1.0f; } else if (mipFormat == gpu::Element::COLOR_SRGBA_32) { @@ -410,19 +480,19 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); compressionOptions.setPitchAlignment(4); compressionOptions.setPixelFormat(32, - 0x000000FF, - 0x0000FF00, - 0x00FF0000, - 0xFF000000); + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000); } else if (mipFormat == gpu::Element::COLOR_SBGRA_32) { compressionOptions.setFormat(nvtt::Format_RGBA); compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); compressionOptions.setPitchAlignment(4); compressionOptions.setPixelFormat(32, - 0x00FF0000, - 0x0000FF00, - 0x000000FF, - 0xFF000000); + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); } else if (mipFormat == gpu::Element::COLOR_R_8) { compressionOptions.setFormat(nvtt::Format_RGB); compressionOptions.setPixelType(nvtt::PixelType_UnsignedNorm); @@ -449,6 +519,17 @@ void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { nvtt::Compressor compressor; compressor.process(inputOptions, compressionOptions, outputOptions); +} + +void generateMips(gpu::Texture* texture, QImage& image, int face = -1) { +#if CPU_MIPMAPS + PROFILE_RANGE(resource_parse, "generateMips"); + + if (image.format() == QIMAGE_HDR_FORMAT) { + generateHDRMips(texture, image, face); + } else { + generateLDRMips(texture, image, face); + } #else texture->autoGenerateMips(-1); #endif @@ -926,24 +1007,46 @@ const CubeLayout CubeLayout::CUBEMAP_LAYOUTS[] = { }; const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS) / sizeof(CubeLayout); +QImage convertToHDRFormat(QImage srcImage) { + QImage hdrImage(srcImage.width(), srcImage.height(), (QImage::Format)QIMAGE_HDR_FORMAT); + + srcImage = srcImage.convertToFormat(QImage::Format_ARGB32); + for (auto y = 0; y < srcImage.height(); y++) { + const QRgb* srcLineIt = (const QRgb*) srcImage.constScanLine(y); + const QRgb* srcLineEnd = srcLineIt + srcImage.width(); + uint32* hdrLineIt = (uint32*) hdrImage.scanLine(y); + glm::vec3 color; + + while (srcLineIt < srcLineEnd) { + color.r = qRed(*srcLineIt); + color.g = qGreen(*srcLineIt); + color.b = qBlue(*srcLineIt); + *hdrLineIt = glm::packF2x11_1x10(color / 255.f); + ++srcLineIt; + ++hdrLineIt; + } + } + return hdrImage; +} + gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool generateIrradiance) { PROFILE_RANGE(resource_parse, "processCubeTextureColorFromImage"); gpu::TexturePointer theTexture = nullptr; if ((srcImage.width() > 0) && (srcImage.height() > 0)) { QImage image = processSourceImage(srcImage, true); - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QIMAGE_HDR_FORMAT) { + image = convertToHDRFormat(image); } gpu::Element formatMip; gpu::Element formatGPU; if (isCubeTexturesCompressionEnabled()) { - formatMip = gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH; - formatGPU = gpu::Element::COLOR_COMPRESSED_SRGBA_HIGH; + formatMip = gpu::Element::COLOR_COMPRESSED_HDR_RGB; + formatGPU = gpu::Element::COLOR_COMPRESSED_HDR_RGB; } else { - formatMip = gpu::Element::COLOR_SRGBA_32; - formatGPU = gpu::Element::COLOR_SRGBA_32; + formatMip = gpu::Element::COLOR_R11G11B10; + formatGPU = gpu::Element::COLOR_R11G11B10; } // Find the layout of the cubemap in the 2D image @@ -991,9 +1094,9 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& // Generate irradiance while we are at it if (generateIrradiance) { PROFILE_RANGE(resource_parse, "generateIrradiance"); - auto irradianceTexture = gpu::Texture::createCube(gpu::Element::COLOR_SRGBA_32, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); + auto irradianceTexture = gpu::Texture::createCube(gpu::Element::COLOR_R11G11B10, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); irradianceTexture->setSource(srcImageName); - irradianceTexture->setStoredMipFormat(gpu::Element::COLOR_SBGRA_32); + irradianceTexture->setStoredMipFormat(gpu::Element::COLOR_R11G11B10); for (uint8 face = 0; face < faces.size(); ++face) { irradianceTexture->assignStoredMipFace(0, face, faces[face].byteCount(), faces[face].constBits()); } diff --git a/libraries/image/src/image/Image.h b/libraries/image/src/image/Image.h index 3bf45ace98..c8be097542 100644 --- a/libraries/image/src/image/Image.h +++ b/libraries/image/src/image/Image.h @@ -13,11 +13,11 @@ #define hifi_image_Image_h #include +#include #include class QByteArray; -class QImage; namespace image { @@ -74,6 +74,11 @@ void setNormalTexturesCompressionEnabled(bool enabled); void setGrayscaleTexturesCompressionEnabled(bool enabled); void setCubeTexturesCompressionEnabled(bool enabled); +enum +{ + QIMAGE_HDR_FORMAT = QImage::Format_RGB30 +}; + gpu::TexturePointer processImage(const QByteArray& content, const std::string& url, int maxNumPixels, TextureUsage::Type textureType); } // namespace image From b8065d46ce5f8a65968568dc1a2302954747da91 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 13 Sep 2017 19:15:51 +0200 Subject: [PATCH 02/79] Fixed bugs with conversion to packed floats --- libraries/gpu/src/gpu/Texture.cpp | 1 - libraries/image/src/image/Image.cpp | 171 +++++++++++++++++++++------- 2 files changed, 128 insertions(+), 44 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index d817d39883..4c2f4960c7 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -698,7 +698,6 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< assert(false); break; } - assert(mipFormat.getSemantic() == gpu::R11G11B10); const uint sqOrder = order*order; diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index f51319fadf..8ada88f008 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -205,6 +205,20 @@ void setCubeTexturesCompressionEnabled(bool enabled) { compressCubeTextures.set(enabled); } +static float denormalize(float value, const float minValue) { + return value < minValue ? 0.f : value; +} + +uint32 packR11G11B10F(const glm::vec3& color) { + // Denormalize else unpacking gives high and incorrect values + // See https://www.khronos.org/opengl/wiki/Small_Float_Formats for this min value + static const auto minValue = 6.10e-5f; + glm::vec3 ucolor; + ucolor.r = denormalize(color.r, minValue); + ucolor.g = denormalize(color.g, minValue); + ucolor.b = denormalize(color.b, minValue); + return glm::packF2x11_1x10(ucolor); +} gpu::TexturePointer processImage(const QByteArray& content, const std::string& filename, int maxNumPixels, TextureUsage::Type textureType) { // Help the QImage loader by extracting the image file format from the url filename ext. @@ -291,8 +305,8 @@ QImage processSourceImage(const QImage& srcImage, bool cubemap) { return srcImage; } -struct MyOutputHandler : public nvtt::OutputHandler { - MyOutputHandler(gpu::Texture* texture, int face) : _texture(texture), _face(face) {} +struct OutputHandler : public nvtt::OutputHandler { + OutputHandler(gpu::Texture* texture, int face) : _texture(texture), _face(face) {} virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) override { _size = size; @@ -310,7 +324,8 @@ struct MyOutputHandler : public nvtt::OutputHandler { virtual void endImage() override { if (_face >= 0) { _texture->assignStoredMipFace(_miplevel, _face, _size, static_cast(_data)); - } else { + } + else { _texture->assignStoredMip(_miplevel, _size, static_cast(_data)); } free(_data); @@ -324,6 +339,51 @@ struct MyOutputHandler : public nvtt::OutputHandler { int _size = 0; int _face = -1; }; + +struct PackedFloatOutputHandler : public OutputHandler { + PackedFloatOutputHandler(gpu::Texture* texture, int face, gpu::Element format) : OutputHandler(texture, face) { + if (format == gpu::Element::COLOR_RGB9E5) { + _packFunc = glm::packF3x9_E1x5; + } else if (format == gpu::Element::COLOR_R11G11B10) { + _packFunc = packR11G11B10F; + } else { + qCWarning(imagelogging) << "Unknown handler format"; + Q_UNREACHABLE(); + } + } + + virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel) override { + // Divide by 3 because we will compress from 3*floats to 1 uint32 + OutputHandler::beginImage(size / 3, width, height, depth, face, miplevel); + } + virtual bool writeData(const void* data, int size) override { + // Expecting to write multiple of floats + if (_packFunc) { + assert((size % sizeof(float)) == 0); + auto floatCount = size / sizeof(float); + const float* floatBegin = (const float*)data; + const float* floatEnd = floatBegin + floatCount; + + while (floatBegin < floatEnd) { + _pixel[_coordIndex] = *floatBegin; + floatBegin++; + _coordIndex++; + if (_coordIndex == 3) { + uint32 packedRGB = _packFunc(_pixel); + _coordIndex = 0; + OutputHandler::writeData(&packedRGB, sizeof(packedRGB)); + } + } + return true; + } + return false; + } + + std::function _packFunc; + glm::vec3 _pixel; + int _coordIndex{ 0 }; +}; + struct MyErrorHandler : public nvtt::ErrorHandler { virtual void error(nvtt::Error e) override { qCWarning(imagelogging) << "Texture compression error:" << nvtt::errorString(e); @@ -336,20 +396,8 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { const int width = image.width(), height = image.height(); std::vector data; std::vector::iterator dataIt; - - data.resize(width*height); - dataIt = data.begin(); - for (auto lineNb = 0; lineNb < height; lineNb++) { - const uint32* srcPixelIt = (const uint32*) image.constScanLine(lineNb); - const uint32* srcPixelEnd = srcPixelIt + width; - - while (srcPixelIt < srcPixelEnd) { - *dataIt = glm::vec4(glm::unpackF2x11_1x10(*srcPixelIt), 1.f); - ++srcPixelIt; - ++dataIt; - } - } - assert(dataIt == data.end()); + auto mipFormat = texture->getStoredMipFormat(); + std::function unpackFunc; nvtt::TextureType textureType = nvtt::TextureType_2D; nvtt::InputFormat inputFormat = nvtt::InputFormat_RGBA_32F; @@ -360,38 +408,55 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { nvtt::CompressionOptions compressionOptions; compressionOptions.setQuality(nvtt::Quality_Production); - auto mipFormat = texture->getStoredMipFormat(); if (mipFormat == gpu::Element::COLOR_COMPRESSED_HDR_RGB) { compressionOptions.setFormat(nvtt::Format_BC6); - } - else if (mipFormat == gpu::Element::COLOR_RGB9E5) { - compressionOptions.setFormat(nvtt::Format_RGB); - compressionOptions.setPixelType(nvtt::PixelType_SharedExp); - compressionOptions.setPitchAlignment(4); - compressionOptions.setPixelFormat(9, 9, 9, 5); - } - else if (mipFormat == gpu::Element::COLOR_R11G11B10) { - // WARNING : With NVTT 2.1, using float 11/10 produces an assertion in the compressor + } else if (mipFormat == gpu::Element::COLOR_RGB9E5) { compressionOptions.setFormat(nvtt::Format_RGB); compressionOptions.setPixelType(nvtt::PixelType_Float); - compressionOptions.setPitchAlignment(4); - compressionOptions.setPixelFormat(11, 11, 10, 0); - } - else { + compressionOptions.setPixelFormat(32, 32, 32, 0); + unpackFunc = glm::unpackF3x9_E1x5; + } else if (mipFormat == gpu::Element::COLOR_R11G11B10) { + compressionOptions.setFormat(nvtt::Format_RGB); + compressionOptions.setPixelType(nvtt::PixelType_Float); + compressionOptions.setPixelFormat(32, 32, 32, 0); + unpackFunc = glm::unpackF2x11_1x10; + } else { qCWarning(imagelogging) << "Unknown mip format"; Q_UNREACHABLE(); return; } + data.resize(width*height); + dataIt = data.begin(); + for (auto lineNb = 0; lineNb < height; lineNb++) { + const uint32* srcPixelIt = (const uint32*)image.constScanLine(lineNb); + const uint32* srcPixelEnd = srcPixelIt + width; + + while (srcPixelIt < srcPixelEnd) { + *dataIt = glm::vec4(unpackFunc(*srcPixelIt), 1.f); + ++srcPixelIt; + ++dataIt; + } + } + assert(dataIt == data.end()); + nvtt::OutputOptions outputOptions; outputOptions.setOutputHeader(false); - MyOutputHandler outputHandler(texture, face); - outputOptions.setOutputHandler(&outputHandler); + std::auto_ptr outputHandler; MyErrorHandler errorHandler; outputOptions.setErrorHandler(&errorHandler); nvtt::Context context; int mipLevel = 0; + if (mipFormat == gpu::Element::COLOR_RGB9E5 || mipFormat == gpu::Element::COLOR_R11G11B10) { + // Don't use NVTT (at least version 2.1) as it outputs wrong RGB9E5 and R11G11B10F values from floats + outputHandler.reset(new PackedFloatOutputHandler(texture, face, mipFormat)); + } else { + outputHandler.reset( new OutputHandler(texture, face) ); + } + + outputOptions.setOutputHandler(outputHandler.get()); + nvtt::Surface surface; surface.setImage(inputFormat, width, height, 1, &(*data.begin())); surface.setAlphaMode(alphaMode); @@ -512,7 +577,7 @@ void generateLDRMips(gpu::Texture* texture, QImage& image, int face) { nvtt::OutputOptions outputOptions; outputOptions.setOutputHeader(false); - MyOutputHandler outputHandler(texture, face); + OutputHandler outputHandler(texture, face); outputOptions.setOutputHandler(&outputHandler); MyErrorHandler errorHandler; outputOptions.setErrorHandler(&errorHandler); @@ -1007,8 +1072,21 @@ const CubeLayout CubeLayout::CUBEMAP_LAYOUTS[] = { }; const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS) / sizeof(CubeLayout); -QImage convertToHDRFormat(QImage srcImage) { +QImage convertToHDRFormat(QImage srcImage, gpu::Element format) { QImage hdrImage(srcImage.width(), srcImage.height(), (QImage::Format)QIMAGE_HDR_FORMAT); + std::function packFunc; + switch (format.getSemantic()) { + case gpu::R11G11B10: + packFunc = packR11G11B10F; + break; + case gpu::RGB9E5: + packFunc = glm::packF3x9_E1x5; + break; + default: + qCWarning(imagelogging) << "Unsupported HDR format"; + Q_UNREACHABLE(); + return srcImage; + } srcImage = srcImage.convertToFormat(QImage::Format_ARGB32); for (auto y = 0; y < srcImage.height(); y++) { @@ -1021,7 +1099,12 @@ QImage convertToHDRFormat(QImage srcImage) { color.r = qRed(*srcLineIt); color.g = qGreen(*srcLineIt); color.b = qBlue(*srcLineIt); - *hdrLineIt = glm::packF2x11_1x10(color / 255.f); + // Normalize and apply gamma + color /= 255.f; + color.r = powf(color.r, 2.2f); + color.g = powf(color.g, 2.2f); + color.b = powf(color.b, 2.2f); + *hdrLineIt = packFunc(color); ++srcLineIt; ++hdrLineIt; } @@ -1035,18 +1118,20 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& gpu::TexturePointer theTexture = nullptr; if ((srcImage.width() > 0) && (srcImage.height() > 0)) { QImage image = processSourceImage(srcImage, true); - if (image.format() != QIMAGE_HDR_FORMAT) { - image = convertToHDRFormat(image); - } + const auto cubeMapHDRFormat = gpu::Element::COLOR_RGB9E5; gpu::Element formatMip; gpu::Element formatGPU; if (isCubeTexturesCompressionEnabled()) { formatMip = gpu::Element::COLOR_COMPRESSED_HDR_RGB; formatGPU = gpu::Element::COLOR_COMPRESSED_HDR_RGB; } else { - formatMip = gpu::Element::COLOR_R11G11B10; - formatGPU = gpu::Element::COLOR_R11G11B10; + formatMip = cubeMapHDRFormat; + formatGPU = cubeMapHDRFormat; + } + + if (image.format() != QIMAGE_HDR_FORMAT) { + image = convertToHDRFormat(image, cubeMapHDRFormat); } // Find the layout of the cubemap in the 2D image @@ -1094,9 +1179,9 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& // Generate irradiance while we are at it if (generateIrradiance) { PROFILE_RANGE(resource_parse, "generateIrradiance"); - auto irradianceTexture = gpu::Texture::createCube(gpu::Element::COLOR_R11G11B10, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); + auto irradianceTexture = gpu::Texture::createCube(cubeMapHDRFormat, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); irradianceTexture->setSource(srcImageName); - irradianceTexture->setStoredMipFormat(gpu::Element::COLOR_R11G11B10); + irradianceTexture->setStoredMipFormat(cubeMapHDRFormat); for (uint8 face = 0; face < faces.size(); ++face) { irradianceTexture->assignStoredMipFace(0, face, faces[face].byteCount(), faces[face].constBits()); } From 353bab5277e3a01b56ef488507ebe72e6fc05fd8 Mon Sep 17 00:00:00 2001 From: beholder Date: Sat, 16 Sep 2017 16:50:45 +0300 Subject: [PATCH 03/79] 7384 On Domains without Edit Access, Create Button Text still Highlights (override color in states if captionColorOverride was specified) --- interface/resources/qml/hifi/tablet/TabletButton.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml index 58091d9fab..ab7179edf1 100644 --- a/interface/resources/qml/hifi/tablet/TabletButton.qml +++ b/interface/resources/qml/hifi/tablet/TabletButton.qml @@ -168,7 +168,7 @@ Item { PropertyChanges { target: text - color: "#ffffff" + color: captionColorOverride !== "" ? captionColorOverride: "#ffffff" text: tabletButton.hoverText } @@ -194,7 +194,7 @@ Item { PropertyChanges { target: text - color: "#333333" + color: captionColorOverride !== "" ? captionColorOverride: "#333333" text: tabletButton.activeText } @@ -225,7 +225,7 @@ Item { PropertyChanges { target: text - color: "#333333" + color: captionColorOverride !== "" ? captionColorOverride: "#333333" text: tabletButton.activeHoverText } From 037550f176b16d258d532297a01094008501c484 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 18 Sep 2017 10:58:38 +0200 Subject: [PATCH 04/79] Switched back to R11G11B10 for HDR cube maps because of sometimes wrong hue shifts with RGB9E5 --- libraries/image/src/image/Image.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index 8ada88f008..b1b87883bb 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -213,10 +213,14 @@ uint32 packR11G11B10F(const glm::vec3& color) { // Denormalize else unpacking gives high and incorrect values // See https://www.khronos.org/opengl/wiki/Small_Float_Formats for this min value static const auto minValue = 6.10e-5f; + static const auto maxValue = 6.50e4f; glm::vec3 ucolor; ucolor.r = denormalize(color.r, minValue); ucolor.g = denormalize(color.g, minValue); ucolor.b = denormalize(color.b, minValue); + ucolor.r = std::min(ucolor.r, maxValue); + ucolor.g = std::min(ucolor.g, maxValue); + ucolor.b = std::min(ucolor.b, maxValue); return glm::packF2x11_1x10(ucolor); } @@ -1072,15 +1076,27 @@ const CubeLayout CubeLayout::CUBEMAP_LAYOUTS[] = { }; const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS) / sizeof(CubeLayout); +//#define DEBUG_COLOR_PACKING + QImage convertToHDRFormat(QImage srcImage, gpu::Element format) { QImage hdrImage(srcImage.width(), srcImage.height(), (QImage::Format)QIMAGE_HDR_FORMAT); std::function packFunc; +#ifdef DEBUG_COLOR_PACKING + std::function unpackFunc; +#endif + switch (format.getSemantic()) { case gpu::R11G11B10: packFunc = packR11G11B10F; +#ifdef DEBUG_COLOR_PACKING + unpackFunc = glm::unpackF2x11_1x10; +#endif break; case gpu::RGB9E5: packFunc = glm::packF3x9_E1x5; +#ifdef DEBUG_COLOR_PACKING + unpackFunc = glm::unpackF3x9_E1x5; +#endif break; default: qCWarning(imagelogging) << "Unsupported HDR format"; @@ -1105,6 +1121,10 @@ QImage convertToHDRFormat(QImage srcImage, gpu::Element format) { color.g = powf(color.g, 2.2f); color.b = powf(color.b, 2.2f); *hdrLineIt = packFunc(color); +#ifdef DEBUG_COLOR_PACKING + glm::vec3 ucolor = unpackFunc(*hdrLineIt); + assert(glm::distance(color, ucolor) <= 5e-2); +#endif ++srcLineIt; ++hdrLineIt; } @@ -1119,7 +1139,7 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& if ((srcImage.width() > 0) && (srcImage.height() > 0)) { QImage image = processSourceImage(srcImage, true); - const auto cubeMapHDRFormat = gpu::Element::COLOR_RGB9E5; + const auto cubeMapHDRFormat = gpu::Element::COLOR_R11G11B10; gpu::Element formatMip; gpu::Element formatGPU; if (isCubeTexturesCompressionEnabled()) { From 5ec9c5bb45da21b7cbfa1503300434bf1c94fbea Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 21 Sep 2017 09:32:34 +0200 Subject: [PATCH 05/79] Fixed some coding standard issues --- libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp | 2 - libraries/gpu/src/gpu/Texture.cpp | 26 +++++----- libraries/image/src/image/Image.cpp | 47 ++++++++++--------- libraries/image/src/image/Image.h | 7 +-- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp index 8d4259e240..192a82dafc 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLTexelFormat.cpp @@ -508,14 +508,12 @@ GLTexelFormat GLTexelFormat::evalGLTexelFormat(const Element& dstFormat, const E case gpu::R11G11B10: texel.format = GL_RGB; texel.type = GL_UNSIGNED_INT_10F_11F_11F_REV; - // the type should be float texel.internalFormat = GL_R11F_G11F_B10F; break; case gpu::RGB9E5: texel.format = GL_RGB; texel.type = GL_UNSIGNED_INT_5_9_9_9_REV; - // the type should be float texel.internalFormat = GL_RGB9_E5; break; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 4c2f4960c7..4a588c3c84 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -686,17 +686,17 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< auto mipFormat = cubeTexture.getStoredMipFormat(); std::function unpackFunc; - switch (mipFormat.getSemantic()) - { - case gpu::R11G11B10: - unpackFunc = glm::unpackF2x11_1x10; - break; - case gpu::RGB9E5: - unpackFunc = glm::unpackF3x9_E1x5; - break; - default: - assert(false); - break; + + switch (mipFormat.getSemantic()) { + case gpu::R11G11B10: + unpackFunc = glm::unpackF2x11_1x10; + break; + case gpu::RGB9E5: + unpackFunc = glm::unpackF3x9_E1x5; + break; + default: + assert(false); + break; } const uint sqOrder = order*order; @@ -732,7 +732,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { PROFILE_RANGE(render_gpu, "ProcessFace"); - auto data = (const uint32*)cubeTexture.accessStoredMipFace(0, face)->readData(); + auto data = reinterpret_cast( cubeTexture.accessStoredMipFace(0, face)->readData() ); if (data == nullptr) { continue; } @@ -813,7 +813,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< // index of texel in texture // get color from texture - glm::vec3 color{ 0.f, 0.f, 0.f }; + glm::vec3 color{ 0.0f, 0.0f, 0.0f }; for (int i = 0; i < stride; ++i) { for (int j = 0; j < stride; ++j) { int k = (int)(x + i - halfStride + (y + j - halfStride) * width); diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index b1b87883bb..2ae62a9ce3 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -67,6 +67,10 @@ glm::uvec2 rectifyToSparseSize(const glm::uvec2& size) { namespace image { +enum { + QIMAGE_HDR_FORMAT = QImage::Format_RGB30 +}; + TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) { switch (type) { case ALBEDO_TEXTURE: @@ -206,7 +210,7 @@ void setCubeTexturesCompressionEnabled(bool enabled) { } static float denormalize(float value, const float minValue) { - return value < minValue ? 0.f : value; + return value < minValue ? 0.0f : value; } uint32 packR11G11B10F(const glm::vec3& color) { @@ -319,17 +323,18 @@ struct OutputHandler : public nvtt::OutputHandler { _data = static_cast(malloc(size)); _current = _data; } + virtual bool writeData(const void* data, int size) override { assert(_current + size <= _data + _size); memcpy(_current, data, size); _current += size; return true; } + virtual void endImage() override { if (_face >= 0) { _texture->assignStoredMipFace(_miplevel, _face, _size, static_cast(_data)); - } - else { + } else { _texture->assignStoredMip(_miplevel, _size, static_cast(_data)); } free(_data); @@ -433,11 +438,11 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { data.resize(width*height); dataIt = data.begin(); for (auto lineNb = 0; lineNb < height; lineNb++) { - const uint32* srcPixelIt = (const uint32*)image.constScanLine(lineNb); + const uint32* srcPixelIt = reinterpret_cast( image.constScanLine(lineNb) ); const uint32* srcPixelEnd = srcPixelIt + width; while (srcPixelIt < srcPixelEnd) { - *dataIt = glm::vec4(unpackFunc(*srcPixelIt), 1.f); + *dataIt = glm::vec4(unpackFunc(*srcPixelIt), 1.0f); ++srcPixelIt; ++dataIt; } @@ -446,7 +451,7 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { nvtt::OutputOptions outputOptions; outputOptions.setOutputHeader(false); - std::auto_ptr outputHandler; + std::unique_ptr outputHandler; MyErrorHandler errorHandler; outputOptions.setErrorHandler(&errorHandler); nvtt::Context context; @@ -1086,29 +1091,29 @@ QImage convertToHDRFormat(QImage srcImage, gpu::Element format) { #endif switch (format.getSemantic()) { - case gpu::R11G11B10: - packFunc = packR11G11B10F; + case gpu::R11G11B10: + packFunc = packR11G11B10F; #ifdef DEBUG_COLOR_PACKING - unpackFunc = glm::unpackF2x11_1x10; + unpackFunc = glm::unpackF2x11_1x10; #endif - break; - case gpu::RGB9E5: - packFunc = glm::packF3x9_E1x5; + break; + case gpu::RGB9E5: + packFunc = glm::packF3x9_E1x5; #ifdef DEBUG_COLOR_PACKING - unpackFunc = glm::unpackF3x9_E1x5; + unpackFunc = glm::unpackF3x9_E1x5; #endif - break; - default: - qCWarning(imagelogging) << "Unsupported HDR format"; - Q_UNREACHABLE(); - return srcImage; + break; + default: + qCWarning(imagelogging) << "Unsupported HDR format"; + Q_UNREACHABLE(); + return srcImage; } srcImage = srcImage.convertToFormat(QImage::Format_ARGB32); for (auto y = 0; y < srcImage.height(); y++) { - const QRgb* srcLineIt = (const QRgb*) srcImage.constScanLine(y); + const QRgb* srcLineIt = reinterpret_cast( srcImage.constScanLine(y) ); const QRgb* srcLineEnd = srcLineIt + srcImage.width(); - uint32* hdrLineIt = (uint32*) hdrImage.scanLine(y); + uint32* hdrLineIt = reinterpret_cast( hdrImage.scanLine(y) ); glm::vec3 color; while (srcLineIt < srcLineEnd) { @@ -1116,7 +1121,7 @@ QImage convertToHDRFormat(QImage srcImage, gpu::Element format) { color.g = qGreen(*srcLineIt); color.b = qBlue(*srcLineIt); // Normalize and apply gamma - color /= 255.f; + color /= 255.0f; color.r = powf(color.r, 2.2f); color.g = powf(color.g, 2.2f); color.b = powf(color.b, 2.2f); diff --git a/libraries/image/src/image/Image.h b/libraries/image/src/image/Image.h index c8be097542..3bf45ace98 100644 --- a/libraries/image/src/image/Image.h +++ b/libraries/image/src/image/Image.h @@ -13,11 +13,11 @@ #define hifi_image_Image_h #include -#include #include class QByteArray; +class QImage; namespace image { @@ -74,11 +74,6 @@ void setNormalTexturesCompressionEnabled(bool enabled); void setGrayscaleTexturesCompressionEnabled(bool enabled); void setCubeTexturesCompressionEnabled(bool enabled); -enum -{ - QIMAGE_HDR_FORMAT = QImage::Format_RGB30 -}; - gpu::TexturePointer processImage(const QByteArray& content, const std::string& url, int maxNumPixels, TextureUsage::Type textureType); } // namespace image From 5699dc6f42356874fb96ca86aed65c3e3e01c133 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 21 Sep 2017 10:03:05 +0200 Subject: [PATCH 06/79] Added KTX support of compressed HDR and HDR formats --- libraries/gpu/src/gpu/Texture_ktx.cpp | 15 +++++++++++++++ libraries/ktx/src/khronos/KHR.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 14fd983ec2..eb21121ebe 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -570,6 +570,12 @@ bool Texture::evalKTXFormat(const Element& mipFormat, const Element& texelFormat header.setCompressed(ktx::GLInternalFormat::COMPRESSED_RG_RGTC2, ktx::GLBaseInternalFormat::RG); } else if (texelFormat == Format::COLOR_COMPRESSED_SRGBA_HIGH && mipFormat == Format::COLOR_COMPRESSED_SRGBA_HIGH) { header.setCompressed(ktx::GLInternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM, ktx::GLBaseInternalFormat::RGBA); + } else if (texelFormat == Format::COLOR_COMPRESSED_HDR_RGB && mipFormat == Format::COLOR_COMPRESSED_HDR_RGB) { + header.setCompressed(ktx::GLInternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, ktx::GLBaseInternalFormat::RGB); + } else if (texelFormat == Format::COLOR_RGB9E5 && mipFormat == Format::COLOR_RGB9E5) { + header.setUncompressed(ktx::GLType::UNSIGNED_INT_5_9_9_9_REV, 1, ktx::GLFormat::RGB, ktx::GLInternalFormat::RGB9_E5, ktx::GLBaseInternalFormat::RGB); + } else if (texelFormat == Format::COLOR_R11G11B10 && mipFormat == Format::COLOR_R11G11B10) { + header.setUncompressed(ktx::GLType::UNSIGNED_INT_10F_11F_11F_REV, 1, ktx::GLFormat::RGB, ktx::GLInternalFormat::R11F_G11F_B10F, ktx::GLBaseInternalFormat::RGB); } else { return false; } @@ -631,6 +637,15 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM) { mipFormat = Format::COLOR_COMPRESSED_SRGBA_HIGH; texelFormat = Format::COLOR_COMPRESSED_SRGBA_HIGH; + } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) { + mipFormat = Format::COLOR_COMPRESSED_HDR_RGB; + texelFormat = Format::COLOR_COMPRESSED_HDR_RGB; + } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::RGB9_E5) { + mipFormat = Format::COLOR_RGB9E5; + texelFormat = Format::COLOR_RGB9E5; + } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::R11F_G11F_B10F) { + mipFormat = Format::COLOR_R11G11B10; + texelFormat = Format::COLOR_R11G11B10; } else { return false; } diff --git a/libraries/ktx/src/khronos/KHR.h b/libraries/ktx/src/khronos/KHR.h index 98cc1a4736..ae23d9cefe 100644 --- a/libraries/ktx/src/khronos/KHR.h +++ b/libraries/ktx/src/khronos/KHR.h @@ -225,6 +225,7 @@ namespace khronos { case InternalFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: // BC3 case InternalFormat::COMPRESSED_RED_RGTC1: // BC4 case InternalFormat::COMPRESSED_RG_RGTC2: // BC5 + case InternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: // BC6 case InternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM: // BC7 return evalAlignedCompressedBlockCount<4>(value); @@ -241,6 +242,7 @@ namespace khronos { return 8; case InternalFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case InternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: case InternalFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case InternalFormat::COMPRESSED_RG_RGTC2: return 16; From 98820f720d986f7b04960e20e5b907d211b677b6 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 21 Sep 2017 13:17:25 +0200 Subject: [PATCH 07/79] KTX serialization / unserialization working with compressed HDR. Not sure with packed floats --- .../src/RenderableModelEntityItem.cpp | 4 +-- libraries/gpu/src/gpu/Texture_ktx.cpp | 32 +++++++++---------- libraries/image/src/image/Image.cpp | 25 ++++++++++----- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 2508b598af..5b790dbddc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -319,7 +319,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // should never fall in here when collision model not fully loaded // hence we assert that all geometries exist and are loaded - assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); + assert(model && model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); @@ -408,7 +408,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { shapeInfo.setParams(type, dimensions, getCompoundShapeURL()); } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { // should never fall in here when model not fully loaded - assert(_model && _model->isLoaded()); + assert(model && model->isLoaded()); updateModelBounds(); model->updateGeometry(); diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index eb21121ebe..2acb5a9be8 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -518,17 +518,17 @@ TexturePointer Texture::build(const ktx::KTXDescriptor& descriptor) { TexturePointer Texture::unserialize(const cache::FilePointer& cacheEntry) { - std::unique_ptr ktxPointer = ktx::KTX::create(std::make_shared(cacheEntry->getFilepath().c_str())); - if (!ktxPointer) { - return nullptr; - } +std::unique_ptr ktxPointer = ktx::KTX::create(std::make_shared(cacheEntry->getFilepath().c_str())); +if (!ktxPointer) { + return nullptr; +} - auto texture = build(ktxPointer->toDescriptor()); - if (texture) { - texture->setKtxBacking(cacheEntry); - } +auto texture = build(ktxPointer->toDescriptor()); +if (texture) { + texture->setKtxBacking(cacheEntry); +} - return texture; +return texture; } TexturePointer Texture::unserialize(const std::string& ktxfile) { @@ -536,7 +536,7 @@ TexturePointer Texture::unserialize(const std::string& ktxfile) { if (!ktxPointer) { return nullptr; } - + auto texture = build(ktxPointer->toDescriptor()); if (texture) { texture->setKtxBacking(ktxfile); @@ -618,6 +618,12 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E } else { return false; } + } else if (header.getGLFormat() == ktx::GLFormat::RGB && header.getGLType() == ktx::GLType::UNSIGNED_INT_10F_11F_11F_REV) { + mipFormat = Format::COLOR_R11G11B10; + texelFormat = Format::COLOR_R11G11B10; + } else if (header.getGLFormat() == ktx::GLFormat::RGB && header.getGLType() == ktx::GLType::UNSIGNED_INT_5_9_9_9_REV) { + mipFormat = Format::COLOR_RGB9E5; + texelFormat = Format::COLOR_RGB9E5; } else if (header.isCompressed()) { if (header.getGLInternaFormat() == ktx::GLInternalFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT) { mipFormat = Format::COLOR_COMPRESSED_SRGB; @@ -640,12 +646,6 @@ bool Texture::evalTextureFormat(const ktx::Header& header, Element& mipFormat, E } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) { mipFormat = Format::COLOR_COMPRESSED_HDR_RGB; texelFormat = Format::COLOR_COMPRESSED_HDR_RGB; - } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::RGB9_E5) { - mipFormat = Format::COLOR_RGB9E5; - texelFormat = Format::COLOR_RGB9E5; - } else if (header.getGLInternaFormat() == ktx::GLInternalFormat::R11F_G11F_B10F) { - mipFormat = Format::COLOR_R11G11B10; - texelFormat = Format::COLOR_R11G11B10; } else { return false; } diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index 2ae62a9ce3..b88a067080 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -43,6 +43,8 @@ bool DEV_DECIMATE_TEXTURES = false; std::atomic DECIMATED_TEXTURE_COUNT{ 0 }; std::atomic RECTIFIED_TEXTURE_COUNT{ 0 }; +static const auto HDR_FORMAT = gpu::Element::COLOR_R11G11B10; + bool needsSparseRectification(const glm::uvec2& size) { // Don't attempt to rectify small textures (textures less than the sparse page size in any dimension) if (glm::any(glm::lessThan(size, SPARSE_PAGE_SIZE))) { @@ -423,18 +425,26 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, int face) { compressionOptions.setFormat(nvtt::Format_RGB); compressionOptions.setPixelType(nvtt::PixelType_Float); compressionOptions.setPixelFormat(32, 32, 32, 0); - unpackFunc = glm::unpackF3x9_E1x5; } else if (mipFormat == gpu::Element::COLOR_R11G11B10) { compressionOptions.setFormat(nvtt::Format_RGB); compressionOptions.setPixelType(nvtt::PixelType_Float); compressionOptions.setPixelFormat(32, 32, 32, 0); - unpackFunc = glm::unpackF2x11_1x10; } else { qCWarning(imagelogging) << "Unknown mip format"; Q_UNREACHABLE(); return; } + if (HDR_FORMAT == gpu::Element::COLOR_RGB9E5) { + unpackFunc = glm::unpackF3x9_E1x5; + } else if (HDR_FORMAT == gpu::Element::COLOR_R11G11B10) { + unpackFunc = glm::unpackF2x11_1x10; + } else { + qCWarning(imagelogging) << "Unknown HDR encoding format in QImage"; + Q_UNREACHABLE(); + return; + } + data.resize(width*height); dataIt = data.begin(); for (auto lineNb = 0; lineNb < height; lineNb++) { @@ -1144,19 +1154,18 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& if ((srcImage.width() > 0) && (srcImage.height() > 0)) { QImage image = processSourceImage(srcImage, true); - const auto cubeMapHDRFormat = gpu::Element::COLOR_R11G11B10; gpu::Element formatMip; gpu::Element formatGPU; if (isCubeTexturesCompressionEnabled()) { formatMip = gpu::Element::COLOR_COMPRESSED_HDR_RGB; formatGPU = gpu::Element::COLOR_COMPRESSED_HDR_RGB; } else { - formatMip = cubeMapHDRFormat; - formatGPU = cubeMapHDRFormat; + formatMip = HDR_FORMAT; + formatGPU = HDR_FORMAT; } if (image.format() != QIMAGE_HDR_FORMAT) { - image = convertToHDRFormat(image, cubeMapHDRFormat); + image = convertToHDRFormat(image, HDR_FORMAT); } // Find the layout of the cubemap in the 2D image @@ -1204,9 +1213,9 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage& // Generate irradiance while we are at it if (generateIrradiance) { PROFILE_RANGE(resource_parse, "generateIrradiance"); - auto irradianceTexture = gpu::Texture::createCube(cubeMapHDRFormat, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); + auto irradianceTexture = gpu::Texture::createCube(HDR_FORMAT, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); irradianceTexture->setSource(srcImageName); - irradianceTexture->setStoredMipFormat(cubeMapHDRFormat); + irradianceTexture->setStoredMipFormat(HDR_FORMAT); for (uint8 face = 0; face < faces.size(); ++face) { irradianceTexture->assignStoredMipFace(0, face, faces[face].byteCount(), faces[face].constBits()); } From f31e9df21cffb3842a746d03e01fe42356ef3140 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 25 Sep 2017 10:31:49 +0200 Subject: [PATCH 08/79] Fixed incorrect pixel byte size computation in KTX --- libraries/ktx/src/khronos/KHR.h | 135 ++++++++++++++++++++++++++++++++ libraries/ktx/src/ktx/KTX.cpp | 17 ++-- libraries/ktx/src/ktx/KTX.h | 2 +- 3 files changed, 145 insertions(+), 9 deletions(-) diff --git a/libraries/ktx/src/khronos/KHR.h b/libraries/ktx/src/khronos/KHR.h index ae23d9cefe..cda22513ee 100644 --- a/libraries/ktx/src/khronos/KHR.h +++ b/libraries/ktx/src/khronos/KHR.h @@ -209,6 +209,137 @@ namespace khronos { COMPRESSED_SIGNED_RG11_EAC = 0x9273, }; + inline uint8_t evalUncompressedBlockBitSize(InternalFormat format) { + switch (format) { + case InternalFormat::R8: + case InternalFormat::R8_SNORM: + return 8; + case InternalFormat::R16: + case InternalFormat::R16_SNORM: + case InternalFormat::RG8: + case InternalFormat::RG8_SNORM: + return 16; + case InternalFormat::RG16: + case InternalFormat::RG16_SNORM: + return 16; + case InternalFormat::R3_G3_B2: + return 8; + case InternalFormat::RGB4: + return 12; + case InternalFormat::RGB5: + case InternalFormat::RGB565: + return 16; + case InternalFormat::RGB8: + case InternalFormat::RGB8_SNORM: + return 24; + case InternalFormat::RGB10: + // TODO: check if this is really the case + return 32; + case InternalFormat::RGB12: + // TODO: check if this is really the case + return 48; + case InternalFormat::RGB16: + case InternalFormat::RGB16_SNORM: + return 48; + case InternalFormat::RGBA2: + return 8; + case InternalFormat::RGBA4: + case InternalFormat::RGB5_A1: + return 16; + case InternalFormat::RGBA8: + case InternalFormat::RGBA8_SNORM: + case InternalFormat::RGB10_A2: + case InternalFormat::RGB10_A2UI: + return 32; + case InternalFormat::RGBA12: + return 48; + case InternalFormat::RGBA16: + case InternalFormat::RGBA16_SNORM: + return 64; + case InternalFormat::SRGB8: + return 24; + case InternalFormat::SRGB8_ALPHA8: + return 32; + case InternalFormat::R16F: + return 16; + case InternalFormat::RG16F: + return 32; + case InternalFormat::RGB16F: + return 48; + case InternalFormat::RGBA16F: + return 64; + case InternalFormat::R32F: + return 32; + case InternalFormat::RG32F: + return 64; + case InternalFormat::RGB32F: + return 96; + case InternalFormat::RGBA32F: + return 128; + case InternalFormat::R11F_G11F_B10F: + case InternalFormat::RGB9_E5: + return 32; + case InternalFormat::R8I: + case InternalFormat::R8UI: + return 8; + case InternalFormat::R16I: + case InternalFormat::R16UI: + return 16; + case InternalFormat::R32I: + case InternalFormat::R32UI: + return 32; + case InternalFormat::RG8I: + case InternalFormat::RG8UI: + return 16; + case InternalFormat::RG16I: + case InternalFormat::RG16UI: + return 32; + case InternalFormat::RG32I: + case InternalFormat::RG32UI: + return 64; + case InternalFormat::RGB8I: + case InternalFormat::RGB8UI: + return 24; + case InternalFormat::RGB16I: + case InternalFormat::RGB16UI: + return 48; + case InternalFormat::RGB32I: + case InternalFormat::RGB32UI: + return 96; + case InternalFormat::RGBA8I: + case InternalFormat::RGBA8UI: + return 32; + case InternalFormat::RGBA16I: + case InternalFormat::RGBA16UI: + return 64; + case InternalFormat::RGBA32I: + case InternalFormat::RGBA32UI: + return 128; + case InternalFormat::DEPTH_COMPONENT16: + return 16; + case InternalFormat::DEPTH_COMPONENT24: + return 24; + case InternalFormat::DEPTH_COMPONENT32: + case InternalFormat::DEPTH_COMPONENT32F: + case InternalFormat::DEPTH24_STENCIL8: + return 32; + case InternalFormat::DEPTH32F_STENCIL8: + // TODO : check if this true + return 40; + case InternalFormat::STENCIL_INDEX1: + return 1; + case InternalFormat::STENCIL_INDEX4: + return 4; + case InternalFormat::STENCIL_INDEX8: + return 8; + case InternalFormat::STENCIL_INDEX16: + return 16; + + default: + return 0; + } + } + template inline uint32_t evalAlignedCompressedBlockCount(uint32_t value) { enum { val = ALIGNMENT && !(ALIGNMENT & (ALIGNMENT - 1)) }; @@ -252,6 +383,10 @@ namespace khronos { } } + inline uint8_t evalCompressedBlockBitSize(InternalFormat format) { + return evalCompressedBlockSize(format) * 8; + } + enum class BaseInternalFormat : uint32_t { // GL 4.4 Table 8.11 DEPTH_COMPONENT = 0x1902, diff --git a/libraries/ktx/src/ktx/KTX.cpp b/libraries/ktx/src/ktx/KTX.cpp index 3b1a12cba7..5bd45549c1 100644 --- a/libraries/ktx/src/ktx/KTX.cpp +++ b/libraries/ktx/src/ktx/KTX.cpp @@ -54,15 +54,13 @@ uint32_t Header::evalPixelOrBlockDepth(uint32_t level) const { return evalMipDimension(level, getPixelDepth()); } -size_t Header::evalPixelOrBlockSize() const { +size_t Header::evalPixelOrBlockBitSize() const { size_t result = 0; + auto format = getGLInternaFormat(); if (isCompressed()) { - auto format = getGLInternaFormat(); - result = khronos::gl::texture::evalCompressedBlockSize(format); + result = khronos::gl::texture::evalCompressedBlockBitSize(format); } else { - // FIXME should really be using the internal format, not the base internal format - auto baseFormat = getGLBaseInternalFormat(); - result = khronos::gl::texture::evalComponentCount(baseFormat); + result = khronos::gl::texture::evalUncompressedBlockBitSize(format); } if (0 == result) { @@ -73,11 +71,14 @@ size_t Header::evalPixelOrBlockSize() const { size_t Header::evalRowSize(uint32_t level) const { auto pixWidth = evalPixelOrBlockWidth(level); - auto pixSize = evalPixelOrBlockSize(); + auto pixSize = evalPixelOrBlockBitSize(); if (pixSize == 0) { return 0; } - return evalPaddedSize(pixWidth * pixSize); + auto totalByteSize = pixWidth * pixSize; + // Round to the nearest upper byte size + totalByteSize = (totalByteSize / 8) + (((totalByteSize % 8) != 0) & 1); + return evalPaddedSize(totalByteSize); } size_t Header::evalFaceSize(uint32_t level) const { diff --git a/libraries/ktx/src/ktx/KTX.h b/libraries/ktx/src/ktx/KTX.h index 8dc4ec7a47..54a8188a42 100644 --- a/libraries/ktx/src/ktx/KTX.h +++ b/libraries/ktx/src/ktx/KTX.h @@ -170,7 +170,7 @@ namespace ktx { uint32_t evalPixelOrBlockHeight(uint32_t level) const; uint32_t evalPixelOrBlockDepth(uint32_t level) const; - size_t evalPixelOrBlockSize() const; + size_t evalPixelOrBlockBitSize() const; size_t evalRowSize(uint32_t level) const; size_t evalFaceSize(uint32_t level) const; size_t evalImageSize(uint32_t level) const; From 014a7bc9b0a234938eac5d4058235da0565ff814 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 25 Sep 2017 08:36:38 -0700 Subject: [PATCH 09/79] Fix bytes downloaded stat tracking --- interface/src/Application.cpp | 14 ++++++++------ .../scripting/AssetMappingsScriptingInterface.cpp | 1 + libraries/networking/src/AssetResourceRequest.cpp | 6 +++--- libraries/networking/src/AssetResourceRequest.h | 2 ++ libraries/networking/src/FileResourceRequest.cpp | 3 +-- libraries/networking/src/HTTPResourceRequest.cpp | 9 ++++----- libraries/networking/src/ResourceRequest.cpp | 11 +++++++++++ libraries/networking/src/ResourceRequest.h | 2 ++ libraries/shared/src/StatTracker.cpp | 4 ++-- libraries/shared/src/StatTracker.h | 6 +++--- 10 files changed, 37 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 480928ccd2..43541c3ac2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1628,12 +1628,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; QJsonObject bytesDownloaded; - bytesDownloaded["atp"] = statTracker->getStat(STAT_ATP_RESOURCE_TOTAL_BYTES).toInt(); - bytesDownloaded["http"] = statTracker->getStat(STAT_HTTP_RESOURCE_TOTAL_BYTES).toInt(); - bytesDownloaded["file"] = statTracker->getStat(STAT_FILE_RESOURCE_TOTAL_BYTES).toInt(); - bytesDownloaded["total"] = bytesDownloaded["atp"].toInt() + bytesDownloaded["http"].toInt() - + bytesDownloaded["file"].toInt(); - properties["bytesDownloaded"] = bytesDownloaded; + auto atpBytes = statTracker->getStat(STAT_ATP_RESOURCE_TOTAL_BYTES).toLongLong(); + auto httpBytes = statTracker->getStat(STAT_HTTP_RESOURCE_TOTAL_BYTES).toLongLong(); + auto fileBytes = statTracker->getStat(STAT_FILE_RESOURCE_TOTAL_BYTES).toLongLong(); + bytesDownloaded["atp"] = atpBytes; + bytesDownloaded["http"] = httpBytes; + bytesDownloaded["file"] = fileBytes; + bytesDownloaded["total"] = atpBytes + httpBytes + fileBytes; + properties["bytes_downloaded"] = bytesDownloaded; auto myAvatar = getMyAvatar(); glm::vec3 avatarPosition = myAvatar->getPosition(); diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index 5031016c3f..0912c869d3 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -21,6 +21,7 @@ #include #include #include +#include static const int AUTO_REFRESH_INTERVAL = 1000; diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index 2dc22a9337..55d0ad4f75 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -155,6 +155,7 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { case AssetRequest::Error::NoError: _data = req->getData(); _result = Success; + recordBytesDownloadedInStats(STAT_ATP_RESOURCE_TOTAL_BYTES, _data.size()); break; case AssetRequest::InvalidHash: _result = InvalidURL; @@ -202,9 +203,8 @@ void AssetResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytes emit progress(bytesReceived, bytesTotal); auto now = p_high_resolution_clock::now(); - - // Recording ATP bytes downloaded in stats - DependencyManager::get()->updateStat(STAT_ATP_RESOURCE_TOTAL_BYTES, bytesReceived); + + recordBytesDownloadedInStats(STAT_ATP_RESOURCE_TOTAL_BYTES, bytesReceived); // if we haven't received the full asset check if it is time to output progress to log // we do so every X seconds to assist with ATP download tracking diff --git a/libraries/networking/src/AssetResourceRequest.h b/libraries/networking/src/AssetResourceRequest.h index 18b82f2573..ac36c83985 100644 --- a/libraries/networking/src/AssetResourceRequest.h +++ b/libraries/networking/src/AssetResourceRequest.h @@ -41,6 +41,8 @@ private: AssetRequest* _assetRequest { nullptr }; p_high_resolution_clock::time_point _lastProgressDebug; + + int64_t _lastRecordedBytesDownloaded { 0 }; }; #endif diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index 26857716e1..dfff21dae6 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -69,8 +69,7 @@ void FileResourceRequest::doSend() { if (_result == ResourceRequest::Success) { statTracker->incrementStat(STAT_FILE_REQUEST_SUCCESS); - // Recording FILE bytes downloaded in stats - statTracker->updateStat(STAT_FILE_RESOURCE_TOTAL_BYTES,fileSize); + statTracker->updateStat(STAT_FILE_RESOURCE_TOTAL_BYTES, fileSize); } else { statTracker->incrementStat(STAT_FILE_REQUEST_FAILED); } diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index edba520bd5..a34f92aaa6 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -141,6 +141,8 @@ void HTTPResourceRequest::onRequestFinished() { } } + recordBytesDownloadedInStats(STAT_HTTP_RESOURCE_TOTAL_BYTES, _data.size()); + break; case QNetworkReply::TimeoutError: @@ -201,11 +203,8 @@ void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesT _sendTimer->start(); emit progress(bytesReceived, bytesTotal); - - // Recording HTTP bytes downloaded in stats - DependencyManager::get()->updateStat(STAT_HTTP_RESOURCE_TOTAL_BYTES, bytesReceived); - - + + recordBytesDownloadedInStats(STAT_HTTP_RESOURCE_TOTAL_BYTES, bytesReceived); } void HTTPResourceRequest::onTimeout() { diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index f028535e2f..5d39583c9e 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -11,6 +11,9 @@ #include "ResourceRequest.h" +#include +#include + #include ResourceRequest::ResourceRequest(const QUrl& url) : _url(url) { } @@ -40,3 +43,11 @@ QString ResourceRequest::getResultString() const { default: return "Unspecified Error"; } } + +void ResourceRequest::recordBytesDownloadedInStats(const QString& statName, int64_t bytesReceived) { + auto dBytes = bytesReceived - _lastRecordedBytesDownloaded; + if (dBytes > 0) { + _lastRecordedBytesDownloaded = bytesReceived; + DependencyManager::get()->updateStat(statName, dBytes); + } +} diff --git a/libraries/networking/src/ResourceRequest.h b/libraries/networking/src/ResourceRequest.h index cf852c1e1b..8dd09ccc49 100644 --- a/libraries/networking/src/ResourceRequest.h +++ b/libraries/networking/src/ResourceRequest.h @@ -85,6 +85,7 @@ signals: protected: virtual void doSend() = 0; + void recordBytesDownloadedInStats(const QString& statName, int64_t bytesReceived); QUrl _url; QUrl _relativePathURL; @@ -97,6 +98,7 @@ protected: ByteRange _byteRange; bool _rangeRequestSuccessful { false }; uint64_t _totalSizeOfResource { 0 }; + int64_t _lastRecordedBytesDownloaded { 0 }; }; #endif diff --git a/libraries/shared/src/StatTracker.cpp b/libraries/shared/src/StatTracker.cpp index 0ac9ab0092..1884037ce8 100644 --- a/libraries/shared/src/StatTracker.cpp +++ b/libraries/shared/src/StatTracker.cpp @@ -17,12 +17,12 @@ QVariant StatTracker::getStat(const QString& name) { return _stats[name]; } -void StatTracker::setStat(const QString& name, int value) { +void StatTracker::setStat(const QString& name, int64_t value) { Lock lock(_statsLock); _stats[name] = value; } -void StatTracker::updateStat(const QString& name, int value) { +void StatTracker::updateStat(const QString& name, int64_t value) { Lock lock(_statsLock); auto itr = _stats.find(name); if (_stats.end() == itr) { diff --git a/libraries/shared/src/StatTracker.h b/libraries/shared/src/StatTracker.h index 38afc2c379..4b84bbcb32 100644 --- a/libraries/shared/src/StatTracker.h +++ b/libraries/shared/src/StatTracker.h @@ -24,15 +24,15 @@ class StatTracker : public Dependency { public: StatTracker(); QVariant getStat(const QString& name); - void setStat(const QString& name, int value); - void updateStat(const QString& name, int mod); + void setStat(const QString& name, int64_t value); + void updateStat(const QString& name, int64_t mod); void incrementStat(const QString& name); void decrementStat(const QString& name); private: using Mutex = std::mutex; using Lock = std::lock_guard; Mutex _statsLock; - QHash _stats; + QHash _stats; }; class CounterStat { From 88810d28c1f39c19ffc1d5f4a29aa0fdcf3d0afd Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 25 Sep 2017 08:40:14 -0700 Subject: [PATCH 10/79] Add activity logging for uploading_asset --- .../AssetMappingsScriptingInterface.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index 0912c869d3..b9ce273901 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -105,6 +105,25 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping, startedCallback.call(); + QFile file { path }; + int64_t size { 0 }; + if (file.open(QIODevice::ReadOnly)) { + size = file.size(); + file.close(); + } + + QString extension = ""; + auto idx = path.lastIndexOf("."); + if (idx) { + extension = path.mid(idx + 1); + } + + UserActivityLogger::getInstance().logAction("uploading_asset", { + { "size", size }, + { "mapping", mapping }, + { "extension", extension} + }); + auto upload = DependencyManager::get()->createUpload(path); QObject::connect(upload, &AssetUpload::finished, this, [=](AssetUpload* upload, const QString& hash) mutable { if (upload->getError() != AssetUpload::NoError) { From 0e3c2f2e50ca12a569dd9c1ba619fda44fcb5fd8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 27 Sep 2017 15:22:23 -0700 Subject: [PATCH 11/79] Fix ambiguous conversion to QVariant in StatTracker --- libraries/shared/src/StatTracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/StatTracker.cpp b/libraries/shared/src/StatTracker.cpp index 1884037ce8..adfafd0ea7 100644 --- a/libraries/shared/src/StatTracker.cpp +++ b/libraries/shared/src/StatTracker.cpp @@ -14,7 +14,7 @@ StatTracker::StatTracker() { QVariant StatTracker::getStat(const QString& name) { std::lock_guard lock(_statsLock); - return _stats[name]; + return QVariant::fromValue(_stats[name]); } void StatTracker::setStat(const QString& name, int64_t value) { From 97bf093cabda4dfcb98d2c1416b122533ef8898b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 28 Sep 2017 08:16:54 -0700 Subject: [PATCH 12/79] Fix ambiguous conversion in AssetMappingScriptingInterface --- interface/src/scripting/AssetMappingsScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index b9ce273901..ba533a5bd1 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -119,7 +119,7 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping, } UserActivityLogger::getInstance().logAction("uploading_asset", { - { "size", size }, + { "size", (qint64)size }, { "mapping", mapping }, { "extension", extension} }); From 15ff4ebecb1dc15e3c1f9496fff7482b73ded0cb Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Wed, 2 Aug 2017 16:03:00 -0400 Subject: [PATCH 13/79] [Case 6491] Adds some debugging prints. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 4df25c41b7..b367d56bbf 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1583,20 +1583,29 @@ SelectionDisplay = (function() { // FUNCTION: SET SPACE MODE that.setSpaceMode = function(newSpaceMode) { + print("======> SetSpaceMode called. ========"); if (spaceMode != newSpaceMode) { + print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode); spaceMode = newSpaceMode; that.updateHandles(); + } else { + print(" Can't update SpaceMode. CurrentMode: " + spaceMode + " DesiredMode: " + newSpaceMode); } + print("====== SetSpaceMode called. <========"); }; // FUNCTION: TOGGLE SPACE MODE that.toggleSpaceMode = function() { + print("========> ToggleSpaceMode called. ========="); if (spaceMode == SPACE_WORLD && SelectionManager.selections.length > 1) { print("Local space editing is not available with multiple selections"); return; } + print( "PreToggle: " + spaceMode); spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; + print( "PostToggle: " + spaceMode); that.updateHandles(); + print("======== ToggleSpaceMode called. <========="); }; // FUNCTION: UNSELECT ALL @@ -1605,6 +1614,9 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLES that.updateHandles = function() { + print( "======> Update Handles =======" ); + print( " Selections Count: " + SelectionManager.selections.length ); + print( " SpaceMode: " + spaceMode ); if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); return; @@ -2334,6 +2346,8 @@ SelectionDisplay = (function() { rotation: Quat.fromPitchYawRollDegrees(90, 0, 0), }); + print( "====== Update Handles <=======" ); + }; // FUNCTION: SET OVERLAYS VISIBLE @@ -3551,15 +3565,22 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE ROTATION DEGREES OVERLAY function updateRotationDegreesOverlay(angleFromZero, handleRotation, centerPosition) { + print( "---> updateRotationDegreesOverlay ---" ); + print(" AngleFromZero: " + angleFromZero ); + print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z ); + print(" CenterPos - " + centerPosition.x + " Y: " + centerPosition.y + " Z: " + centerPosition.z ); var angle = angleFromZero * (Math.PI / 180); var position = { x: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, y: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, z: 0, }; + print(" Angle: " + angle ); + print(" InitialPos: " + position.x + ", " + position.y + ", " + position.z); position = Vec3.multiplyQbyV(handleRotation, position); position = Vec3.sum(centerPosition, position); - Overlays.editOverlay(rotationDegreesDisplay, { + print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); + var overlayProps = { position: position, dimensions: { x: innerRadius * ROTATION_DISPLAY_SIZE_X_MULTIPLIER, @@ -3567,7 +3588,12 @@ SelectionDisplay = (function() { }, lineHeight: innerRadius * ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER, text: normalizeDegrees(angleFromZero) + "°", - }); + }; + print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z ); + print(" OverlayLineHeight: " + overlayProps.lineHeight ); + print(" OverlayText: " + overlayProps.text ); + Overlays.editOverlay(rotationDegreesDisplay, overlayProps); + print( "<--- updateRotationDegreesOverlay ---" ); } // YAW GRABBER TOOL DEFINITION @@ -3575,6 +3601,7 @@ SelectionDisplay = (function() { addGrabberTool(yawHandle, { mode: "ROTATE_YAW", onBegin: function(event) { + print("================== HANDLE_ROLL(Beg) -> ======================="); SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; @@ -3616,8 +3643,10 @@ SelectionDisplay = (function() { }); updateRotationDegreesOverlay(0, yawHandleRotation, yawCenter); + print("================== HANDLE_YAW(Beg) <- ======================="); }, onEnd: function(event, reason) { + print("================== HANDLE_YAW(End) -> ======================="); Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -3632,8 +3661,10 @@ SelectionDisplay = (function() { }); pushCommandForSelections(); + print("================== HANDLE_YAW(End) <- ======================="); }, onMove: function(event) { + print("================== HANDLE_YAW(Mve) -> ======================="); var pickRay = generalComputePickRay(event.x, event.y); Overlays.editOverlay(selectionBox, { visible: false @@ -3651,6 +3682,7 @@ SelectionDisplay = (function() { var centerToIntersect = Vec3.subtract(result.intersection, center); // Note: orientedAngle which wants normalized centerToZero and centerToIntersect // handles that internally, so it's to pass unnormalized vectors here. + print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); var snapToInner = distanceFromCenter < innerRadius; @@ -3736,6 +3768,7 @@ SelectionDisplay = (function() { } } + print("================== HANDLE_YAW(Mve) <- ======================="); } }); @@ -3743,6 +3776,7 @@ SelectionDisplay = (function() { addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", onBegin: function(event) { + print("================== HANDLE_PITCH(Beg) -> ======================="); SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; @@ -3784,8 +3818,10 @@ SelectionDisplay = (function() { }); updateRotationDegreesOverlay(0, pitchHandleRotation, pitchCenter); + print("================== HANDLE_PITCH(Beg) <- ======================="); }, onEnd: function(event, reason) { + print("================== HANDLE_PITCH(End) -> ======================="); Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -3800,8 +3836,10 @@ SelectionDisplay = (function() { }); pushCommandForSelections(); + print("================== HANDLE_PITCH(End) <- ======================="); }, onMove: function(event) { + print("================== HANDLE_PITCH(Mve) -> ======================="); var pickRay = generalComputePickRay(event.x, event.y); Overlays.editOverlay(selectionBox, { visible: false @@ -3818,6 +3856,7 @@ SelectionDisplay = (function() { var centerToIntersect = Vec3.subtract(result.intersection, center); // Note: orientedAngle which wants normalized centerToZero & centerToIntersect, handles // this internally, so it's fine to pass non-normalized versions here. + print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); @@ -3894,6 +3933,7 @@ SelectionDisplay = (function() { }); } } + print("================== HANDLE_PITCH(Mve) <- ======================="); } }); @@ -3901,6 +3941,7 @@ SelectionDisplay = (function() { addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", onBegin: function(event) { + print("================== HANDLE_ROLL(Beg) -> ======================="); SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; @@ -3942,8 +3983,10 @@ SelectionDisplay = (function() { }); updateRotationDegreesOverlay(0, rollHandleRotation, rollCenter); + print("================== HANDLE_ROLL(Beg) <- ======================="); }, onEnd: function(event, reason) { + print("================== HANDLE_ROLL(End) -> ======================="); Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -3958,8 +4001,10 @@ SelectionDisplay = (function() { }); pushCommandForSelections(); + print("================== HANDLE_ROLL(End) <- ======================="); }, onMove: function(event) { + print("================== HANDLE_ROLL(Mve) -> ======================="); var pickRay = generalComputePickRay(event.x, event.y); Overlays.editOverlay(selectionBox, { visible: false @@ -3976,6 +4021,7 @@ SelectionDisplay = (function() { var centerToIntersect = Vec3.subtract(result.intersection, center); // Note: orientedAngle which wants normalized centerToZero & centerToIntersect, handles // this internally, so it's fine to pass non-normalized versions here. + print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); @@ -4051,6 +4097,8 @@ SelectionDisplay = (function() { }); } } + print("================== HANDLE_ROLL(Mve) <- ======================="); + } }); @@ -4086,7 +4134,10 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE PRESS EVENT that.mousePressEvent = function(event) { - var wantDebug = false; + var wantDebug = true; + if ( wantDebug ) { + print( "=============== eST::MousePressEvent BEG ======================="); + } if (!event.isLeftButton && !that.triggered) { // if another mouse button than left is pressed ignore it return false; @@ -4118,6 +4169,7 @@ SelectionDisplay = (function() { var tool = grabberTools[result.overlayID]; if (tool) { + print("Intersected with known table tool."); activeTool = tool; mode = tool.mode; somethingClicked = 'tool'; @@ -4125,8 +4177,10 @@ SelectionDisplay = (function() { activeTool.onBegin(event); } } else { + print("Intersected with unregistered tool..."); switch (result.overlayID) { case grabberMoveUp: + print("grabberMoveUp"); mode = "TRANSLATE_UP_DOWN"; somethingClicked = mode; @@ -4142,6 +4196,7 @@ SelectionDisplay = (function() { case grabberNEAR: case grabberEdgeTN: // TODO: maybe this should be TOP+NEAR stretching? case grabberEdgeBN: // TODO: maybe this should be BOTTOM+FAR stretching? + print("grabberNear variant"); mode = "STRETCH_NEAR"; somethingClicked = mode; break; @@ -4149,31 +4204,37 @@ SelectionDisplay = (function() { case grabberFAR: case grabberEdgeTF: // TODO: maybe this should be TOP+FAR stretching? case grabberEdgeBF: // TODO: maybe this should be BOTTOM+FAR stretching? + print("grabberFar variant"); mode = "STRETCH_FAR"; somethingClicked = mode; break; case grabberTOP: + print("grabberTOP"); mode = "STRETCH_TOP"; somethingClicked = mode; break; case grabberBOTTOM: + print("grabberBOTTOM"); mode = "STRETCH_BOTTOM"; somethingClicked = mode; break; case grabberRIGHT: case grabberEdgeTR: // TODO: maybe this should be TOP+RIGHT stretching? case grabberEdgeBR: // TODO: maybe this should be BOTTOM+RIGHT stretching? + print("grabberRight variant"); mode = "STRETCH_RIGHT"; somethingClicked = mode; break; case grabberLEFT: case grabberEdgeTL: // TODO: maybe this should be TOP+LEFT stretching? case grabberEdgeBL: // TODO: maybe this should be BOTTOM+LEFT stretching? + print("grabberLeft variant"); mode = "STRETCH_LEFT"; somethingClicked = mode; break; default: + print("UNKNOWN( " + result.overlayID + " )"); mode = "UNKNOWN"; break; } @@ -4183,6 +4244,7 @@ SelectionDisplay = (function() { // if one of the items above was clicked, then we know we are in translate or stretch mode, and we // should hide our rotate handles... if (somethingClicked) { + print("Click is triggering hiding of handles, hopefully"); Overlays.editOverlay(yawHandle, { visible: false }); @@ -4225,6 +4287,7 @@ SelectionDisplay = (function() { originalRoll = roll; if (result.intersects) { + print("Intersection detected with handle..."); var resultTool = grabberTools[result.overlayID]; if (resultTool) { activeTool = resultTool; @@ -4236,15 +4299,18 @@ SelectionDisplay = (function() { } switch (result.overlayID) { case yawHandle: + print("Handle_YAW"); mode = "ROTATE_YAW"; somethingClicked = mode; overlayOrientation = yawHandleRotation; overlayCenter = yawCenter; yawZero = result.intersection; rotationNormal = yawNormal; + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); break; case pitchHandle: + print("Handle_PITCH"); mode = "ROTATE_PITCH"; initialPosition = SelectionManager.worldPosition; somethingClicked = mode; @@ -4252,15 +4318,18 @@ SelectionDisplay = (function() { overlayCenter = pitchCenter; pitchZero = result.intersection; rotationNormal = pitchNormal; + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); break; case rollHandle: + print("Handle_ROLL"); mode = "ROTATE_ROLL"; somethingClicked = mode; overlayOrientation = rollHandleRotation; overlayCenter = rollCenter; rollZero = result.intersection; rotationNormal = rollNormal; + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); break; default: @@ -4463,6 +4532,10 @@ SelectionDisplay = (function() { ignoreRayIntersection: false }); + if ( wantDebug ) { + print( "=============== eST::MousePressEvent END ======================="); + } + return somethingClicked; }; From ae8ae6f6cc3f105f9009314fae572874f028bc33 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Thu, 3 Aug 2017 17:02:09 -0400 Subject: [PATCH 14/79] [Case 6491] Grabbers stay invisible while rotating (details below). This fixes the issue where grabbers would re-appear when rotating the selected object rather than staying hidden. updateHandles will now take the mode into account when deciding if the non-light grabber handles should be visible. This can be subverted by the user selecting a light source as in line with the previous behavior. Adds some debug prints in event handlers guarded by local wantDebug checks. Has some minor cleanup changes: * Remove unused var within updateRotationHandles * Readability improvement for light check within updateHandles * Pulled up rotate mode check within updateHandles * Added grabberCloner visibility flag within updateHandles Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 566 +++++++++++------- 1 file changed, 335 insertions(+), 231 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b367d56bbf..934a9081a3 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1530,7 +1530,6 @@ SelectionDisplay = (function() { var rotateHandlesVisible = true; var rotationOverlaysVisible = false; var translateHandlesVisible = true; - var stretchHandlesVisible = true; var selectionBoxVisible = true; var isPointLight = false; @@ -1543,11 +1542,9 @@ SelectionDisplay = (function() { rotationOverlaysVisible = true; rotateHandlesVisible = false; translateHandlesVisible = false; - stretchHandlesVisible = false; selectionBoxVisible = false; } else if (mode == "TRANSLATE_UP_DOWN" || isPointLight) { rotateHandlesVisible = false; - stretchHandlesVisible = false; } else if (mode != "UNKNOWN") { // every other mode is a stretch mode... rotateHandlesVisible = false; @@ -1622,6 +1619,7 @@ SelectionDisplay = (function() { return; } + //print( " Triggering updateRotationHandles"); that.updateRotationHandles(); var rotation, dimensions, position, registrationPoint; @@ -1849,201 +1847,212 @@ SelectionDisplay = (function() { EdgeFR = Vec3.sum(position, EdgeFR); EdgeFL = Vec3.sum(position, EdgeFL); - var stretchHandlesVisible = spaceMode == SPACE_LOCAL; - var extendedStretchHandlesVisible = stretchHandlesVisible && showExtendedStretchHandles; + var inModeRotate = (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL"); + var stretchHandlesVisible = !inModeRotate && (spaceMode == SPACE_LOCAL); + var extendedStretchHandlesVisible = (stretchHandlesVisible && showExtendedStretchHandles); + var cloneHandleVisible = !inModeRotate; + //print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); + var isSingleSelection = (selectionManager.selections.length == 1); - if (selectionManager.selections.length == 1) { + if (isSingleSelection) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); - if (properties.type == "Light" && properties.isSpotlight) { + var isLightSelection = (properties.type == "Light"); + if ( isLightSelection ) { + //print(" Light Selection revoking Non-Light Grabbers Visibility!"); stretchHandlesVisible = false; extendedStretchHandlesVisible = false; + cloneHandleVisible = false; + if(properties.isSpotlight) { + //print(" Trying to show all SpotLight related grabbers"); + Overlays.editOverlay(grabberSpotLightCenter, { + position: position, + visible: false, + }); + Overlays.editOverlay(grabberSpotLightRadius, { + position: NEAR, + rotation: rotation, + visible: true, + }); + var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); - Overlays.editOverlay(grabberSpotLightCenter, { - position: position, - visible: false, - }); - Overlays.editOverlay(grabberSpotLightRadius, { - position: NEAR, - rotation: rotation, - visible: true, - }); - var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); + Overlays.editOverlay(grabberSpotLightL, { + position: EdgeNL, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightR, { + position: EdgeNR, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightT, { + position: EdgeTN, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightB, { + position: EdgeBN, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightCircle, { + position: NEAR, + dimensions: { + x: distance, + y: distance, + z: 1 + }, + lineWidth: 1.5, + rotation: rotation, + visible: true, + }); - Overlays.editOverlay(grabberSpotLightL, { - position: EdgeNL, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightR, { - position: EdgeNR, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightT, { - position: EdgeTN, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightB, { - position: EdgeBN, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightCircle, { - position: NEAR, - dimensions: { - x: distance, - y: distance, - z: 1 - }, - lineWidth: 1.5, - rotation: rotation, - visible: true, - }); + Overlays.editOverlay(grabberSpotLightLineT, { + start: position, + end: EdgeTN, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightLineB, { + start: position, + end: EdgeBN, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightLineR, { + start: position, + end: EdgeNR, + visible: true, + }); + Overlays.editOverlay(grabberSpotLightLineL, { + start: position, + end: EdgeNL, + visible: true, + }); - Overlays.editOverlay(grabberSpotLightLineT, { - start: position, - end: EdgeTN, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightLineB, { - start: position, - end: EdgeBN, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightLineR, { - start: position, - end: EdgeNR, - visible: true, - }); - Overlays.editOverlay(grabberSpotLightLineL, { - start: position, - end: EdgeNL, - visible: true, - }); + //print(" Trying to hide all PointLight related grabbers"); + Overlays.editOverlay(grabberPointLightCircleX, { + visible: false + }); + Overlays.editOverlay(grabberPointLightCircleY, { + visible: false + }); + Overlays.editOverlay(grabberPointLightCircleZ, { + visible: false + }); + Overlays.editOverlay(grabberPointLightT, { + visible: false + }); + Overlays.editOverlay(grabberPointLightB, { + visible: false + }); + Overlays.editOverlay(grabberPointLightL, { + visible: false + }); + Overlays.editOverlay(grabberPointLightR, { + visible: false + }); + Overlays.editOverlay(grabberPointLightF, { + visible: false + }); + Overlays.editOverlay(grabberPointLightN, { + visible: false + }); + } else { //..it's a PointLight + //print(" Trying to show all PointLight related grabbers"); + Overlays.editOverlay(grabberPointLightT, { + position: TOP, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightB, { + position: BOTTOM, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightL, { + position: LEFT, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightR, { + position: RIGHT, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightF, { + position: FAR, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightN, { + position: NEAR, + rotation: rotation, + visible: true, + }); + Overlays.editOverlay(grabberPointLightCircleX, { + position: position, + rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)), + dimensions: { + x: properties.dimensions.z / 2.0, + y: properties.dimensions.z / 2.0, + z: 1 + }, + visible: true, + }); + Overlays.editOverlay(grabberPointLightCircleY, { + position: position, + rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(90, 0, 0)), + dimensions: { + x: properties.dimensions.z / 2.0, + y: properties.dimensions.z / 2.0, + z: 1 + }, + visible: true, + }); + Overlays.editOverlay(grabberPointLightCircleZ, { + position: position, + rotation: rotation, + dimensions: { + x: properties.dimensions.z / 2.0, + y: properties.dimensions.z / 2.0, + z: 1 + }, + visible: true, + }); - Overlays.editOverlay(grabberPointLightCircleX, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleY, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleZ, { - visible: false - }); - Overlays.editOverlay(grabberPointLightT, { - visible: false - }); - Overlays.editOverlay(grabberPointLightB, { - visible: false - }); - Overlays.editOverlay(grabberPointLightL, { - visible: false - }); - Overlays.editOverlay(grabberPointLightR, { - visible: false - }); - Overlays.editOverlay(grabberPointLightF, { - visible: false - }); - Overlays.editOverlay(grabberPointLightN, { - visible: false - }); - } else if (properties.type == "Light" && !properties.isSpotlight) { - stretchHandlesVisible = false; - extendedStretchHandlesVisible = false; - Overlays.editOverlay(grabberPointLightT, { - position: TOP, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightB, { - position: BOTTOM, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightL, { - position: LEFT, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightR, { - position: RIGHT, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightF, { - position: FAR, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightN, { - position: NEAR, - rotation: rotation, - visible: true, - }); - Overlays.editOverlay(grabberPointLightCircleX, { - position: position, - rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)), - dimensions: { - x: properties.dimensions.z / 2.0, - y: properties.dimensions.z / 2.0, - z: 1 - }, - visible: true, - }); - Overlays.editOverlay(grabberPointLightCircleY, { - position: position, - rotation: Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(90, 0, 0)), - dimensions: { - x: properties.dimensions.z / 2.0, - y: properties.dimensions.z / 2.0, - z: 1 - }, - visible: true, - }); - Overlays.editOverlay(grabberPointLightCircleZ, { - position: position, - rotation: rotation, - dimensions: { - x: properties.dimensions.z / 2.0, - y: properties.dimensions.z / 2.0, - z: 1 - }, - visible: true, - }); - - Overlays.editOverlay(grabberSpotLightRadius, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightB, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightCircle, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineB, { - visible: false - }); - } else { + //print(" Trying to hide all SpotLight related grabbers"); + Overlays.editOverlay(grabberSpotLightRadius, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightL, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightR, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightT, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightB, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightCircle, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightLineL, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightLineR, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightLineT, { + visible: false + }); + Overlays.editOverlay(grabberSpotLightLineB, { + visible: false + }); + } + } else { //..it's not a light at all + //print(" Trying to hide all Light related grabbers"); Overlays.editOverlay(grabberSpotLightCenter, { visible: false }); @@ -2106,7 +2115,7 @@ SelectionDisplay = (function() { visible: false }); } - } + }//--end of isSingleSelection @@ -2184,7 +2193,7 @@ SelectionDisplay = (function() { }); Overlays.editOverlay(grabberCloner, { - visible: true, + visible: cloneHandleVisible, rotation: rotation, position: EdgeTR }); @@ -2195,7 +2204,7 @@ SelectionDisplay = (function() { position: selectionBoxPosition, dimensions: dimensions, rotation: rotation, - visible: !(mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL"), + visible: !inModeRotate, }); // Create more selection box overlays if we don't have enough @@ -2332,7 +2341,7 @@ SelectionDisplay = (function() { }); Overlays.editOverlay(baseOfEntityProjectionOverlay, { - visible: mode != "ROTATE_YAW" && mode != "ROTATE_PITCH" && mode != "ROTATE_ROLL", + visible: !inModeRotate, solid: true, position: { x: selectionManager.worldPosition.x, @@ -4134,7 +4143,7 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE PRESS EVENT that.mousePressEvent = function(event) { - var wantDebug = true; + var wantDebug = false; if ( wantDebug ) { print( "=============== eST::MousePressEvent BEG ======================="); } @@ -4169,7 +4178,9 @@ SelectionDisplay = (function() { var tool = grabberTools[result.overlayID]; if (tool) { - print("Intersected with known table tool."); + if (wantDebug) { + print("Intersected with known table tool( mode: " + tool.mode + " )"); + } activeTool = tool; mode = tool.mode; somethingClicked = 'tool'; @@ -4177,10 +4188,14 @@ SelectionDisplay = (function() { activeTool.onBegin(event); } } else { - print("Intersected with unregistered tool..."); + if (wantDebug) { + print("Intersected with unregistered tool..."); + } switch (result.overlayID) { case grabberMoveUp: - print("grabberMoveUp"); + if (wantDebug){ + print("grabberMoveUp"); + } mode = "TRANSLATE_UP_DOWN"; somethingClicked = mode; @@ -4196,7 +4211,9 @@ SelectionDisplay = (function() { case grabberNEAR: case grabberEdgeTN: // TODO: maybe this should be TOP+NEAR stretching? case grabberEdgeBN: // TODO: maybe this should be BOTTOM+FAR stretching? - print("grabberNear variant"); + if(wantDebug){ + print("grabberNear variant"); + } mode = "STRETCH_NEAR"; somethingClicked = mode; break; @@ -4204,47 +4221,64 @@ SelectionDisplay = (function() { case grabberFAR: case grabberEdgeTF: // TODO: maybe this should be TOP+FAR stretching? case grabberEdgeBF: // TODO: maybe this should be BOTTOM+FAR stretching? - print("grabberFar variant"); + if(wantDebug){ + print("grabberFar variant"); + } mode = "STRETCH_FAR"; somethingClicked = mode; break; case grabberTOP: - print("grabberTOP"); + if(wantDebug){ + print("grabberTOP"); + } mode = "STRETCH_TOP"; somethingClicked = mode; break; case grabberBOTTOM: - print("grabberBOTTOM"); + if(wantDebug){ + print("grabberBOTTOM"); + } mode = "STRETCH_BOTTOM"; somethingClicked = mode; break; case grabberRIGHT: case grabberEdgeTR: // TODO: maybe this should be TOP+RIGHT stretching? case grabberEdgeBR: // TODO: maybe this should be BOTTOM+RIGHT stretching? - print("grabberRight variant"); + if(wantDebug){ + print("grabberRight variant"); + } mode = "STRETCH_RIGHT"; somethingClicked = mode; break; case grabberLEFT: case grabberEdgeTL: // TODO: maybe this should be TOP+LEFT stretching? case grabberEdgeBL: // TODO: maybe this should be BOTTOM+LEFT stretching? - print("grabberLeft variant"); + if(wantDebug){ + print("grabberLeft variant"); + } mode = "STRETCH_LEFT"; somethingClicked = mode; break; default: - print("UNKNOWN( " + result.overlayID + " )"); + if(wantDebug){ + print("UNKNOWN( " + result.overlayID + " )"); + } mode = "UNKNOWN"; break; } + if(wantDebug){ + print(" Unregistered Tool Mode: " + mode ); + } } } // if one of the items above was clicked, then we know we are in translate or stretch mode, and we // should hide our rotate handles... if (somethingClicked) { - print("Click is triggering hiding of handles, hopefully"); + if(wantDebug){ + print(" Trying to hide PitchYawRoll Handles"); + } Overlays.editOverlay(yawHandle, { visible: false }); @@ -4256,6 +4290,9 @@ SelectionDisplay = (function() { }); if (mode != "TRANSLATE_UP_DOWN") { + if(wantDebug){ + print(" Trying to hide GrabberMoveUp"); + } Overlays.editOverlay(grabberMoveUp, { visible: false }); @@ -4287,30 +4324,46 @@ SelectionDisplay = (function() { originalRoll = roll; if (result.intersects) { - print("Intersection detected with handle..."); var resultTool = grabberTools[result.overlayID]; + if(wantDebug){ + print("Intersection detected with handle..."); + } if (resultTool) { + if(wantDebug){ + print(" " + resultTool.mode); + } activeTool = resultTool; mode = resultTool.mode; somethingClicked = 'tool'; if (activeTool && activeTool.onBegin) { + if(wantDebug){ + print(" Triggering Tool's onBegin"); + } activeTool.onBegin(event); + } else if(wantDebug) { + print(" Tool's missing onBegin"); } } switch (result.overlayID) { case yawHandle: - print("Handle_YAW"); + if(wantDebug){ + print("Handle_YAW"); + } mode = "ROTATE_YAW"; somethingClicked = mode; overlayOrientation = yawHandleRotation; overlayCenter = yawCenter; yawZero = result.intersection; rotationNormal = yawNormal; - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + if(wantDebug){ + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + } break; case pitchHandle: - print("Handle_PITCH"); + if(wantDebug){ + print("Handle_PITCH"); + } mode = "ROTATE_PITCH"; initialPosition = SelectionManager.worldPosition; somethingClicked = mode; @@ -4318,18 +4371,24 @@ SelectionDisplay = (function() { overlayCenter = pitchCenter; pitchZero = result.intersection; rotationNormal = pitchNormal; - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + if(wantDebug){ + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + } break; case rollHandle: - print("Handle_ROLL"); + if(wantDebug){ + print("Handle_ROLL"); + } mode = "ROTATE_ROLL"; somethingClicked = mode; overlayOrientation = rollHandleRotation; overlayCenter = rollCenter; rollZero = result.intersection; rotationNormal = rollNormal; - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + if(wantDebug){ + print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); + } break; default: @@ -4347,6 +4406,9 @@ SelectionDisplay = (function() { if (somethingClicked) { + if(wantDebug){ + print(" Trying to show rotateOverlay Handles"); + } Overlays.editOverlay(rotateOverlayTarget, { visible: true, rotation: overlayOrientation, @@ -4371,6 +4433,9 @@ SelectionDisplay = (function() { startAt: 0, endAt: 0 }); + if(wantDebug){ + print(" Trying to hide PitchYawRoll Handles"); + } Overlays.editOverlay(yawHandle, { visible: false }); @@ -4381,15 +4446,11 @@ SelectionDisplay = (function() { visible: false }); + if(wantDebug){ + print(" Trying to hide Non-Light GrabberHandles"); + } - // TODO: these three duplicate prior three, remove them. - Overlays.editOverlay(yawHandle, { - visible: false - }); - Overlays.editOverlay(pitchHandle, { - visible: false - }); - Overlays.editOverlay(rollHandle, { + Overlays.editOverlay(grabberCloner, { visible: false }); Overlays.editOverlay(grabberMoveUp, { @@ -4485,6 +4546,9 @@ SelectionDisplay = (function() { switch (result.overlayID) { case selectionBox: activeTool = translateXZTool; + if(wantDebug){ + print("Clicked selectionBox, Activating Tool: " + activeTool.mode ); + } translateXZTool.pickPlanePosition = result.intersection; translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); @@ -4518,7 +4582,10 @@ SelectionDisplay = (function() { } // reset everything as intersectable... - // TODO: we could optimize this since some of these were already flipped back + // TODO: we could optimize this since some of these were already flipped back(i.e: just get rid of this) + if(wantDebug){ + print("Trying to set SelectionBox & PitchYawRoll Handles to NOT_IGNORE Rays"); + } Overlays.editOverlay(selectionBox, { ignoreRayIntersection: false }); @@ -4541,9 +4608,25 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE MOVE EVENT that.mouseMoveEvent = function(event) { + var wantDebug = false; + if(wantDebug){ + print( "=============== eST::MouseMoveEvent BEG ======================="); + } if (activeTool) { + if(wantDebug){ + print(" Trigger ActiveTool( " + activeTool.mode + " )'s onMove"); + } activeTool.onMove(event); + + if(wantDebug){ + print(" Trigger SelectionManager::update"); + } SelectionManager._update(); + + if(wantDebug){ + print( "=============== eST::MouseMoveEvent END ======================="); + } + //--EARLY EXIT--( Move handled via active tool) return true; } @@ -4666,6 +4749,9 @@ SelectionDisplay = (function() { } } + if(wantDebug){ + print("=============== eST::MouseMoveEvent END ======================="); + } return false; }; @@ -4710,13 +4796,27 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE RELEASE EVENT that.mouseReleaseEvent = function(event) { - var showHandles = false; - if (activeTool && activeTool.onEnd) { - activeTool.onEnd(event); + var wantDebug = false; + if(wantDebug){ + print("=============== eST::MouseReleaseEvent BEG ======================="); } - activeTool = null; + var showHandles = false; + if (activeTool) { + if( activeTool.onEnd ) { + if(wantDebug){ + print(" Triggering ActiveTool( " + activeTool.mode + " )'s onEnd"); + } + activeTool.onEnd(event); + }else if(wantDebug){ + print(" ActiveTool( " + activeTool.mode + " )'s missing onEnd"); + } + } + // hide our rotation overlays..., and show our handles if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL") { + if(wantDebug){ + print(" Triggering hide of RotateOverlays"); + } Overlays.editOverlay(rotateOverlayTarget, { visible: false }); @@ -4729,22 +4829,26 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); - showHandles = true; - } - - if (mode != "UNKNOWN") { - showHandles = true; + } + showHandles = (mode != "UNKNOWN");// Date: Mon, 7 Aug 2017 18:10:55 -0400 Subject: [PATCH 15/79] [Case 6491] Cleanup of mousePressEvent/tool(s) onBegin (details below). * Removes unregister tools switch which was never reached. * Rolls all code rotation handle related code within mousePressEvent to the respective rotation handler onBegin functions. * onBegin call site updated accordingly to provide intersection data that code depends upon. * Moves all translateXZTool code explicitly within mousePressEvent to the tool's onBegin function. * onBegin signature updated accordingly to provide intersect results that the tool relies upon. * Found and fixed a bug with translateXZTool where its startingElevation and startingDistance properties were _only_ set when local _debug_ var was set. * This appears to have been responsible for being able to move the object farther than was visible. Re-tested with fix and wasn't able to get that behavior any longer. * Wrap intersect tests within more reader friendly functions. NOTE(s): * Tested GrabberMoveUp and Rotation Handles. They work as they did previously as expected. * Tested selection behavior and it currently maintains as expected. * Tested translationXZTool and it maintains its prior behavior with the improvement noted above. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 515 +++++++++--------- 1 file changed, 244 insertions(+), 271 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 934a9081a3..ce93a6f366 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2392,13 +2392,30 @@ SelectionDisplay = (function() { greatestDimension: 0.0, startingDistance: 0.0, startingElevation: 0.0, - onBegin: function(event,isAltFromGrab) { + onBegin: function(event,isAltFromGrab, intersectInfo) { + var wantDebug = true; + if(wantDebug){ + print("================== TRANSLATE_XZ(Beg) -> ======================="); + Vec3.print(" intersectInfo.queryRay", intersectInfo.queryRay); + Vec3.print(" intersectInfo.queryRay.origin", intersectInfo.queryRay.origin); + Vec3.print(" intersectInfo.results.intersection", intersectInfo.results.intersection); + } + SelectionManager.saveProperties(); startPosition = SelectionManager.worldPosition; - var dimensions = SelectionManager.worldDimensions; + mode = translateXZTool.mode; - var pickRay = generalComputePickRay(event.x, event.y); - initialXZPick = rayPlaneIntersection(pickRay, translateXZTool.pickPlanePosition, { + translateXZTool.pickPlanePosition = intersectInfo.results.intersection; + translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); + translateXZTool.startingDistance = Vec3.distance(intersectInfo.queryRay.origin, SelectionManager.position); + translateXZTool.startingElevation = translateXZTool.elevation(intersectInfo.queryRay.origin, translateXZTool.pickPlanePosition); + if (wantDebug) { + print(" longest dimension: " + translateXZTool.greatestDimension); + print(" starting distance: " + translateXZTool.startingDistance); + print(" starting elevation: " + translateXZTool.startingElevation); + } + + initialXZPick = rayPlaneIntersection(intersectInfo.queryRay, translateXZTool.pickPlanePosition, { x: 0, y: 1, z: 0 @@ -2424,6 +2441,9 @@ SelectionDisplay = (function() { } isConstrained = false; + if(wantDebug){ + print("================== TRANSLATE_XZ(End) <- ======================="); + } }, onEnd: function(event, reason) { pushCommandForSelections(duplicatedEntityIDs); @@ -2452,8 +2472,10 @@ SelectionDisplay = (function() { // this will happen when someone drags across the horizon from the side they started on. if (!pick) { if (wantDebug) { - print("Pick ray does not intersect XZ plane."); + print(" "+ translateXZTool.mode + "Pick ray does not intersect XZ plane."); } + + //--EARLY EXIT--( Invalid ray detected. ) return; } @@ -2468,8 +2490,10 @@ SelectionDisplay = (function() { if ((translateXZTool.startingElevation > 0.0 && elevation < MIN_ELEVATION) || (translateXZTool.startingElevation < 0.0 && elevation > -MIN_ELEVATION)) { if (wantDebug) { - print("too close to horizon!"); + print(" "+ translateXZTool.mode + " - too close to horizon!"); } + + //--EARLY EXIT--( Don't proceed past the reached limit. ) return; } @@ -3610,9 +3634,24 @@ SelectionDisplay = (function() { addGrabberTool(yawHandle, { mode: "ROTATE_YAW", onBegin: function(event) { - print("================== HANDLE_ROLL(Beg) -> ======================="); + var wantDebug = true; + if (wantDebug) { + print("================== HANDLE_YAW(Beg) -> ======================="); + } SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; + mode = "ROTATE_YAW"; + rotationNormal = yawNormal; + //note: It's expected that the intersection is passed when this is called. + if (arguments.length >= 2 ) { + yawZero = arguments[ 1 ]; + } else { + print("ERROR( yawHandle.onBegin ) - Intersection wasn't passed!"); + } + + if (wantDebug) { + Vec3.print(" yawZero: ", yawZero); + } // Size the overlays to the current selection size var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; @@ -3623,15 +3662,19 @@ SelectionDisplay = (function() { var outerAlpha = 0.2; Overlays.editOverlay(rotateOverlayInner, { visible: true, + rotation: yawHandleRotation, + position: yawCenter, size: innerRadius, innerRadius: 0.9, startAt: 0, endAt: 360, - alpha: innerAlpha + alpha: innerAlpha, }); Overlays.editOverlay(rotateOverlayOuter, { visible: true, + rotation: yawHandleRotation, + position: yawCenter, size: outerRadius, innerRadius: 0.9, startAt: 0, @@ -3641,18 +3684,28 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayCurrent, { visible: true, + rotation: yawHandleRotation, + position: yawCenter, size: outerRadius, startAt: 0, endAt: 0, innerRadius: 0.9, }); + Overlays.editOverlay(rotateOverlayTarget, { + visible: true, + rotation: yawHandleRotation, + position: yawCenter + }); + Overlays.editOverlay(rotationDegreesDisplay, { visible: true, }); updateRotationDegreesOverlay(0, yawHandleRotation, yawCenter); - print("================== HANDLE_YAW(Beg) <- ======================="); + if(wantDebug){ + print("================== HANDLE_YAW(Beg) <- ======================="); + } }, onEnd: function(event, reason) { print("================== HANDLE_YAW(End) -> ======================="); @@ -3784,10 +3837,25 @@ SelectionDisplay = (function() { // PITCH GRABBER TOOL DEFINITION addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", - onBegin: function(event) { - print("================== HANDLE_PITCH(Beg) -> ======================="); + onBegin: function (event) { + var wantDebug = true; + if (wantDebug){ + print("================== HANDLE_PITCH(Beg) -> ======================="); + } SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; + mode = "ROTATE_PITCH"; + rotationNormal = pitchNormal; + //note: It's expected that the intersection is passed when this is called. + if (arguments.length >= 2 ) { + pitchZero = arguments[ 1 ]; + } else { + print("ERROR( pitchHandle.onBegin ) - Intersection wasn't passed!"); + } + + if (wantDebug) { + Vec3.print(" pitchZero: ", pitchZero); + } // Size the overlays to the current selection size var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; @@ -3798,6 +3866,8 @@ SelectionDisplay = (function() { var outerAlpha = 0.2; Overlays.editOverlay(rotateOverlayInner, { visible: true, + rotation: pitchHandleRotation, + position: pitchCenter, size: innerRadius, innerRadius: 0.9, startAt: 0, @@ -3807,6 +3877,8 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayOuter, { visible: true, + rotation: pitchHandleRotation, + position: pitchCenter, size: outerRadius, innerRadius: 0.9, startAt: 0, @@ -3816,6 +3888,8 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayCurrent, { visible: true, + rotation: pitchHandleRotation, + position: pitchCenter, size: outerRadius, startAt: 0, endAt: 0, @@ -3826,8 +3900,16 @@ SelectionDisplay = (function() { visible: true, }); + Overlays.editOverlay(rotateOverlayTarget, { + visible: true, + rotation: pitchHandleRotation, + position: pitchCenter + }); + updateRotationDegreesOverlay(0, pitchHandleRotation, pitchCenter); - print("================== HANDLE_PITCH(Beg) <- ======================="); + if(wantDebug){ + print("================== HANDLE_PITCH(Beg) <- ======================="); + } }, onEnd: function(event, reason) { print("================== HANDLE_PITCH(End) -> ======================="); @@ -3847,7 +3929,7 @@ SelectionDisplay = (function() { pushCommandForSelections(); print("================== HANDLE_PITCH(End) <- ======================="); }, - onMove: function(event) { + onMove: function (event) { print("================== HANDLE_PITCH(Mve) -> ======================="); var pickRay = generalComputePickRay(event.x, event.y); Overlays.editOverlay(selectionBox, { @@ -3949,10 +4031,25 @@ SelectionDisplay = (function() { // ROLL GRABBER TOOL DEFINITION addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", - onBegin: function(event) { - print("================== HANDLE_ROLL(Beg) -> ======================="); + onBegin: function (event) { + var wantDebug = true; + if(wantDebug){ + print("================== HANDLE_ROLL(Beg) -> ======================="); + } SelectionManager.saveProperties(); initialPosition = SelectionManager.worldPosition; + mode = "ROTATE_ROLL"; + rotationNormal = rollNormal; + //note: It's expected that the intersection is passed when this is called. + if (arguments.length >= 2 ) { + rollZero = arguments[ 1 ]; + } else { + print("ERROR( rollHandle.onBegin ) - Intersection wasn't passed!"); + } + + if (wantDebug) { + Vec3.print(" rollZero: ", rollZero); + } // Size the overlays to the current selection size var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; @@ -3963,6 +4060,8 @@ SelectionDisplay = (function() { var outerAlpha = 0.2; Overlays.editOverlay(rotateOverlayInner, { visible: true, + rotation: rollHandleRotation, + position: rollCenter, size: innerRadius, innerRadius: 0.9, startAt: 0, @@ -3972,6 +4071,8 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayOuter, { visible: true, + rotation: rollHandleRotation, + position: rollCenter, size: outerRadius, innerRadius: 0.9, startAt: 0, @@ -3981,6 +4082,8 @@ SelectionDisplay = (function() { Overlays.editOverlay(rotateOverlayCurrent, { visible: true, + rotation: rollHandleRotation, + position: rollCenter, size: outerRadius, startAt: 0, endAt: 0, @@ -3991,10 +4094,18 @@ SelectionDisplay = (function() { visible: true, }); + Overlays.editOverlay(rotateOverlayTarget, { + visible: true, + rotation: rollHandleRotation, + position: rollCenter + }); + updateRotationDegreesOverlay(0, rollHandleRotation, rollCenter); - print("================== HANDLE_ROLL(Beg) <- ======================="); + if(wantDebug){ + print("================== HANDLE_ROLL(Beg) <- ======================="); + } }, - onEnd: function(event, reason) { + onEnd: function (event, reason) { print("================== HANDLE_ROLL(End) -> ======================="); Overlays.editOverlay(rotateOverlayInner, { visible: false @@ -4141,11 +4252,68 @@ SelectionDisplay = (function() { } }; + + // FUNCTION DEF(s): Intersection Check Helpers + function testRayIntersect(queryRay, overlayIncludes, overlayExcludes) { + var wantDebug = true; + if ((queryRay === undefined) || (queryRay === null)) { + if (wantDebug) { + print("testRayIntersect - EARLY EXIT -> queryRay is undefined OR null!"); + } + return null; + } + + var intersectObj = Overlays.findRayIntersection(queryRay, true, overlayIncludes, overlayExcludes); + + if (wantDebug) { + if ( ! overlayIncludes ){ + print("testRayIntersect - no overlayIncludes provided."); + } + if ( ! overlayExcludes ){ + print("testRayIntersect - no overlayExcludes provided."); + } + print("testRayIntersect - Hit: " + intersectObj.intersects); + print(" intersectObj.overlayID:" + intersectObj.overlayID + "[" + overlayNames[intersectObj.overlayID] + "]"); + print(" OverlayName: " + overlayNames[intersectObj.overlayID]); + print(" intersectObj.distance:" + intersectObj.distance); + print(" intersectObj.face:" + intersectObj.face); + Vec3.print(" intersectObj.intersection:", intersectObj.intersection); + } + + return intersectObj; + } + + function checkIntersectWithHUD(queryRay) { + var intersectObj = testRayIntersect(queryRay, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); + + return intersectObj; + } + + function checkIntersectWithNonSelectionItems(queryRay) { + var intersectObj = testRayIntersect(queryRay, null, [yawHandle, pitchHandle, rollHandle, selectionBox]); + + return intersectObj; + } + + function checkIntersectWithRotationHandles(queryRay) { + var intersectObj = testRayIntersect(queryRay, [yawHandle, pitchHandle, rollHandle]); + + return intersectObj; + } + + function checkIntersectWithSelectionBox(queryRay) { + var intersectObj = testRayIntersect(queryRay, [selectionBox]); + + return intersectObj; + } + //-------------------- + + //--------------------------------------- // FUNCTION: MOUSE PRESS EVENT - that.mousePressEvent = function(event) { - var wantDebug = false; - if ( wantDebug ) { - print( "=============== eST::MousePressEvent BEG ======================="); + that.mousePressEvent = function (event) { + var wantDebug = true; + if (wantDebug) { + print("=============== eST::MousePressEvent BEG ======================="); } if (!event.isLeftButton && !that.triggered) { // if another mouse button than left is pressed ignore it @@ -4155,28 +4323,18 @@ SelectionDisplay = (function() { var somethingClicked = false; var pickRay = generalComputePickRay(event.x, event.y); - var result = Overlays.findRayIntersection(pickRay, true, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); - if (result.intersects) { + var results_checkHUD = checkIntersectWithHUD(pickRay); + if (results_checkHUD.intersects) { // mouse clicks on the tablet should override the edit affordances return false; } - entityIconOverlayManager.setIconsSelectable(selectionManager.selections,true); + entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); // ignore ray intersection for our selection box and yaw/pitch/roll - result = Overlays.findRayIntersection(pickRay, true, null, [ yawHandle, pitchHandle, rollHandle, selectionBox ] ); - if (result.intersects) { - if (wantDebug) { - print("something intersects... "); - print(" result.overlayID:" + result.overlayID + "[" + overlayNames[result.overlayID] + "]"); - print(" result.intersects:" + result.intersects); - print(" result.overlayID:" + result.overlayID); - print(" result.distance:" + result.distance); - print(" result.face:" + result.face); - Vec3.print(" result.intersection:", result.intersection); - } - - var tool = grabberTools[result.overlayID]; + var results_checkNonSelection = checkIntersectWithNonSelectionItems(pickRay); + if (results_checkNonSelection.intersects) { + var tool = grabberTools[results_checkNonSelection.overlayID]; if (tool) { if (wantDebug) { print("Intersected with known table tool( mode: " + tool.mode + " )"); @@ -4184,99 +4342,20 @@ SelectionDisplay = (function() { activeTool = tool; mode = tool.mode; somethingClicked = 'tool'; - if (activeTool && activeTool.onBegin) { + if (activeTool.onBegin) { activeTool.onBegin(event); + } else if (wantDebug) { + print(" ActiveTool( " + activeTool.mode + " ) missing onBegin"); } } else { - if (wantDebug) { - print("Intersected with unregistered tool..."); - } - switch (result.overlayID) { - case grabberMoveUp: - if (wantDebug){ - print("grabberMoveUp"); - } - mode = "TRANSLATE_UP_DOWN"; - somethingClicked = mode; - - // in translate mode, we hide our stretch handles... - for (var i = 0; i < stretchHandles.length; i++) { - Overlays.editOverlay(stretchHandles[i], { - visible: false - }); - } - break; - - - case grabberNEAR: - case grabberEdgeTN: // TODO: maybe this should be TOP+NEAR stretching? - case grabberEdgeBN: // TODO: maybe this should be BOTTOM+FAR stretching? - if(wantDebug){ - print("grabberNear variant"); - } - mode = "STRETCH_NEAR"; - somethingClicked = mode; - break; - - case grabberFAR: - case grabberEdgeTF: // TODO: maybe this should be TOP+FAR stretching? - case grabberEdgeBF: // TODO: maybe this should be BOTTOM+FAR stretching? - if(wantDebug){ - print("grabberFar variant"); - } - mode = "STRETCH_FAR"; - somethingClicked = mode; - break; - case grabberTOP: - if(wantDebug){ - print("grabberTOP"); - } - mode = "STRETCH_TOP"; - somethingClicked = mode; - break; - case grabberBOTTOM: - if(wantDebug){ - print("grabberBOTTOM"); - } - mode = "STRETCH_BOTTOM"; - somethingClicked = mode; - break; - case grabberRIGHT: - case grabberEdgeTR: // TODO: maybe this should be TOP+RIGHT stretching? - case grabberEdgeBR: // TODO: maybe this should be BOTTOM+RIGHT stretching? - if(wantDebug){ - print("grabberRight variant"); - } - mode = "STRETCH_RIGHT"; - somethingClicked = mode; - break; - case grabberLEFT: - case grabberEdgeTL: // TODO: maybe this should be TOP+LEFT stretching? - case grabberEdgeBL: // TODO: maybe this should be BOTTOM+LEFT stretching? - if(wantDebug){ - print("grabberLeft variant"); - } - mode = "STRETCH_LEFT"; - somethingClicked = mode; - break; - - default: - if(wantDebug){ - print("UNKNOWN( " + result.overlayID + " )"); - } - mode = "UNKNOWN"; - break; - } - if(wantDebug){ - print(" Unregistered Tool Mode: " + mode ); - } - } - } + mode = "UNKNOWN"; + }//--End_if(tool) + }//--End_if(results_checkNonSelection.intersects) // if one of the items above was clicked, then we know we are in translate or stretch mode, and we // should hide our rotate handles... if (somethingClicked) { - if(wantDebug){ + if (wantDebug) { print(" Trying to hide PitchYawRoll Handles"); } Overlays.editOverlay(yawHandle, { @@ -4307,133 +4386,45 @@ SelectionDisplay = (function() { // Only intersect versus yaw/pitch/roll. - result = Overlays.findRayIntersection(pickRay, true, [ yawHandle, pitchHandle, rollHandle ] ); - - var overlayOrientation; - var overlayCenter; - + var results_checkRotationHandles = checkIntersectWithRotationHandles(pickRay); var properties = Entities.getEntityProperties(selectionManager.selections[0]); var angles = Quat.safeEulerAngles(properties.rotation); var pitch = angles.x; var yaw = angles.y; var roll = angles.z; + //TODO_Case6491: Should these only be updated when we actually touched + // a handle. (The answer is most likley: Yes) Potentially move chunk + // to either tool's onBegin or before rayCast here when refactored. originalRotation = properties.rotation; originalPitch = pitch; originalYaw = yaw; originalRoll = roll; - if (result.intersects) { - var resultTool = grabberTools[result.overlayID]; - if(wantDebug){ + if (results_checkRotationHandles.intersects) { + var resultTool = grabberTools[results_checkRotationHandles.overlayID]; + if (wantDebug) { print("Intersection detected with handle..."); } if (resultTool) { - if(wantDebug){ + if (wantDebug) { print(" " + resultTool.mode); } activeTool = resultTool; - mode = resultTool.mode; - somethingClicked = 'tool'; - if (activeTool && activeTool.onBegin) { - if(wantDebug){ - print(" Triggering Tool's onBegin"); - } - activeTool.onBegin(event); - } else if(wantDebug) { - print(" Tool's missing onBegin"); + somethingClicked = resultTool.mode; + if(activeTool.onBegin) { + activeTool.onBegin(event, results_checkRotationHandles.intersection); + } else if (wantDebug) { + print(" ActiveTool( " + activeTool.mode + " ) missing onBegin"); } - } - switch (result.overlayID) { - case yawHandle: - if(wantDebug){ - print("Handle_YAW"); - } - mode = "ROTATE_YAW"; - somethingClicked = mode; - overlayOrientation = yawHandleRotation; - overlayCenter = yawCenter; - yawZero = result.intersection; - rotationNormal = yawNormal; - if(wantDebug){ - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); - } - break; + }//--End_If(resultTool) + }//--End_If(results_checkRotationHandles.intersects) - case pitchHandle: - if(wantDebug){ - print("Handle_PITCH"); - } - mode = "ROTATE_PITCH"; - initialPosition = SelectionManager.worldPosition; - somethingClicked = mode; - overlayOrientation = pitchHandleRotation; - overlayCenter = pitchCenter; - pitchZero = result.intersection; - rotationNormal = pitchNormal; - if(wantDebug){ - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); - } - break; + if (somethingClicked) { - case rollHandle: - if(wantDebug){ - print("Handle_ROLL"); - } - mode = "ROTATE_ROLL"; - somethingClicked = mode; - overlayOrientation = rollHandleRotation; - overlayCenter = rollCenter; - rollZero = result.intersection; - rotationNormal = rollNormal; - if(wantDebug){ - print("rotationNormal set to: " + rotationNormal.x + ", " + rotationNormal.y + ", " + rotationNormal.z); - } - break; - - default: - if (wantDebug) { - print("mousePressEvent()...... " + overlayNames[result.overlayID]); - } - mode = "UNKNOWN"; - break; - } - } - if (wantDebug) { - print(" somethingClicked:" + somethingClicked); - print(" mode:" + mode); - } - - if (somethingClicked) { - - if(wantDebug){ - print(" Trying to show rotateOverlay Handles"); - } - Overlays.editOverlay(rotateOverlayTarget, { - visible: true, - rotation: overlayOrientation, - position: overlayCenter - }); - Overlays.editOverlay(rotateOverlayInner, { - visible: true, - rotation: overlayOrientation, - position: overlayCenter - }); - Overlays.editOverlay(rotateOverlayOuter, { - visible: true, - rotation: overlayOrientation, - position: overlayCenter, - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayCurrent, { - visible: true, - rotation: overlayOrientation, - position: overlayCenter, - startAt: 0, - endAt: 0 - }); - if(wantDebug){ + if (wantDebug) { + print(" somethingClicked:" + somethingClicked); + print(" mode:" + mode); print(" Trying to hide PitchYawRoll Handles"); } Overlays.editOverlay(yawHandle, { @@ -4541,49 +4532,31 @@ SelectionDisplay = (function() { if (!somethingClicked) { // Only intersect versus selectionBox. - result = Overlays.findRayIntersection(pickRay, true, [selectionBox]); - if (result.intersects) { - switch (result.overlayID) { - case selectionBox: - activeTool = translateXZTool; - if(wantDebug){ - print("Clicked selectionBox, Activating Tool: " + activeTool.mode ); - } - translateXZTool.pickPlanePosition = result.intersection; - translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), - SelectionManager.worldDimensions.z); - if (wantDebug) { - print("longest dimension: " + translateXZTool.greatestDimension); - translateXZTool.startingDistance = Vec3.distance(pickRay.origin, SelectionManager.position); - print("starting distance: " + translateXZTool.startingDistance); - translateXZTool.startingElevation = translateXZTool.elevation(pickRay.origin, translateXZTool.pickPlanePosition); - print(" starting elevation: " + translateXZTool.startingElevation); - } - - mode = translateXZTool.mode; - activeTool.onBegin(event); - somethingClicked = 'selectionBox'; - break; - default: - if (wantDebug) { - print("mousePressEvent()...... " + overlayNames[result.overlayID]); - } - mode = "UNKNOWN"; - break; + var results_checkSelectionBox = checkIntersectWithSelectionBox( pickRay ); + if (results_checkSelectionBox.intersects) { + activeTool = translateXZTool; + if(wantDebug){ + print("Clicked selectionBox, Activating Tool: " + activeTool.mode ); } + var intersectInfo = { + queryRay: pickRay, + results: results_checkSelectionBox + }; + activeTool.onBegin(event, null, intersectInfo); + somethingClicked = 'selectionBox'; } } if (somethingClicked) { - pickRay = generalComputePickRay(event.x, event.y); if (wantDebug) { - print("mousePressEvent()...... " + overlayNames[result.overlayID]); + print("mousePressEvent()...... " + somethingClicked); + print(" mode: " + mode); } } // reset everything as intersectable... // TODO: we could optimize this since some of these were already flipped back(i.e: just get rid of this) - if(wantDebug){ + if (wantDebug) { print("Trying to set SelectionBox & PitchYawRoll Handles to NOT_IGNORE Rays"); } Overlays.editOverlay(selectionBox, { @@ -4599,8 +4572,8 @@ SelectionDisplay = (function() { ignoreRayIntersection: false }); - if ( wantDebug ) { - print( "=============== eST::MousePressEvent END ======================="); + if (wantDebug) { + print("=============== eST::MousePressEvent END ======================="); } return somethingClicked; @@ -4613,18 +4586,18 @@ SelectionDisplay = (function() { print( "=============== eST::MouseMoveEvent BEG ======================="); } if (activeTool) { - if(wantDebug){ + if (wantDebug) { print(" Trigger ActiveTool( " + activeTool.mode + " )'s onMove"); } activeTool.onMove(event); - - if(wantDebug){ + + if (wantDebug) { print(" Trigger SelectionManager::update"); } SelectionManager._update(); - - if(wantDebug){ - print( "=============== eST::MouseMoveEvent END ======================="); + + if (wantDebug) { + print("=============== eST::MouseMoveEvent END ======================="); } //--EARLY EXIT--( Move handled via active tool) return true; @@ -4710,7 +4683,7 @@ SelectionDisplay = (function() { pickedAlpha = grabberAlpha; highlightNeeded = true; break; - + default: if (previousHandle) { Overlays.editOverlay(previousHandle, { From 18cc632df5f40a04cdb0937b23d36e4fe584dc66 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Tue, 8 Aug 2017 16:37:59 -0400 Subject: [PATCH 16/79] [Case 6491] Minor: Switching off wantDebug flags that were left on. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index ce93a6f366..85e28d7170 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2393,7 +2393,7 @@ SelectionDisplay = (function() { startingDistance: 0.0, startingElevation: 0.0, onBegin: function(event,isAltFromGrab, intersectInfo) { - var wantDebug = true; + var wantDebug = false; if(wantDebug){ print("================== TRANSLATE_XZ(Beg) -> ======================="); Vec3.print(" intersectInfo.queryRay", intersectInfo.queryRay); @@ -3634,7 +3634,7 @@ SelectionDisplay = (function() { addGrabberTool(yawHandle, { mode: "ROTATE_YAW", onBegin: function(event) { - var wantDebug = true; + var wantDebug = false; if (wantDebug) { print("================== HANDLE_YAW(Beg) -> ======================="); } @@ -3838,7 +3838,7 @@ SelectionDisplay = (function() { addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", onBegin: function (event) { - var wantDebug = true; + var wantDebug = false; if (wantDebug){ print("================== HANDLE_PITCH(Beg) -> ======================="); } @@ -4032,7 +4032,7 @@ SelectionDisplay = (function() { addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", onBegin: function (event) { - var wantDebug = true; + var wantDebug = false; if(wantDebug){ print("================== HANDLE_ROLL(Beg) -> ======================="); } @@ -4255,7 +4255,7 @@ SelectionDisplay = (function() { // FUNCTION DEF(s): Intersection Check Helpers function testRayIntersect(queryRay, overlayIncludes, overlayExcludes) { - var wantDebug = true; + var wantDebug = false; if ((queryRay === undefined) || (queryRay === null)) { if (wantDebug) { print("testRayIntersect - EARLY EXIT -> queryRay is undefined OR null!"); @@ -4306,12 +4306,10 @@ SelectionDisplay = (function() { return intersectObj; } - //-------------------- - //--------------------------------------- // FUNCTION: MOUSE PRESS EVENT that.mousePressEvent = function (event) { - var wantDebug = true; + var wantDebug = false; if (wantDebug) { print("=============== eST::MousePressEvent BEG ======================="); } From 926789437c1b6571c0bf27e2a7299f01956367ff Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Tue, 8 Aug 2017 18:47:01 -0400 Subject: [PATCH 17/79] [Case 6491] Propagates rotation reposition fix from YawHandle (details below). This wraps the selections rotation update handling into common helper function utilized by all rotation handle tools (yaw,pitch,roll). This function is the generalized fix previously exclusive to yawHandle. This functions is now called within onMove for yaw, pitch, & rollHandle tools. NOTE(s): * Tested yaw, pitch, & roll rotation didn't see any aberrant behavior. ** Tested overlapping shapes and selecting the overlapping portions followed by a rotation handle. Only one took hold as a selection. ** Tested multiple selection and objects rotated & repositioned about the encapsulating bounding box's center point as expected. * Tested translation with multiple items selected and it behaved as expected. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 77 +++++++++---------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 85e28d7170..159b009725 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -3629,6 +3629,38 @@ SelectionDisplay = (function() { print( "<--- updateRotationDegreesOverlay ---" ); } + // FUNCTION DEF: updateSelectionsRotation + // Helper func used by rotation grabber tools + function updateSelectionsRotation( rotationChange ) { + if ( ! rotationChange ) { + print("ERROR( updateSelectionsRotation ) - Invalid arg specified!!"); + + //--EARLY EXIT-- + return; + } + + // Entities should only reposition if we are rotating multiple selections around + // the selections center point. Otherwise, the rotation will be around the entities + // registration point which does not need repositioning. + var reposition = (SelectionManager.selections.length > 1); + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID]; + + var newProperties = { + rotation: Quat.multiply(rotationChange, initialProperties.rotation), + }; + + if (reposition) { + var dPos = Vec3.subtract(initialProperties.position, initialPosition); + dPos = Vec3.multiplyQbyV(rotationChange, dPos); + newProperties.position = Vec3.sum(initialPosition, dPos); + } + + Entities.editEntity(entityID, newProperties); + } + } + // YAW GRABBER TOOL DEFINITION var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { @@ -3756,27 +3788,7 @@ SelectionDisplay = (function() { z: 0 }); - // Entities should only reposition if we are rotating multiple selections around - // the selections center point. Otherwise, the rotation will be around the entities - // registration point which does not need repositioning. - var reposition = SelectionManager.selections.length > 1; - for (var i = 0; i < SelectionManager.selections.length; i++) { - var entityID = SelectionManager.selections[i]; - var properties = Entities.getEntityProperties(entityID); - var initialProperties = SelectionManager.savedProperties[entityID]; - - var newProperties = { - rotation: Quat.multiply(yawChange, initialProperties.rotation), - }; - - if (reposition) { - var dPos = Vec3.subtract(initialProperties.position, initialPosition); - dPos = Vec3.multiplyQbyV(yawChange, dPos); - newProperties.position = Vec3.sum(initialPosition, dPos); - } - - Entities.editEntity(entityID, newProperties); - } + updateSelectionsRotation( yawChange ); updateRotationDegreesOverlay(angleFromZero, yawHandleRotation, yawCenter); @@ -3961,17 +3973,7 @@ SelectionDisplay = (function() { z: 0 }); - for (var i = 0; i < SelectionManager.selections.length; i++) { - var entityID = SelectionManager.selections[i]; - var initialProperties = SelectionManager.savedProperties[entityID]; - var dPos = Vec3.subtract(initialProperties.position, initialPosition); - dPos = Vec3.multiplyQbyV(pitchChange, dPos); - - Entities.editEntity(entityID, { - position: Vec3.sum(initialPosition, dPos), - rotation: Quat.multiply(pitchChange, initialProperties.rotation), - }); - } + updateSelectionsRotation( pitchChange ); updateRotationDegreesOverlay(angleFromZero, pitchHandleRotation, pitchCenter); @@ -4154,17 +4156,8 @@ SelectionDisplay = (function() { y: 0, z: angleFromZero }); - for (var i = 0; i < SelectionManager.selections.length; i++) { - var entityID = SelectionManager.selections[i]; - var initialProperties = SelectionManager.savedProperties[entityID]; - var dPos = Vec3.subtract(initialProperties.position, initialPosition); - dPos = Vec3.multiplyQbyV(rollChange, dPos); - Entities.editEntity(entityID, { - position: Vec3.sum(initialPosition, dPos), - rotation: Quat.multiply(rollChange, initialProperties.rotation), - }); - } + updateSelectionsRotation( rollChange ); updateRotationDegreesOverlay(angleFromZero, rollHandleRotation, rollCenter); From 96afbeca23a1d2581ec90c246ad677e64f9989ef Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Wed, 9 Aug 2017 13:56:08 -0400 Subject: [PATCH 18/79] [Case 6491] Dedupe rotation handle tool code (details below). Pulled the common code shared between the rotation handle tools out into helper funcs: * helperRotationHandleOnBegin * helperRotationHandleOnMove * helperRotationHandleOnEnd These functions either take in or derive the necessary info needed to handle a specific rotation axis. NOTE(s): * Tested yaw, pitch, & roll handles using a box. The behavior remained consistent with that prior to this commit. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 743 ++++++------------ 1 file changed, 226 insertions(+), 517 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 159b009725..eb3deb590d 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -3661,557 +3661,266 @@ SelectionDisplay = (function() { } } + function helperRotationHandleOnBegin( rotMode, rotNormal, rotCenter, handleRotation ) { + var wantDebug = false; + if (wantDebug) { + print("================== " + rotMode + "(onBegin) -> ======================="); + } + + SelectionManager.saveProperties(); + initialPosition = SelectionManager.worldPosition; + mode = rotMode; + rotationNormal = rotNormal; + + // Size the overlays to the current selection size + var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; + var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); + innerRadius = diagonal; + outerRadius = diagonal * 1.15; + var innerAlpha = 0.2; + var outerAlpha = 0.2; + Overlays.editOverlay(rotateOverlayInner, { + visible: true, + rotation: handleRotation, + position: rotCenter, + size: innerRadius, + innerRadius: 0.9, + startAt: 0, + endAt: 360, + alpha: innerAlpha, + }); + + Overlays.editOverlay(rotateOverlayOuter, { + visible: true, + rotation: handleRotation, + position: rotCenter, + size: outerRadius, + innerRadius: 0.9, + startAt: 0, + endAt: 360, + alpha: outerAlpha, + }); + + Overlays.editOverlay(rotateOverlayCurrent, { + visible: true, + rotation: handleRotation, + position: rotCenter, + size: outerRadius, + startAt: 0, + endAt: 0, + innerRadius: 0.9, + }); + + Overlays.editOverlay(rotateOverlayTarget, { + visible: true, + rotation: handleRotation, + position: rotCenter + }); + + Overlays.editOverlay(rotationDegreesDisplay, { + visible: true, + }); + + updateRotationDegreesOverlay(0, handleRotation, rotCenter); + if (wantDebug) { + print("================== " + rotMode + "(onBegin) <- ======================="); + } + }//--End_Function( helperRotationHandleOnBegin ) + + function helperRotationHandleOnMove( event, rotMode, rotZero, rotCenter, handleRotation ) { + + if ( ! (rotMode == "ROTATE_YAW" || rotMode == "ROTATE_PITCH" || rotMode == "ROTATE_ROLL") ) { + print("ERROR( handleRotationHandleOnMove ) - Encountered Unknown/Invalid RotationMode: " + rotMode ); + + //--EARLY EXIT-- + return; + } else if ( ! rotZero ) { + print("ERROR( handleRotationHandleOnMove ) - Invalid RotationZero Specified" ); + + //--EARLY EXIT-- + return; + } + + var wantDebug = false; + if (wantDebug) { + print("================== "+ rotMode + "(onMove) -> ======================="); + Vec3.print(" rotZero: ", rotZero); + } + var pickRay = generalComputePickRay(event.x, event.y); + Overlays.editOverlay(selectionBox, { + visible: false + }); + Overlays.editOverlay(baseOfEntityProjectionOverlay, { + visible: false + }); + + var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]); + if (result.intersects) { + var centerToZero = Vec3.subtract(rotZero, rotCenter); + var centerToIntersect = Vec3.subtract(result.intersection, rotCenter); + if (wantDebug) { + Vec3.print(" RotationNormal: ", rotationNormal); + } + // Note: orientedAngle which wants normalized centerToZero and centerToIntersect + // handles that internally, so it's to pass unnormalized vectors here. + var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); + + var distanceFromCenter = Vec3.distance(rotCenter, result.intersection); + var snapToInner = distanceFromCenter < innerRadius; + var snapAngle = snapToInner ? innerSnapAngle : 1.0; + angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; + + var rotChange = null; + switch( rotMode ) { + case "ROTATE_YAW": + rotChange = Quat.fromVec3Degrees( {x: 0, y: angleFromZero, z: 0} ); + break; + case "ROTATE_PITCH": + rotChange = Quat.fromVec3Degrees( {x: angleFromZero, y: 0, z: 0} ); + break; + case "ROTATE_ROLL": + rotChange = Quat.fromVec3Degrees( {x: 0, y: 0, z: angleFromZero} ); + break; + } + updateSelectionsRotation( rotChange ); + + updateRotationDegreesOverlay(angleFromZero, handleRotation, rotCenter); + + // update the rotation display accordingly... + var startAtCurrent = 0; + var endAtCurrent = angleFromZero; + var startAtRemainder = angleFromZero; + var endAtRemainder = 360; + if (angleFromZero < 0) { + startAtCurrent = 360 + angleFromZero; + endAtCurrent = 360; + startAtRemainder = 0; + endAtRemainder = startAtCurrent; + } + if (snapToInner) { + Overlays.editOverlay(rotateOverlayOuter, { + startAt: 0, + endAt: 360 + }); + Overlays.editOverlay(rotateOverlayInner, { + startAt: startAtRemainder, + endAt: endAtRemainder + }); + Overlays.editOverlay(rotateOverlayCurrent, { + startAt: startAtCurrent, + endAt: endAtCurrent, + size: innerRadius, + majorTickMarksAngle: innerSnapAngle, + minorTickMarksAngle: 0, + majorTickMarksLength: -0.25, + minorTickMarksLength: 0, + }); + } else { + Overlays.editOverlay(rotateOverlayInner, { + startAt: 0, + endAt: 360 + }); + Overlays.editOverlay(rotateOverlayOuter, { + startAt: startAtRemainder, + endAt: endAtRemainder + }); + Overlays.editOverlay(rotateOverlayCurrent, { + startAt: startAtCurrent, + endAt: endAtCurrent, + size: outerRadius, + majorTickMarksAngle: 45.0, + minorTickMarksAngle: 5, + majorTickMarksLength: 0.25, + minorTickMarksLength: 0.1, + }); + } + }//--End_If( results.intersects ) + + if (wantDebug) { + print("================== "+ rotMode + "(onMove) <- ======================="); + } + }//--End_Function( helperRotationHandleOnMove ) + + function helperRotationHandleOnEnd() { + var wantDebug = false; + if (wantDebug) { + print("================== " + mode + "(onEnd) -> ======================="); + } + Overlays.editOverlay(rotateOverlayInner, { + visible: false + }); + Overlays.editOverlay(rotateOverlayOuter, { + visible: false + }); + Overlays.editOverlay(rotateOverlayCurrent, { + visible: false + }); + Overlays.editOverlay(rotationDegreesDisplay, { + visible: false + }); + + pushCommandForSelections(); + + if (wantDebug) { + print("================== " + mode + "(onEnd) <- ======================="); + } + }//--End_Function( helperRotationHandleOnEnd ) + + // YAW GRABBER TOOL DEFINITION var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { mode: "ROTATE_YAW", - onBegin: function(event) { - var wantDebug = false; - if (wantDebug) { - print("================== HANDLE_YAW(Beg) -> ======================="); - } - SelectionManager.saveProperties(); - initialPosition = SelectionManager.worldPosition; - mode = "ROTATE_YAW"; - rotationNormal = yawNormal; + onBegin: function(event, zeroPoint) { //note: It's expected that the intersection is passed when this is called. - if (arguments.length >= 2 ) { - yawZero = arguments[ 1 ]; - } else { - print("ERROR( yawHandle.onBegin ) - Intersection wasn't passed!"); - } + // validity will be checked later as a pre-requisite for onMove handling. + yawZero = zeroPoint; - if (wantDebug) { - Vec3.print(" yawZero: ", yawZero); - } - - // Size the overlays to the current selection size - var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); - innerRadius = diagonal; - outerRadius = diagonal * 1.15; - var innerAlpha = 0.2; - var outerAlpha = 0.2; - Overlays.editOverlay(rotateOverlayInner, { - visible: true, - rotation: yawHandleRotation, - position: yawCenter, - size: innerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: innerAlpha, - }); - - Overlays.editOverlay(rotateOverlayOuter, { - visible: true, - rotation: yawHandleRotation, - position: yawCenter, - size: outerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: outerAlpha, - }); - - Overlays.editOverlay(rotateOverlayCurrent, { - visible: true, - rotation: yawHandleRotation, - position: yawCenter, - size: outerRadius, - startAt: 0, - endAt: 0, - innerRadius: 0.9, - }); - - Overlays.editOverlay(rotateOverlayTarget, { - visible: true, - rotation: yawHandleRotation, - position: yawCenter - }); - - Overlays.editOverlay(rotationDegreesDisplay, { - visible: true, - }); - - updateRotationDegreesOverlay(0, yawHandleRotation, yawCenter); - if(wantDebug){ - print("================== HANDLE_YAW(Beg) <- ======================="); - } + helperRotationHandleOnBegin( "ROTATE_YAW", yawNormal, yawCenter, yawHandleRotation ); }, onEnd: function(event, reason) { - print("================== HANDLE_YAW(End) -> ======================="); - Overlays.editOverlay(rotateOverlayInner, { - visible: false - }); - Overlays.editOverlay(rotateOverlayOuter, { - visible: false - }); - Overlays.editOverlay(rotateOverlayCurrent, { - visible: false - }); - Overlays.editOverlay(rotationDegreesDisplay, { - visible: false - }); - - pushCommandForSelections(); - print("================== HANDLE_YAW(End) <- ======================="); + helperRotationHandleOnEnd(); }, onMove: function(event) { - print("================== HANDLE_YAW(Mve) -> ======================="); - var pickRay = generalComputePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { - visible: false - }); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { - visible: false - }); - - var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]); - - if (result.intersects) { - var center = yawCenter; - var zero = yawZero; - var centerToZero = Vec3.subtract(zero, center); - var centerToIntersect = Vec3.subtract(result.intersection, center); - // Note: orientedAngle which wants normalized centerToZero and centerToIntersect - // handles that internally, so it's to pass unnormalized vectors here. - print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = distanceFromCenter < innerRadius; - var snapAngle = snapToInner ? innerSnapAngle : 1.0; - angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; - var yawChange = Quat.fromVec3Degrees({ - x: 0, - y: angleFromZero, - z: 0 - }); - - updateSelectionsRotation( yawChange ); - - updateRotationDegreesOverlay(angleFromZero, yawHandleRotation, yawCenter); - - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; - } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayInner, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: innerRadius, - majorTickMarksAngle: innerSnapAngle, - minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, - minorTickMarksLength: 0, - }); - } else { - Overlays.editOverlay(rotateOverlayInner, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayOuter, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: outerRadius, - majorTickMarksAngle: 45.0, - minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, - minorTickMarksLength: 0.1, - }); - } - - } - print("================== HANDLE_YAW(Mve) <- ======================="); + helperRotationHandleOnMove( event, "ROTATE_YAW", yawZero, yawCenter, yawHandleRotation ); } }); + // PITCH GRABBER TOOL DEFINITION addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", - onBegin: function (event) { - var wantDebug = false; - if (wantDebug){ - print("================== HANDLE_PITCH(Beg) -> ======================="); - } - SelectionManager.saveProperties(); - initialPosition = SelectionManager.worldPosition; - mode = "ROTATE_PITCH"; - rotationNormal = pitchNormal; + onBegin: function (event, zeroPoint) { //note: It's expected that the intersection is passed when this is called. - if (arguments.length >= 2 ) { - pitchZero = arguments[ 1 ]; - } else { - print("ERROR( pitchHandle.onBegin ) - Intersection wasn't passed!"); - } - - if (wantDebug) { - Vec3.print(" pitchZero: ", pitchZero); - } + // validity will be checked later as a pre-requisite for onMove handling. + pitchZero = zeroPoint; - // Size the overlays to the current selection size - var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); - innerRadius = diagonal; - outerRadius = diagonal * 1.15; - var innerAlpha = 0.2; - var outerAlpha = 0.2; - Overlays.editOverlay(rotateOverlayInner, { - visible: true, - rotation: pitchHandleRotation, - position: pitchCenter, - size: innerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: innerAlpha - }); - - Overlays.editOverlay(rotateOverlayOuter, { - visible: true, - rotation: pitchHandleRotation, - position: pitchCenter, - size: outerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: outerAlpha, - }); - - Overlays.editOverlay(rotateOverlayCurrent, { - visible: true, - rotation: pitchHandleRotation, - position: pitchCenter, - size: outerRadius, - startAt: 0, - endAt: 0, - innerRadius: 0.9, - }); - - Overlays.editOverlay(rotationDegreesDisplay, { - visible: true, - }); - - Overlays.editOverlay(rotateOverlayTarget, { - visible: true, - rotation: pitchHandleRotation, - position: pitchCenter - }); - - updateRotationDegreesOverlay(0, pitchHandleRotation, pitchCenter); - if(wantDebug){ - print("================== HANDLE_PITCH(Beg) <- ======================="); - } + helperRotationHandleOnBegin( "ROTATE_PITCH", pitchNormal, pitchCenter, pitchHandleRotation ); }, onEnd: function(event, reason) { - print("================== HANDLE_PITCH(End) -> ======================="); - Overlays.editOverlay(rotateOverlayInner, { - visible: false - }); - Overlays.editOverlay(rotateOverlayOuter, { - visible: false - }); - Overlays.editOverlay(rotateOverlayCurrent, { - visible: false - }); - Overlays.editOverlay(rotationDegreesDisplay, { - visible: false - }); - - pushCommandForSelections(); - print("================== HANDLE_PITCH(End) <- ======================="); + helperRotationHandleOnEnd(); }, onMove: function (event) { - print("================== HANDLE_PITCH(Mve) -> ======================="); - var pickRay = generalComputePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { - visible: false - }); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { - visible: false - }); - var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]); - - if (result.intersects) { - var center = pitchCenter; - var zero = pitchZero; - var centerToZero = Vec3.subtract(zero, center); - var centerToIntersect = Vec3.subtract(result.intersection, center); - // Note: orientedAngle which wants normalized centerToZero & centerToIntersect, handles - // this internally, so it's fine to pass non-normalized versions here. - print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = distanceFromCenter < innerRadius; - var snapAngle = snapToInner ? innerSnapAngle : 1.0; - angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; - - var pitchChange = Quat.fromVec3Degrees({ - x: angleFromZero, - y: 0, - z: 0 - }); - - updateSelectionsRotation( pitchChange ); - - updateRotationDegreesOverlay(angleFromZero, pitchHandleRotation, pitchCenter); - - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; - } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayInner, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: innerRadius, - majorTickMarksAngle: innerSnapAngle, - minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, - minorTickMarksLength: 0, - }); - } else { - Overlays.editOverlay(rotateOverlayInner, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayOuter, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: outerRadius, - majorTickMarksAngle: 45.0, - minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, - minorTickMarksLength: 0.1, - }); - } - } - print("================== HANDLE_PITCH(Mve) <- ======================="); + helperRotationHandleOnMove( event, "ROTATE_PITCH", pitchZero, pitchCenter, pitchHandleRotation ); } }); + // ROLL GRABBER TOOL DEFINITION addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", - onBegin: function (event) { - var wantDebug = false; - if(wantDebug){ - print("================== HANDLE_ROLL(Beg) -> ======================="); - } - SelectionManager.saveProperties(); - initialPosition = SelectionManager.worldPosition; - mode = "ROTATE_ROLL"; - rotationNormal = rollNormal; + onBegin: function (event, zeroPoint) { //note: It's expected that the intersection is passed when this is called. - if (arguments.length >= 2 ) { - rollZero = arguments[ 1 ]; - } else { - print("ERROR( rollHandle.onBegin ) - Intersection wasn't passed!"); - } - - if (wantDebug) { - Vec3.print(" rollZero: ", rollZero); - } + // validity will be checked later as a pre-requisite for onMove handling. + rollZero = zeroPoint; - // Size the overlays to the current selection size - var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); - innerRadius = diagonal; - outerRadius = diagonal * 1.15; - var innerAlpha = 0.2; - var outerAlpha = 0.2; - Overlays.editOverlay(rotateOverlayInner, { - visible: true, - rotation: rollHandleRotation, - position: rollCenter, - size: innerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: innerAlpha - }); - - Overlays.editOverlay(rotateOverlayOuter, { - visible: true, - rotation: rollHandleRotation, - position: rollCenter, - size: outerRadius, - innerRadius: 0.9, - startAt: 0, - endAt: 360, - alpha: outerAlpha, - }); - - Overlays.editOverlay(rotateOverlayCurrent, { - visible: true, - rotation: rollHandleRotation, - position: rollCenter, - size: outerRadius, - startAt: 0, - endAt: 0, - innerRadius: 0.9, - }); - - Overlays.editOverlay(rotationDegreesDisplay, { - visible: true, - }); - - Overlays.editOverlay(rotateOverlayTarget, { - visible: true, - rotation: rollHandleRotation, - position: rollCenter - }); - - updateRotationDegreesOverlay(0, rollHandleRotation, rollCenter); - if(wantDebug){ - print("================== HANDLE_ROLL(Beg) <- ======================="); - } + helperRotationHandleOnBegin( "ROTATE_ROLL", rollNormal, rollCenter, rollHandleRotation ); }, onEnd: function (event, reason) { - print("================== HANDLE_ROLL(End) -> ======================="); - Overlays.editOverlay(rotateOverlayInner, { - visible: false - }); - Overlays.editOverlay(rotateOverlayOuter, { - visible: false - }); - Overlays.editOverlay(rotateOverlayCurrent, { - visible: false - }); - Overlays.editOverlay(rotationDegreesDisplay, { - visible: false - }); - - pushCommandForSelections(); - print("================== HANDLE_ROLL(End) <- ======================="); + helperRotationHandleOnEnd(); }, onMove: function(event) { - print("================== HANDLE_ROLL(Mve) -> ======================="); - var pickRay = generalComputePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { - visible: false - }); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { - visible: false - }); - var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]); - - if (result.intersects) { - var center = rollCenter; - var zero = rollZero; - var centerToZero = Vec3.subtract(zero, center); - var centerToIntersect = Vec3.subtract(result.intersection, center); - // Note: orientedAngle which wants normalized centerToZero & centerToIntersect, handles - // this internally, so it's fine to pass non-normalized versions here. - print(" RotNormal - X: " + rotationNormal.x + " Y: " + rotationNormal.y + " Z: " + rotationNormal.z); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = distanceFromCenter < innerRadius; - var snapAngle = snapToInner ? innerSnapAngle : 1.0; - angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; - - var rollChange = Quat.fromVec3Degrees({ - x: 0, - y: 0, - z: angleFromZero - }); - - updateSelectionsRotation( rollChange ); - - updateRotationDegreesOverlay(angleFromZero, rollHandleRotation, rollCenter); - - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; - } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayInner, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: innerRadius, - majorTickMarksAngle: innerSnapAngle, - minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, - minorTickMarksLength: 0, - }); - } else { - Overlays.editOverlay(rotateOverlayInner, { - startAt: 0, - endAt: 360 - }); - Overlays.editOverlay(rotateOverlayOuter, { - startAt: startAtRemainder, - endAt: endAtRemainder - }); - Overlays.editOverlay(rotateOverlayCurrent, { - startAt: startAtCurrent, - endAt: endAtCurrent, - size: outerRadius, - majorTickMarksAngle: 45.0, - minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, - minorTickMarksLength: 0.1, - }); - } - } - print("================== HANDLE_ROLL(Mve) <- ======================="); - + helperRotationHandleOnMove( event, "ROTATE_ROLL", rollZero, rollCenter, rollHandleRotation ); } }); From fe171af31bef16bf87d3424546c908c241f536be Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Wed, 9 Aug 2017 18:11:44 -0400 Subject: [PATCH 19/79] [Case 6491] entitySelectionTool mousePressEvent refactor/cleanup (details below). Fixes situations where attempting to click on a rotate, grab, or scale handle that was in front of others might unexpectedly activate the obscured handle. As of this commit the flow of mousePressEvent such that the first item whether it be a tool or selection is what reacts and absorbs the click/touch. This is counter to the prior behavior where whichever item or tool last passed the check would determine what was hit and handled the touch _even_ when it wasn't the first thing to be touched. * Got rid of some unused/stale vars * Added some convenience functions * setRotationHandlesVisible function * setStretchHandlesVisible function * setGrabberMoveUpVisible function * Removed checkIntersectWith helper functions as they're no longer used. * Normalized onBegin signatures for all GrabberTools to support the new flow within mousePressEvent. * These are tools registered via addGrabberTool/makeStretchTool. * The onBegin signature changes from onBegin( event ) to onBegin( event, intersectResult ). * This allows for a simpler tool triggering where tools which utilized the additional information provided will have it, those which may need it the future shall have it with little issue, and those that don't care may ignore it. NOTE(s): * Tested normal movement within opening creation menu: Passed * With Creation Menu Open: * Tested clicking around the world in empty space: Passed * Tested single selection: Passed * Tested single selection rotation (pitch, yaw, roll): Passed * Tested single selection translation (xz, y): Passed * Tested multiple selection: Passed * Tested multiple selection rotation (pitch, yaw, roll): Passed * Tested multiple selection translation (xz, y): Passed Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 374 +++++------------- 1 file changed, 92 insertions(+), 282 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index eb3deb590d..3c36f307d0 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -306,11 +306,6 @@ SelectionDisplay = (function() { var rollNormal; var rotationNormal; - var originalRotation; - var originalPitch; - var originalYaw; - var originalRoll; - var handleColor = { red: 255, @@ -2375,6 +2370,28 @@ SelectionDisplay = (function() { } }; + // FUNCTION: SET ROTATION HANDLES VISIBLE + that.setRotationHandlesVisible = function(isVisible) { + var visibilityUpdate = { visible: isVisible }; + Overlays.editOverlay(yawHandle, visibilityUpdate); + Overlays.editOverlay(pitchHandle, visibilityUpdate); + Overlays.editOverlay(rollHandle, visibilityUpdate); + }; + + // FUNCTION: SET STRETCH HANDLES VISIBLE + that.setStretchHandlesVisible = function(isVisible) { + var numHandles = stretchHandles.length; + var visibilityUpdate = { visible: isVisible }; + for (var handleIndex = 0; handleIndex < numHandles; ++handleIndex) { + Overlays.editOverlay(stretchHandles[ handleIndex ], visibilityUpdate); + } + }; + + // FUNCTION: SET GRABBER MOVE UP VISIBLE + that.setGrabberMoveUpVisible = function(isVisible) { + Overlays.editOverlay(grabberMoveUp, { visible: isVisible }); + }; + // FUNCTION: UNSELECT // TODO?: Needs implementation that.unselect = function(entityID) {}; @@ -2392,7 +2409,7 @@ SelectionDisplay = (function() { greatestDimension: 0.0, startingDistance: 0.0, startingElevation: 0.0, - onBegin: function(event,isAltFromGrab, intersectInfo) { + onBegin: function(event,isAltFromGrab,intersectInfo) { var wantDebug = false; if(wantDebug){ print("================== TRANSLATE_XZ(Beg) -> ======================="); @@ -2402,6 +2419,9 @@ SelectionDisplay = (function() { } SelectionManager.saveProperties(); + that.setRotationHandlesVisible( false ); + that.setGrabberMoveUpVisible( false ); + startPosition = SelectionManager.worldPosition; mode = translateXZTool.mode; @@ -2603,7 +2623,7 @@ SelectionDisplay = (function() { var upDownPickNormal = null; addGrabberTool(grabberMoveUp, { mode: "TRANSLATE_UP_DOWN", - onBegin: function(event) { + onBegin: function(event, intersectResult) { pickRay = generalComputePickRay(event.x, event.y); upDownPickNormal = Quat.getForward(lastCameraOrientation); @@ -2613,6 +2633,8 @@ SelectionDisplay = (function() { lastXYPick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal); SelectionManager.saveProperties(); + that.setGrabberMoveUpVisible( true ); + that.setRotationHandlesVisible( false ); // Duplicate entities if alt is pressed. This will make a // copy of the selected entities and move the _original_ entities, not @@ -2676,15 +2698,23 @@ SelectionDisplay = (function() { // GRABBER TOOL: GRABBER CLONER addGrabberTool(grabberCloner, { mode: "CLONE", - onBegin: function(event) { + onBegin: function(event, intersectResult) { var pickRay = generalComputePickRay(event.x, event.y); + //TODO_Case6491: This may be doing duplicate works that's handled + // within translateXZTool.onBegin. Verify and if so + // remove... var result = Overlays.findRayIntersection(pickRay); translateXZTool.pickPlanePosition = result.intersection; translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); - translateXZTool.onBegin(event,true); + var intersectInfo = { + queryRay: pickRay, + results: intersectResult + }; + + translateXZTool.onBegin(event,true,intersectInfo); }, elevation: function (event) { translateXZTool.elevation(event); @@ -2715,6 +2745,7 @@ SelectionDisplay = (function() { // direction - direction to stretch in // pivot - point to use as a pivot // offset - the position of the overlay tool relative to the selections center position + // @return: tool obj var makeStretchTool = function(stretchMode, direction, pivot, offset, customOnMove) { // directionFor3DStretch - direction and pivot for 3D stretch // distanceFor3DStretch - distance from the intersection point and the handController @@ -2756,7 +2787,7 @@ SelectionDisplay = (function() { var pickRayPosition3D = null; var rotation = null; - var onBegin = function(event) { + var onBegin = function(event, intersectResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); @@ -3668,6 +3699,10 @@ SelectionDisplay = (function() { } SelectionManager.saveProperties(); + that.setRotationHandlesVisible( false ); + that.setStretchHandlesVisible( false ); + that.setGrabberMoveUpVisible( false ); + initialPosition = SelectionManager.worldPosition; mode = rotMode; rotationNormal = rotNormal; @@ -3871,10 +3906,10 @@ SelectionDisplay = (function() { var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { mode: "ROTATE_YAW", - onBegin: function(event, zeroPoint) { - //note: It's expected that the intersection is passed when this is called. + onBegin: function(event, intersectResult) { + //note: It's expected that the intersect result is passed when this is called. // validity will be checked later as a pre-requisite for onMove handling. - yawZero = zeroPoint; + yawZero = intersectResult.intersection; helperRotationHandleOnBegin( "ROTATE_YAW", yawNormal, yawCenter, yawHandleRotation ); }, @@ -3890,10 +3925,10 @@ SelectionDisplay = (function() { // PITCH GRABBER TOOL DEFINITION addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", - onBegin: function (event, zeroPoint) { - //note: It's expected that the intersection is passed when this is called. + onBegin: function (event, intersectResult) { + //note: It's expected that the intersect result is passed when this is called. // validity will be checked later as a pre-requisite for onMove handling. - pitchZero = zeroPoint; + pitchZero = intersectResult.intersection; helperRotationHandleOnBegin( "ROTATE_PITCH", pitchNormal, pitchCenter, pitchHandleRotation ); }, @@ -3909,10 +3944,10 @@ SelectionDisplay = (function() { // ROLL GRABBER TOOL DEFINITION addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", - onBegin: function (event, zeroPoint) { - //note: It's expected that the intersection is passed when this is called. + onBegin: function (event, intersectResult) { + //note: It's expected that the intersect result is passed when this is called. // validity will be checked later as a pre-requisite for onMove handling. - rollZero = zeroPoint; + rollZero = intersectResult.intersection; helperRotationHandleOnBegin( "ROTATE_ROLL", rollNormal, rollCenter, rollHandleRotation ); }, @@ -3985,30 +4020,6 @@ SelectionDisplay = (function() { return intersectObj; } - function checkIntersectWithHUD(queryRay) { - var intersectObj = testRayIntersect(queryRay, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); - - return intersectObj; - } - - function checkIntersectWithNonSelectionItems(queryRay) { - var intersectObj = testRayIntersect(queryRay, null, [yawHandle, pitchHandle, rollHandle, selectionBox]); - - return intersectObj; - } - - function checkIntersectWithRotationHandles(queryRay) { - var intersectObj = testRayIntersect(queryRay, [yawHandle, pitchHandle, rollHandle]); - - return intersectObj; - } - - function checkIntersectWithSelectionBox(queryRay) { - var intersectObj = testRayIntersect(queryRay, [selectionBox]); - - return intersectObj; - } - // FUNCTION: MOUSE PRESS EVENT that.mousePressEvent = function (event) { var wantDebug = false; @@ -4016,267 +4027,66 @@ SelectionDisplay = (function() { print("=============== eST::MousePressEvent BEG ======================="); } if (!event.isLeftButton && !that.triggered) { - // if another mouse button than left is pressed ignore it + //--EARLY EXIT-(if another mouse button than left is pressed ignore it) return false; } - var somethingClicked = false; var pickRay = generalComputePickRay(event.x, event.y); - - var results_checkHUD = checkIntersectWithHUD(pickRay); - if (results_checkHUD.intersects) { - // mouse clicks on the tablet should override the edit affordances - return false; - } - - entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); - - // ignore ray intersection for our selection box and yaw/pitch/roll - var results_checkNonSelection = checkIntersectWithNonSelectionItems(pickRay); - if (results_checkNonSelection.intersects) { - var tool = grabberTools[results_checkNonSelection.overlayID]; - if (tool) { - if (wantDebug) { - print("Intersected with known table tool( mode: " + tool.mode + " )"); - } - activeTool = tool; - mode = tool.mode; - somethingClicked = 'tool'; - if (activeTool.onBegin) { - activeTool.onBegin(event); - } else if (wantDebug) { - print(" ActiveTool( " + activeTool.mode + " ) missing onBegin"); - } - } else { - mode = "UNKNOWN"; - }//--End_if(tool) - }//--End_if(results_checkNonSelection.intersects) - - // if one of the items above was clicked, then we know we are in translate or stretch mode, and we - // should hide our rotate handles... - if (somethingClicked) { - if (wantDebug) { - print(" Trying to hide PitchYawRoll Handles"); - } - Overlays.editOverlay(yawHandle, { - visible: false - }); - Overlays.editOverlay(pitchHandle, { - visible: false - }); - Overlays.editOverlay(rollHandle, { - visible: false - }); - - if (mode != "TRANSLATE_UP_DOWN") { - if(wantDebug){ - print(" Trying to hide GrabberMoveUp"); - } - Overlays.editOverlay(grabberMoveUp, { - visible: false - }); + //TODO_Case6491: Move this out to setup just to make it once + var interactiveOverlays = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, selectionBox]; + for (var key in grabberTools) { + if (grabberTools.hasOwnProperty(key)) { + interactiveOverlays.push( key ); } } - if (!somethingClicked) { - - if (wantDebug) { - print("rotate handle case..."); + mode = "UNKNOWN"; + var results = testRayIntersect( pickRay, interactiveOverlays ); + if ( results.intersects ){ + var hitOverlayID = results.overlayID; + if ( (hitOverlayID == HMD.tabletID) || (hitOverlayID == HMD.tabletScreenID) || (hitOverlayID == HMD.homeButtonID) ) { + //--EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) + return false; } + entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); + //TODO_Case6491: Merge if..else( selectionBox ) when onBegin of transXZ is normalized. + if ( hitOverlayID == selectionBox ) { - // Only intersect versus yaw/pitch/roll. - var results_checkRotationHandles = checkIntersectWithRotationHandles(pickRay); - var properties = Entities.getEntityProperties(selectionManager.selections[0]); - var angles = Quat.safeEulerAngles(properties.rotation); - var pitch = angles.x; - var yaw = angles.y; - var roll = angles.z; - - //TODO_Case6491: Should these only be updated when we actually touched - // a handle. (The answer is most likley: Yes) Potentially move chunk - // to either tool's onBegin or before rayCast here when refactored. - originalRotation = properties.rotation; - originalPitch = pitch; - originalYaw = yaw; - originalRoll = roll; - - if (results_checkRotationHandles.intersects) { - var resultTool = grabberTools[results_checkRotationHandles.overlayID]; - if (wantDebug) { - print("Intersection detected with handle..."); - } - if (resultTool) { - if (wantDebug) { - print(" " + resultTool.mode); - } - activeTool = resultTool; - somethingClicked = resultTool.mode; - if(activeTool.onBegin) { - activeTool.onBegin(event, results_checkRotationHandles.intersection); - } else if (wantDebug) { - print(" ActiveTool( " + activeTool.mode + " ) missing onBegin"); - } - }//--End_If(resultTool) - }//--End_If(results_checkRotationHandles.intersects) - - if (somethingClicked) { - - if (wantDebug) { - print(" somethingClicked:" + somethingClicked); - print(" mode:" + mode); - print(" Trying to hide PitchYawRoll Handles"); - } - Overlays.editOverlay(yawHandle, { - visible: false - }); - Overlays.editOverlay(pitchHandle, { - visible: false - }); - Overlays.editOverlay(rollHandle, { - visible: false - }); - - if(wantDebug){ - print(" Trying to hide Non-Light GrabberHandles"); - } - - Overlays.editOverlay(grabberCloner, { - visible: false - }); - Overlays.editOverlay(grabberMoveUp, { - visible: false - }); - Overlays.editOverlay(grabberLBN, { - visible: false - }); - Overlays.editOverlay(grabberLBF, { - visible: false - }); - Overlays.editOverlay(grabberRBN, { - visible: false - }); - Overlays.editOverlay(grabberRBF, { - visible: false - }); - Overlays.editOverlay(grabberLTN, { - visible: false - }); - Overlays.editOverlay(grabberLTF, { - visible: false - }); - Overlays.editOverlay(grabberRTN, { - visible: false - }); - Overlays.editOverlay(grabberRTF, { - visible: false - }); - - Overlays.editOverlay(grabberTOP, { - visible: false - }); - Overlays.editOverlay(grabberBOTTOM, { - visible: false - }); - Overlays.editOverlay(grabberLEFT, { - visible: false - }); - Overlays.editOverlay(grabberRIGHT, { - visible: false - }); - Overlays.editOverlay(grabberNEAR, { - visible: false - }); - Overlays.editOverlay(grabberFAR, { - visible: false - }); - - Overlays.editOverlay(grabberEdgeTR, { - visible: false - }); - Overlays.editOverlay(grabberEdgeTL, { - visible: false - }); - Overlays.editOverlay(grabberEdgeTF, { - visible: false - }); - Overlays.editOverlay(grabberEdgeTN, { - visible: false - }); - Overlays.editOverlay(grabberEdgeBR, { - visible: false - }); - Overlays.editOverlay(grabberEdgeBL, { - visible: false - }); - Overlays.editOverlay(grabberEdgeBF, { - visible: false - }); - Overlays.editOverlay(grabberEdgeBN, { - visible: false - }); - Overlays.editOverlay(grabberEdgeNR, { - visible: false - }); - Overlays.editOverlay(grabberEdgeNL, { - visible: false - }); - Overlays.editOverlay(grabberEdgeFR, { - visible: false - }); - Overlays.editOverlay(grabberEdgeFL, { - visible: false - }); - } - } - - if (!somethingClicked) { - // Only intersect versus selectionBox. - var results_checkSelectionBox = checkIntersectWithSelectionBox( pickRay ); - if (results_checkSelectionBox.intersects) { activeTool = translateXZTool; if(wantDebug){ - print("Clicked selectionBox, Activating Tool: " + activeTool.mode ); + print(" Clicked selectionBox, Activating Tool: " + activeTool.mode ); } var intersectInfo = { queryRay: pickRay, - results: results_checkSelectionBox + results: results }; + activeTool.onBegin(event, null, intersectInfo); - somethingClicked = 'selectionBox'; - } - } - - if (somethingClicked) { - if (wantDebug) { - print("mousePressEvent()...... " + somethingClicked); - print(" mode: " + mode); - } - } - - // reset everything as intersectable... - // TODO: we could optimize this since some of these were already flipped back(i.e: just get rid of this) - if (wantDebug) { - print("Trying to set SelectionBox & PitchYawRoll Handles to NOT_IGNORE Rays"); - } - Overlays.editOverlay(selectionBox, { - ignoreRayIntersection: false - }); - Overlays.editOverlay(yawHandle, { - ignoreRayIntersection: false - }); - Overlays.editOverlay(pitchHandle, { - ignoreRayIntersection: false - }); - Overlays.editOverlay(rollHandle, { - ignoreRayIntersection: false - }); + } else { //...see if a tool was hit as that's the only thing left that we care about. + var hitTool = grabberTools[ hitOverlayID ]; + if ( hitTool ) { + activeTool = hitTool; + mode = activeTool.mode; //< TODO: Is this centrally handled in all tool begins? + if (activeTool.onBegin) { + activeTool.onBegin(event, results); + } else { + print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool( " + activeTool.mode + " ) missing onBegin"); + } + } else { + print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); + }//--End_if( hitTool ) + }//--End_if( hitOverlayID == selectionBox ) + }//--End_If( results.intersects ) if (wantDebug) { + print(" SelectionDisplay.mode: " + mode ); print("=============== eST::MousePressEvent END ======================="); } - return somethingClicked; + // If mode is known then we successfully handled this; + // otherwise, we're missing a tool or a tool.onBegin. + return (mode != "UNKNOWN"); }; // FUNCTION: MOUSE MOVE EVENT From fa74fbc986550b5cfe662a6da59d9198f3b02b7c Mon Sep 17 00:00:00 2001 From: Leander Hasty <1p-cusack@1stplayable.com> Date: Thu, 10 Aug 2017 13:29:57 -0400 Subject: [PATCH 20/79] [Case 6491] fixes rotation skip near 0 and 180. Previously, when rotating, it would be easy to achieve 1 degree granularity, except near the 0 degree and 180 degree "poles", where it would often e.g. jump from 10 to -10, or 174 to -175, or similar. yawZero/pitchZero/rollZero were all based on the yawHandle/pitchHandle/rollHandle ray intersection, and were not necessarily coplanar with rotateOverlayTarget. As a result, centerToZero didn't lie on the expected plane, while centerToIntersect did. This had the effect of distorting the rotation range. We also have a possible issue in here with editOverlay(rotationOverlayTarget,{rotation:...}) not taking effect immediately. Better to take the existing ray and cast against a known plane, as e.g. translateXZTool and such do. No risk of stale rotation in that case. This also cleans up rotationHelper args a bit to avoid some string switches and keep flow a little more readable. TODO: propagate ray-plane test to helperRotationHandleOnMove rather than relying on ray hit location; normalize onBegin/onMove/etc across all tools to take queryRay and results args to avoid recreating the ray. Reviewed-by: LaShonda Hopper --- .../system/libraries/entitySelectionTool.js | 85 ++++++++----------- 1 file changed, 36 insertions(+), 49 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 3c36f307d0..d37b57e130 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -298,9 +298,7 @@ SelectionDisplay = (function() { var yawCenter; var pitchCenter; var rollCenter; - var yawZero; - var pitchZero; - var rollZero; + var rotZero; var yawNormal; var pitchNormal; var rollNormal; @@ -3692,10 +3690,10 @@ SelectionDisplay = (function() { } } - function helperRotationHandleOnBegin( rotMode, rotNormal, rotCenter, handleRotation ) { + function helperRotationHandleOnBegin( event, rotNormal, rotCenter, handleRotation ) { var wantDebug = false; if (wantDebug) { - print("================== " + rotMode + "(onBegin) -> ======================="); + print("================== " + mode + "(rotation helper onBegin) -> ======================="); } SelectionManager.saveProperties(); @@ -3704,7 +3702,6 @@ SelectionDisplay = (function() { that.setGrabberMoveUpVisible( false ); initialPosition = SelectionManager.worldPosition; - mode = rotMode; rotationNormal = rotNormal; // Size the overlays to the current selection size @@ -3757,28 +3754,31 @@ SelectionDisplay = (function() { }); updateRotationDegreesOverlay(0, handleRotation, rotCenter); + + // Compute zero position now that the overlay is set up. + // TODO editOverlays sync + var pickRay = generalComputePickRay(event.x, event.y); + + var result = rayPlaneIntersection( pickRay, rotCenter, rotationNormal ); + rotZero = result; + if (wantDebug) { - print("================== " + rotMode + "(onBegin) <- ======================="); + print("================== " + mode + "(rotation helper onBegin) <- ======================="); } }//--End_Function( helperRotationHandleOnBegin ) - function helperRotationHandleOnMove( event, rotMode, rotZero, rotCenter, handleRotation ) { + function helperRotationHandleOnMove( event, rotAroundAxis, rotCenter, handleRotation ) { - if ( ! (rotMode == "ROTATE_YAW" || rotMode == "ROTATE_PITCH" || rotMode == "ROTATE_ROLL") ) { - print("ERROR( handleRotationHandleOnMove ) - Encountered Unknown/Invalid RotationMode: " + rotMode ); - - //--EARLY EXIT-- - return; - } else if ( ! rotZero ) { - print("ERROR( handleRotationHandleOnMove ) - Invalid RotationZero Specified" ); + if ( ! rotZero ) { + print("ERROR( handleRotationHandleOnMove ) - Invalid RotationZero Specified (missed rotation target plane?)" ); //--EARLY EXIT-- return; } - var wantDebug = false; + var wantDebug = true; if (wantDebug) { - print("================== "+ rotMode + "(onMove) -> ======================="); + print("================== "+ mode + "(rotation helper onMove) -> ======================="); Vec3.print(" rotZero: ", rotZero); } var pickRay = generalComputePickRay(event.x, event.y); @@ -3794,7 +3794,12 @@ SelectionDisplay = (function() { var centerToZero = Vec3.subtract(rotZero, rotCenter); var centerToIntersect = Vec3.subtract(result.intersection, rotCenter); if (wantDebug) { - Vec3.print(" RotationNormal: ", rotationNormal); + Vec3.print(" RotationNormal: ", rotationNormal); + Vec3.print(" rotZero: ", rotZero); + Vec3.print(" rotCenter: ", rotCenter); + Vec3.print(" intersect: ", result.intersection); + Vec3.print(" centerToZero: ", centerToZero); + Vec3.print(" centerToIntersect: ", centerToIntersect); } // Note: orientedAngle which wants normalized centerToZero and centerToIntersect // handles that internally, so it's to pass unnormalized vectors here. @@ -3805,18 +3810,9 @@ SelectionDisplay = (function() { var snapAngle = snapToInner ? innerSnapAngle : 1.0; angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; - var rotChange = null; - switch( rotMode ) { - case "ROTATE_YAW": - rotChange = Quat.fromVec3Degrees( {x: 0, y: angleFromZero, z: 0} ); - break; - case "ROTATE_PITCH": - rotChange = Quat.fromVec3Degrees( {x: angleFromZero, y: 0, z: 0} ); - break; - case "ROTATE_ROLL": - rotChange = Quat.fromVec3Degrees( {x: 0, y: 0, z: angleFromZero} ); - break; - } + var vec3Degrees = { x: 0, y: 0, z: 0 }; + vec3Degrees[rotAroundAxis] = angleFromZero; + var rotChange = Quat.fromVec3Degrees( vec3Degrees ); updateSelectionsRotation( rotChange ); updateRotationDegreesOverlay(angleFromZero, handleRotation, rotCenter); @@ -3872,7 +3868,7 @@ SelectionDisplay = (function() { }//--End_If( results.intersects ) if (wantDebug) { - print("================== "+ rotMode + "(onMove) <- ======================="); + print("================== "+ mode + "(rotation helper onMove) <- ======================="); } }//--End_Function( helperRotationHandleOnMove ) @@ -3907,17 +3903,14 @@ SelectionDisplay = (function() { addGrabberTool(yawHandle, { mode: "ROTATE_YAW", onBegin: function(event, intersectResult) { - //note: It's expected that the intersect result is passed when this is called. - // validity will be checked later as a pre-requisite for onMove handling. - yawZero = intersectResult.intersection; - - helperRotationHandleOnBegin( "ROTATE_YAW", yawNormal, yawCenter, yawHandleRotation ); + mode = "ROTATE_YAW"; + helperRotationHandleOnBegin( event, yawNormal, yawCenter, yawHandleRotation ); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); }, onMove: function(event) { - helperRotationHandleOnMove( event, "ROTATE_YAW", yawZero, yawCenter, yawHandleRotation ); + helperRotationHandleOnMove( event, "y", yawCenter, yawHandleRotation ); } }); @@ -3926,17 +3919,14 @@ SelectionDisplay = (function() { addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", onBegin: function (event, intersectResult) { - //note: It's expected that the intersect result is passed when this is called. - // validity will be checked later as a pre-requisite for onMove handling. - pitchZero = intersectResult.intersection; - - helperRotationHandleOnBegin( "ROTATE_PITCH", pitchNormal, pitchCenter, pitchHandleRotation ); + mode = "ROTATE_PITCH"; + helperRotationHandleOnBegin( event, pitchNormal, pitchCenter, pitchHandleRotation ); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); }, onMove: function (event) { - helperRotationHandleOnMove( event, "ROTATE_PITCH", pitchZero, pitchCenter, pitchHandleRotation ); + helperRotationHandleOnMove( event, "x", pitchCenter, pitchHandleRotation ); } }); @@ -3945,17 +3935,14 @@ SelectionDisplay = (function() { addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", onBegin: function (event, intersectResult) { - //note: It's expected that the intersect result is passed when this is called. - // validity will be checked later as a pre-requisite for onMove handling. - rollZero = intersectResult.intersection; - - helperRotationHandleOnBegin( "ROTATE_ROLL", rollNormal, rollCenter, rollHandleRotation ); + mode = "ROTATE_ROLL"; + helperRotationHandleOnBegin( event, rollNormal, rollCenter, rollHandleRotation ); }, onEnd: function (event, reason) { helperRotationHandleOnEnd(); }, onMove: function(event) { - helperRotationHandleOnMove( event, "ROTATE_ROLL", rollZero, rollCenter, rollHandleRotation ); + helperRotationHandleOnMove( event, "z", rollCenter, rollHandleRotation ); } }); From 74734f35e98807b1a23a4c796ac5dab0d44b6cfa Mon Sep 17 00:00:00 2001 From: Leander Hasty <1p-cusack@1stplayable.com> Date: Thu, 10 Aug 2017 15:12:36 -0400 Subject: [PATCH 21/79] [Case 6491] more uniform grabber tools; more distrust of rotateOverlayTarget. Rotation tools' onMove methods now use rayPlaneIntersection rather than using the giant invisible rotateOverlayTarget. It can likely be entirely removed in the next commit. tool.onBegin's signature is now (event, pickRay, pickResult, ...) -- this allows us to avoid recomputing the ray or intersection when unnecessary. translateXZTool is now a part of the grabberTools array; addGrabberTool and addStretchTool have been modified to return the tool reference (and not disassemble and reassemble the tools, so they can keep their own local functions and state). This does make the array potentially less type-uniform, which may (?) undo some javascript optimizations, but allows us to eventually remove some state -- and they're only 1x/frame methods. We now compute rotationNormal in rotation tool onBegin, rather than having many different normals lying around. Merged the final branches in mousePressEvent. Also fixed issue with mode TRANSLATE_XZ test within updateRotationHandles. Reviewed-by: LaShonda Hopper --- .../system/libraries/entitySelectionTool.js | 209 +++++------------- 1 file changed, 54 insertions(+), 155 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index d37b57e130..9fd5bfcdee 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -299,9 +299,6 @@ SelectionDisplay = (function() { var pitchCenter; var rollCenter; var rotZero; - var yawNormal; - var pitchNormal; - var rollNormal; var rotationNormal; @@ -1093,12 +1090,8 @@ SelectionDisplay = (function() { return controllerComputePickRay() || Camera.computePickRay(x, y); } function addGrabberTool(overlay, tool) { - grabberTools[overlay] = { - mode: tool.mode, - onBegin: tool.onBegin, - onMove: tool.onMove, - onEnd: tool.onEnd, - }; + grabberTools[overlay] = tool; + return tool; } @@ -1228,22 +1221,6 @@ SelectionDisplay = (function() { z: 0 }); - yawNormal = { - x: 0, - y: 1, - z: 0 - }; - pitchNormal = { - x: 1, - y: 0, - z: 0 - }; - rollNormal = { - x: 0, - y: 0, - z: 1 - }; - yawCorner = { x: left + rotateHandleOffset, y: bottom - rotateHandleOffset, @@ -1305,23 +1282,6 @@ SelectionDisplay = (function() { z: 90 }); - yawNormal = { - x: 0, - y: 1, - z: 0 - }; - pitchNormal = { - x: 1, - y: 0, - z: 0 - }; - rollNormal = { - x: 0, - y: 0, - z: 1 - }; - - yawCorner = { x: left + rotateHandleOffset, y: bottom - rotateHandleOffset, @@ -1385,22 +1345,6 @@ SelectionDisplay = (function() { z: 180 }); - yawNormal = { - x: 0, - y: 1, - z: 0 - }; - pitchNormal = { - x: 1, - y: 0, - z: 0 - }; - rollNormal = { - x: 0, - y: 0, - z: 1 - }; - yawCorner = { x: right - rotateHandleOffset, y: bottom - rotateHandleOffset, @@ -1460,22 +1404,6 @@ SelectionDisplay = (function() { z: 180 }); - yawNormal = { - x: 0, - y: 1, - z: 0 - }; - rollNormal = { - x: 0, - y: 0, - z: 1 - }; - pitchNormal = { - x: 1, - y: 0, - z: 0 - }; - yawCorner = { x: right - rotateHandleOffset, y: bottom - rotateHandleOffset, @@ -1531,7 +1459,7 @@ SelectionDisplay = (function() { isPointLight = properties.type == "Light" && !properties.isSpotlight; } - if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_X in case they Z") { + if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_XZ") { rotationOverlaysVisible = true; rotateHandlesVisible = false; translateHandlesVisible = false; @@ -2401,19 +2329,19 @@ SelectionDisplay = (function() { var duplicatedEntityIDs = null; // TOOL DEFINITION: TRANSLATE XZ TOOL - var translateXZTool = { + var translateXZTool = addGrabberTool(selectionBox,{ mode: 'TRANSLATE_XZ', pickPlanePosition: { x: 0, y: 0, z: 0 }, greatestDimension: 0.0, startingDistance: 0.0, startingElevation: 0.0, - onBegin: function(event,isAltFromGrab,intersectInfo) { + onBegin: function(event, pickRay, pickResult, doClone) { var wantDebug = false; if(wantDebug){ print("================== TRANSLATE_XZ(Beg) -> ======================="); - Vec3.print(" intersectInfo.queryRay", intersectInfo.queryRay); - Vec3.print(" intersectInfo.queryRay.origin", intersectInfo.queryRay.origin); - Vec3.print(" intersectInfo.results.intersection", intersectInfo.results.intersection); + Vec3.print(" pickRay", pickRay); + Vec3.print(" pickRay.origin", pickRay.origin); + Vec3.print(" pickResult.intersection", pickResult.intersection); } SelectionManager.saveProperties(); @@ -2421,19 +2349,19 @@ SelectionDisplay = (function() { that.setGrabberMoveUpVisible( false ); startPosition = SelectionManager.worldPosition; - mode = translateXZTool.mode; + mode = translateXZTool.mode; // Note this overrides mode = "CLONE" - translateXZTool.pickPlanePosition = intersectInfo.results.intersection; + translateXZTool.pickPlanePosition = pickResult.intersection; translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); - translateXZTool.startingDistance = Vec3.distance(intersectInfo.queryRay.origin, SelectionManager.position); - translateXZTool.startingElevation = translateXZTool.elevation(intersectInfo.queryRay.origin, translateXZTool.pickPlanePosition); + translateXZTool.startingDistance = Vec3.distance(pickRay.origin, SelectionManager.position); + translateXZTool.startingElevation = translateXZTool.elevation(pickRay.origin, translateXZTool.pickPlanePosition); if (wantDebug) { print(" longest dimension: " + translateXZTool.greatestDimension); print(" starting distance: " + translateXZTool.startingDistance); print(" starting elevation: " + translateXZTool.startingElevation); } - initialXZPick = rayPlaneIntersection(intersectInfo.queryRay, translateXZTool.pickPlanePosition, { + initialXZPick = rayPlaneIntersection(pickRay, translateXZTool.pickPlanePosition, { x: 0, y: 1, z: 0 @@ -2442,7 +2370,7 @@ SelectionDisplay = (function() { // Duplicate entities if alt is pressed. This will make a // copy of the selected entities and move the _original_ entities, not // the new ones. - if (event.isAlt || isAltFromGrab) { + if (event.isAlt || doClone) { duplicatedEntityIDs = []; for (var otherEntityID in SelectionManager.savedProperties) { var properties = SelectionManager.savedProperties[otherEntityID]; @@ -2614,16 +2542,14 @@ SelectionDisplay = (function() { SelectionManager._update(); } - }; - + }); + // GRABBER TOOL: GRABBER MOVE UP var lastXYPick = null; var upDownPickNormal = null; addGrabberTool(grabberMoveUp, { mode: "TRANSLATE_UP_DOWN", - onBegin: function(event, intersectResult) { - pickRay = generalComputePickRay(event.x, event.y); - + onBegin: function(event, pickRay, pickResult) { upDownPickNormal = Quat.getForward(lastCameraOrientation); // Remove y component so the y-axis lies along the plane we picking on - this will // give movements that follow the mouse. @@ -2696,23 +2622,9 @@ SelectionDisplay = (function() { // GRABBER TOOL: GRABBER CLONER addGrabberTool(grabberCloner, { mode: "CLONE", - onBegin: function(event, intersectResult) { - - var pickRay = generalComputePickRay(event.x, event.y); - //TODO_Case6491: This may be doing duplicate works that's handled - // within translateXZTool.onBegin. Verify and if so - // remove... - var result = Overlays.findRayIntersection(pickRay); - translateXZTool.pickPlanePosition = result.intersection; - translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), - SelectionManager.worldDimensions.z); - - var intersectInfo = { - queryRay: pickRay, - results: intersectResult - }; - - translateXZTool.onBegin(event,true,intersectInfo); + onBegin: function(event, pickRay, pickResult) { + var doClone = true; + translateXZTool.onBegin(event,pickRay,pickResult,doClone); }, elevation: function (event) { translateXZTool.elevation(event); @@ -2785,7 +2697,7 @@ SelectionDisplay = (function() { var pickRayPosition3D = null; var rotation = null; - var onBegin = function(event, intersectResult) { + var onBegin = function(event, pickRay, pickResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); @@ -3167,7 +3079,7 @@ SelectionDisplay = (function() { } var tool = makeStretchTool(mode, direction, pivot, offset, handleMove); - addGrabberTool(overlay, tool); + return addGrabberTool(overlay, tool); } // FUNCTION: CUTOFF STRETCH FUNC @@ -3690,7 +3602,7 @@ SelectionDisplay = (function() { } } - function helperRotationHandleOnBegin( event, rotNormal, rotCenter, handleRotation ) { + function helperRotationHandleOnBegin( event, pickRay, rotAroundAxis, rotCenter, handleRotation ) { var wantDebug = false; if (wantDebug) { print("================== " + mode + "(rotation helper onBegin) -> ======================="); @@ -3702,7 +3614,8 @@ SelectionDisplay = (function() { that.setGrabberMoveUpVisible( false ); initialPosition = SelectionManager.worldPosition; - rotationNormal = rotNormal; + rotationNormal = { x: 0, y: 0, z: 0 }; + rotationNormal[rotAroundAxis] = 1; // Size the overlays to the current selection size var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; @@ -3755,11 +3668,11 @@ SelectionDisplay = (function() { updateRotationDegreesOverlay(0, handleRotation, rotCenter); - // Compute zero position now that the overlay is set up. - // TODO editOverlays sync - var pickRay = generalComputePickRay(event.x, event.y); - + // editOverlays may not have committed rotation changes. + // Compute zero position based on where the overlay will be eventually. var result = rayPlaneIntersection( pickRay, rotCenter, rotationNormal ); + // In case of a parallel ray, this will be null, which will cause early-out + // in the onMove helper. rotZero = result; if (wantDebug) { @@ -3776,7 +3689,7 @@ SelectionDisplay = (function() { return; } - var wantDebug = true; + var wantDebug = false; if (wantDebug) { print("================== "+ mode + "(rotation helper onMove) -> ======================="); Vec3.print(" rotZero: ", rotZero); @@ -3789,15 +3702,15 @@ SelectionDisplay = (function() { visible: false }); - var result = Overlays.findRayIntersection(pickRay, true, [rotateOverlayTarget]); - if (result.intersects) { + var result = rayPlaneIntersection( pickRay, rotCenter, rotationNormal ); + if (result) { var centerToZero = Vec3.subtract(rotZero, rotCenter); - var centerToIntersect = Vec3.subtract(result.intersection, rotCenter); + var centerToIntersect = Vec3.subtract(result, rotCenter); if (wantDebug) { Vec3.print(" RotationNormal: ", rotationNormal); Vec3.print(" rotZero: ", rotZero); Vec3.print(" rotCenter: ", rotCenter); - Vec3.print(" intersect: ", result.intersection); + Vec3.print(" intersect: ", result); Vec3.print(" centerToZero: ", centerToZero); Vec3.print(" centerToIntersect: ", centerToIntersect); } @@ -3805,7 +3718,7 @@ SelectionDisplay = (function() { // handles that internally, so it's to pass unnormalized vectors here. var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - var distanceFromCenter = Vec3.distance(rotCenter, result.intersection); + var distanceFromCenter = Vec3.length(centerToIntersect); var snapToInner = distanceFromCenter < innerRadius; var snapAngle = snapToInner ? innerSnapAngle : 1.0; angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; @@ -3902,9 +3815,8 @@ SelectionDisplay = (function() { var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { mode: "ROTATE_YAW", - onBegin: function(event, intersectResult) { - mode = "ROTATE_YAW"; - helperRotationHandleOnBegin( event, yawNormal, yawCenter, yawHandleRotation ); + onBegin: function(event, pickRay, pickResult) { + helperRotationHandleOnBegin( event, pickRay, "y", yawCenter, yawHandleRotation ); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); @@ -3918,9 +3830,8 @@ SelectionDisplay = (function() { // PITCH GRABBER TOOL DEFINITION addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", - onBegin: function (event, intersectResult) { - mode = "ROTATE_PITCH"; - helperRotationHandleOnBegin( event, pitchNormal, pitchCenter, pitchHandleRotation ); + onBegin: function(event, pickRay, pickResult) { + helperRotationHandleOnBegin( event, pickRay, "x", pitchCenter, pitchHandleRotation ); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); @@ -3934,9 +3845,8 @@ SelectionDisplay = (function() { // ROLL GRABBER TOOL DEFINITION addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", - onBegin: function (event, intersectResult) { - mode = "ROTATE_ROLL"; - helperRotationHandleOnBegin( event, rollNormal, rollCenter, rollHandleRotation ); + onBegin: function(event, pickRay, pickResult) { + helperRotationHandleOnBegin( event, pickRay, "z", rollCenter, rollHandleRotation ); }, onEnd: function (event, reason) { helperRotationHandleOnEnd(); @@ -4027,7 +3937,9 @@ SelectionDisplay = (function() { } } + // Start with unknown mode, in case no tool can handle this. mode = "UNKNOWN"; + var results = testRayIntersect( pickRay, interactiveOverlays ); if ( results.intersects ){ var hitOverlayID = results.overlayID; @@ -4038,32 +3950,19 @@ SelectionDisplay = (function() { entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); //TODO_Case6491: Merge if..else( selectionBox ) when onBegin of transXZ is normalized. - if ( hitOverlayID == selectionBox ) { - activeTool = translateXZTool; - if(wantDebug){ - print(" Clicked selectionBox, Activating Tool: " + activeTool.mode ); - } - var intersectInfo = { - queryRay: pickRay, - results: results - }; - - activeTool.onBegin(event, null, intersectInfo); - } else { //...see if a tool was hit as that's the only thing left that we care about. - var hitTool = grabberTools[ hitOverlayID ]; - if ( hitTool ) { - activeTool = hitTool; - mode = activeTool.mode; //< TODO: Is this centrally handled in all tool begins? - if (activeTool.onBegin) { - activeTool.onBegin(event, results); - } else { - print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool( " + activeTool.mode + " ) missing onBegin"); - } + var hitTool = grabberTools[ hitOverlayID ]; + if ( hitTool ) { + activeTool = hitTool; + mode = activeTool.mode; + if (activeTool.onBegin) { + activeTool.onBegin(event, pickRay, results); } else { - print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); - }//--End_if( hitTool ) - }//--End_if( hitOverlayID == selectionBox ) + print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool( " + activeTool.mode + " ) missing onBegin"); + } + } else { + print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); + }//--End_if( hitTool ) }//--End_If( results.intersects ) if (wantDebug) { From 0b8616950091f35f722cdf7eaa4d687f5a434e17 Mon Sep 17 00:00:00 2001 From: Leander Hasty <1p-cusack@1stplayable.com> Date: Thu, 10 Aug 2017 15:20:58 -0400 Subject: [PATCH 22/79] [Case 6491] remove rotateOverlayTarget. It is no longer used. Reviewed-by: LaShonda Hopper --- .../system/libraries/entitySelectionTool.js | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 9fd5bfcdee..0501b2842e 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -288,7 +288,6 @@ SelectionDisplay = (function() { }; var handleHoverAlpha = 1.0; - var rotateOverlayTargetSize = 10000; // really big target var innerSnapAngle = 22.5; // the angle which we snap to on the inner rotation tool var innerRadius; var outerRadius; @@ -805,24 +804,6 @@ SelectionDisplay = (function() { }); - var rotateOverlayTarget = Overlays.addOverlay("circle3d", { - position: { - x: 0, - y: 0, - z: 0 - }, - size: rotateOverlayTargetSize, - color: { - red: 0, - green: 0, - blue: 0 - }, - alpha: 0.0, - solid: true, - visible: false, - rotation: yawOverlayRotation, - }); - var rotateOverlayInner = Overlays.addOverlay("circle3d", { position: { x: 0, @@ -979,7 +960,6 @@ SelectionDisplay = (function() { yawHandle, pitchHandle, rollHandle, - rotateOverlayTarget, rotateOverlayInner, rotateOverlayOuter, rotateOverlayCurrent, @@ -1034,7 +1014,6 @@ SelectionDisplay = (function() { overlayNames[pitchHandle] = "pitchHandle"; overlayNames[rollHandle] = "rollHandle"; - overlayNames[rotateOverlayTarget] = "rotateOverlayTarget"; overlayNames[rotateOverlayInner] = "rotateOverlayInner"; overlayNames[rotateOverlayOuter] = "rotateOverlayOuter"; overlayNames[rotateOverlayCurrent] = "rotateOverlayCurrent"; @@ -1472,9 +1451,6 @@ SelectionDisplay = (function() { translateHandlesVisible = false; } - Overlays.editOverlay(rotateOverlayTarget, { - visible: rotationOverlaysVisible - }); Overlays.editOverlay(rotateZeroOverlay, { visible: rotationOverlaysVisible }); @@ -3656,12 +3632,6 @@ SelectionDisplay = (function() { innerRadius: 0.9, }); - Overlays.editOverlay(rotateOverlayTarget, { - visible: true, - rotation: handleRotation, - position: rotCenter - }); - Overlays.editOverlay(rotationDegreesDisplay, { visible: true, }); @@ -4186,9 +4156,6 @@ SelectionDisplay = (function() { if(wantDebug){ print(" Triggering hide of RotateOverlays"); } - Overlays.editOverlay(rotateOverlayTarget, { - visible: false - }); Overlays.editOverlay(rotateOverlayInner, { visible: false }); From 45c4a1081b8c8fdaf8a0b4fd1a3913058db37ce4 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Fri, 11 Aug 2017 11:27:32 -0400 Subject: [PATCH 23/79] [Case 6491] entityToolSelection logging/print review (details below). * Added some wantDebug guards to print sections without them. * Normalized error logging statements to have script name and/or specific script function where reasonable. * All error statements contain at least the script name and a descriptive snippet of the error or clue to resolve it. * Removed some stale todos. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 105 ++++++++++++------ 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 0501b2842e..d1f480e55a 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -45,11 +45,12 @@ SelectionManager = (function() { return; } + var wantDebug = false; var messageParsed; try { messageParsed = JSON.parse(message); } catch (err) { - print("error -- entitySelectionTool got malformed message: " + message); + print("ERROR: entitySelectionTool.handleEntitySelectionToolUpdates - got malformed message: " + message); } // if (message === 'callUpdate') { @@ -57,7 +58,9 @@ SelectionManager = (function() { // } if (messageParsed.method === "selectEntity") { - print("setting selection to " + messageParsed.entityID); + if (wantDebug) { + print("setting selection to " + messageParsed.entityID); + } that.setSelections([messageParsed.entityID]); } } @@ -225,7 +228,7 @@ SelectionManager = (function() { try { listeners[j](selectionUpdated === true); } catch (e) { - print("EntitySelectionTool got exception: " + JSON.stringify(e)); + print("ERROR: entitySelectionTool.update got exception: " + JSON.stringify(e)); } } }; @@ -1477,29 +1480,46 @@ SelectionDisplay = (function() { // FUNCTION: SET SPACE MODE that.setSpaceMode = function(newSpaceMode) { - print("======> SetSpaceMode called. ========"); + var wantDebug = false; + if (wantDebug) { + print("======> SetSpaceMode called. ========"); + } + if (spaceMode != newSpaceMode) { - print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode); + if (wantDebug){ + print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode); + } spaceMode = newSpaceMode; that.updateHandles(); - } else { - print(" Can't update SpaceMode. CurrentMode: " + spaceMode + " DesiredMode: " + newSpaceMode); + } else if(wantDebug){ + print("WARNING: entitySelectionTool.setSpaceMode - Can't update SpaceMode. CurrentMode: " + spaceMode + " DesiredMode: " + newSpaceMode); + } + if(wantDebug) { + print("====== SetSpaceMode called. <========"); } - print("====== SetSpaceMode called. <========"); }; // FUNCTION: TOGGLE SPACE MODE that.toggleSpaceMode = function() { - print("========> ToggleSpaceMode called. ========="); + var wantDebug = false; + if (wantDebug){ + print("========> ToggleSpaceMode called. ========="); + } if (spaceMode == SPACE_WORLD && SelectionManager.selections.length > 1) { - print("Local space editing is not available with multiple selections"); + if (wantDebug){ + print("Local space editing is not available with multiple selections"); + } return; } - print( "PreToggle: " + spaceMode); + if(wantDebug) { + print( "PreToggle: " + spaceMode); + } spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; - print( "PostToggle: " + spaceMode); that.updateHandles(); - print("======== ToggleSpaceMode called. <========="); + if (wantDebug){ + print( "PostToggle: " + spaceMode); + print("======== ToggleSpaceMode called. <========="); + } }; // FUNCTION: UNSELECT ALL @@ -1508,9 +1528,12 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLES that.updateHandles = function() { - print( "======> Update Handles =======" ); - print( " Selections Count: " + SelectionManager.selections.length ); - print( " SpaceMode: " + spaceMode ); + var wantDebug = false; + if(wantDebug){ + print( "======> Update Handles =======" ); + print( " Selections Count: " + SelectionManager.selections.length ); + print( " SpaceMode: " + spaceMode ); + } if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); return; @@ -2252,7 +2275,9 @@ SelectionDisplay = (function() { rotation: Quat.fromPitchYawRollDegrees(90, 0, 0), }); - print( "====== Update Handles <=======" ); + if(wantDebug){ + print( "====== Update Handles <=======" ); + } }; @@ -2527,7 +2552,7 @@ SelectionDisplay = (function() { mode: "TRANSLATE_UP_DOWN", onBegin: function(event, pickRay, pickResult) { upDownPickNormal = Quat.getForward(lastCameraOrientation); - // Remove y component so the y-axis lies along the plane we picking on - this will + // Remove y component so the y-axis lies along the plane we're picking on - this will // give movements that follow the mouse. upDownPickNormal.y = 0; lastXYPick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal); @@ -3061,7 +3086,10 @@ SelectionDisplay = (function() { // FUNCTION: CUTOFF STRETCH FUNC function cutoffStretchFunc(vector, change) { vector = change; - Vec3.print("Radius stretch: ", vector); + var wantDebug = false; + if (wantDebug){ + Vec3.print("Radius stretch: ", vector); + } var length = vector.x + vector.y + vector.z; var props = selectionManager.savedProperties[selectionManager.selections[0]]; @@ -3515,21 +3543,27 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE ROTATION DEGREES OVERLAY function updateRotationDegreesOverlay(angleFromZero, handleRotation, centerPosition) { - print( "---> updateRotationDegreesOverlay ---" ); - print(" AngleFromZero: " + angleFromZero ); - print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z ); - print(" CenterPos - " + centerPosition.x + " Y: " + centerPosition.y + " Z: " + centerPosition.z ); + var wantDebug = false; + if(wantDebug){ + print( "---> updateRotationDegreesOverlay ---" ); + print(" AngleFromZero: " + angleFromZero ); + print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z ); + print(" CenterPos - " + centerPosition.x + " Y: " + centerPosition.y + " Z: " + centerPosition.z ); + } + var angle = angleFromZero * (Math.PI / 180); var position = { x: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, y: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, z: 0, }; - print(" Angle: " + angle ); - print(" InitialPos: " + position.x + ", " + position.y + ", " + position.z); + if(wantDebug){ + print(" Angle: " + angle ); + print(" InitialPos: " + position.x + ", " + position.y + ", " + position.z); + } + position = Vec3.multiplyQbyV(handleRotation, position); position = Vec3.sum(centerPosition, position); - print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); var overlayProps = { position: position, dimensions: { @@ -3539,18 +3573,24 @@ SelectionDisplay = (function() { lineHeight: innerRadius * ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER, text: normalizeDegrees(angleFromZero) + "°", }; - print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z ); - print(" OverlayLineHeight: " + overlayProps.lineHeight ); - print(" OverlayText: " + overlayProps.text ); + if(wantDebug){ + print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); + print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z ); + print(" OverlayLineHeight: " + overlayProps.lineHeight ); + print(" OverlayText: " + overlayProps.text ); + } + Overlays.editOverlay(rotationDegreesDisplay, overlayProps); - print( "<--- updateRotationDegreesOverlay ---" ); + if (wantDebug){ + print( "<--- updateRotationDegreesOverlay ---" ); + } } // FUNCTION DEF: updateSelectionsRotation // Helper func used by rotation grabber tools function updateSelectionsRotation( rotationChange ) { if ( ! rotationChange ) { - print("ERROR( updateSelectionsRotation ) - Invalid arg specified!!"); + print("ERROR: entitySelectionTool.updateSelectionsRotation - Invalid arg specified!!"); //--EARLY EXIT-- return; @@ -3653,7 +3693,7 @@ SelectionDisplay = (function() { function helperRotationHandleOnMove( event, rotAroundAxis, rotCenter, handleRotation ) { if ( ! rotZero ) { - print("ERROR( handleRotationHandleOnMove ) - Invalid RotationZero Specified (missed rotation target plane?)" ); + print("ERROR: entitySelectionTool.handleRotationHandleOnMove - Invalid RotationZero Specified (missed rotation target plane?)" ); //--EARLY EXIT-- return; @@ -3919,7 +3959,6 @@ SelectionDisplay = (function() { } entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); - //TODO_Case6491: Merge if..else( selectionBox ) when onBegin of transXZ is normalized. var hitTool = grabberTools[ hitOverlayID ]; if ( hitTool ) { From c286ee95a47f3a468c5f6f5783eb010a42439032 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Fri, 11 Aug 2017 14:26:33 -0400 Subject: [PATCH 24/79] [Case 6491] Zero state improvements (details below). Fixes issue where when translating the selected object(s), user view was obstructed by grabber handles. This also brings more consistency to the selection ui state between rotation and translation user interactions. Both types of interactions feel nicer with the selection ui as concise as possible during the action, limited only to that useful for the current interaction. Expected Behavior: Note the following presumes you're in creation mode. * When the selection is clicked, the rotation, stretch, clone, and translateY handles should turn invisible. * When moving a selection along either the x or z axis, the rotation, stretch, clone, and translateY handles should be invisible and remain that way until the user releases the selection. * When the selection is released, the rotation, stretch, clone, and translateY handles should become visible. * When the translateY handle is clicked, the rotation, stretch, and clone handles should turn invisible. The translateY handle should remain visible. * When moving the selection along the y axis, the rotation, stretch, and clone handles should be invisible and remain that way until the user releases the selection. The translateY handle should be visible during the entire interaction. * When the selection is released, the rotation, stretch, clone should become visible. The translateY handle, visible the entire time, should already be visible. * When the user click somewhere other than a selection, entity object, creation menu or tools, then any current selection should be unselected and all creation ui local to it should turn invisible. * When the user exits creation mode, any current selection should be unselected and all creation ui local to it should turn invisible. TODO: * We may want to visit the scaling interaction ui as well; however, that could be a later task as it's tangential. The changes here are a good first step. * The idea with that interaction is perhaps only showing the handle for the current scaling operation. Currently when scaling all of the other handles remain visible, though their appearance does update. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 225 ++++++------------ 1 file changed, 73 insertions(+), 152 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index d1f480e55a..b1a42bf1ab 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -580,6 +580,12 @@ SelectionDisplay = (function() { var grabberSpotLightT = Overlays.addOverlay("cube", grabberPropertiesEdge); var grabberSpotLightB = Overlays.addOverlay("cube", grabberPropertiesEdge); + var spotLightGrabberHandles = [ + grabberSpotLightCircle, grabberSpotLightCenter, grabberSpotLightRadius, + grabberSpotLightLineT, grabberSpotLightLineB, grabberSpotLightLineL, grabberSpotLightLineR, + grabberSpotLightT, grabberSpotLightB, grabberSpotLightL, grabberSpotLightR + ]; + var grabberPointLightCircleX = Overlays.addOverlay("circle3d", { rotation: Quat.fromPitchYawRollDegrees(0, 90, 0), color: lightOverlayColor, @@ -605,6 +611,12 @@ SelectionDisplay = (function() { var grabberPointLightF = Overlays.addOverlay("cube", grabberPropertiesEdge); var grabberPointLightN = Overlays.addOverlay("cube", grabberPropertiesEdge); + var pointLightGrabberHandles = [ + grabberPointLightCircleX, grabberPointLightCircleY, grabberPointLightCircleZ, + grabberPointLightT, grabberPointLightB, grabberPointLightL, + grabberPointLightR, grabberPointLightF, grabberPointLightN, + ]; + var grabberCloner = Overlays.addOverlay("cube", grabberPropertiesCloner); var stretchHandles = [ @@ -1432,10 +1444,12 @@ SelectionDisplay = (function() { var rotateHandlesVisible = true; var rotationOverlaysVisible = false; - var translateHandlesVisible = true; - var selectionBoxVisible = true; + //note: Commented out as these are currently unused here; however, + // leaving them around as they document intent of state as it + // relates to modes that may be useful later. + //var translateHandlesVisible = true; + //var selectionBoxVisible = true; var isPointLight = false; - if (selectionManager.selections.length == 1) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); isPointLight = properties.type == "Light" && !properties.isSpotlight; @@ -1444,14 +1458,14 @@ SelectionDisplay = (function() { if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_XZ") { rotationOverlaysVisible = true; rotateHandlesVisible = false; - translateHandlesVisible = false; - selectionBoxVisible = false; + //translateHandlesVisible = false; + //selectionBoxVisible = false; } else if (mode == "TRANSLATE_UP_DOWN" || isPointLight) { rotateHandlesVisible = false; } else if (mode != "UNKNOWN") { // every other mode is a stretch mode... rotateHandlesVisible = false; - translateHandlesVisible = false; + //translateHandlesVisible = false; } Overlays.editOverlay(rotateZeroOverlay, { @@ -1533,6 +1547,7 @@ SelectionDisplay = (function() { print( "======> Update Handles =======" ); print( " Selections Count: " + SelectionManager.selections.length ); print( " SpaceMode: " + spaceMode ); + print( " DisplayMode: " + mode ); } if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); @@ -1768,22 +1783,28 @@ SelectionDisplay = (function() { EdgeFL = Vec3.sum(position, EdgeFL); var inModeRotate = (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL"); - var stretchHandlesVisible = !inModeRotate && (spaceMode == SPACE_LOCAL); + var inModeTranslate = (mode == "TRANSLATE_XZ" || mode == "CLONE" || mode == "TRANSLATE_UP_DOWN"); + var stretchHandlesVisible = !(inModeRotate || inModeTranslate) && (spaceMode == SPACE_LOCAL); var extendedStretchHandlesVisible = (stretchHandlesVisible && showExtendedStretchHandles); - var cloneHandleVisible = !inModeRotate; - //print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); + var cloneHandleVisible = !(inModeRotate || inModeTranslate); + if(wantDebug){ + print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); + } var isSingleSelection = (selectionManager.selections.length == 1); if (isSingleSelection) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); var isLightSelection = (properties.type == "Light"); if ( isLightSelection ) { - //print(" Light Selection revoking Non-Light Grabbers Visibility!"); + if(wantDebug){ + print(" Light Selection revoking Non-Light Grabbers Visibility!"); + } stretchHandlesVisible = false; extendedStretchHandlesVisible = false; cloneHandleVisible = false; if(properties.isSpotlight) { - //print(" Trying to show all SpotLight related grabbers"); + that.setPointLightHandlesVisible( false ); + Overlays.editOverlay(grabberSpotLightCenter, { position: position, visible: false, @@ -1848,36 +1869,9 @@ SelectionDisplay = (function() { visible: true, }); - //print(" Trying to hide all PointLight related grabbers"); - Overlays.editOverlay(grabberPointLightCircleX, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleY, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleZ, { - visible: false - }); - Overlays.editOverlay(grabberPointLightT, { - visible: false - }); - Overlays.editOverlay(grabberPointLightB, { - visible: false - }); - Overlays.editOverlay(grabberPointLightL, { - visible: false - }); - Overlays.editOverlay(grabberPointLightR, { - visible: false - }); - Overlays.editOverlay(grabberPointLightF, { - visible: false - }); - Overlays.editOverlay(grabberPointLightN, { - visible: false - }); } else { //..it's a PointLight - //print(" Trying to show all PointLight related grabbers"); + that.setSpotLightHandlesVisible( false ); + Overlays.editOverlay(grabberPointLightT, { position: TOP, rotation: rotation, @@ -1938,102 +1932,10 @@ SelectionDisplay = (function() { }, visible: true, }); - - //print(" Trying to hide all SpotLight related grabbers"); - Overlays.editOverlay(grabberSpotLightRadius, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightB, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightCircle, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineB, { - visible: false - }); } } else { //..it's not a light at all - //print(" Trying to hide all Light related grabbers"); - Overlays.editOverlay(grabberSpotLightCenter, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightRadius, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightB, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightCircle, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineL, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineR, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineT, { - visible: false - }); - Overlays.editOverlay(grabberSpotLightLineB, { - visible: false - }); - - Overlays.editOverlay(grabberPointLightCircleX, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleY, { - visible: false - }); - Overlays.editOverlay(grabberPointLightCircleZ, { - visible: false - }); - Overlays.editOverlay(grabberPointLightT, { - visible: false - }); - Overlays.editOverlay(grabberPointLightB, { - visible: false - }); - Overlays.editOverlay(grabberPointLightL, { - visible: false - }); - Overlays.editOverlay(grabberPointLightR, { - visible: false - }); - Overlays.editOverlay(grabberPointLightF, { - visible: false - }); - Overlays.editOverlay(grabberPointLightN, { - visible: false - }); + that.setSpotLightHandlesVisible( false ); + that.setPointLightHandlesVisible( false ); } }//--end of isSingleSelection @@ -2281,20 +2183,18 @@ SelectionDisplay = (function() { }; + function helperSetOverlaysVisibility( handleArray, isVisible ){ + var numHandles = handleArray.length; + var visibilityUpdate = { visible: isVisible }; + for (var handleIndex = 0; handleIndex < numHandles; ++handleIndex) { + Overlays.editOverlay(handleArray[ handleIndex ], visibilityUpdate); + } + } + // FUNCTION: SET OVERLAYS VISIBLE that.setOverlaysVisible = function(isVisible) { - var length = allOverlays.length; - for (var overlayIndex = 0; overlayIndex < length; overlayIndex++) { - Overlays.editOverlay(allOverlays[overlayIndex], { - visible: isVisible - }); - } - length = selectionBoxes.length; - for (var boxIndex = 0; boxIndex < length; boxIndex++) { - Overlays.editOverlay(selectionBoxes[boxIndex], { - visible: isVisible - }); - } + helperSetOverlaysVisibility( allOverlays, isVisible ); + helperSetOverlaysVisibility( selectionBoxes, isVisible ); }; // FUNCTION: SET ROTATION HANDLES VISIBLE @@ -2307,11 +2207,7 @@ SelectionDisplay = (function() { // FUNCTION: SET STRETCH HANDLES VISIBLE that.setStretchHandlesVisible = function(isVisible) { - var numHandles = stretchHandles.length; - var visibilityUpdate = { visible: isVisible }; - for (var handleIndex = 0; handleIndex < numHandles; ++handleIndex) { - Overlays.editOverlay(stretchHandles[ handleIndex ], visibilityUpdate); - } + helperSetOverlaysVisibility( stretchHandles, isVisible ); }; // FUNCTION: SET GRABBER MOVE UP VISIBLE @@ -2319,6 +2215,29 @@ SelectionDisplay = (function() { Overlays.editOverlay(grabberMoveUp, { visible: isVisible }); }; + // FUNCTION: SET GRABBER TOOLS UP VISIBLE + that.setGrabberToolsVisible = function(isVisible) { + var visibilityUpdate = { visible: isVisible }; + for ( var toolKey in grabberTools ) { + if ( ! grabberTools.hasOwnProperty( toolKey ) ){ + //--EARLY ITERATION EXIT--( On to the next one ) + continue; + } + + Overlays.editOverlay( toolKey, visibilityUpdate ); + } + }; + + // FUNCTION: SET POINT LIGHT HANDLES VISIBLE + that.setPointLightHandlesVisible = function(isVisible) { + helperSetOverlaysVisibility( pointLightGrabberHandles, isVisible ); + }; + + // FUNCTION: SET SPOT LIGHT HANDLES VISIBLE + that.setSpotLightHandlesVisible = function(isVisible) { + helperSetOverlaysVisibility( spotLightGrabberHandles, isVisible ); + }; + // FUNCTION: UNSELECT // TODO?: Needs implementation that.unselect = function(entityID) {}; @@ -2347,6 +2266,7 @@ SelectionDisplay = (function() { SelectionManager.saveProperties(); that.setRotationHandlesVisible( false ); + that.setStretchHandlesVisible( false ); that.setGrabberMoveUpVisible( false ); startPosition = SelectionManager.worldPosition; @@ -2559,6 +2479,7 @@ SelectionDisplay = (function() { SelectionManager.saveProperties(); that.setGrabberMoveUpVisible( true ); + that.setStretchHandlesVisible( false ); that.setRotationHandlesVisible( false ); // Duplicate entities if alt is pressed. This will make a @@ -3980,7 +3901,7 @@ SelectionDisplay = (function() { } // If mode is known then we successfully handled this; - // otherwise, we're missing a tool or a tool.onBegin. + // otherwise, we're missing a tool. return (mode != "UNKNOWN"); }; From 9279290b2ea6f74c11815efa4eb19941a16e2905 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Fri, 11 Aug 2017 15:10:25 -0400 Subject: [PATCH 25/79] [Case 6491] Remove dupe pickRay var (details below). Ran lint pass and found the dupe define. As noted in a previous commit, the only remaining lint issues are as follows: * scripts/system/libraries/entitySelectionTool.js: line 17, col 1, Read only. * HIFI_PUBLIC_BUCKET assignment * scripts/system/libraries/entitySelectionTool.js: line 19, col 1, Read only. * SPACE_WORLD assignment * scripts/system/libraries/entitySelectionTool.js: line 30, col 1, Read only. * SelectionManager assignment Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b1a42bf1ab..259ac6bd80 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2770,7 +2770,6 @@ SelectionDisplay = (function() { } planeNormal = Vec3.multiplyQbyV(rotation, planeNormal); - var pickRay = generalComputePickRay(event.x, event.y); lastPick = rayPlaneIntersection(pickRay, pickRayPosition, planeNormal); From 3a174780c2b3809e3112551d320de94efafb2798 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Fri, 11 Aug 2017 15:23:43 -0400 Subject: [PATCH 26/79] [Case 6491] Minor: Move that.updateHandleSizes up (details below). It was down below the amidst the mouse event handlers. This just moves it up with the other that.update handle functions definitions. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 259ac6bd80..ccc2e0f47d 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1492,6 +1492,45 @@ SelectionDisplay = (function() { }); }; + // FUNCTION: UPDATE HANDLE SIZES + that.updateHandleSizes = function() { + if (selectionManager.hasSelection()) { + var diff = Vec3.subtract(selectionManager.worldPosition, Camera.getPosition()); + var grabberSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 5; + var dimensions = SelectionManager.worldDimensions; + var avgDimension = (dimensions.x + dimensions.y + dimensions.z) / 3; + grabberSize = Math.min(grabberSize, avgDimension / 10); + + for (var i = 0; i < stretchHandles.length; i++) { + Overlays.editOverlay(stretchHandles[i], { + size: grabberSize, + }); + } + var handleSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 7; + handleSize = Math.min(handleSize, avgDimension / 3); + + Overlays.editOverlay(yawHandle, { + scale: handleSize, + }); + Overlays.editOverlay(pitchHandle, { + scale: handleSize, + }); + Overlays.editOverlay(rollHandle, { + scale: handleSize, + }); + var pos = Vec3.sum(grabberMoveUpPosition, { + x: 0, + y: Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3, + z: 0 + }); + Overlays.editOverlay(grabberMoveUp, { + position: pos, + scale: handleSize / 1.25, + }); + } + }; + Script.update.connect(that.updateHandleSizes); + // FUNCTION: SET SPACE MODE that.setSpaceMode = function(newSpaceMode) { var wantDebug = false; @@ -4053,45 +4092,6 @@ SelectionDisplay = (function() { return false; }; - // FUNCTION: UPDATE HANDLE SIZES - that.updateHandleSizes = function() { - if (selectionManager.hasSelection()) { - var diff = Vec3.subtract(selectionManager.worldPosition, Camera.getPosition()); - var grabberSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 5; - var dimensions = SelectionManager.worldDimensions; - var avgDimension = (dimensions.x + dimensions.y + dimensions.z) / 3; - grabberSize = Math.min(grabberSize, avgDimension / 10); - - for (var i = 0; i < stretchHandles.length; i++) { - Overlays.editOverlay(stretchHandles[i], { - size: grabberSize, - }); - } - var handleSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 7; - handleSize = Math.min(handleSize, avgDimension / 3); - - Overlays.editOverlay(yawHandle, { - scale: handleSize, - }); - Overlays.editOverlay(pitchHandle, { - scale: handleSize, - }); - Overlays.editOverlay(rollHandle, { - scale: handleSize, - }); - var pos = Vec3.sum(grabberMoveUpPosition, { - x: 0, - y: Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3, - z: 0 - }); - Overlays.editOverlay(grabberMoveUp, { - position: pos, - scale: handleSize / 1.25, - }); - } - }; - Script.update.connect(that.updateHandleSizes); - // FUNCTION: MOUSE RELEASE EVENT that.mouseReleaseEvent = function(event) { var wantDebug = false; From 9fb76340c70f52d4e1af2116abd73e25d69a6232 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Fri, 11 Aug 2017 19:17:00 -0400 Subject: [PATCH 27/79] [Case 6491] removes SelectionDisplay.mode (details below). This var isn't needed as the var essentially piggy backed off of activeTool and activeTool.mode. This also helps guard against the _majority_ of situations where mode check fails due to typo inserted when composing the check. Most instances of manual string checks have been replaced by querying activeTool via new isActiveTool function. For instances that still require a direct mode check getMode will return the mode string associated with the current activeTool. TODO: Get this code reviewed. --- .../system/libraries/entitySelectionTool.js | 74 +++++++++++++------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index ccc2e0f47d..ec004c9ca4 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -275,7 +275,6 @@ SelectionDisplay = (function() { var showExtendedStretchHandles = false; var spaceMode = SPACE_LOCAL; - var mode = "UNKNOWN"; var overlayNames = []; var lastCameraPosition = Camera.getPosition(); var lastCameraOrientation = Camera.getOrientation(); @@ -1088,6 +1087,35 @@ SelectionDisplay = (function() { return tool; } + // toolHandle: The overlayID associated with the tool + // that correlates to the tool you wish to query. + // @return: bool - Indicates if the activeTool is that queried. + function isActiveTool(toolHandle) { + var wantDebug = true; + if ( ! activeTool || ! toolHandle ){ + if(wantDebug){ + if ( activeTool ){ + print("WARNING: entitySelectionTool.isActiveTool - Encountered invalid toolHandle: " + toolHandle ); + } + } + return false; + } + if ( ! grabberTools.hasOwnProperty( toolHandle ) ) { + if(wantDebug){ + print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle ); + } + return false; + } + + return (activeTool === grabberTools[ toolHandle ]); + } + + // @return string - The mode of the currently active tool; + // otherwise, "UNKNOWN" if there's no active tool. + function getMode() { + return (activeTool ? activeTool.mode : "UNKNOWN"); + } + that.cleanup = function() { for (var i = 0; i < allOverlays.length; i++) { @@ -1455,14 +1483,15 @@ SelectionDisplay = (function() { isPointLight = properties.type == "Light" && !properties.isSpotlight; } - if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_XZ") { + if ( isActiveTool(yawHandle) || isActiveTool(pitchHandle) || + isActiveTool(rollHandle) || isActiveTool(selectionBox) || isActiveTool(grabberCloner)) { rotationOverlaysVisible = true; rotateHandlesVisible = false; //translateHandlesVisible = false; //selectionBoxVisible = false; - } else if (mode == "TRANSLATE_UP_DOWN" || isPointLight) { + } else if ( isActiveTool(grabberMoveUp) || isPointLight) { rotateHandlesVisible = false; - } else if (mode != "UNKNOWN") { + } else if ( activeTool ) { // every other mode is a stretch mode... rotateHandlesVisible = false; //translateHandlesVisible = false; @@ -1581,12 +1610,12 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLES that.updateHandles = function() { - var wantDebug = false; + var wantDebug = true; if(wantDebug){ print( "======> Update Handles =======" ); print( " Selections Count: " + SelectionManager.selections.length ); print( " SpaceMode: " + spaceMode ); - print( " DisplayMode: " + mode ); + print( " DisplayMode: " + getMode() ); } if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); @@ -1821,8 +1850,8 @@ SelectionDisplay = (function() { EdgeFR = Vec3.sum(position, EdgeFR); EdgeFL = Vec3.sum(position, EdgeFL); - var inModeRotate = (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL"); - var inModeTranslate = (mode == "TRANSLATE_XZ" || mode == "CLONE" || mode == "TRANSLATE_UP_DOWN"); + var inModeRotate = (isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)); + var inModeTranslate = (isActiveTool(selectionBox) || isActiveTool(grabberCloner) || isActiveTool(grabberMoveUp)); var stretchHandlesVisible = !(inModeRotate || inModeTranslate) && (spaceMode == SPACE_LOCAL); var extendedStretchHandlesVisible = (stretchHandlesVisible && showExtendedStretchHandles); var cloneHandleVisible = !(inModeRotate || inModeTranslate); @@ -2198,7 +2227,7 @@ SelectionDisplay = (function() { z: position.z }; Overlays.editOverlay(grabberMoveUp, { - visible: (activeTool === null) || (mode == "TRANSLATE_UP_DOWN") + visible: ( ! activeTool ) || isActiveTool(grabberMoveUp) }); Overlays.editOverlay(baseOfEntityProjectionOverlay, { @@ -2309,7 +2338,6 @@ SelectionDisplay = (function() { that.setGrabberMoveUpVisible( false ); startPosition = SelectionManager.worldPosition; - mode = translateXZTool.mode; // Note this overrides mode = "CLONE" translateXZTool.pickPlanePosition = pickResult.intersection; translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); @@ -2843,7 +2871,7 @@ SelectionDisplay = (function() { }; var onMove = function(event) { - var proportional = spaceMode == SPACE_WORLD || event.isShifted || activeTool.mode == "STRETCH_RADIUS"; + var proportional = spaceMode == SPACE_WORLD || event.isShifted || isActiveTool(grabberSpotLightRadius); var position, dimensions, rotation; if (spaceMode == SPACE_LOCAL) { @@ -3580,7 +3608,7 @@ SelectionDisplay = (function() { function helperRotationHandleOnBegin( event, pickRay, rotAroundAxis, rotCenter, handleRotation ) { var wantDebug = false; if (wantDebug) { - print("================== " + mode + "(rotation helper onBegin) -> ======================="); + print("================== " + getMode() + "(rotation helper onBegin) -> ======================="); } SelectionManager.saveProperties(); @@ -3645,7 +3673,7 @@ SelectionDisplay = (function() { rotZero = result; if (wantDebug) { - print("================== " + mode + "(rotation helper onBegin) <- ======================="); + print("================== " + getMode() + "(rotation helper onBegin) <- ======================="); } }//--End_Function( helperRotationHandleOnBegin ) @@ -3660,7 +3688,7 @@ SelectionDisplay = (function() { var wantDebug = false; if (wantDebug) { - print("================== "+ mode + "(rotation helper onMove) -> ======================="); + print("================== "+ getMode() + "(rotation helper onMove) -> ======================="); Vec3.print(" rotZero: ", rotZero); } var pickRay = generalComputePickRay(event.x, event.y); @@ -3750,14 +3778,14 @@ SelectionDisplay = (function() { }//--End_If( results.intersects ) if (wantDebug) { - print("================== "+ mode + "(rotation helper onMove) <- ======================="); + print("================== "+ getMode() + "(rotation helper onMove) <- ======================="); } }//--End_Function( helperRotationHandleOnMove ) function helperRotationHandleOnEnd() { var wantDebug = false; if (wantDebug) { - print("================== " + mode + "(onEnd) -> ======================="); + print("================== " + getMode() + "(onEnd) -> ======================="); } Overlays.editOverlay(rotateOverlayInner, { visible: false @@ -3775,7 +3803,7 @@ SelectionDisplay = (function() { pushCommandForSelections(); if (wantDebug) { - print("================== " + mode + "(onEnd) <- ======================="); + print("================== " + getMode() + "(onEnd) <- ======================="); } }//--End_Function( helperRotationHandleOnEnd ) @@ -3907,7 +3935,7 @@ SelectionDisplay = (function() { } // Start with unknown mode, in case no tool can handle this. - mode = "UNKNOWN"; + activeTool = null; var results = testRayIntersect( pickRay, interactiveOverlays ); if ( results.intersects ){ @@ -3922,7 +3950,6 @@ SelectionDisplay = (function() { var hitTool = grabberTools[ hitOverlayID ]; if ( hitTool ) { activeTool = hitTool; - mode = activeTool.mode; if (activeTool.onBegin) { activeTool.onBegin(event, pickRay, results); } else { @@ -3934,13 +3961,13 @@ SelectionDisplay = (function() { }//--End_If( results.intersects ) if (wantDebug) { - print(" SelectionDisplay.mode: " + mode ); + print(" DisplayMode: " + getMode()); print("=============== eST::MousePressEvent END ======================="); } // If mode is known then we successfully handled this; // otherwise, we're missing a tool. - return (mode != "UNKNOWN"); + return activeTool; }; // FUNCTION: MOUSE MOVE EVENT @@ -4111,7 +4138,7 @@ SelectionDisplay = (function() { } // hide our rotation overlays..., and show our handles - if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL") { + if ( isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)) { if(wantDebug){ print(" Triggering hide of RotateOverlays"); } @@ -4127,8 +4154,7 @@ SelectionDisplay = (function() { } - showHandles = (mode != "UNKNOWN");// Date: Wed, 16 Aug 2017 18:15:36 -0400 Subject: [PATCH 28/79] [Case 6491] Fixes consistency issue with lights (details below). Fixes issue with light selection actions having inconsistent ui in comparison to other selections from an earlier commit change. As of this commit: * When translating point lights, the edge grabbers are no longer be visible. * When rotating or translating spot lights, the edge grabbers are no longer visible. Note: * For both point & spot lights, when translating and/or rotating, their circle and/or radial guides should remain visible. This commit shouldn't have any influence on that behavior. Tested: * Rotating and translating spot lights. * Translating point lights. Didn't test rotation as only spot lights support rotation. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index ec004c9ca4..49fa11813a 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1091,7 +1091,7 @@ SelectionDisplay = (function() { // that correlates to the tool you wish to query. // @return: bool - Indicates if the activeTool is that queried. function isActiveTool(toolHandle) { - var wantDebug = true; + var wantDebug = false; if ( ! activeTool || ! toolHandle ){ if(wantDebug){ if ( activeTool ){ @@ -1610,7 +1610,7 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLES that.updateHandles = function() { - var wantDebug = true; + var wantDebug = false; if(wantDebug){ print( "======> Update Handles =======" ); print( " Selections Count: " + SelectionManager.selections.length ); @@ -1873,6 +1873,8 @@ SelectionDisplay = (function() { if(properties.isSpotlight) { that.setPointLightHandlesVisible( false ); + var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); + var showEdgeSpotGrabbers = ! (inModeTranslate || inModeRotate); Overlays.editOverlay(grabberSpotLightCenter, { position: position, visible: false, @@ -1880,29 +1882,28 @@ SelectionDisplay = (function() { Overlays.editOverlay(grabberSpotLightRadius, { position: NEAR, rotation: rotation, - visible: true, + visible: showEdgeSpotGrabbers, }); - var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); Overlays.editOverlay(grabberSpotLightL, { position: EdgeNL, rotation: rotation, - visible: true, + visible: showEdgeSpotGrabbers, }); Overlays.editOverlay(grabberSpotLightR, { position: EdgeNR, rotation: rotation, - visible: true, + visible: showEdgeSpotGrabbers, }); Overlays.editOverlay(grabberSpotLightT, { position: EdgeTN, rotation: rotation, - visible: true, + visible: showEdgeSpotGrabbers, }); Overlays.editOverlay(grabberSpotLightB, { position: EdgeBN, rotation: rotation, - visible: true, + visible: showEdgeSpotGrabbers, }); Overlays.editOverlay(grabberSpotLightCircle, { position: NEAR, @@ -1939,36 +1940,37 @@ SelectionDisplay = (function() { } else { //..it's a PointLight that.setSpotLightHandlesVisible( false ); - + + var showEdgePointGrabbers = ! inModeTranslate; Overlays.editOverlay(grabberPointLightT, { position: TOP, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightB, { position: BOTTOM, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightL, { position: LEFT, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightR, { position: RIGHT, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightF, { position: FAR, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightN, { position: NEAR, rotation: rotation, - visible: true, + visible: showEdgePointGrabbers, }); Overlays.editOverlay(grabberPointLightCircleX, { position: position, From 2bb76a357a81b25e6fa132402c530579fb88c552 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper <1p-cusack@1stplayable.com> Date: Thu, 17 Aug 2017 17:28:12 -0400 Subject: [PATCH 29/79] [Case 6491] Some adjustments to isActiveTool (details below). * isActiveTool now respects null and undefined args. * If null or undefined toolHandle is passed, activeTool is directly tested against those values. Rather than explicitly returning false. * Added some clarification to unknown tool warning message. Reviewed-by: Leander Hasty Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 49fa11813a..9f0d820f69 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1087,23 +1087,23 @@ SelectionDisplay = (function() { return tool; } - // toolHandle: The overlayID associated with the tool - // that correlates to the tool you wish to query. + // @param: toolHandle: The overlayID associated with the tool + // that correlates to the tool you wish to query. + // @note: If toolHandle is null or undefined then activeTool + // will be checked against those values as opposed to + // the tool registered under toolHandle. Null & Undefined + // are treated as separate values. // @return: bool - Indicates if the activeTool is that queried. function isActiveTool(toolHandle) { - var wantDebug = false; - if ( ! activeTool || ! toolHandle ){ - if(wantDebug){ - if ( activeTool ){ - print("WARNING: entitySelectionTool.isActiveTool - Encountered invalid toolHandle: " + toolHandle ); - } - } - return false; + if ( ! toolHandle ) { + // Allow isActiveTool( null ) and similar to return true if there's + // no active tool + return ( activeTool === toolHandle ); } + if ( ! grabberTools.hasOwnProperty( toolHandle ) ) { - if(wantDebug){ - print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle ); - } + print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle + ". Tools should be egistered via addGrabberTool." ); + //--EARLY EXIT-- return false; } From 0deabf54ef98c2019d9114897804539be6f332d1 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 8 Sep 2017 16:31:59 -0400 Subject: [PATCH 30/79] [Case 6491] Minor: fixes some coding standard spacing with wantDebug statements. --- .../system/libraries/entitySelectionTool.js | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 9f0d820f69..6c5e3b0522 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1568,15 +1568,15 @@ SelectionDisplay = (function() { } if (spaceMode != newSpaceMode) { - if (wantDebug){ + if (wantDebug) { print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode); } spaceMode = newSpaceMode; that.updateHandles(); - } else if(wantDebug){ + } else if (wantDebug) { print("WARNING: entitySelectionTool.setSpaceMode - Can't update SpaceMode. CurrentMode: " + spaceMode + " DesiredMode: " + newSpaceMode); } - if(wantDebug) { + if (wantDebug) { print("====== SetSpaceMode called. <========"); } }; @@ -1584,21 +1584,21 @@ SelectionDisplay = (function() { // FUNCTION: TOGGLE SPACE MODE that.toggleSpaceMode = function() { var wantDebug = false; - if (wantDebug){ + if (wantDebug) { print("========> ToggleSpaceMode called. ========="); } if (spaceMode == SPACE_WORLD && SelectionManager.selections.length > 1) { - if (wantDebug){ + if (wantDebug) { print("Local space editing is not available with multiple selections"); } return; } - if(wantDebug) { + if (wantDebug) { print( "PreToggle: " + spaceMode); } spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; that.updateHandles(); - if (wantDebug){ + if (wantDebug) { print( "PostToggle: " + spaceMode); print("======== ToggleSpaceMode called. <========="); } @@ -1611,7 +1611,7 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLES that.updateHandles = function() { var wantDebug = false; - if(wantDebug){ + if (wantDebug) { print( "======> Update Handles =======" ); print( " Selections Count: " + SelectionManager.selections.length ); print( " SpaceMode: " + spaceMode ); @@ -1855,7 +1855,7 @@ SelectionDisplay = (function() { var stretchHandlesVisible = !(inModeRotate || inModeTranslate) && (spaceMode == SPACE_LOCAL); var extendedStretchHandlesVisible = (stretchHandlesVisible && showExtendedStretchHandles); var cloneHandleVisible = !(inModeRotate || inModeTranslate); - if(wantDebug){ + if (wantDebug) { print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); } var isSingleSelection = (selectionManager.selections.length == 1); @@ -1864,13 +1864,13 @@ SelectionDisplay = (function() { var properties = Entities.getEntityProperties(selectionManager.selections[0]); var isLightSelection = (properties.type == "Light"); if ( isLightSelection ) { - if(wantDebug){ + if (wantDebug) { print(" Light Selection revoking Non-Light Grabbers Visibility!"); } stretchHandlesVisible = false; extendedStretchHandlesVisible = false; cloneHandleVisible = false; - if(properties.isSpotlight) { + if (properties.isSpotlight) { that.setPointLightHandlesVisible( false ); var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); @@ -2247,13 +2247,13 @@ SelectionDisplay = (function() { rotation: Quat.fromPitchYawRollDegrees(90, 0, 0), }); - if(wantDebug){ + if (wantDebug) { print( "====== Update Handles <=======" ); } }; - function helperSetOverlaysVisibility( handleArray, isVisible ){ + function helperSetOverlaysVisibility( handleArray, isVisible ) { var numHandles = handleArray.length; var visibilityUpdate = { visible: isVisible }; for (var handleIndex = 0; handleIndex < numHandles; ++handleIndex) { @@ -2289,7 +2289,7 @@ SelectionDisplay = (function() { that.setGrabberToolsVisible = function(isVisible) { var visibilityUpdate = { visible: isVisible }; for ( var toolKey in grabberTools ) { - if ( ! grabberTools.hasOwnProperty( toolKey ) ){ + if ( ! grabberTools.hasOwnProperty( toolKey ) ) { //--EARLY ITERATION EXIT--( On to the next one ) continue; } @@ -2327,7 +2327,7 @@ SelectionDisplay = (function() { startingElevation: 0.0, onBegin: function(event, pickRay, pickResult, doClone) { var wantDebug = false; - if(wantDebug){ + if (wantDebug) { print("================== TRANSLATE_XZ(Beg) -> ======================="); Vec3.print(" pickRay", pickRay); Vec3.print(" pickRay.origin", pickRay.origin); @@ -2377,7 +2377,7 @@ SelectionDisplay = (function() { } isConstrained = false; - if(wantDebug){ + if (wantDebug) { print("================== TRANSLATE_XZ(End) <- ======================="); } }, @@ -3076,7 +3076,7 @@ SelectionDisplay = (function() { function cutoffStretchFunc(vector, change) { vector = change; var wantDebug = false; - if (wantDebug){ + if (wantDebug) { Vec3.print("Radius stretch: ", vector); } var length = vector.x + vector.y + vector.z; @@ -3533,7 +3533,7 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE ROTATION DEGREES OVERLAY function updateRotationDegreesOverlay(angleFromZero, handleRotation, centerPosition) { var wantDebug = false; - if(wantDebug){ + if (wantDebug) { print( "---> updateRotationDegreesOverlay ---" ); print(" AngleFromZero: " + angleFromZero ); print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z ); @@ -3546,7 +3546,7 @@ SelectionDisplay = (function() { y: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, z: 0, }; - if(wantDebug){ + if (wantDebug) { print(" Angle: " + angle ); print(" InitialPos: " + position.x + ", " + position.y + ", " + position.z); } @@ -3562,7 +3562,7 @@ SelectionDisplay = (function() { lineHeight: innerRadius * ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER, text: normalizeDegrees(angleFromZero) + "°", }; - if(wantDebug){ + if (wantDebug) { print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z ); print(" OverlayLineHeight: " + overlayProps.lineHeight ); @@ -3570,7 +3570,7 @@ SelectionDisplay = (function() { } Overlays.editOverlay(rotationDegreesDisplay, overlayProps); - if (wantDebug){ + if (wantDebug) { print( "<--- updateRotationDegreesOverlay ---" ); } } @@ -3899,10 +3899,10 @@ SelectionDisplay = (function() { var intersectObj = Overlays.findRayIntersection(queryRay, true, overlayIncludes, overlayExcludes); if (wantDebug) { - if ( ! overlayIncludes ){ + if ( ! overlayIncludes ) { print("testRayIntersect - no overlayIncludes provided."); } - if ( ! overlayExcludes ){ + if ( ! overlayExcludes ) { print("testRayIntersect - no overlayExcludes provided."); } print("testRayIntersect - Hit: " + intersectObj.intersects); @@ -3940,7 +3940,7 @@ SelectionDisplay = (function() { activeTool = null; var results = testRayIntersect( pickRay, interactiveOverlays ); - if ( results.intersects ){ + if ( results.intersects ) { var hitOverlayID = results.overlayID; if ( (hitOverlayID == HMD.tabletID) || (hitOverlayID == HMD.tabletScreenID) || (hitOverlayID == HMD.homeButtonID) ) { //--EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) @@ -3959,7 +3959,7 @@ SelectionDisplay = (function() { } } else { print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); - }//--End_if( hitTool ) + }//--End_if ( hitTool ) }//--End_If( results.intersects ) if (wantDebug) { @@ -3975,7 +3975,7 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE MOVE EVENT that.mouseMoveEvent = function(event) { var wantDebug = false; - if(wantDebug){ + if (wantDebug) { print( "=============== eST::MouseMoveEvent BEG ======================="); } if (activeTool) { @@ -4115,7 +4115,7 @@ SelectionDisplay = (function() { } } - if(wantDebug){ + if (wantDebug) { print("=============== eST::MouseMoveEvent END ======================="); } return false; @@ -4124,24 +4124,24 @@ SelectionDisplay = (function() { // FUNCTION: MOUSE RELEASE EVENT that.mouseReleaseEvent = function(event) { var wantDebug = false; - if(wantDebug){ + if (wantDebug) { print("=============== eST::MouseReleaseEvent BEG ======================="); } var showHandles = false; if (activeTool) { - if( activeTool.onEnd ) { - if(wantDebug){ + if ( activeTool.onEnd ) { + if (wantDebug) { print(" Triggering ActiveTool( " + activeTool.mode + " )'s onEnd"); } activeTool.onEnd(event); - }else if(wantDebug){ + }else if (wantDebug) { print(" ActiveTool( " + activeTool.mode + " )'s missing onEnd"); } } // hide our rotation overlays..., and show our handles if ( isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)) { - if(wantDebug){ + if (wantDebug) { print(" Triggering hide of RotateOverlays"); } Overlays.editOverlay(rotateOverlayInner, { @@ -4162,14 +4162,14 @@ SelectionDisplay = (function() { // if something is selected, then reset the "original" properties for any potential next click+move operation if (SelectionManager.hasSelection()) { if (showHandles) { - if(wantDebug){ + if (wantDebug) { print(" Triggering that.select"); } that.select(SelectionManager.selections[0], event); } } - if(wantDebug){ + if (wantDebug) { print("=============== eST::MouseReleaseEvent END ======================="); } }; From f427b5ba3f830c54991b511e2606ea78c685bbad Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 8 Sep 2017 16:40:22 -0400 Subject: [PATCH 31/79] Adding vscode ignores (details below). vscode ignore settings taken from from Github Global Ignores master@435c4d92 https://github.com/github/gitignore/commits/master/Global/VisualStudioCode.gitignore --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index 8aa82865a4..072e6001da 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,15 @@ Makefile local.properties android/libraries +# VSCode +# List taken from Github Global Ignores master@435c4d92 +# https://github.com/github/gitignore/commits/master/Global/VisualStudioCode.gitignore +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + # Xcode *.xcodeproj *.xcworkspace From ff051db79a2ed32d8629f9b087f9f39fc6223d28 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 13 Sep 2017 16:59:21 -0400 Subject: [PATCH 32/79] [Case 6491] Minor: Fixes some paren spacing. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 182 +++++++++--------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 6c5e3b0522..183fba1670 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1095,14 +1095,14 @@ SelectionDisplay = (function() { // are treated as separate values. // @return: bool - Indicates if the activeTool is that queried. function isActiveTool(toolHandle) { - if ( ! toolHandle ) { - // Allow isActiveTool( null ) and similar to return true if there's + if (!toolHandle) { + // Allow isActiveTool(null) and similar to return true if there's // no active tool - return ( activeTool === toolHandle ); + return (activeTool === toolHandle); } - if ( ! grabberTools.hasOwnProperty( toolHandle ) ) { - print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle + ". Tools should be egistered via addGrabberTool." ); + if (!grabberTools.hasOwnProperty(toolHandle)) { + print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle + ". Tools should be egistered via addGrabberTool."); //--EARLY EXIT-- return false; } @@ -1483,15 +1483,15 @@ SelectionDisplay = (function() { isPointLight = properties.type == "Light" && !properties.isSpotlight; } - if ( isActiveTool(yawHandle) || isActiveTool(pitchHandle) || + if (isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle) || isActiveTool(selectionBox) || isActiveTool(grabberCloner)) { rotationOverlaysVisible = true; rotateHandlesVisible = false; //translateHandlesVisible = false; //selectionBoxVisible = false; - } else if ( isActiveTool(grabberMoveUp) || isPointLight) { + } else if (isActiveTool(grabberMoveUp) || isPointLight) { rotateHandlesVisible = false; - } else if ( activeTool ) { + } else if (activeTool) { // every other mode is a stretch mode... rotateHandlesVisible = false; //translateHandlesVisible = false; @@ -1594,12 +1594,12 @@ SelectionDisplay = (function() { return; } if (wantDebug) { - print( "PreToggle: " + spaceMode); + print("PreToggle: " + spaceMode); } spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; that.updateHandles(); if (wantDebug) { - print( "PostToggle: " + spaceMode); + print("PostToggle: " + spaceMode); print("======== ToggleSpaceMode called. <========="); } }; @@ -1612,17 +1612,17 @@ SelectionDisplay = (function() { that.updateHandles = function() { var wantDebug = false; if (wantDebug) { - print( "======> Update Handles =======" ); - print( " Selections Count: " + SelectionManager.selections.length ); - print( " SpaceMode: " + spaceMode ); - print( " DisplayMode: " + getMode() ); + print("======> Update Handles ======="); + print(" Selections Count: " + SelectionManager.selections.length); + print(" SpaceMode: " + spaceMode); + print(" DisplayMode: " + getMode()); } if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); return; } - //print( " Triggering updateRotationHandles"); + //print(" Triggering updateRotationHandles"); that.updateRotationHandles(); var rotation, dimensions, position, registrationPoint; @@ -1863,7 +1863,7 @@ SelectionDisplay = (function() { if (isSingleSelection) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); var isLightSelection = (properties.type == "Light"); - if ( isLightSelection ) { + if (isLightSelection) { if (wantDebug) { print(" Light Selection revoking Non-Light Grabbers Visibility!"); } @@ -1871,10 +1871,10 @@ SelectionDisplay = (function() { extendedStretchHandlesVisible = false; cloneHandleVisible = false; if (properties.isSpotlight) { - that.setPointLightHandlesVisible( false ); + that.setPointLightHandlesVisible(false); var distance = (properties.dimensions.z / 2) * Math.sin(properties.cutoff * (Math.PI / 180)); - var showEdgeSpotGrabbers = ! (inModeTranslate || inModeRotate); + var showEdgeSpotGrabbers = !(inModeTranslate || inModeRotate); Overlays.editOverlay(grabberSpotLightCenter, { position: position, visible: false, @@ -1939,9 +1939,9 @@ SelectionDisplay = (function() { }); } else { //..it's a PointLight - that.setSpotLightHandlesVisible( false ); + that.setSpotLightHandlesVisible(false); - var showEdgePointGrabbers = ! inModeTranslate; + var showEdgePointGrabbers = !inModeTranslate; Overlays.editOverlay(grabberPointLightT, { position: TOP, rotation: rotation, @@ -2004,8 +2004,8 @@ SelectionDisplay = (function() { }); } } else { //..it's not a light at all - that.setSpotLightHandlesVisible( false ); - that.setPointLightHandlesVisible( false ); + that.setSpotLightHandlesVisible(false); + that.setPointLightHandlesVisible(false); } }//--end of isSingleSelection @@ -2229,7 +2229,7 @@ SelectionDisplay = (function() { z: position.z }; Overlays.editOverlay(grabberMoveUp, { - visible: ( ! activeTool ) || isActiveTool(grabberMoveUp) + visible: (!activeTool) || isActiveTool(grabberMoveUp) }); Overlays.editOverlay(baseOfEntityProjectionOverlay, { @@ -2248,12 +2248,12 @@ SelectionDisplay = (function() { }); if (wantDebug) { - print( "====== Update Handles <=======" ); + print("====== Update Handles <======="); } }; - function helperSetOverlaysVisibility( handleArray, isVisible ) { + function helperSetOverlaysVisibility(handleArray, isVisible) { var numHandles = handleArray.length; var visibilityUpdate = { visible: isVisible }; for (var handleIndex = 0; handleIndex < numHandles; ++handleIndex) { @@ -2263,8 +2263,8 @@ SelectionDisplay = (function() { // FUNCTION: SET OVERLAYS VISIBLE that.setOverlaysVisible = function(isVisible) { - helperSetOverlaysVisibility( allOverlays, isVisible ); - helperSetOverlaysVisibility( selectionBoxes, isVisible ); + helperSetOverlaysVisibility(allOverlays, isVisible); + helperSetOverlaysVisibility(selectionBoxes, isVisible); }; // FUNCTION: SET ROTATION HANDLES VISIBLE @@ -2277,7 +2277,7 @@ SelectionDisplay = (function() { // FUNCTION: SET STRETCH HANDLES VISIBLE that.setStretchHandlesVisible = function(isVisible) { - helperSetOverlaysVisibility( stretchHandles, isVisible ); + helperSetOverlaysVisibility(stretchHandles, isVisible); }; // FUNCTION: SET GRABBER MOVE UP VISIBLE @@ -2288,24 +2288,24 @@ SelectionDisplay = (function() { // FUNCTION: SET GRABBER TOOLS UP VISIBLE that.setGrabberToolsVisible = function(isVisible) { var visibilityUpdate = { visible: isVisible }; - for ( var toolKey in grabberTools ) { - if ( ! grabberTools.hasOwnProperty( toolKey ) ) { - //--EARLY ITERATION EXIT--( On to the next one ) + for (var toolKey in grabberTools) { + if (!grabberTools.hasOwnProperty(toolKey)) { + //--EARLY ITERATION EXIT--(On to the next one) continue; } - Overlays.editOverlay( toolKey, visibilityUpdate ); + Overlays.editOverlay(toolKey, visibilityUpdate); } }; // FUNCTION: SET POINT LIGHT HANDLES VISIBLE that.setPointLightHandlesVisible = function(isVisible) { - helperSetOverlaysVisibility( pointLightGrabberHandles, isVisible ); + helperSetOverlaysVisibility(pointLightGrabberHandles, isVisible); }; // FUNCTION: SET SPOT LIGHT HANDLES VISIBLE that.setSpotLightHandlesVisible = function(isVisible) { - helperSetOverlaysVisibility( spotLightGrabberHandles, isVisible ); + helperSetOverlaysVisibility(spotLightGrabberHandles, isVisible); }; // FUNCTION: UNSELECT @@ -2335,9 +2335,9 @@ SelectionDisplay = (function() { } SelectionManager.saveProperties(); - that.setRotationHandlesVisible( false ); - that.setStretchHandlesVisible( false ); - that.setGrabberMoveUpVisible( false ); + that.setRotationHandlesVisible(false); + that.setStretchHandlesVisible(false); + that.setGrabberMoveUpVisible(false); startPosition = SelectionManager.worldPosition; @@ -2411,7 +2411,7 @@ SelectionDisplay = (function() { print(" "+ translateXZTool.mode + "Pick ray does not intersect XZ plane."); } - //--EARLY EXIT--( Invalid ray detected. ) + //--EARLY EXIT--(Invalid ray detected.) return; } @@ -2429,7 +2429,7 @@ SelectionDisplay = (function() { print(" "+ translateXZTool.mode + " - too close to horizon!"); } - //--EARLY EXIT--( Don't proceed past the reached limit. ) + //--EARLY EXIT--(Don't proceed past the reached limit.) return; } @@ -2547,9 +2547,9 @@ SelectionDisplay = (function() { lastXYPick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal); SelectionManager.saveProperties(); - that.setGrabberMoveUpVisible( true ); - that.setStretchHandlesVisible( false ); - that.setRotationHandlesVisible( false ); + that.setGrabberMoveUpVisible(true); + that.setStretchHandlesVisible(false); + that.setRotationHandlesVisible(false); // Duplicate entities if alt is pressed. This will make a // copy of the selected entities and move the _original_ entities, not @@ -3534,10 +3534,10 @@ SelectionDisplay = (function() { function updateRotationDegreesOverlay(angleFromZero, handleRotation, centerPosition) { var wantDebug = false; if (wantDebug) { - print( "---> updateRotationDegreesOverlay ---" ); - print(" AngleFromZero: " + angleFromZero ); - print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z ); - print(" CenterPos - " + centerPosition.x + " Y: " + centerPosition.y + " Z: " + centerPosition.z ); + print("---> updateRotationDegreesOverlay ---"); + print(" AngleFromZero: " + angleFromZero); + print(" HandleRotation - X: " + handleRotation.x + " Y: " + handleRotation.y + " Z: " + handleRotation.z); + print(" CenterPos - " + centerPosition.x + " Y: " + centerPosition.y + " Z: " + centerPosition.z); } var angle = angleFromZero * (Math.PI / 180); @@ -3547,7 +3547,7 @@ SelectionDisplay = (function() { z: 0, }; if (wantDebug) { - print(" Angle: " + angle ); + print(" Angle: " + angle); print(" InitialPos: " + position.x + ", " + position.y + ", " + position.z); } @@ -3564,21 +3564,21 @@ SelectionDisplay = (function() { }; if (wantDebug) { print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); - print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z ); - print(" OverlayLineHeight: " + overlayProps.lineHeight ); - print(" OverlayText: " + overlayProps.text ); + print(" OverlayDim - X: " + overlayProps.dimensions.x + " Y: " + overlayProps.dimensions.y + " Z: " + overlayProps.dimensions.z); + print(" OverlayLineHeight: " + overlayProps.lineHeight); + print(" OverlayText: " + overlayProps.text); } Overlays.editOverlay(rotationDegreesDisplay, overlayProps); if (wantDebug) { - print( "<--- updateRotationDegreesOverlay ---" ); + print("<--- updateRotationDegreesOverlay ---"); } } // FUNCTION DEF: updateSelectionsRotation // Helper func used by rotation grabber tools - function updateSelectionsRotation( rotationChange ) { - if ( ! rotationChange ) { + function updateSelectionsRotation(rotationChange) { + if (!rotationChange) { print("ERROR: entitySelectionTool.updateSelectionsRotation - Invalid arg specified!!"); //--EARLY EXIT-- @@ -3607,16 +3607,16 @@ SelectionDisplay = (function() { } } - function helperRotationHandleOnBegin( event, pickRay, rotAroundAxis, rotCenter, handleRotation ) { + function helperRotationHandleOnBegin(event, pickRay, rotAroundAxis, rotCenter, handleRotation) { var wantDebug = false; if (wantDebug) { print("================== " + getMode() + "(rotation helper onBegin) -> ======================="); } SelectionManager.saveProperties(); - that.setRotationHandlesVisible( false ); - that.setStretchHandlesVisible( false ); - that.setGrabberMoveUpVisible( false ); + that.setRotationHandlesVisible(false); + that.setStretchHandlesVisible(false); + that.setGrabberMoveUpVisible(false); initialPosition = SelectionManager.worldPosition; rotationNormal = { x: 0, y: 0, z: 0 }; @@ -3669,7 +3669,7 @@ SelectionDisplay = (function() { // editOverlays may not have committed rotation changes. // Compute zero position based on where the overlay will be eventually. - var result = rayPlaneIntersection( pickRay, rotCenter, rotationNormal ); + var result = rayPlaneIntersection(pickRay, rotCenter, rotationNormal); // In case of a parallel ray, this will be null, which will cause early-out // in the onMove helper. rotZero = result; @@ -3677,12 +3677,12 @@ SelectionDisplay = (function() { if (wantDebug) { print("================== " + getMode() + "(rotation helper onBegin) <- ======================="); } - }//--End_Function( helperRotationHandleOnBegin ) + }//--End_Function(helperRotationHandleOnBegin) - function helperRotationHandleOnMove( event, rotAroundAxis, rotCenter, handleRotation ) { + function helperRotationHandleOnMove(event, rotAroundAxis, rotCenter, handleRotation) { - if ( ! rotZero ) { - print("ERROR: entitySelectionTool.handleRotationHandleOnMove - Invalid RotationZero Specified (missed rotation target plane?)" ); + if (!rotZero) { + print("ERROR: entitySelectionTool.handleRotationHandleOnMove - Invalid RotationZero Specified (missed rotation target plane?)"); //--EARLY EXIT-- return; @@ -3701,7 +3701,7 @@ SelectionDisplay = (function() { visible: false }); - var result = rayPlaneIntersection( pickRay, rotCenter, rotationNormal ); + var result = rayPlaneIntersection(pickRay, rotCenter, rotationNormal); if (result) { var centerToZero = Vec3.subtract(rotZero, rotCenter); var centerToIntersect = Vec3.subtract(result, rotCenter); @@ -3724,8 +3724,8 @@ SelectionDisplay = (function() { var vec3Degrees = { x: 0, y: 0, z: 0 }; vec3Degrees[rotAroundAxis] = angleFromZero; - var rotChange = Quat.fromVec3Degrees( vec3Degrees ); - updateSelectionsRotation( rotChange ); + var rotChange = Quat.fromVec3Degrees(vec3Degrees); + updateSelectionsRotation(rotChange); updateRotationDegreesOverlay(angleFromZero, handleRotation, rotCenter); @@ -3777,12 +3777,12 @@ SelectionDisplay = (function() { minorTickMarksLength: 0.1, }); } - }//--End_If( results.intersects ) + }//--End_If(results.intersects) if (wantDebug) { print("================== "+ getMode() + "(rotation helper onMove) <- ======================="); } - }//--End_Function( helperRotationHandleOnMove ) + }//--End_Function(helperRotationHandleOnMove) function helperRotationHandleOnEnd() { var wantDebug = false; @@ -3807,7 +3807,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("================== " + getMode() + "(onEnd) <- ======================="); } - }//--End_Function( helperRotationHandleOnEnd ) + }//--End_Function(helperRotationHandleOnEnd) // YAW GRABBER TOOL DEFINITION @@ -3815,13 +3815,13 @@ SelectionDisplay = (function() { addGrabberTool(yawHandle, { mode: "ROTATE_YAW", onBegin: function(event, pickRay, pickResult) { - helperRotationHandleOnBegin( event, pickRay, "y", yawCenter, yawHandleRotation ); + helperRotationHandleOnBegin(event, pickRay, "y", yawCenter, yawHandleRotation); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); }, onMove: function(event) { - helperRotationHandleOnMove( event, "y", yawCenter, yawHandleRotation ); + helperRotationHandleOnMove(event, "y", yawCenter, yawHandleRotation); } }); @@ -3830,13 +3830,13 @@ SelectionDisplay = (function() { addGrabberTool(pitchHandle, { mode: "ROTATE_PITCH", onBegin: function(event, pickRay, pickResult) { - helperRotationHandleOnBegin( event, pickRay, "x", pitchCenter, pitchHandleRotation ); + helperRotationHandleOnBegin(event, pickRay, "x", pitchCenter, pitchHandleRotation); }, onEnd: function(event, reason) { helperRotationHandleOnEnd(); }, onMove: function (event) { - helperRotationHandleOnMove( event, "x", pitchCenter, pitchHandleRotation ); + helperRotationHandleOnMove(event, "x", pitchCenter, pitchHandleRotation); } }); @@ -3845,13 +3845,13 @@ SelectionDisplay = (function() { addGrabberTool(rollHandle, { mode: "ROTATE_ROLL", onBegin: function(event, pickRay, pickResult) { - helperRotationHandleOnBegin( event, pickRay, "z", rollCenter, rollHandleRotation ); + helperRotationHandleOnBegin(event, pickRay, "z", rollCenter, rollHandleRotation); }, onEnd: function (event, reason) { helperRotationHandleOnEnd(); }, onMove: function(event) { - helperRotationHandleOnMove( event, "z", rollCenter, rollHandleRotation ); + helperRotationHandleOnMove(event, "z", rollCenter, rollHandleRotation); } }); @@ -3899,10 +3899,10 @@ SelectionDisplay = (function() { var intersectObj = Overlays.findRayIntersection(queryRay, true, overlayIncludes, overlayExcludes); if (wantDebug) { - if ( ! overlayIncludes ) { + if (!overlayIncludes) { print("testRayIntersect - no overlayIncludes provided."); } - if ( ! overlayExcludes ) { + if (!overlayExcludes) { print("testRayIntersect - no overlayExcludes provided."); } print("testRayIntersect - Hit: " + intersectObj.intersects); @@ -3932,17 +3932,17 @@ SelectionDisplay = (function() { var interactiveOverlays = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, selectionBox]; for (var key in grabberTools) { if (grabberTools.hasOwnProperty(key)) { - interactiveOverlays.push( key ); + interactiveOverlays.push(key); } } // Start with unknown mode, in case no tool can handle this. activeTool = null; - var results = testRayIntersect( pickRay, interactiveOverlays ); - if ( results.intersects ) { + var results = testRayIntersect(pickRay, interactiveOverlays); + if (results.intersects) { var hitOverlayID = results.overlayID; - if ( (hitOverlayID == HMD.tabletID) || (hitOverlayID == HMD.tabletScreenID) || (hitOverlayID == HMD.homeButtonID) ) { + if ((hitOverlayID == HMD.tabletID) || (hitOverlayID == HMD.tabletScreenID) || (hitOverlayID == HMD.homeButtonID)) { //--EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) return false; } @@ -3950,17 +3950,17 @@ SelectionDisplay = (function() { entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); var hitTool = grabberTools[ hitOverlayID ]; - if ( hitTool ) { + if (hitTool) { activeTool = hitTool; if (activeTool.onBegin) { activeTool.onBegin(event, pickRay, results); } else { - print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool( " + activeTool.mode + " ) missing onBegin"); + print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool(" + activeTool.mode + ") missing onBegin"); } } else { print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); - }//--End_if ( hitTool ) - }//--End_If( results.intersects ) + }//--End_if (hitTool) + }//--End_If(results.intersects) if (wantDebug) { print(" DisplayMode: " + getMode()); @@ -3976,11 +3976,11 @@ SelectionDisplay = (function() { that.mouseMoveEvent = function(event) { var wantDebug = false; if (wantDebug) { - print( "=============== eST::MouseMoveEvent BEG ======================="); + print("=============== eST::MouseMoveEvent BEG ======================="); } if (activeTool) { if (wantDebug) { - print(" Trigger ActiveTool( " + activeTool.mode + " )'s onMove"); + print(" Trigger ActiveTool(" + activeTool.mode + ")'s onMove"); } activeTool.onMove(event); @@ -3992,7 +3992,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("=============== eST::MouseMoveEvent END ======================="); } - //--EARLY EXIT--( Move handled via active tool) + //--EARLY EXIT--(Move handled via active tool) return true; } @@ -4129,18 +4129,18 @@ SelectionDisplay = (function() { } var showHandles = false; if (activeTool) { - if ( activeTool.onEnd ) { + if (activeTool.onEnd) { if (wantDebug) { - print(" Triggering ActiveTool( " + activeTool.mode + " )'s onEnd"); + print(" Triggering ActiveTool(" + activeTool.mode + ")'s onEnd"); } activeTool.onEnd(event); }else if (wantDebug) { - print(" ActiveTool( " + activeTool.mode + " )'s missing onEnd"); + print(" ActiveTool(" + activeTool.mode + ")'s missing onEnd"); } } // hide our rotation overlays..., and show our handles - if ( isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)) { + if (isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)) { if (wantDebug) { print(" Triggering hide of RotateOverlays"); } From ff019d619516cb1e9b91006c311ff0bdca7a3730 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 28 Sep 2017 13:56:49 -0700 Subject: [PATCH 33/79] Fix extension detection when tracking asset uploads --- interface/src/scripting/AssetMappingsScriptingInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index ba533a5bd1..2d288a8804 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -114,7 +114,7 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping, QString extension = ""; auto idx = path.lastIndexOf("."); - if (idx) { + if (idx >= 0) { extension = path.mid(idx + 1); } @@ -384,4 +384,4 @@ void AssetMappingModel::setupRoles() { roleNames[Qt::DisplayRole] = "name"; roleNames[Qt::UserRole + 5] = "baked"; setItemRoleNames(roleNames); -} \ No newline at end of file +} From b59ec07171505422e958f6c87a3cce44bc302130 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 29 Sep 2017 09:49:08 -0700 Subject: [PATCH 34/79] move hud rendering to render thread, still need to separate out hud overlays --- interface/resources/qml/desktop/Desktop.qml | 10 +-- interface/resources/shaders/hmd_ui.frag | 30 ------- interface/resources/shaders/hmd_ui.vert | 28 ------ interface/src/Application.cpp | 18 +--- interface/src/Application.h | 2 +- .../ControllerScriptingInterface.cpp | 4 +- .../scripting/ControllerScriptingInterface.h | 2 +- .../scripting/DesktopScriptingInterface.cpp | 2 +- .../src/scripting/DesktopScriptingInterface.h | 2 +- interface/src/ui/overlays/Base3DOverlay.cpp | 12 ++- interface/src/ui/overlays/Base3DOverlay.h | 3 + interface/src/ui/overlays/Circle3DOverlay.cpp | 2 +- interface/src/ui/overlays/Cube3DOverlay.cpp | 2 +- interface/src/ui/overlays/Image3DOverlay.cpp | 2 +- interface/src/ui/overlays/Overlay.cpp | 14 --- interface/src/ui/overlays/Overlay.h | 3 - interface/src/ui/overlays/Overlays.cpp | 62 +------------ interface/src/ui/overlays/Overlays.h | 6 -- interface/src/ui/overlays/OverlaysPayload.cpp | 3 +- interface/src/ui/overlays/Shape3DOverlay.cpp | 2 +- interface/src/ui/overlays/Sphere3DOverlay.cpp | 2 +- .../src/display-plugins/CompositorHelper.h | 2 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 54 ++++-------- .../src/display-plugins/OpenGLDisplayPlugin.h | 12 +-- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 88 ++++++------------- .../display-plugins/hmd/HmdDisplayPlugin.h | 15 ++-- libraries/gpu/src/gpu/Batch.h | 2 +- libraries/gpu/src/gpu/Frame.h | 4 - .../plugins/src/plugins/DisplayPlugin.cpp | 9 ++ libraries/plugins/src/plugins/DisplayPlugin.h | 9 +- .../render-utils/src/MeshPartPayload.cpp | 2 +- libraries/render-utils/src/Model.h | 2 + .../render-utils/src/RenderDeferredTask.cpp | 15 ++++ .../render-utils/src/RenderDeferredTask.h | 8 ++ libraries/render-utils/src/hmd_ui.slf | 37 ++++++++ libraries/render-utils/src/hmd_ui.slv | 36 ++++++++ libraries/render/src/render/Args.h | 3 + .../controllerModules/hudOverlayPointer.js | 10 +-- scripts/system/libraries/toolBars.js | 10 +-- 39 files changed, 224 insertions(+), 305 deletions(-) delete mode 100644 interface/resources/shaders/hmd_ui.frag delete mode 100644 interface/resources/shaders/hmd_ui.vert create mode 100644 libraries/render-utils/src/hmd_ui.slf create mode 100644 libraries/render-utils/src/hmd_ui.slv diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 579b4e7fd6..d5b01fd494 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -88,7 +88,7 @@ FocusScope { return; } var oldRecommendedRect = recommendedRect; - var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect(); + var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect(); var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, newRecommendedRectJS.width, newRecommendedRectJS.height); @@ -271,7 +271,7 @@ FocusScope { var oldRecommendedRect = recommendedRect; var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height }; - var newRecommendedRect = Controller.getRecommendedOverlayRect(); + var newRecommendedRect = Controller.getRecommendedHUDRect(); var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height }; var windows = d.getTopLevelWindows(); for (var i = 0; i < windows.length; ++i) { @@ -393,7 +393,7 @@ FocusScope { return; } - var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect(); + var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedHUDRect(); var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, newRecommendedRectJS.width, newRecommendedRectJS.height); @@ -425,7 +425,7 @@ FocusScope { var oldRecommendedRect = recommendedRect; var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height }; - var newRecommendedRect = Controller.getRecommendedOverlayRect(); + var newRecommendedRect = Controller.getRecommendedHUDRect(); var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height }; repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions); } @@ -442,7 +442,7 @@ FocusScope { return; } - var recommended = Controller.getRecommendedOverlayRect(); + var recommended = Controller.getRecommendedHUDRect(); var maxX = recommended.x + recommended.width; var maxY = recommended.y + recommended.height; var newPosition = Qt.vector2d(targetWindow.x, targetWindow.y); diff --git a/interface/resources/shaders/hmd_ui.frag b/interface/resources/shaders/hmd_ui.frag deleted file mode 100644 index 5341ab575d..0000000000 --- a/interface/resources/shaders/hmd_ui.frag +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/07/11 -// Copyright 2013-2016 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 -// - -uniform sampler2D sampler; - -struct OverlayData { - mat4 mvp; - float alpha; -}; - -layout(std140) uniform overlayBuffer { - OverlayData overlay; -}; - -in vec2 vTexCoord; - -out vec4 FragColor; - -void main() { - FragColor = texture(sampler, vTexCoord); - FragColor.a *= overlay.alpha; - if (FragColor.a <= 0.0) { - discard; - } -} \ No newline at end of file diff --git a/interface/resources/shaders/hmd_ui.vert b/interface/resources/shaders/hmd_ui.vert deleted file mode 100644 index 41b9b3666f..0000000000 --- a/interface/resources/shaders/hmd_ui.vert +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by Bradley Austin Davis on 2016/07/11 -// Copyright 2013-2016 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 -// - -struct OverlayData { - mat4 mvp; - float alpha; -}; - -layout(std140) uniform overlayBuffer { - OverlayData overlay; -}; - -mat4 mvp = overlay.mvp; - -layout(location = 0) in vec3 Position; -layout(location = 3) in vec2 TexCoord; - -out vec2 vTexCoord; - -void main() { - gl_Position = mvp * vec4(Position, 1); - vTexCoord = TexCoord; -} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6668f5cfa0..5e52b443e1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2590,6 +2590,8 @@ void Application::paintGL() { // in the overlay render? // Viewport is assigned to the size of the framebuffer renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + renderArgs._hudOperator = displayPlugin->getHUDOperator(); + renderArgs._hudTexture = _applicationOverlay.getOverlayTexture(); auto baseProjection = renderArgs.getViewFrustum().getProjection(); if (displayPlugin->isStereo()) { // Stereo modes will typically have a larger projection matrix overall, @@ -2632,24 +2634,12 @@ void Application::paintGL() { displaySide(&renderArgs, _myCamera); } - gpu::Batch postCompositeBatch; - { - PROFILE_RANGE(render, "/postComposite"); - PerformanceTimer perfTimer("postComposite"); - renderArgs._batch = &postCompositeBatch; - renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); - renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); - _overlays.render3DHUDOverlays(&renderArgs); - } - auto frame = _gpuContext->endFrame(); frame->frameIndex = _frameCount; frame->framebuffer = finalFramebuffer; frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ DependencyManager::get()->releaseFramebuffer(framebuffer); }; - frame->overlay = _applicationOverlay.getOverlayTexture(); - frame->postCompositeBatch = postCompositeBatch; // deliver final scene rendering commands to the display plugin { PROFILE_RANGE(render, "/pluginOutput"); @@ -7209,11 +7199,11 @@ glm::uvec2 Application::getUiSize() const { return result; } -QRect Application::getRecommendedOverlayRect() const { +QRect Application::getRecommendedHUDRect() const { auto uiSize = getUiSize(); QRect result(0, 0, uiSize.x, uiSize.y); if (_displayPlugin) { - result = getActiveDisplayPlugin()->getRecommendedOverlayRect(); + result = getActiveDisplayPlugin()->getRecommendedHUDRect(); } return result; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 74e84ae92c..7d84504f70 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -157,7 +157,7 @@ public: QRect getRenderingGeometry() const; glm::uvec2 getUiSize() const; - QRect getRecommendedOverlayRect() const; + QRect getRecommendedHUDRect() const; QSize getDeviceSize() const; bool hasFocus() const; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 9fbd01817a..5c55e2094b 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -91,8 +91,8 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const { return qApp->getUiSize(); } -QVariant ControllerScriptingInterface::getRecommendedOverlayRect() const { - auto rect = qApp->getRecommendedOverlayRect(); +QVariant ControllerScriptingInterface::getRecommendedHUDRect() const { + auto rect = qApp->getRecommendedHUDRect(); return qRectToVariant(rect); } diff --git a/interface/src/scripting/ControllerScriptingInterface.h b/interface/src/scripting/ControllerScriptingInterface.h index 6d197477bb..8c825a17de 100644 --- a/interface/src/scripting/ControllerScriptingInterface.h +++ b/interface/src/scripting/ControllerScriptingInterface.h @@ -66,7 +66,7 @@ public slots: virtual void releaseEntityClickEvents(); virtual glm::vec2 getViewportDimensions() const; - virtual QVariant getRecommendedOverlayRect() const; + virtual QVariant getRecommendedHUDRect() const; signals: void keyPressEvent(const KeyEvent& event); diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp index efab178798..34f196ac70 100644 --- a/interface/src/scripting/DesktopScriptingInterface.cpp +++ b/interface/src/scripting/DesktopScriptingInterface.cpp @@ -29,7 +29,7 @@ int DesktopScriptingInterface::getHeight() { return size.height(); } -void DesktopScriptingInterface::setOverlayAlpha(float alpha) { +void DesktopScriptingInterface::setHUDAlpha(float alpha) { qApp->getApplicationCompositor().setAlpha(alpha); } diff --git a/interface/src/scripting/DesktopScriptingInterface.h b/interface/src/scripting/DesktopScriptingInterface.h index 2825065e90..e62a3584d6 100644 --- a/interface/src/scripting/DesktopScriptingInterface.h +++ b/interface/src/scripting/DesktopScriptingInterface.h @@ -22,7 +22,7 @@ class DesktopScriptingInterface : public QObject, public Dependency { Q_PROPERTY(int height READ getHeight) // Physical height of screen(s) including task bars and system menus public: - Q_INVOKABLE void setOverlayAlpha(float alpha); + Q_INVOKABLE void setHUDAlpha(float alpha); Q_INVOKABLE void show(const QString& path, const QString& title); int getWidth(); diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 9afab80243..e711767ec2 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -26,7 +26,8 @@ Base3DOverlay::Base3DOverlay() : _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), _ignoreRayIntersection(false), - _drawInFront(false) + _drawInFront(false), + _drawHUDLayer(false) { } @@ -38,6 +39,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : _isDashedLine(base3DOverlay->_isDashedLine), _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection), _drawInFront(base3DOverlay->_drawInFront), + _drawHUDLayer(base3DOverlay->_drawHUDLayer), _isGrabbable(base3DOverlay->_isGrabbable) { setTransform(base3DOverlay->getTransform()); @@ -125,13 +127,19 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { bool needRenderItemUpdate = false; auto drawInFront = properties["drawInFront"]; - if (drawInFront.isValid()) { bool value = drawInFront.toBool(); setDrawInFront(value); needRenderItemUpdate = true; } + auto drawHUDLayer = properties["drawHUDLayer"]; + if (drawHUDLayer.isValid()) { + bool value = drawHUDLayer.toBool(); + setDrawHUDLayer(value); + needRenderItemUpdate = true; + } + auto isGrabbable = properties["grabbable"]; if (isGrabbable.isValid()) { setIsGrabbable(isGrabbable.toBool()); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 93a973e60a..190d2f6cc6 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -41,6 +41,7 @@ public: bool getIsSolidLine() const { return !_isDashedLine; } bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } bool getDrawInFront() const { return _drawInFront; } + bool getDrawHUDLayer() const { return _drawHUDLayer; } bool getIsGrabbable() const { return _isGrabbable; } void setLineWidth(float lineWidth) { _lineWidth = lineWidth; } @@ -48,6 +49,7 @@ public: void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } void setDrawInFront(bool value) { _drawInFront = value; } + void setDrawHUDLayer(bool value) { _drawHUDLayer = value; } void setIsGrabbable(bool value) { _isGrabbable = value; } virtual AABox getBounds() const override = 0; @@ -81,6 +83,7 @@ protected: bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; + bool _drawHUDLayer; bool _isGrabbable { false }; mutable bool _renderTransformDirty{ true }; diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 4e51844d21..536b2c764f 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -263,7 +263,7 @@ const render::ShapeKey Circle3DOverlay::getShapeKey() { if (isTransparent()) { builder.withTranslucent(); } - if (!getIsSolid() || shouldDrawHUDLayer()) { + if (!getIsSolid()) { builder.withUnlit().withDepthBias(); } return builder.build(); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 0ac9dba34b..b6df1dbc31 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -113,7 +113,7 @@ const render::ShapeKey Cube3DOverlay::getShapeKey() { if (isTransparent()) { builder.withTranslucent(); } - if (!getIsSolid() || shouldDrawHUDLayer()) { + if (!getIsSolid()) { builder.withUnlit().withDepthBias(); } return builder.build(); diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index 998cc312eb..d0024d9710 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -132,7 +132,7 @@ void Image3DOverlay::render(RenderArgs* args) { const render::ShapeKey Image3DOverlay::getShapeKey() { auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); - if (_emissive || shouldDrawHUDLayer()) { + if (_emissive) { builder.withUnlit(); } if (isTransparent()) { diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 8b88d1e963..01ad56f20e 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -32,7 +32,6 @@ Overlay::Overlay() : _colorPulse(0.0f), _color(DEFAULT_OVERLAY_COLOR), _visible(true), - _drawHUDLayer(false), _anchor(NO_ANCHOR) { } @@ -51,7 +50,6 @@ Overlay::Overlay(const Overlay* overlay) : _colorPulse(overlay->_colorPulse), _color(overlay->_color), _visible(overlay->_visible), - _drawHUDLayer(overlay->_drawHUDLayer), _anchor(overlay->_anchor) { } @@ -90,11 +88,6 @@ void Overlay::setProperties(const QVariantMap& properties) { setColorPulse(properties["colorPulse"].toFloat()); } - if (properties["drawHUDLayer"].isValid()) { - bool drawHUDLayer = properties["drawHUDLayer"].toBool(); - setDrawHUDLayer(drawHUDLayer); - } - if (properties["visible"].isValid()) { bool visible = properties["visible"].toBool(); setVisible(visible); @@ -170,13 +163,6 @@ float Overlay::getAlpha() { return (_alphaPulse >= 0.0f) ? _alpha * pulseLevel : _alpha * (1.0f - pulseLevel); } -void Overlay::setDrawHUDLayer(bool drawHUDLayer) { - if (drawHUDLayer != _drawHUDLayer) { - qApp->getOverlays().setOverlayDrawHUDLayer(getOverlayID(), drawHUDLayer); - _drawHUDLayer = drawHUDLayer; - } -} - // pulse travels from min to max, then max to min in one period. float Overlay::updatePulse() { if (_pulsePeriod <= 0.0f) { diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index db2979b4d5..1c35f4d8a5 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -58,7 +58,6 @@ public: virtual bool is3D() const = 0; bool isLoaded() { return _isLoaded; } bool getVisible() const { return _visible; } - bool shouldDrawHUDLayer() const { return _drawHUDLayer; } virtual bool isTransparent() { return getAlphaPulse() != 0.0f || getAlpha() != 1.0f; }; xColor getColor(); float getAlpha(); @@ -74,7 +73,6 @@ public: // setters void setVisible(bool visible) { _visible = visible; } - void setDrawHUDLayer(bool drawHUDLayer); void setColor(const xColor& color) { _color = color; } void setAlpha(float alpha) { _alpha = alpha; } void setAnchor(Anchor anchor) { _anchor = anchor; } @@ -117,7 +115,6 @@ protected: xColor _color; bool _visible; // should the overlay be drawn at all - bool _drawHUDLayer; // should the overlay be drawn on the HUD layer Anchor _anchor; unsigned int _stackOrder { 0 }; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index c93d225718..0280cf2038 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -37,29 +37,22 @@ #include "Web3DOverlay.h" #include -#include "render/ShapePipeline.h" - Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays") extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false); void Overlays::cleanupAllOverlays() { QMap overlaysHUD; - QMap overlays3DHUD; QMap overlaysWorld; { QMutexLocker locker(&_mutex); overlaysHUD.swap(_overlaysHUD); - overlays3DHUD.swap(_overlays3DHUD); overlaysWorld.swap(_overlaysWorld); } foreach(Overlay::Pointer overlay, overlaysHUD) { _overlaysToDelete.push_back(overlay); } - foreach(Overlay::Pointer overlay, overlays3DHUD) { - _overlaysToDelete.push_back(overlay); - } foreach(Overlay::Pointer overlay, overlaysWorld) { _overlaysToDelete.push_back(overlay); } @@ -73,8 +66,6 @@ void Overlays::init() { #if OVERLAY_PANELS _scriptEngine = new QScriptEngine(); #endif - _shapePlumber = std::make_shared(); - initOverlay3DPipelines(*_shapePlumber, true); } void Overlays::update(float deltatime) { @@ -83,9 +74,6 @@ void Overlays::update(float deltatime) { foreach(const auto& thisOverlay, _overlaysHUD) { thisOverlay->update(deltatime); } - foreach(const auto& thisOverlay, _overlays3DHUD) { - thisOverlay->update(deltatime); - } foreach(const auto& thisOverlay, _overlaysWorld) { thisOverlay->update(deltatime); } @@ -142,23 +130,6 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { } } -void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) { - PROFILE_RANGE(render_overlays, __FUNCTION__); - gpu::Batch& batch = *renderArgs->_batch; - - auto textureCache = DependencyManager::get(); - - QMutexLocker lock(&_mutex); - foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) { - // Reset necessary batch pipeline settings between overlays - batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this?? - batch.setModelTransform(Transform()); - - renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey()); - thisOverlay->render(renderArgs); - } -} - void Overlays::disable() { _enabled = false; } @@ -173,8 +144,6 @@ Overlay::Pointer Overlays::getOverlay(OverlayID id) const { QMutexLocker locker(&_mutex); if (_overlaysHUD.contains(id)) { return _overlaysHUD[id]; - } else if (_overlays3DHUD.contains(id)) { - return _overlays3DHUD[id]; } else if (_overlaysWorld.contains(id)) { return _overlaysWorld[id]; } @@ -232,7 +201,7 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) { OverlayID thisID = OverlayID(QUuid::createUuid()); overlay->setOverlayID(thisID); overlay->setStackOrder(_stackOrder++); - if (overlay->is3D() && !overlay->shouldDrawHUDLayer()) { + if (overlay->is3D()) { { QMutexLocker locker(&_mutex); _overlaysWorld[thisID] = overlay; @@ -242,9 +211,6 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) { render::Transaction transaction; overlay->addToScene(overlay, scene, transaction); scene->enqueueTransaction(transaction); - } else if (overlay->is3D() && overlay->shouldDrawHUDLayer()) { - QMutexLocker locker(&_mutex); - _overlays3DHUD[thisID] = overlay; } else { QMutexLocker locker(&_mutex); _overlaysHUD[thisID] = overlay; @@ -253,28 +219,6 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) { return thisID; } -void Overlays::setOverlayDrawHUDLayer(const OverlayID& id, const bool drawHUDLayer) { - QMutexLocker locker(&_mutex); - if (drawHUDLayer && _overlaysWorld.contains(id)) { - std::shared_ptr overlay = _overlaysWorld.take(id); - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - auto itemID = overlay->getRenderItemID(); - if (render::Item::isValidID(itemID)) { - overlay->removeFromScene(overlay, scene, transaction); - scene->enqueueTransaction(transaction); - } - _overlays3DHUD[id] = overlay; - } else if (!drawHUDLayer && _overlays3DHUD.contains(id)) { - std::shared_ptr overlay = _overlays3DHUD.take(id); - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - overlay->addToScene(overlay, scene, transaction); - scene->enqueueTransaction(transaction); - _overlaysWorld[id] = overlay; - } -} - OverlayID Overlays::cloneOverlay(OverlayID id) { if (QThread::currentThread() != thread()) { OverlayID result; @@ -361,8 +305,6 @@ void Overlays::deleteOverlay(OverlayID id) { QMutexLocker locker(&_mutex); if (_overlaysHUD.contains(id)) { overlayToDelete = _overlaysHUD.take(id); - } else if (_overlays3DHUD.contains(id)) { - overlayToDelete = _overlays3DHUD.take(id); } else if (_overlaysWorld.contains(id)) { overlayToDelete = _overlaysWorld.take(id); } else { @@ -771,7 +713,7 @@ bool Overlays::isAddedOverlay(OverlayID id) { } QMutexLocker locker(&_mutex); - return _overlaysHUD.contains(id) || _overlays3DHUD.contains(id) || _overlaysWorld.contains(id); + return _overlaysHUD.contains(id) || _overlaysWorld.contains(id); } void Overlays::sendMousePressOnOverlay(const OverlayID& overlayID, const PointerEvent& event) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 1e85562485..732a437eae 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -90,7 +90,6 @@ public: void init(); void update(float deltatime); void renderHUD(RenderArgs* renderArgs); - void render3DHUDOverlays(RenderArgs* renderArgs); void disable(); void enable(); @@ -103,8 +102,6 @@ public: OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); } OverlayID addOverlay(const Overlay::Pointer& overlay); - void setOverlayDrawHUDLayer(const OverlayID& id, const bool drawHUDLayer); - bool mousePressEvent(QMouseEvent* event); bool mouseDoublePressEvent(QMouseEvent* event); bool mouseReleaseEvent(QMouseEvent* event); @@ -334,11 +331,8 @@ private: mutable QMutex _mutex { QMutex::Recursive }; QMap _overlaysHUD; - QMap _overlays3DHUD; QMap _overlaysWorld; - render::ShapePlumberPointer _shapePlumber; - #if OVERLAY_PANELS QMap _panels; #endif diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index 887bf7ff8e..7beb96c061 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -34,7 +34,8 @@ namespace render { template <> const ItemKey payloadGetKey(const Overlay::Pointer& overlay) { auto builder = ItemKey::Builder().withTypeShape(); if (overlay->is3D()) { - if (std::static_pointer_cast(overlay)->getDrawInFront()) { + auto overlay3D = std::static_pointer_cast(overlay); + if (overlay3D->getDrawInFront() || overlay3D->getDrawHUDLayer()) { builder.withLayered(); } if (overlay->isTransparent()) { diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index 2c1df478f6..a3b51d40bf 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -55,7 +55,7 @@ const render::ShapeKey Shape3DOverlay::getShapeKey() { if (isTransparent()) { builder.withTranslucent(); } - if (!getIsSolid() || shouldDrawHUDLayer()) { + if (!getIsSolid()) { builder.withUnlit().withDepthBias(); } return builder.build(); diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index f2c9968687..c9fc25b252 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -60,7 +60,7 @@ const render::ShapeKey Sphere3DOverlay::getShapeKey() { if (isTransparent()) { builder.withTranslucent(); } - if (!getIsSolid() || shouldDrawHUDLayer()) { + if (!getIsSolid()) { builder.withUnlit().withDepthBias(); } return builder.build(); diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index b1d2815f65..f448375f0d 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -74,6 +74,7 @@ public: void setModelTransform(const Transform& transform) { _modelTransform = transform; } const Transform& getModelTransform() const { return _modelTransform; } + glm::mat4 getUiTransform() const; float getAlpha() const { return _alpha; } void setAlpha(float alpha) { if (alpha != _alpha) { emit alphaChanged(); _alpha = alpha; } } @@ -122,7 +123,6 @@ protected slots: void sendFakeMouseEvent(); private: - glm::mat4 getUiTransform() const; void updateTooltips(); DisplayPluginPointer _currentDisplayPlugin; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 98f4e04492..0872edcd95 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -307,7 +307,7 @@ bool OpenGLDisplayPlugin::activate() { auto compositorHelper = DependencyManager::get(); connect(compositorHelper.data(), &CompositorHelper::alphaChanged, [this] { auto compositorHelper = DependencyManager::get(); - auto animation = new QPropertyAnimation(this, "overlayAlpha"); + auto animation = new QPropertyAnimation(this, "hudAlpha"); animation->setDuration(200); animation->setEndValue(compositorHelper->getAlpha()); animation->start(); @@ -415,7 +415,7 @@ void OpenGLDisplayPlugin::customizeContext() { state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - _overlayPipeline = gpu::Pipeline::create(program, state); + _hudPipeline = gpu::Pipeline::create(program, state); } { @@ -437,7 +437,7 @@ void OpenGLDisplayPlugin::customizeContext() { void OpenGLDisplayPlugin::uncustomizeContext() { _presentPipeline.reset(); _cursorPipeline.reset(); - _overlayPipeline.reset(); + _hudPipeline.reset(); _compositeFramebuffer.reset(); withPresentThreadLock([&] { _currentFrame.reset(); @@ -562,12 +562,11 @@ void OpenGLDisplayPlugin::updateFrameData() { }); } -void OpenGLDisplayPlugin::compositeOverlay() { - render([&](gpu::Batch& batch){ +std::function OpenGLDisplayPlugin::getHUDOperator() { + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { batch.enableStereo(false); - batch.setFramebuffer(_compositeFramebuffer); - batch.setPipeline(_overlayPipeline); - batch.setResourceTexture(0, _currentFrame->overlay); + batch.setPipeline(_hudPipeline); + batch.setResourceTexture(0, hudTexture); if (isStereo()) { for_each_eye([&](Eye eye) { batch.setViewportTransform(eyeViewport(eye)); @@ -577,7 +576,7 @@ void OpenGLDisplayPlugin::compositeOverlay() { batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); } - }); + }; } void OpenGLDisplayPlugin::compositePointer() { @@ -626,29 +625,15 @@ void OpenGLDisplayPlugin::compositeLayers() { compositeScene(); } - // Clear the depth framebuffer after drawing the scene so that the HUD elements can depth test against each other - render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setFramebuffer(_compositeFramebuffer); - batch.clearDepthFramebuffer((float) UINT32_MAX); - }); - #ifdef HIFI_ENABLE_NSIGHT_DEBUG - if (false) // do not compositeoverlay if running nsight debug + if (false) // do not draw the HUD if running nsight debug #endif { - PROFILE_RANGE_EX(render_detail, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount()) - compositeOverlay(); - } - - // Only render HUD layer 3D overlays in HMD mode - if (isHmd()) { - PROFILE_RANGE_EX(render_detail, "compositeHUDOverlays", 0xff0077ff, (uint64_t)presentCount()) - render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setFramebuffer(_compositeFramebuffer); + PROFILE_RANGE_EX(render_detail, "handleHUDBatch", 0xff0077ff, (uint64_t)presentCount()) + auto hudOperator = getHUDOperator(); + withPresentThreadLock([&] { + _hudOperator = hudOperator; }); - _gpuContext->executeBatch(_currentFrame->postCompositeBatch); } { @@ -656,13 +641,7 @@ void OpenGLDisplayPlugin::compositeLayers() { compositeExtra(); } - // Clear the depth buffer again and draw the pointer last so it's on top of everything - render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setFramebuffer(_compositeFramebuffer); - batch.clearDepthFramebuffer((float) UINT32_MAX); - }); - + // Draw the pointer last so it's on top of everything auto compositorHelper = DependencyManager::get(); if (compositorHelper->getReticleVisible()) { PROFILE_RANGE_EX(render_detail, "compositePointer", 0xff0077ff, (uint64_t)presentCount()) @@ -844,7 +823,7 @@ void OpenGLDisplayPlugin::assertIsPresentThread() const { bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) { withNonPresentThreadLock([&] { - _compositeOverlayAlpha = _overlayAlpha; + _compositeHUDAlpha = _hudAlpha; }); return Parent::beginFrameRender(frameIndex); } @@ -887,8 +866,7 @@ OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { void OpenGLDisplayPlugin::updateCompositeFramebuffer() { auto renderSize = getRecommendedRenderSize(); if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) { - auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); - _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, depthFormat, renderSize.x, renderSize.y)); + _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y)); } } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 2080fa5ea6..c6e9b7f5be 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -22,6 +22,8 @@ #include #include +#include + namespace gpu { namespace gl { class GLBackend; @@ -30,7 +32,7 @@ namespace gpu { class OpenGLDisplayPlugin : public DisplayPlugin { Q_OBJECT - Q_PROPERTY(float overlayAlpha MEMBER _overlayAlpha) + Q_PROPERTY(float hudAlpha MEMBER _hudAlpha) using Parent = DisplayPlugin; protected: using Mutex = std::mutex; @@ -93,7 +95,7 @@ protected: virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; } virtual void compositeLayers(); virtual void compositeScene(); - virtual void compositeOverlay(); + virtual std::function getHUDOperator(); virtual void compositePointer(); virtual void compositeExtra() {}; @@ -137,12 +139,12 @@ protected: gpu::FramePointer _currentFrame; gpu::Frame* _lastFrame { nullptr }; gpu::FramebufferPointer _compositeFramebuffer; - gpu::PipelinePointer _overlayPipeline; + gpu::PipelinePointer _hudPipeline; gpu::PipelinePointer _simplePipeline; gpu::PipelinePointer _presentPipeline; gpu::PipelinePointer _cursorPipeline; gpu::TexturePointer _displayTexture{}; - float _compositeOverlayAlpha { 1.0f }; + float _compositeHUDAlpha { 1.0f }; struct CursorData { QImage image; @@ -176,6 +178,6 @@ protected: // Any resource shared by the main thread and the presentation thread must // be serialized through this mutex mutable Mutex _presentMutex; - float _overlayAlpha{ 1.0f }; + float _hudAlpha{ 1.0f }; }; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 88ec94eefb..6d0134ec23 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -33,6 +33,9 @@ #include "../Logging.h" #include "../CompositorHelper.h" +#include "render-utils/hmd_ui_vert.h" +#include "render-utils/hmd_ui_frag.h" + static const QString MONO_PREVIEW = "Mono Preview"; static const QString DISABLE_PREVIEW = "Disable Preview"; static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate"; @@ -58,7 +61,7 @@ glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const { return CompositorHelper::VIRTUAL_SCREEN_SIZE; } -QRect HmdDisplayPlugin::getRecommendedOverlayRect() const { +QRect HmdDisplayPlugin::getRecommendedHUDRect() const { return CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT; } @@ -108,7 +111,7 @@ void HmdDisplayPlugin::internalDeactivate() { void HmdDisplayPlugin::customizeContext() { Parent::customizeContext(); - _overlayRenderer.build(); + _hudRenderer.build(); } void HmdDisplayPlugin::uncustomizeContext() { @@ -121,7 +124,7 @@ void HmdDisplayPlugin::uncustomizeContext() { batch.setFramebuffer(_compositeFramebuffer); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0)); }); - _overlayRenderer = OverlayRenderer(); + _hudRenderer = HUDRenderer(); _previewTexture.reset(); Parent::uncustomizeContext(); } @@ -171,7 +174,7 @@ float HmdDisplayPlugin::getLeftCenterPixel() const { void HmdDisplayPlugin::internalPresent() { PROFILE_RANGE_EX(render, __FUNCTION__, 0xff00ff00, (uint64_t)presentCount()) - // Composite together the scene, overlay and mouse cursor + // Composite together the scene, hud and mouse cursor hmdPresent(); if (_displayTexture) { @@ -344,17 +347,9 @@ void HmdDisplayPlugin::updateFrameData() { auto correction = glm::inverse(batchPose) * currentPose; getGLBackend()->setCameraCorrection(correction); } - - auto compositorHelper = DependencyManager::get(); - glm::mat4 modelMat = compositorHelper->getModelTransform().getMatrix(); - - for_each_eye([&](Eye eye) { - auto modelView = glm::inverse(_currentPresentFrameInfo.presentPose * getEyeToHeadTransform(eye)) * modelMat; - _overlayRenderer.mvps[eye] = _eyeProjections[eye] * modelView; - }); } -void HmdDisplayPlugin::OverlayRenderer::build() { +void HmdDisplayPlugin::HUDRenderer::build() { vertices = std::make_shared(); indices = std::make_shared(); @@ -410,38 +405,20 @@ void HmdDisplayPlugin::OverlayRenderer::build() { format = std::make_shared(); // 1 for everyone format->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); format->setAttribute(gpu::Stream::TEXCOORD, gpu::Stream::TEXCOORD, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - uniformBuffers[0] = std::make_shared(sizeof(Uniforms), nullptr); - uniformBuffers[1] = std::make_shared(sizeof(Uniforms), nullptr); + uniformsBuffer = std::make_shared(sizeof(Uniforms), nullptr); updatePipeline(); } -void HmdDisplayPlugin::OverlayRenderer::updatePipeline() { - static const QString vsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui.vert"; - static const QString fsFile = PathUtils::resourcesPath() + "/shaders/hmd_ui.frag"; - -#if LIVE_SHADER_RELOAD - static qint64 vsBuiltAge = 0; - static qint64 fsBuiltAge = 0; - QFileInfo vsInfo(vsFile); - QFileInfo fsInfo(fsFile); - auto vsAge = vsInfo.lastModified().toMSecsSinceEpoch(); - auto fsAge = fsInfo.lastModified().toMSecsSinceEpoch(); - if (!pipeline || vsAge > vsBuiltAge || fsAge > fsBuiltAge) { - vsBuiltAge = vsAge; - fsBuiltAge = fsAge; -#else +void HmdDisplayPlugin::HUDRenderer::updatePipeline() { if (!pipeline) { -#endif - QString vsSource = readFile(vsFile); - QString fsSource = readFile(fsFile); - auto vs = gpu::Shader::createVertex(vsSource.toLocal8Bit().toStdString()); - auto ps = gpu::Shader::createPixel(fsSource.toLocal8Bit().toStdString()); + auto vs = gpu::Shader::createVertex(std::string(hmd_ui_vert)); + auto ps = gpu::Shader::createPixel(std::string(hmd_ui_frag)); auto program = gpu::Shader::createProgram(vs, ps); gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet()); - this->uniformsLocation = program->getUniformBuffers().findLocation("overlayBuffer"); + uniformsLocation = program->getUniformBuffers().findLocation("hudBuffer"); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - state->setDepthTest(gpu::State::DepthTest(false, false, gpu::LESS_EQUAL)); + state->setDepthTest(gpu::State::DepthTest(true, true, gpu::LESS_EQUAL)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); @@ -450,30 +427,27 @@ void HmdDisplayPlugin::OverlayRenderer::updatePipeline() { } } -void HmdDisplayPlugin::OverlayRenderer::render(HmdDisplayPlugin& plugin) { +std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { updatePipeline(); - for_each_eye([&](Eye eye){ - uniforms.mvp = mvps[eye]; - uniformBuffers[eye]->setSubData(0, uniforms); - }); - plugin.render([&](gpu::Batch& batch) { - batch.enableStereo(false); - batch.setFramebuffer(plugin._compositeFramebuffer); + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { batch.setPipeline(pipeline); + batch.setInputFormat(format); gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); batch.setInputBuffer(gpu::Stream::POSITION, posView); batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); batch.setIndexBuffer(gpu::UINT16, indices, 0); - batch.setResourceTexture(0, plugin._currentFrame->overlay); - // FIXME use stereo information input to set both MVPs in the uniforms - for_each_eye([&](Eye eye) { - batch.setUniformBuffer(uniformsLocation, uniformBuffers[eye]); - batch.setViewportTransform(plugin.eyeViewport(eye)); - batch.drawIndexed(gpu::TRIANGLES, indexCount); - }); - }); + + uniformsBuffer->setSubData(0, uniforms); + batch.setUniformBuffer(uniformsLocation, uniformsBuffer); + + auto compositorHelper = DependencyManager::get(); + batch.setModelTransform(compositorHelper->getUiTransform()); + batch.setResourceTexture(0, hudTexture); + + batch.drawIndexed(gpu::TRIANGLES, indexCount); + }; } void HmdDisplayPlugin::compositePointer() { @@ -500,12 +474,8 @@ void HmdDisplayPlugin::compositePointer() { }); } -void HmdDisplayPlugin::compositeOverlay() { - if (!_currentFrame || !_currentFrame->overlay) { - return; - } - - _overlayRenderer.render(*this); +std::function HmdDisplayPlugin::getHUDOperator() { + return _hudRenderer.render(*this); } HmdDisplayPlugin::~HmdDisplayPlugin() { diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index db4e0ff7a1..a7a6d2938d 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -33,7 +33,7 @@ public: glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; } bool isDisplayVisible() const override { return isHmdMounted(); } - QRect getRecommendedOverlayRect() const override final; + QRect getRecommendedHUDRect() const override final; virtual glm::mat4 getHeadPose() const override; @@ -53,7 +53,7 @@ protected: bool internalActivate() override; void internalDeactivate() override; - void compositeOverlay() override; + std::function getHUDOperator() override; void compositePointer() override; void internalPresent() override; void customizeContext() override; @@ -91,7 +91,7 @@ private: gpu::TexturePointer _previewTexture; glm::vec2 _lastWindowSize; - struct OverlayRenderer { + struct HUDRenderer { gpu::Stream::FormatPointer format; gpu::BufferPointer vertices; gpu::BufferPointer indices; @@ -99,12 +99,9 @@ private: gpu::PipelinePointer pipeline; int32_t uniformsLocation { -1 }; - // FIXME this is stupid, use the built in transformation pipeline - std::array uniformBuffers; - std::array mvps; + gpu::BufferPointer uniformsBuffer; struct Uniforms { - mat4 mvp; float alpha { 1.0f }; } uniforms; @@ -119,6 +116,6 @@ private: void build(); void updatePipeline(); - void render(HmdDisplayPlugin& plugin); - } _overlayRenderer; + std::function render(HmdDisplayPlugin& plugin); + } _hudRenderer; }; diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 77d22258b2..fca220c224 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -92,7 +92,7 @@ public: void captureNamedDrawCallInfo(std::string name); Batch(); - explicit Batch(const Batch& batch); + Batch(const Batch& batch); ~Batch(); void clear(); diff --git a/libraries/gpu/src/gpu/Frame.h b/libraries/gpu/src/gpu/Frame.h index 69872906e3..1ed77a26b7 100644 --- a/libraries/gpu/src/gpu/Frame.h +++ b/libraries/gpu/src/gpu/Frame.h @@ -32,14 +32,10 @@ namespace gpu { Mat4 pose; /// The collection of batches which make up the frame Batches batches; - /// Single batch containing overlays to be drawn in the composite framebuffer - Batch postCompositeBatch; /// The main thread updates to buffers that are applicable for this frame. BufferUpdates bufferUpdates; /// The destination framebuffer in which the results will be placed FramebufferPointer framebuffer; - /// The destination texture containing the 2D overlay - TexturePointer overlay; /// How to process the framebuffer when the frame dies. MUST BE THREAD SAFE FramebufferRecycler framebufferRecycler; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.cpp b/libraries/plugins/src/plugins/DisplayPlugin.cpp index 20c72159c4..e43d5e76f3 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.cpp +++ b/libraries/plugins/src/plugins/DisplayPlugin.cpp @@ -33,4 +33,13 @@ void DisplayPlugin::waitForPresent() { break; } } +} + +std::function DisplayPlugin::getHUDOperator() { + std::function hudOperator; + { + QMutexLocker locker(&_presentMutex); + hudOperator = _hudOperator; + } + return hudOperator; } \ No newline at end of file diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index d3054c9bd8..11ca6f754a 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -156,8 +156,8 @@ public: return aspect(getRecommendedRenderSize()); } - // The recommended bounds for primary overlay placement - virtual QRect getRecommendedOverlayRect() const { + // The recommended bounds for primary HUD placement + virtual QRect getRecommendedHUDRect() const { const int DESKTOP_SCREEN_PADDING = 50; auto recommendedSize = getRecommendedUiSize() - glm::uvec2(DESKTOP_SCREEN_PADDING); return QRect(0, 0, recommendedSize.x, recommendedSize.y); @@ -204,8 +204,9 @@ public: void waitForPresent(); - static const QString& MENU_PATH(); + std::function getHUDOperator(); + static const QString& MENU_PATH(); signals: void recommendedFramebufferSizeChanged(const QSize& size); @@ -217,6 +218,8 @@ protected: gpu::ContextPointer _gpuContext; + std::function _hudOperator { std::function() }; + private: QMutex _presentMutex; QWaitCondition _presentCondition; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index dc419c03c3..942da69dd7 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -385,7 +385,7 @@ ItemKey ModelMeshPartPayload::getKey() const { builder.withInvisible(); } - if (model->isLayeredInFront()) { + if (model->isLayeredInFront() || model->isLayeredInHUD()) { builder.withLayered(); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 6d338b4598..395a45b952 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -101,6 +101,7 @@ public: bool isVisible() const { return _isVisible; } bool isLayeredInFront() const { return _isLayeredInFront; } + bool isLayeredInHUD() const { return _isLayeredInHUD; } virtual void updateRenderItems(); void setRenderItemsNeedUpdate() { _renderItemsNeedUpdate = true; } @@ -410,6 +411,7 @@ protected: int _renderInfoHasTransparent { false }; bool _isLayeredInFront { false }; + bool _isLayeredInHUD { false }; private: float _loadingPriority { 0.0f }; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index c67a1c7875..cb00734edc 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -233,6 +233,9 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // AA job to be revisited task.addJob("Antialiasing", primaryFramebuffer); + // Composite the HUD + task.addJob("HUD"); + task.addJob("ToneAndPostRangeTimer", toneAndPostRangeTimer); // Blit! @@ -407,6 +410,18 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& } } +void CompositeHUD::run(const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_context); + + // Grab the HUD texture + gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) { + if (renderContext->args->_hudOperator) { + renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture); + } + }); +} + void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) { assert(renderContext->args); assert(renderContext->args->_context); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 865849b579..452420589b 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -155,6 +155,14 @@ protected: bool _opaquePass { true }; }; +class CompositeHUD { +public: + using JobModel = render::Job::Model; + + CompositeHUD() {} + void run(const render::RenderContextPointer& renderContext); +}; + class Blit { public: using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/hmd_ui.slf b/libraries/render-utils/src/hmd_ui.slf new file mode 100644 index 0000000000..959e8d733c --- /dev/null +++ b/libraries/render-utils/src/hmd_ui.slf @@ -0,0 +1,37 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// hmd_ui.frag +// fragment shader +// +// Created by Sam Gondelman on 9/28/17. +// Copyright 2017 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 +// + +uniform sampler2D hudTexture; + +struct HUDData { + float alpha; +}; + +layout(std140) uniform hudBuffer { + HUDData hud; +}; + +in vec2 _texCoord0; + +out vec4 fragColor0; + +void main() { + vec4 color = texture(hudTexture, _texCoord0); + color.a *= hud.alpha; + if (color.a <= 0.0) { + discard; + } + + fragColor0 = color; +} \ No newline at end of file diff --git a/libraries/render-utils/src/hmd_ui.slv b/libraries/render-utils/src/hmd_ui.slv new file mode 100644 index 0000000000..d6e02ff4cb --- /dev/null +++ b/libraries/render-utils/src/hmd_ui.slv @@ -0,0 +1,36 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// hmd_ui.vert +// vertex shader +// +// Created by Sam Gondelman on 9/28/17. +// Copyright 2017 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 gpu/Inputs.slh@> +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + +struct HUDData { + float alpha; +}; + +layout(std140) uniform hudBuffer { + HUDData hud; +}; + +out vec2 _texCoord0; + +void main() { + _texCoord0 = inTexCoord0.st; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> +} diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index 7070a4def5..a76b60ffe6 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -121,6 +121,9 @@ namespace render { RenderDetails _details; render::ScenePointer _scene; int8_t _cameraMode { -1 }; + + std::function _hudOperator; + gpu::TexturePointer _hudTexture; }; } diff --git a/scripts/system/controllers/controllerModules/hudOverlayPointer.js b/scripts/system/controllers/controllerModules/hudOverlayPointer.js index 487e491201..9da91417ed 100644 --- a/scripts/system/controllers/controllerModules/hudOverlayPointer.js +++ b/scripts/system/controllers/controllerModules/hudOverlayPointer.js @@ -31,7 +31,7 @@ glow: 1.0, lineWidth: 5, ignoreRayIntersection: true, // always ignore this - drawHUDLayer: true, // Even when burried inside of something, show it. + drawHUDLayer: true, parentID: AVATAR_SELF_ID }; var halfEnd = { @@ -40,7 +40,7 @@ color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE, alpha: 0.9, ignoreRayIntersection: true, - drawHUDLayer: true, // Even when burried inside of something, show it. + drawHUDLayer: true, visible: true }; var fullPath = { @@ -52,7 +52,7 @@ glow: 1.0, lineWidth: 5, ignoreRayIntersection: true, // always ignore this - drawHUDLayer: true, // Even when burried inside of something, show it. + drawHUDLayer: true, parentID: AVATAR_SELF_ID }; var fullEnd = { @@ -61,7 +61,7 @@ color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE, alpha: 0.9, ignoreRayIntersection: true, - drawHUDLayer: true, // Even when burried inside of something, show it. + drawHUDLayer: true, visible: true }; var holdPath = { @@ -73,7 +73,7 @@ glow: 1.0, lineWidth: 5, ignoreRayIntersection: true, // always ignore this - drawHUDLayer: true, // Even when burried inside of something, show it. + drawHUDLayer: true, parentID: AVATAR_SELF_ID }; diff --git a/scripts/system/libraries/toolBars.js b/scripts/system/libraries/toolBars.js index 351f10e7bd..058910940b 100644 --- a/scripts/system/libraries/toolBars.js +++ b/scripts/system/libraries/toolBars.js @@ -370,7 +370,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit return Math.min(Math.max(value, min), max); } - var recommendedRect = Controller.getRecommendedOverlayRect(); + var recommendedRect = Controller.getRecommendedHUDRect(); var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height }; that.windowDimensions = recommendedDimmensions; // Controller.getViewportDimensions(); that.origin = { x: recommendedRect.x, y: recommendedRect.y }; @@ -378,7 +378,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit // For example, maybe we want "keep the same percentage to whatever two edges are closest to the edge of screen". // If we change that, the places to do so are onResizeViewport, save (maybe), and the initial move based on Settings, below. that.onResizeViewport = function (newSize) { // Can be overridden or extended by clients. - var recommendedRect = Controller.getRecommendedOverlayRect(); + var recommendedRect = Controller.getRecommendedHUDRect(); var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height }; var originRelativeX = (that.x - that.origin.x - that.offset.x); var originRelativeY = (that.y - that.origin.y - that.offset.y); @@ -396,7 +396,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit // code once the new toolbar position is well established with users. this.isNewPositionKey = optionalPersistenceKey + '.isNewPosition'; this.save = function () { - var recommendedRect = Controller.getRecommendedOverlayRect(); + var recommendedRect = Controller.getRecommendedHUDRect(); var screenSize = { x: recommendedRect.width, y: recommendedRect.height }; if (screenSize.x > 0 && screenSize.y > 0) { // Guard against invalid screen size that can occur at shut-down. @@ -443,7 +443,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit that.move(that.dragOffsetX + event.x, that.dragOffsetY + event.y); }; that.checkResize = function () { // Can be overriden or extended, but usually not. See onResizeViewport. - var recommendedRect = Controller.getRecommendedOverlayRect(); + var recommendedRect = Controller.getRecommendedHUDRect(); var currentWindowSize = { x: recommendedRect.width, y: recommendedRect.height }; if ((currentWindowSize.x !== that.windowDimensions.x) || (currentWindowSize.y !== that.windowDimensions.y)) { @@ -471,7 +471,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit var savedFraction = isNewPosition ? JSON.parse(Settings.getValue(this.fractionKey) || "0") : 0; Settings.setValue(this.isNewPositionKey, true); - var recommendedRect = Controller.getRecommendedOverlayRect(); + var recommendedRect = Controller.getRecommendedHUDRect(); var screenSize = { x: recommendedRect.width, y: recommendedRect.height }; if (savedFraction) { // If we have saved data, keep the toolbar at the same proportion of the screen width/height. From 6571aef997acdb466a9bafcd2528806be357d437 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 29 Sep 2017 18:52:39 -0400 Subject: [PATCH 35/79] [Case 6491] makeStretchTool: Fix z undefined issue (details below). z:z appears to have been a typo, as there's no var z. Should likely be z:1. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 183fba1670..efe68fe973 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2833,7 +2833,7 @@ SelectionDisplay = (function() { planeNormal = { x: 0, y: 0, - z: z + z: 1 }; } } From dbf8d19095d2e9b56de89bf426289cb3017b86fd Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 2 Oct 2017 12:18:13 -0400 Subject: [PATCH 36/79] [Case 6491] eslint pass: fixes issues with equality checks. * Also adds some paren grouping to help with readability of some statements. * eslint pass on script using .eslintrc.js Changes to be committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index efe68fe973..61664ce245 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -140,12 +140,12 @@ SelectionManager = (function() { if (entityID) { var idx = -1; for (var i = 0; i < that.selections.length; i++) { - if (entityID == that.selections[i]) { + if (entityID === that.selections[i]) { idx = i; break; } } - if (idx == -1) { + if (idx === -1) { that.selections.push(entityID); } else if (toggleSelection) { that.selections.splice(idx, 1); @@ -175,7 +175,7 @@ SelectionManager = (function() { that.localPosition = null; that.worldDimensions = null; that.worldPosition = null; - } else if (that.selections.length == 1) { + } else if (that.selections.length === 1) { properties = Entities.getEntityProperties(that.selections[0]); that.localDimensions = properties.dimensions; that.localPosition = properties.position; @@ -1186,7 +1186,7 @@ SelectionDisplay = (function() { var top, far, left, bottom, near, right, boundsCenter, objectCenter, BLN, BRN, BLF, TLN, TRN, TLF, TRF; var dimensions, rotation; - if (spaceMode == SPACE_LOCAL) { + if (spaceMode === SPACE_LOCAL) { rotation = SelectionManager.localRotation; } else { rotation = SelectionManager.worldRotation; @@ -1478,9 +1478,9 @@ SelectionDisplay = (function() { //var translateHandlesVisible = true; //var selectionBoxVisible = true; var isPointLight = false; - if (selectionManager.selections.length == 1) { + if (selectionManager.selections.length === 1) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); - isPointLight = properties.type == "Light" && !properties.isSpotlight; + isPointLight = (properties.type === "Light") && !properties.isSpotlight; } if (isActiveTool(yawHandle) || isActiveTool(pitchHandle) || @@ -1567,7 +1567,7 @@ SelectionDisplay = (function() { print("======> SetSpaceMode called. ========"); } - if (spaceMode != newSpaceMode) { + if (spaceMode !== newSpaceMode) { if (wantDebug) { print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode); } @@ -1587,7 +1587,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("========> ToggleSpaceMode called. ========="); } - if (spaceMode == SPACE_WORLD && SelectionManager.selections.length > 1) { + if ((spaceMode === SPACE_WORLD) && (SelectionManager.selections.length > 1)) { if (wantDebug) { print("Local space editing is not available with multiple selections"); } @@ -1596,7 +1596,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("PreToggle: " + spaceMode); } - spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; + spaceMode = (spaceMode === SPACE_LOCAL) ? SPACE_WORLD : SPACE_LOCAL; that.updateHandles(); if (wantDebug) { print("PostToggle: " + spaceMode); @@ -1627,7 +1627,7 @@ SelectionDisplay = (function() { var rotation, dimensions, position, registrationPoint; - if (spaceMode == SPACE_LOCAL) { + if (spaceMode === SPACE_LOCAL) { rotation = SelectionManager.localRotation; dimensions = SelectionManager.localDimensions; position = SelectionManager.localPosition; @@ -1852,17 +1852,17 @@ SelectionDisplay = (function() { var inModeRotate = (isActiveTool(yawHandle) || isActiveTool(pitchHandle) || isActiveTool(rollHandle)); var inModeTranslate = (isActiveTool(selectionBox) || isActiveTool(grabberCloner) || isActiveTool(grabberMoveUp)); - var stretchHandlesVisible = !(inModeRotate || inModeTranslate) && (spaceMode == SPACE_LOCAL); + var stretchHandlesVisible = !(inModeRotate || inModeTranslate) && (spaceMode === SPACE_LOCAL); var extendedStretchHandlesVisible = (stretchHandlesVisible && showExtendedStretchHandles); var cloneHandleVisible = !(inModeRotate || inModeTranslate); if (wantDebug) { print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); } - var isSingleSelection = (selectionManager.selections.length == 1); + var isSingleSelection = (selectionManager.selections.length === 1); if (isSingleSelection) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); - var isLightSelection = (properties.type == "Light"); + var isLightSelection = (properties.type === "Light"); if (isLightSelection) { if (wantDebug) { print(" Light Selection revoking Non-Light Grabbers Visibility!"); @@ -2691,9 +2691,9 @@ SelectionDisplay = (function() { var onBegin = function(event, pickRay, pickResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; - rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); + rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); - if (spaceMode == SPACE_LOCAL) { + if (spaceMode === SPACE_LOCAL) { rotation = SelectionManager.localRotation; initialPosition = SelectionManager.localPosition; initialDimensions = SelectionManager.localDimensions; @@ -2739,7 +2739,7 @@ SelectionDisplay = (function() { } var start = null; var end = null; - if (numDimensions == 1 && mask.x) { + if ((numDimensions === 1) && mask.x) { start = Vec3.multiplyQbyV(rotation, { x: -10000, y: 0, @@ -2758,7 +2758,7 @@ SelectionDisplay = (function() { visible: true, }); } - if (numDimensions == 1 && mask.y) { + if ((numDimensions === 1) && mask.y) { start = Vec3.multiplyQbyV(rotation, { x: 0, y: -10000, @@ -2777,7 +2777,7 @@ SelectionDisplay = (function() { visible: true, }); } - if (numDimensions == 1 && mask.z) { + if ((numDimensions === 1) && mask.z) { start = Vec3.multiplyQbyV(rotation, { x: 0, y: 0, @@ -2796,14 +2796,14 @@ SelectionDisplay = (function() { visible: true, }); } - if (numDimensions == 1) { - if (mask.x == 1) { + if (numDimensions === 1) { + if (mask.x === 1) { planeNormal = { x: 0, y: 1, z: 0 }; - } else if (mask.y == 1) { + } else if (mask.y === 1) { planeNormal = { x: 1, y: 0, @@ -2816,7 +2816,7 @@ SelectionDisplay = (function() { z: 0 }; } - } else if (numDimensions == 2) { + } else if (numDimensions === 2) { if (mask.x === 0) { planeNormal = { x: 1, @@ -2873,10 +2873,10 @@ SelectionDisplay = (function() { }; var onMove = function(event) { - var proportional = spaceMode == SPACE_WORLD || event.isShifted || isActiveTool(grabberSpotLightRadius); + var proportional = (spaceMode === SPACE_WORLD) || event.isShifted || isActiveTool(grabberSpotLightRadius); var position, dimensions, rotation; - if (spaceMode == SPACE_LOCAL) { + if (spaceMode === SPACE_LOCAL) { position = SelectionManager.localPosition; dimensions = SelectionManager.localDimensions; rotation = SelectionManager.localRotation; @@ -3942,7 +3942,7 @@ SelectionDisplay = (function() { var results = testRayIntersect(pickRay, interactiveOverlays); if (results.intersects) { var hitOverlayID = results.overlayID; - if ((hitOverlayID == HMD.tabletID) || (hitOverlayID == HMD.tabletScreenID) || (hitOverlayID == HMD.homeButtonID)) { + if ((hitOverlayID === HMD.tabletID) || (hitOverlayID === HMD.tabletScreenID) || (hitOverlayID === HMD.homeButtonID)) { //--EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) return false; } From a610946af1c7c8bba2b4a3fc7e924a43f23f1e45 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 2 Oct 2017 12:31:10 -0400 Subject: [PATCH 37/79] [Case 6491] eslint pass: fixes undefined center var in that.updateHandles. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 61664ce245..cbd49e9ed8 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1646,7 +1646,7 @@ SelectionDisplay = (function() { }; // Center of entity, relative to registration point - center = getRelativeCenterPosition(dimensions, registrationPoint); + var center = getRelativeCenterPosition(dimensions, registrationPoint); // Distances in world coordinates relative to the registration point var left = -registrationPointDimensions.x; From c131686f1bd0cffa785abbf2d6610637d37fc29b Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 2 Oct 2017 12:55:51 -0400 Subject: [PATCH 38/79] [Case 6491] eslint pass: Addressing some comment issues. * This should reduces the noise for the eslint passes on this script. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index cbd49e9ed8..63d4c3cb2a 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1042,7 +1042,7 @@ SelectionDisplay = (function() { // But we dont' get mousePressEvents. that.triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); Script.scriptEnding.connect(that.triggerMapping.disable); - that.TRIGGER_GRAB_VALUE = 0.85; // From handControllerGrab/Pointer.js. Should refactor. + that.TRIGGER_GRAB_VALUE = 0.85; // From handControllerGrab/Pointer.js. Should refactor. that.TRIGGER_ON_VALUE = 0.4; that.TRIGGER_OFF_VALUE = 0.15; that.triggered = false; @@ -1103,7 +1103,7 @@ SelectionDisplay = (function() { if (!grabberTools.hasOwnProperty(toolHandle)) { print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle + ". Tools should be egistered via addGrabberTool."); - //--EARLY EXIT-- + // EARLY EXIT return false; } @@ -1472,11 +1472,11 @@ SelectionDisplay = (function() { var rotateHandlesVisible = true; var rotationOverlaysVisible = false; - //note: Commented out as these are currently unused here; however, - // leaving them around as they document intent of state as it - // relates to modes that may be useful later. - //var translateHandlesVisible = true; - //var selectionBoxVisible = true; + // note: Commented out as these are currently unused here; however, + // leaving them around as they document intent of state as it + // relates to modes that may be useful later. + // var translateHandlesVisible = true; + // var selectionBoxVisible = true; var isPointLight = false; if (selectionManager.selections.length === 1) { var properties = Entities.getEntityProperties(selectionManager.selections[0]); @@ -1487,14 +1487,14 @@ SelectionDisplay = (function() { isActiveTool(rollHandle) || isActiveTool(selectionBox) || isActiveTool(grabberCloner)) { rotationOverlaysVisible = true; rotateHandlesVisible = false; - //translateHandlesVisible = false; - //selectionBoxVisible = false; + // translateHandlesVisible = false; + // selectionBoxVisible = false; } else if (isActiveTool(grabberMoveUp) || isPointLight) { rotateHandlesVisible = false; } else if (activeTool) { // every other mode is a stretch mode... rotateHandlesVisible = false; - //translateHandlesVisible = false; + // translateHandlesVisible = false; } Overlays.editOverlay(rotateZeroOverlay, { @@ -1622,7 +1622,7 @@ SelectionDisplay = (function() { return; } - //print(" Triggering updateRotationHandles"); + // print(" Triggering updateRotationHandles"); that.updateRotationHandles(); var rotation, dimensions, position, registrationPoint; @@ -1938,7 +1938,7 @@ SelectionDisplay = (function() { visible: true, }); - } else { //..it's a PointLight + } else { // ..it's a PointLight that.setSpotLightHandlesVisible(false); var showEdgePointGrabbers = !inModeTranslate; @@ -2003,11 +2003,11 @@ SelectionDisplay = (function() { visible: true, }); } - } else { //..it's not a light at all + } else { // ..it's not a light at all that.setSpotLightHandlesVisible(false); that.setPointLightHandlesVisible(false); } - }//--end of isSingleSelection + }// end of isSingleSelection @@ -2290,7 +2290,7 @@ SelectionDisplay = (function() { var visibilityUpdate = { visible: isVisible }; for (var toolKey in grabberTools) { if (!grabberTools.hasOwnProperty(toolKey)) { - //--EARLY ITERATION EXIT--(On to the next one) + // EARLY ITERATION EXIT--(On to the next one) continue; } @@ -2411,14 +2411,14 @@ SelectionDisplay = (function() { print(" "+ translateXZTool.mode + "Pick ray does not intersect XZ plane."); } - //--EARLY EXIT--(Invalid ray detected.) + // EARLY EXIT--(Invalid ray detected.) return; } var vector = Vec3.subtract(pick, initialXZPick); // If the mouse is too close to the horizon of the pick plane, stop moving - var MIN_ELEVATION = 0.02; // largest dimension of object divided by distance to it + var MIN_ELEVATION = 0.02; // largest dimension of object divided by distance to it var elevation = translateXZTool.elevation(pickRay.origin, pick); if (wantDebug) { print("Start Elevation: " + translateXZTool.startingElevation + ", elevation: " + elevation); @@ -2429,12 +2429,12 @@ SelectionDisplay = (function() { print(" "+ translateXZTool.mode + " - too close to horizon!"); } - //--EARLY EXIT--(Don't proceed past the reached limit.) + // EARLY EXIT--(Don't proceed past the reached limit.) return; } // If the angular size of the object is too small, stop moving - var MIN_ANGULAR_SIZE = 0.01; // Radians + var MIN_ANGULAR_SIZE = 0.01; // Radians if (translateXZTool.greatestDimension > 0) { var angularSize = Math.atan(translateXZTool.greatestDimension / Vec3.distance(pickRay.origin, pick)); if (wantDebug) { @@ -2592,7 +2592,7 @@ SelectionDisplay = (function() { print(" event.y:" + event.y); Vec3.print(" newIntersection:", newIntersection); Vec3.print(" vector:", vector); - //Vec3.print(" newPosition:", newPosition); + // Vec3.print(" newPosition:", newPosition); } for (var i = 0; i < SelectionManager.selections.length; i++) { var id = SelectionManager.selections[i]; @@ -2970,10 +2970,10 @@ SelectionDisplay = (function() { var wantDebug = false; if (wantDebug) { print(stretchMode); - //Vec3.print(" newIntersection:", newIntersection); + // Vec3.print(" newIntersection:", newIntersection); Vec3.print(" vector:", vector); - //Vec3.print(" oldPOS:", oldPOS); - //Vec3.print(" newPOS:", newPOS); + // Vec3.print(" oldPOS:", oldPOS); + // Vec3.print(" newPOS:", newPOS); Vec3.print(" changeInDimensions:", changeInDimensions); Vec3.print(" newDimensions:", newDimensions); @@ -2983,7 +2983,7 @@ SelectionDisplay = (function() { } SelectionManager._update(); - };//--End of onMove def + };// End of onMove def return { mode: stretchMode, @@ -3581,7 +3581,7 @@ SelectionDisplay = (function() { if (!rotationChange) { print("ERROR: entitySelectionTool.updateSelectionsRotation - Invalid arg specified!!"); - //--EARLY EXIT-- + // EARLY EXIT return; } @@ -3677,14 +3677,14 @@ SelectionDisplay = (function() { if (wantDebug) { print("================== " + getMode() + "(rotation helper onBegin) <- ======================="); } - }//--End_Function(helperRotationHandleOnBegin) + }// End_Function(helperRotationHandleOnBegin) function helperRotationHandleOnMove(event, rotAroundAxis, rotCenter, handleRotation) { if (!rotZero) { print("ERROR: entitySelectionTool.handleRotationHandleOnMove - Invalid RotationZero Specified (missed rotation target plane?)"); - //--EARLY EXIT-- + // EARLY EXIT return; } @@ -3777,12 +3777,12 @@ SelectionDisplay = (function() { minorTickMarksLength: 0.1, }); } - }//--End_If(results.intersects) + }// End_If(results.intersects) if (wantDebug) { print("================== "+ getMode() + "(rotation helper onMove) <- ======================="); } - }//--End_Function(helperRotationHandleOnMove) + }// End_Function(helperRotationHandleOnMove) function helperRotationHandleOnEnd() { var wantDebug = false; @@ -3807,7 +3807,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("================== " + getMode() + "(onEnd) <- ======================="); } - }//--End_Function(helperRotationHandleOnEnd) + }// End_Function(helperRotationHandleOnEnd) // YAW GRABBER TOOL DEFINITION @@ -3860,7 +3860,7 @@ SelectionDisplay = (function() { if (SelectionManager.hasSelection()) { // FIXME - this cause problems with editing in the entity properties window - //SelectionManager._update(); + // SelectionManager._update(); if (!Vec3.equal(Camera.getPosition(), lastCameraPosition) || !Quat.equal(Camera.getOrientation(), lastCameraOrientation)) { @@ -3923,12 +3923,12 @@ SelectionDisplay = (function() { print("=============== eST::MousePressEvent BEG ======================="); } if (!event.isLeftButton && !that.triggered) { - //--EARLY EXIT-(if another mouse button than left is pressed ignore it) + // EARLY EXIT-(if another mouse button than left is pressed ignore it) return false; } var pickRay = generalComputePickRay(event.x, event.y); - //TODO_Case6491: Move this out to setup just to make it once + // TODO_Case6491: Move this out to setup just to make it once var interactiveOverlays = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, selectionBox]; for (var key in grabberTools) { if (grabberTools.hasOwnProperty(key)) { @@ -3943,7 +3943,7 @@ SelectionDisplay = (function() { if (results.intersects) { var hitOverlayID = results.overlayID; if ((hitOverlayID === HMD.tabletID) || (hitOverlayID === HMD.tabletScreenID) || (hitOverlayID === HMD.homeButtonID)) { - //--EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) + // EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) return false; } @@ -3959,8 +3959,8 @@ SelectionDisplay = (function() { } } else { print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays"); - }//--End_if (hitTool) - }//--End_If(results.intersects) + }// End_if (hitTool) + }// End_If(results.intersects) if (wantDebug) { print(" DisplayMode: " + getMode()); @@ -3992,7 +3992,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("=============== eST::MouseMoveEvent END ======================="); } - //--EARLY EXIT--(Move handled via active tool) + // EARLY EXIT--(Move handled via active tool) return true; } @@ -4156,7 +4156,7 @@ SelectionDisplay = (function() { } - showHandles = activeTool;// Date: Mon, 2 Oct 2017 13:21:10 -0400 Subject: [PATCH 39/79] [Case 6491] eslint pass: Cleaning up comma-dangle noise. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 63d4c3cb2a..db16acac94 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -217,7 +217,7 @@ SelectionManager = (function() { that.worldPosition = { x: brn.x + (that.worldDimensions.x / 2), y: brn.y + (that.worldDimensions.y / 2), - z: brn.z + (that.worldDimensions.z / 2), + z: brn.z + (that.worldDimensions.z / 2) }; // For 1+ selections we can only modify selections in world space @@ -373,7 +373,7 @@ SelectionDisplay = (function() { dashed: false, lineWidth: grabberLineWidth, drawInFront: true, - borderSize: 1.4, + borderSize: 1.4 }; var grabberPropertiesEdge = { @@ -390,7 +390,7 @@ SelectionDisplay = (function() { dashed: false, lineWidth: grabberLineWidth, drawInFront: true, - borderSize: 1.4, + borderSize: 1.4 }; var grabberPropertiesFace = { @@ -407,7 +407,7 @@ SelectionDisplay = (function() { dashed: false, lineWidth: grabberLineWidth, drawInFront: true, - borderSize: 1.4, + borderSize: 1.4 }; var grabberPropertiesCloner = { @@ -424,12 +424,12 @@ SelectionDisplay = (function() { dashed: false, lineWidth: grabberLineWidth, drawInFront: true, - borderSize: 1.4, + borderSize: 1.4 }; var spotLightLineProperties = { color: lightOverlayColor, - lineWidth: 1.5, + lineWidth: 1.5 }; var highlightBox = Overlays.addOverlay("cube", { @@ -469,7 +469,7 @@ SelectionDisplay = (function() { solid: false, visible: false, dashed: false, - lineWidth: 1.0, + lineWidth: 1.0 }); var selectionBoxes = []; @@ -505,7 +505,7 @@ SelectionDisplay = (function() { topMargin: 0, rightMargin: 0, bottomMargin: 0, - leftMargin: 0, + leftMargin: 0 }); var grabberMoveUp = Overlays.addOverlay("image3d", { @@ -521,7 +521,7 @@ SelectionDisplay = (function() { size: 0.1, scale: 0.1, isFacingAvatar: true, - drawInFront: true, + drawInFront: true }); // var normalLine = Overlays.addOverlay("line3d", { @@ -613,7 +613,7 @@ SelectionDisplay = (function() { var pointLightGrabberHandles = [ grabberPointLightCircleX, grabberPointLightCircleY, grabberPointLightCircleZ, grabberPointLightT, grabberPointLightB, grabberPointLightL, - grabberPointLightR, grabberPointLightF, grabberPointLightN, + grabberPointLightR, grabberPointLightF, grabberPointLightN ]; var grabberCloner = Overlays.addOverlay("cube", grabberPropertiesCloner); @@ -692,7 +692,7 @@ SelectionDisplay = (function() { width: 300, height: 200, rotation: baseOverlayRotation, - ignoreRayIntersection: true, // always ignore this + ignoreRayIntersection: true // always ignore this }); var yawOverlayAngles = { @@ -793,7 +793,7 @@ SelectionDisplay = (function() { green: 0, blue: 0 }, - ignoreRayIntersection: true, // always ignore this + ignoreRayIntersection: true // always ignore this }); var rotateCurrentOverlay = Overlays.addOverlay("line3d", { @@ -814,7 +814,7 @@ SelectionDisplay = (function() { green: 0, blue: 255 }, - ignoreRayIntersection: true, // always ignore this + ignoreRayIntersection: true // always ignore this }); @@ -849,7 +849,7 @@ SelectionDisplay = (function() { green: 0, blue: 0 }, - ignoreRayIntersection: true, // always ignore this + ignoreRayIntersection: true // always ignore this }); var rotateOverlayOuter = Overlays.addOverlay("circle3d", { @@ -884,7 +884,7 @@ SelectionDisplay = (function() { green: 0, blue: 0 }, - ignoreRayIntersection: true, // always ignore this + ignoreRayIntersection: true // always ignore this }); var rotateOverlayCurrent = Overlays.addOverlay("circle3d", { @@ -914,7 +914,7 @@ SelectionDisplay = (function() { red: 0, green: 0, blue: 0 - }, + } }); var yawHandle = Overlays.addOverlay("image3d", { @@ -930,7 +930,7 @@ SelectionDisplay = (function() { size: 0.1, scale: 0.1, isFacingAvatar: false, - drawInFront: true, + drawInFront: true }); @@ -947,7 +947,7 @@ SelectionDisplay = (function() { size: 0.1, scale: 0.1, isFacingAvatar: false, - drawInFront: true, + drawInFront: true }); @@ -964,7 +964,7 @@ SelectionDisplay = (function() { size: 0.1, scale: 0.1, isFacingAvatar: false, - drawInFront: true, + drawInFront: true }); var allOverlays = [ @@ -987,7 +987,7 @@ SelectionDisplay = (function() { grabberSpotLightCircle, grabberPointLightCircleX, grabberPointLightCircleY, - grabberPointLightCircleZ, + grabberPointLightCircleZ ].concat(stretchHandles); @@ -1532,20 +1532,20 @@ SelectionDisplay = (function() { for (var i = 0; i < stretchHandles.length; i++) { Overlays.editOverlay(stretchHandles[i], { - size: grabberSize, + size: grabberSize }); } var handleSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 7; handleSize = Math.min(handleSize, avgDimension / 3); Overlays.editOverlay(yawHandle, { - scale: handleSize, + scale: handleSize }); Overlays.editOverlay(pitchHandle, { - scale: handleSize, + scale: handleSize }); Overlays.editOverlay(rollHandle, { - scale: handleSize, + scale: handleSize }); var pos = Vec3.sum(grabberMoveUpPosition, { x: 0, @@ -1554,7 +1554,7 @@ SelectionDisplay = (function() { }); Overlays.editOverlay(grabberMoveUp, { position: pos, - scale: handleSize / 1.25, + scale: handleSize / 1.25 }); } }; @@ -1642,7 +1642,7 @@ SelectionDisplay = (function() { var registrationPointDimensions = { x: dimensions.x * registrationPoint.x, y: dimensions.y * registrationPoint.y, - z: dimensions.z * registrationPoint.z, + z: dimensions.z * registrationPoint.z }; // Center of entity, relative to registration point @@ -1877,33 +1877,33 @@ SelectionDisplay = (function() { var showEdgeSpotGrabbers = !(inModeTranslate || inModeRotate); Overlays.editOverlay(grabberSpotLightCenter, { position: position, - visible: false, + visible: false }); Overlays.editOverlay(grabberSpotLightRadius, { position: NEAR, rotation: rotation, - visible: showEdgeSpotGrabbers, + visible: showEdgeSpotGrabbers }); Overlays.editOverlay(grabberSpotLightL, { position: EdgeNL, rotation: rotation, - visible: showEdgeSpotGrabbers, + visible: showEdgeSpotGrabbers }); Overlays.editOverlay(grabberSpotLightR, { position: EdgeNR, rotation: rotation, - visible: showEdgeSpotGrabbers, + visible: showEdgeSpotGrabbers }); Overlays.editOverlay(grabberSpotLightT, { position: EdgeTN, rotation: rotation, - visible: showEdgeSpotGrabbers, + visible: showEdgeSpotGrabbers }); Overlays.editOverlay(grabberSpotLightB, { position: EdgeBN, rotation: rotation, - visible: showEdgeSpotGrabbers, + visible: showEdgeSpotGrabbers }); Overlays.editOverlay(grabberSpotLightCircle, { position: NEAR, @@ -1914,28 +1914,28 @@ SelectionDisplay = (function() { }, lineWidth: 1.5, rotation: rotation, - visible: true, + visible: true }); Overlays.editOverlay(grabberSpotLightLineT, { start: position, end: EdgeTN, - visible: true, + visible: true }); Overlays.editOverlay(grabberSpotLightLineB, { start: position, end: EdgeBN, - visible: true, + visible: true }); Overlays.editOverlay(grabberSpotLightLineR, { start: position, end: EdgeNR, - visible: true, + visible: true }); Overlays.editOverlay(grabberSpotLightLineL, { start: position, end: EdgeNL, - visible: true, + visible: true }); } else { // ..it's a PointLight @@ -1945,32 +1945,32 @@ SelectionDisplay = (function() { Overlays.editOverlay(grabberPointLightT, { position: TOP, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightB, { position: BOTTOM, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightL, { position: LEFT, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightR, { position: RIGHT, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightF, { position: FAR, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightN, { position: NEAR, rotation: rotation, - visible: showEdgePointGrabbers, + visible: showEdgePointGrabbers }); Overlays.editOverlay(grabberPointLightCircleX, { position: position, @@ -1980,7 +1980,7 @@ SelectionDisplay = (function() { y: properties.dimensions.z / 2.0, z: 1 }, - visible: true, + visible: true }); Overlays.editOverlay(grabberPointLightCircleY, { position: position, @@ -1990,7 +1990,7 @@ SelectionDisplay = (function() { y: properties.dimensions.z / 2.0, z: 1 }, - visible: true, + visible: true }); Overlays.editOverlay(grabberPointLightCircleZ, { position: position, @@ -2000,7 +2000,7 @@ SelectionDisplay = (function() { y: properties.dimensions.z / 2.0, z: 1 }, - visible: true, + visible: true }); } } else { // ..it's not a light at all @@ -2096,7 +2096,7 @@ SelectionDisplay = (function() { position: selectionBoxPosition, dimensions: dimensions, rotation: rotation, - visible: !inModeRotate, + visible: !inModeRotate }); // Create more selection box overlays if we don't have enough @@ -2120,7 +2120,7 @@ SelectionDisplay = (function() { visible: false, dashed: false, lineWidth: 1.0, - ignoreRayIntersection: true, + ignoreRayIntersection: true })); } @@ -2150,7 +2150,7 @@ SelectionDisplay = (function() { color: color, rotation: props.rotation, dimensions: props.dimensions, - visible: true, + visible: true }); } } @@ -2244,7 +2244,7 @@ SelectionDisplay = (function() { x: selectionManager.worldDimensions.x, y: selectionManager.worldDimensions.z }, - rotation: Quat.fromPitchYawRollDegrees(90, 0, 0), + rotation: Quat.fromPitchYawRollDegrees(90, 0, 0) }); if (wantDebug) { @@ -2368,7 +2368,7 @@ SelectionDisplay = (function() { var entityID = Entities.addEntity(properties); duplicatedEntityIDs.push({ entityID: entityID, - properties: properties, + properties: properties }); } } @@ -2519,7 +2519,7 @@ SelectionDisplay = (function() { z: vector.z }); Entities.editEntity(SelectionManager.selections[i], { - position: newPosition, + position: newPosition }); if (wantDebug) { @@ -2562,7 +2562,7 @@ SelectionDisplay = (function() { var entityID = Entities.addEntity(properties); duplicatedEntityIDs.push({ entityID: entityID, - properties: properties, + properties: properties }); } } @@ -2602,12 +2602,12 @@ SelectionDisplay = (function() { var newPosition = Vec3.sum(properties.position, vector); Entities.editEntity(id, { - position: newPosition, + position: newPosition }); } SelectionManager._update(); - }, + } }); // GRABBER TOOL: GRABBER CLONER @@ -2661,13 +2661,13 @@ SelectionDisplay = (function() { var signs = { x: direction.x < 0 ? -1 : (direction.x > 0 ? 1 : 0), y: direction.y < 0 ? -1 : (direction.y > 0 ? 1 : 0), - z: direction.z < 0 ? -1 : (direction.z > 0 ? 1 : 0), + z: direction.z < 0 ? -1 : (direction.z > 0 ? 1 : 0) }; var mask = { x: Math.abs(direction.x) > 0 ? 1 : 0, y: Math.abs(direction.y) > 0 ? 1 : 0, - z: Math.abs(direction.z) > 0 ? 1 : 0, + z: Math.abs(direction.z) > 0 ? 1 : 0 }; @@ -2755,7 +2755,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(xRailOverlay, { start: start, end: end, - visible: true, + visible: true }); } if ((numDimensions === 1) && mask.y) { @@ -2774,7 +2774,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(yRailOverlay, { start: start, end: end, - visible: true, + visible: true }); } if ((numDimensions === 1) && mask.z) { @@ -2793,7 +2793,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(zRailOverlay, { start: start, end: end, - visible: true, + visible: true }); } if (numDimensions === 1) { @@ -2962,7 +2962,7 @@ SelectionDisplay = (function() { for (var i = 0; i < SelectionManager.selections.length; i++) { Entities.editEntity(SelectionManager.selections[i], { position: newPosition, - dimensions: newDimensions, + dimensions: newDimensions }); } @@ -3090,7 +3090,7 @@ SelectionDisplay = (function() { var cutoff = Math.atan2(newSize, radius) * 180 / Math.PI; Entities.editEntity(selectionManager.selections[0], { - cutoff: cutoff, + cutoff: cutoff }); SelectionManager._update(); @@ -3117,7 +3117,7 @@ SelectionDisplay = (function() { }; Entities.editEntity(selectionManager.selections[0], { - dimensions: newDimensions, + dimensions: newDimensions }); SelectionManager._update(); @@ -3544,7 +3544,7 @@ SelectionDisplay = (function() { var position = { x: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, y: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - z: 0, + z: 0 }; if (wantDebug) { print(" Angle: " + angle); @@ -3560,7 +3560,7 @@ SelectionDisplay = (function() { y: innerRadius * ROTATION_DISPLAY_SIZE_Y_MULTIPLIER }, lineHeight: innerRadius * ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER, - text: normalizeDegrees(angleFromZero) + "°", + text: normalizeDegrees(angleFromZero) + "°" }; if (wantDebug) { print(" TranslatedPos: " + position.x + ", " + position.y + ", " + position.z); @@ -3594,7 +3594,7 @@ SelectionDisplay = (function() { var initialProperties = SelectionManager.savedProperties[entityID]; var newProperties = { - rotation: Quat.multiply(rotationChange, initialProperties.rotation), + rotation: Quat.multiply(rotationChange, initialProperties.rotation) }; if (reposition) { @@ -3637,7 +3637,7 @@ SelectionDisplay = (function() { innerRadius: 0.9, startAt: 0, endAt: 360, - alpha: innerAlpha, + alpha: innerAlpha }); Overlays.editOverlay(rotateOverlayOuter, { @@ -3648,7 +3648,7 @@ SelectionDisplay = (function() { innerRadius: 0.9, startAt: 0, endAt: 360, - alpha: outerAlpha, + alpha: outerAlpha }); Overlays.editOverlay(rotateOverlayCurrent, { @@ -3658,11 +3658,11 @@ SelectionDisplay = (function() { size: outerRadius, startAt: 0, endAt: 0, - innerRadius: 0.9, + innerRadius: 0.9 }); Overlays.editOverlay(rotationDegreesDisplay, { - visible: true, + visible: true }); updateRotationDegreesOverlay(0, handleRotation, rotCenter); @@ -3756,7 +3756,7 @@ SelectionDisplay = (function() { majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, majorTickMarksLength: -0.25, - minorTickMarksLength: 0, + minorTickMarksLength: 0 }); } else { Overlays.editOverlay(rotateOverlayInner, { @@ -3774,7 +3774,7 @@ SelectionDisplay = (function() { majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, majorTickMarksLength: 0.25, - minorTickMarksLength: 0.1, + minorTickMarksLength: 0.1 }); } }// End_If(results.intersects) From cb264b5552594ebb552972b14a45fb042dc60c68 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 2 Oct 2017 13:28:43 -0400 Subject: [PATCH 40/79] [Case 6491] eslint pass: Addresses curly bracket, keyword spacing issues. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index db16acac94..191d7a0748 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -238,8 +238,14 @@ SelectionManager = (function() { // Normalize degrees to be in the range (-180, 180] function normalizeDegrees(degrees) { - while (degrees > 180) degrees -= 360; - while (degrees <= -180) degrees += 360; + while (degrees > 180) { + degrees -= 360; + } + + while (degrees <= -180) { + degrees += 360; + } + return degrees; } @@ -2143,7 +2149,9 @@ SelectionDisplay = (function() { var curBoxPosition = Vec3.sum(props.position, offset); var color = {red: 255, green: 128, blue: 0}; - if (i >= selectionManager.selections.length - 1) color = {red: 255, green: 255, blue: 64}; + if (i >= selectionManager.selections.length - 1) { + color = {red: 255, green: 255, blue: 64}; + } Overlays.editOverlay(selectionBoxes[i], { position: curBoxPosition, @@ -4134,7 +4142,7 @@ SelectionDisplay = (function() { print(" Triggering ActiveTool(" + activeTool.mode + ")'s onEnd"); } activeTool.onEnd(event); - }else if (wantDebug) { + } else if (wantDebug) { print(" ActiveTool(" + activeTool.mode + ")'s missing onEnd"); } } From 477dfdff1ea3e48ae2a580007f4ea27ead945815 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 4 Oct 2017 11:45:21 -0700 Subject: [PATCH 41/79] wip hud layering and fix crashes --- interface/src/ui/overlays/ModelOverlay.cpp | 9 +++++ interface/src/ui/overlays/ModelOverlay.h | 2 ++ interface/src/ui/overlays/OverlaysPayload.cpp | 13 +++---- .../display-plugins/OpenGLDisplayPlugin.cpp | 13 +++++-- .../src/display-plugins/OpenGLDisplayPlugin.h | 1 + .../display-plugins/hmd/HmdDisplayPlugin.cpp | 28 ++++++++------- .../render-utils/src/MeshPartPayload.cpp | 14 ++++---- libraries/render-utils/src/Model.cpp | 15 ++++++++ libraries/render-utils/src/Model.h | 1 + .../render-utils/src/RenderDeferredTask.cpp | 34 ++++++++++++++----- libraries/render/src/render/FilterTask.cpp | 13 ++++--- libraries/render/src/render/FilterTask.h | 8 ++--- libraries/render/src/render/Item.h | 7 +++- 13 files changed, 111 insertions(+), 47 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 8ce6e7f1f3..a3088e1ddb 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -88,6 +88,10 @@ void ModelOverlay::update(float deltatime) { _drawInFrontDirty = false; _model->setLayeredInFront(getDrawInFront(), scene); } + if (_drawInHUDDirty) { + _drawInHUDDirty = false; + _model->setLayeredInHUD(getDrawHUDLayer(), scene); + } scene->enqueueTransaction(transaction); } @@ -112,6 +116,11 @@ void ModelOverlay::setDrawInFront(bool drawInFront) { _drawInFrontDirty = true; } +void ModelOverlay::setDrawHUDLayer(bool drawHUDLayer) { + Base3DOverlay::setDrawHUDLayer(drawHUDLayer); + _drawInHUDDirty = true; +} + void ModelOverlay::setProperties(const QVariantMap& properties) { auto origPosition = getPosition(); auto origRotation = getRotation(); diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index ba1ffa86c1..ea0eff170c 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -51,6 +51,7 @@ public: void setVisible(bool visible) override; void setDrawInFront(bool drawInFront) override; + void setDrawHUDLayer(bool drawHUDLayer) override; protected: Transform evalRenderTransform() override; @@ -98,6 +99,7 @@ private: bool _visibleDirty { false }; bool _drawInFrontDirty { false }; + bool _drawInHUDDirty { false }; }; diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index 7beb96c061..194c530df0 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -50,20 +50,17 @@ namespace render { return overlay->getBounds(); } template <> int payloadGetLayer(const Overlay::Pointer& overlay) { - // Magic number while we are defining the layering mechanism: - const int LAYER_2D = 2; - const int LAYER_3D_FRONT = 1; - const int LAYER_3D = 0; - if (overlay->is3D()) { auto overlay3D = std::dynamic_pointer_cast(overlay); if (overlay3D->getDrawInFront()) { - return LAYER_3D_FRONT; + return Item::LAYER_3D_FRONT; + } else if (overlay3D->getDrawHUDLayer()) { + return Item::LAYER_3D_HUD; } else { - return LAYER_3D; + return Item::LAYER_3D; } } else { - return LAYER_2D; + return Item::LAYER_2D; } } template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 0872edcd95..93e648f441 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -569,11 +569,11 @@ std::function OpenGLDisplayPlugin batch.setResourceTexture(0, hudTexture); if (isStereo()) { for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye)); + batch.setViewportTransform(eyeViewport(eye, getRecommendedRenderSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); }); } else { - batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize())); + batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); } }; @@ -838,6 +838,15 @@ ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye) const { return ivec4(vpPos, vpSize); } +ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye, uvec2 vpSize) const { + vpSize.x /= 2; + uvec2 vpPos; + if (eye == Eye::Right) { + vpPos.x = vpSize.x; + } + return ivec4(vpPos, vpSize); +} + gpu::gl::GLBackend* OpenGLDisplayPlugin::getGLBackend() { if (!_gpuContext || !_gpuContext->getBackend()) { return nullptr; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ec775aed4c..4bb82f3651 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -125,6 +125,7 @@ protected: void present(); virtual void swapBuffers(); ivec4 eyeViewport(Eye eye) const; + ivec4 eyeViewport(Eye eye, uvec2 vpSize) const; void render(std::function f); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 6d0134ec23..e5e1295786 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -430,23 +430,25 @@ void HmdDisplayPlugin::HUDRenderer::updatePipeline() { std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { updatePipeline(); return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { - batch.setPipeline(pipeline); + if (pipeline) { - batch.setInputFormat(format); - gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); - gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); - batch.setInputBuffer(gpu::Stream::POSITION, posView); - batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); - batch.setIndexBuffer(gpu::UINT16, indices, 0); + batch.setPipeline(pipeline); + batch.setInputFormat(format); + gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); + gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); + batch.setInputBuffer(gpu::Stream::POSITION, posView); + batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView); + batch.setIndexBuffer(gpu::UINT16, indices, 0); - uniformsBuffer->setSubData(0, uniforms); - batch.setUniformBuffer(uniformsLocation, uniformsBuffer); + uniformsBuffer->setSubData(0, uniforms); + batch.setUniformBuffer(uniformsLocation, uniformsBuffer); - auto compositorHelper = DependencyManager::get(); - batch.setModelTransform(compositorHelper->getUiTransform()); - batch.setResourceTexture(0, hudTexture); + auto compositorHelper = DependencyManager::get(); + batch.setModelTransform(compositorHelper->getUiTransform()); + batch.setResourceTexture(0, hudTexture); - batch.drawIndexed(gpu::TRIANGLES, indexCount); + batch.drawIndexed(gpu::TRIANGLES, indexCount); + } }; } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 942da69dd7..8b65c9f7ce 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -404,15 +404,15 @@ ItemKey ModelMeshPartPayload::getKey() const { } int ModelMeshPartPayload::getLayer() const { - // MAgic number while we are defining the layering mechanism: - const int LAYER_3D_FRONT = 1; - const int LAYER_3D = 0; ModelPointer model = _model.lock(); - if (model && model->isLayeredInFront()) { - return LAYER_3D_FRONT; - } else { - return LAYER_3D; + if (model) { + if (model->isLayeredInFront()) { + return Item::LAYER_3D_FRONT; + } else if (model->isLayeredInHUD()) { + return Item::LAYER_3D_HUD; + } } + return Item::LAYER_3D; } ShapeKey ModelMeshPartPayload::getShapeKey() const { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index f25cad8a6e..252afada5d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -598,6 +598,21 @@ void Model::setLayeredInFront(bool layered, const render::ScenePointer& scene) { } } +void Model::setLayeredInHUD(bool layered, const render::ScenePointer& scene) { + if (_isLayeredInHUD != layered) { + _isLayeredInHUD = layered; + + render::Transaction transaction; + foreach(auto item, _modelMeshRenderItemsMap.keys()) { + transaction.resetItem(item, _modelMeshRenderItemsMap[item]); + } + foreach(auto item, _collisionRenderItemsMap.keys()) { + transaction.resetItem(item, _collisionRenderItemsMap[item]); + } + scene->enqueueTransaction(transaction); + } +} + bool Model::addToScene(const render::ScenePointer& scene, render::Transaction& transaction, render::Item::Status::Getters& statusGetters) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 395a45b952..ee68258e2d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -84,6 +84,7 @@ public: // new Scene/Engine rendering support void setVisibleInScene(bool newValue, const render::ScenePointer& scene); void setLayeredInFront(bool layered, const render::ScenePointer& scene); + void setLayeredInHUD(bool layered, const render::ScenePointer& scene); bool needsFixupInScene() const; bool needsReload() const { return _needsReload; } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 7681642753..a0bef828fa 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -187,14 +187,19 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren } // Overlays - const auto overlayOpaquesInputs = DrawOverlay3D::Inputs(overlayOpaques, lightingModel).asVarying(); - const auto overlayTransparentsInputs = DrawOverlay3D::Inputs(overlayTransparents, lightingModel).asVarying(); - task.addJob("DrawOverlay3DOpaque", overlayOpaquesInputs, true); - task.addJob("DrawOverlay3DTransparent", overlayTransparentsInputs, false); + const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT); + const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT); + const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0); + const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN(0); - { // Debug the bounds of the rendered Overlay items, still look at the zbuffer - task.addJob("DrawOverlayOpaqueBounds", overlayOpaques); - task.addJob("DrawOverlayTransparentBounds", overlayTransparents); + const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel).asVarying(); + const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel).asVarying(); + task.addJob("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true); + task.addJob("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false); + + { // Debug the bounds of the rendered Overlay items that are marked drawInFront, still look at the zbuffer + task.addJob("DrawOverlayInFrontOpaqueBounds", overlaysInFrontOpaque); + task.addJob("DrawOverlayInFrontTransparentBounds", overlaysInFrontTransparent); } // Debugging stages @@ -233,9 +238,22 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // AA job to be revisited task.addJob("Antialiasing", primaryFramebuffer); - // Composite the HUD + // Composite the HUD and HUD overlays task.addJob("HUD"); + const auto overlaysHUDOpaque = filteredOverlaysOpaque.getN(1); + const auto overlaysHUDTransparent = filteredOverlaysTransparent.getN(1); + + const auto overlayHUDOpaquesInputs = DrawOverlay3D::Inputs(overlaysHUDOpaque, lightingModel).asVarying(); + const auto overlayHUDTransparentsInputs = DrawOverlay3D::Inputs(overlaysHUDTransparent, lightingModel).asVarying(); + task.addJob("DrawOverlayHUDOpaque", overlayHUDOpaquesInputs, true); + task.addJob("DrawOverlayHUDTransparent", overlayHUDTransparentsInputs, false); + + { // Debug the bounds of the rendered Overlay items that are marked drawHUDLayer, still look at the zbuffer + task.addJob("DrawOverlayHUDOpaqueBounds", overlaysHUDOpaque); + task.addJob("DrawOverlayHUDOpaqueBounds", overlaysHUDTransparent); + } + task.addJob("ToneAndPostRangeTimer", toneAndPostRangeTimer); // Blit! diff --git a/libraries/render/src/render/FilterTask.cpp b/libraries/render/src/render/FilterTask.cpp index e0298c2a44..49a9ada91e 100644 --- a/libraries/render/src/render/FilterTask.cpp +++ b/libraries/render/src/render/FilterTask.cpp @@ -21,19 +21,24 @@ using namespace render; -void FilterLayeredItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { +void FilterLayeredItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, Outputs& outputs) { auto& scene = renderContext->_scene; - // Clear previous values - outItems.clear(); + ItemBounds matchedItems; + ItemBounds nonMatchItems; // For each item, filter it into one bucket for (auto& itemBound : inItems) { auto& item = scene->getItem(itemBound.id); if (item.getLayer() == _keepLayer) { - outItems.emplace_back(itemBound); + matchedItems.emplace_back(itemBound); + } else { + nonMatchItems.emplace_back(itemBound); } } + + outputs.edit0() = matchedItems; + outputs.edit1() = nonMatchItems; } void SliceItems::run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems) { diff --git a/libraries/render/src/render/FilterTask.h b/libraries/render/src/render/FilterTask.h index 1e023a8bb9..a7180b6cde 100644 --- a/libraries/render/src/render/FilterTask.h +++ b/libraries/render/src/render/FilterTask.h @@ -65,15 +65,15 @@ namespace render { // Filter the items belonging to the job's keep layer class FilterLayeredItems { public: - using JobModel = Job::ModelIO; + using Outputs = render::VaryingSet2; + using JobModel = Job::ModelIO; - FilterLayeredItems() {} FilterLayeredItems(int keepLayer) : _keepLayer(keepLayer) {} - int _keepLayer { 0 }; + int _keepLayer; - void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, ItemBounds& outItems); + void run(const RenderContextPointer& renderContext, const ItemBounds& inItems, Outputs& outputs); }; // SliceItems job config defining the slice range diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 96faf9719e..8cdb41de45 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -356,9 +356,14 @@ public: // Get the bound of the item expressed in world space (or eye space depending on the key.isWorldSpace()) const Bound getBound() const { return _payload->getBound(); } - // Get the layer where the item belongs. 0 by default meaning NOT LAYERED + // Get the layer where the item belongs. int getLayer() const { return _payload->getLayer(); } + static const int LAYER_2D = 0; + static const int LAYER_3D = 1; + static const int LAYER_3D_FRONT = 2; + static const int LAYER_3D_HUD = 3; + // Render call for the item void render(RenderArgs* args) const { _payload->render(args); } From a5f5f9fc5d7b3d4a6c2fddf54961b3c5070e441c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 4 Oct 2017 12:05:13 -0700 Subject: [PATCH 42/79] try to improve performance --- .../src/EntityTreeRenderer.cpp | 10 ------- .../src/RenderableEntityItem.cpp | 17 ------------ .../src/RenderableEntityItem.h | 26 ------------------- .../src/RenderableModelEntityItem.cpp | 9 ++++--- .../src/RenderableModelEntityItem.h | 6 ++--- 5 files changed, 8 insertions(+), 60 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0cb25a2e2f..f8c40a5229 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -222,16 +222,6 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene _renderablesToUpdate.insert({ entityId, renderable }); } - // NOTE: Looping over all the entity renderers is likely to be a bottleneck in the future - // Currently, this is necessary because the model entity loading logic requires constant polling - // This was working fine because the entity server used to send repeated updates as your view changed, - // but with the improved entity server logic (PR 11141), updateInScene (below) would not be triggered enough - for (const auto& entry : _entitiesInScene) { - const auto& renderable = entry.second; - if (renderable) { - renderable->update(scene, transaction); - } - } if (!_renderablesToUpdate.empty()) { for (const auto& entry : _renderablesToUpdate) { const auto& renderable = entry.second; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index ea514d3181..3f1e89b86c 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -291,18 +291,6 @@ void EntityRenderer::updateInScene(const ScenePointer& scene, Transaction& trans }); } -void EntityRenderer::update(const ScenePointer& scene, Transaction& transaction) { - if (!isValidRenderItem()) { - return; - } - - if (!needsUpdate()) { - return; - } - - doUpdate(scene, transaction, _entity); -} - // // Internal methods // @@ -316,11 +304,6 @@ bool EntityRenderer::needsRenderUpdate() const { return needsRenderUpdateFromEntity(_entity); } -// Returns true if the item needs to have update called -bool EntityRenderer::needsUpdate() const { - return needsUpdateFromEntity(_entity); -} - // Returns true if the item in question needs to have updateInScene called because of changes in the entity bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity) const { bool success = false; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 56cb39252f..6b47ff8b1d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -49,8 +49,6 @@ public: virtual bool addToScene(const ScenePointer& scene, Transaction& transaction) final; virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction); - virtual void update(const ScenePointer& scene, Transaction& transaction); - protected: virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); } virtual void onAddToScene(const EntityItemPointer& entity); @@ -73,12 +71,6 @@ protected: // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const; - // Returns true if the item in question needs to have update called - virtual bool needsUpdate() const; - - // Returns true if the item in question needs to have update called because of changes in the entity - virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const { return false; } - // Will be called on the main thread from updateInScene. This can be used to fetch things like // network textures or model geometry from resource caches virtual void doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } @@ -88,8 +80,6 @@ protected: // data in this method if using multi-threaded rendering virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity); - virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { } - // Called by the `render` method after `needsRenderUpdate` virtual void doRender(RenderArgs* args) = 0; @@ -158,15 +148,6 @@ protected: onRemoveFromSceneTyped(_typedEntity); } - using Parent::needsUpdateFromEntity; - // Returns true if the item in question needs to have update called because of changes in the entity - virtual bool needsUpdateFromEntity(const EntityItemPointer& entity) const override final { - if (Parent::needsUpdateFromEntity(entity)) { - return true; - } - return needsUpdateFromTypedEntity(_typedEntity); - } - using Parent::needsRenderUpdateFromEntity; // Returns true if the item in question needs to have updateInScene called because of changes in the entity virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const override final { @@ -181,11 +162,6 @@ protected: doRenderUpdateSynchronousTyped(scene, transaction, _typedEntity); } - virtual void doUpdate(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) override final { - Parent::doUpdate(scene, transaction, entity); - doUpdateTyped(scene, transaction, _typedEntity); - } - virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity) override final { Parent::doRenderUpdateAsynchronous(entity); doRenderUpdateAsynchronousTyped(_typedEntity); @@ -194,8 +170,6 @@ protected: virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { } - virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; } - virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { } virtual void onAddToSceneTyped(const TypedEntityPointer& entity) { } virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) { } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index d1e47fd906..19da8a77f4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1026,7 +1026,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { entity->copyAnimationJointDataToModel(); } -bool ModelEntityRenderer::needsUpdate() const { +bool ModelEntityRenderer::needsRenderUpdate() const { ModelPointer model; withReadLock([&] { model = _model; @@ -1061,10 +1061,10 @@ bool ModelEntityRenderer::needsUpdate() const { return true; } } - return Parent::needsUpdate(); + return Parent::needsRenderUpdate(); } -bool ModelEntityRenderer::needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const { +bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { if (entity->hasModel() != _hasModel) { return true; @@ -1126,7 +1126,7 @@ bool ModelEntityRenderer::needsUpdateFromTypedEntity(const TypedEntityPointer& e return false; } -void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { if (_hasModel != entity->hasModel()) { _hasModel = entity->hasModel(); } @@ -1250,6 +1250,7 @@ void ModelEntityRenderer::doUpdateTyped(const ScenePointer& scene, Transaction& void ModelEntityRenderer::handleModelLoaded(bool success) { if (success) { _modelJustLoaded = true; + emit requestRenderUpdate(); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index ad0afeee0a..77121c30d9 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -138,10 +138,10 @@ protected: virtual ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) override; - virtual bool needsUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual bool needsUpdate() const override; + virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual bool needsRenderUpdate() const override; virtual void doRender(RenderArgs* args) override; - virtual void doUpdateTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; private: void animate(const TypedEntityPointer& entity); From a5b913a8b992f73216cc2c4af7c308deb85b9b09 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 4 Oct 2017 17:36:28 -0400 Subject: [PATCH 43/79] [Case 6491] Fixes minor spacing issue, on while loop missed previous eslint pass. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 191d7a0748..30c050d7e5 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -239,13 +239,13 @@ SelectionManager = (function() { // Normalize degrees to be in the range (-180, 180] function normalizeDegrees(degrees) { while (degrees > 180) { - degrees -= 360; + degrees -= 360; } while (degrees <= -180) { - degrees += 360; + degrees += 360; } - + return degrees; } From 9de1ca4e1af3f22431a30af5e68bde0774692a9c Mon Sep 17 00:00:00 2001 From: druiz17 Date: Wed, 4 Oct 2017 13:44:36 -0700 Subject: [PATCH 44/79] allow farGrab module to run when stylus is visible --- .../controllerModules/tabletStylusInput.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 36ed7920dd..29fa878cb1 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -248,17 +248,20 @@ Script.include("/~/system/libraries/controllers.js"); } }; - this.nearGrabWantsToRun = function(controllerData) { - var moduleName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; - var module = getEnabledModuleByName(moduleName); - var ready = module ? module.isReady(controllerData) : makeRunningValues(false, [], []); - return ready.active; + this.otherModuleNeedsToRun = function(controllerData) { + var grabOverlayModuleName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; + var grabOverlayModule = getEnabledModuleByName(grabOverlayModuleName); + var grabOverlayModuleReady = grabOverlayModule ? grabOverlayModule.isReady(controllerData) : makeRunningValues(false, [], []); + var farGrabModuleName = this.hand === RIGHT_HAND ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"; + var farGrabModule = getEnabledModuleByName(farGrabModuleName); + var farGrabModuleReady = farGrabModule ? farGrabModule.isReady(controllerData) : makeRunningValues(false, [], []); + return grabOverlayModuleReady.active || farGrabModuleReady.active; }; this.processStylus = function(controllerData) { this.updateStylusTip(); - if (!this.stylusTip.valid || this.overlayLaserActive(controllerData) || this.nearGrabWantsToRun(controllerData)) { + if (!this.stylusTip.valid || this.overlayLaserActive(controllerData) || this.otherModuleNeedsToRun(controllerData)) { this.pointFinger(false); this.hideStylus(); return false; From ac81b22cc92480f6ff7769f41068d95c54205c9b Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 4 Oct 2017 20:24:20 -0400 Subject: [PATCH 45/79] [Case 6491] eslint pass: Fixes references to SelectionManager (details below). SelectionManager was being referred to as selectionManager. * eslint pass used .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 30c050d7e5..62e265b5fd 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1176,8 +1176,8 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE ROTATION HANDLES that.updateRotationHandles = function() { - var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); + var diagonal = (Vec3.length(SelectionManager.worldDimensions) / 2) * 1.1; + var halfDimensions = Vec3.multiply(SelectionManager.worldDimensions, 0.5); var innerActive = false; var innerAlpha = 0.2; var outerAlpha = 0.2; @@ -1484,8 +1484,8 @@ SelectionDisplay = (function() { // var translateHandlesVisible = true; // var selectionBoxVisible = true; var isPointLight = false; - if (selectionManager.selections.length === 1) { - var properties = Entities.getEntityProperties(selectionManager.selections[0]); + if (SelectionManager.selections.length === 1) { + var properties = Entities.getEntityProperties(SelectionManager.selections[0]); isPointLight = (properties.type === "Light") && !properties.isSpotlight; } @@ -1529,8 +1529,8 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE HANDLE SIZES that.updateHandleSizes = function() { - if (selectionManager.hasSelection()) { - var diff = Vec3.subtract(selectionManager.worldPosition, Camera.getPosition()); + if (SelectionManager.hasSelection()) { + var diff = Vec3.subtract(SelectionManager.worldPosition, Camera.getPosition()); var grabberSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 5; var dimensions = SelectionManager.worldDimensions; var avgDimension = (dimensions.x + dimensions.y + dimensions.z) / 3; @@ -1864,10 +1864,10 @@ SelectionDisplay = (function() { if (wantDebug) { print(" Set Non-Light Grabbers Visible - Norm: " + stretchHandlesVisible + " Ext: " + extendedStretchHandlesVisible); } - var isSingleSelection = (selectionManager.selections.length === 1); + var isSingleSelection = (SelectionManager.selections.length === 1); if (isSingleSelection) { - var properties = Entities.getEntityProperties(selectionManager.selections[0]); + var properties = Entities.getEntityProperties(SelectionManager.selections[0]); var isLightSelection = (properties.type === "Light"); if (isLightSelection) { if (wantDebug) { @@ -2106,7 +2106,7 @@ SelectionDisplay = (function() { }); // Create more selection box overlays if we don't have enough - var overlaysNeeded = selectionManager.selections.length - selectionBoxes.length; + var overlaysNeeded = SelectionManager.selections.length - selectionBoxes.length; for (var i = 0; i < overlaysNeeded; i++) { selectionBoxes.push( Overlays.addOverlay("cube", { @@ -2132,9 +2132,9 @@ SelectionDisplay = (function() { i = 0; // Only show individual selections boxes if there is more than 1 selection - if (selectionManager.selections.length > 1) { - for (; i < selectionManager.selections.length; i++) { - var props = Entities.getEntityProperties(selectionManager.selections[i]); + if (SelectionManager.selections.length > 1) { + for (; i < SelectionManager.selections.length; i++) { + var props = Entities.getEntityProperties(SelectionManager.selections[i]); // Adjust overlay position to take registrationPoint into account // centeredRP = registrationPoint with range [-0.5, 0.5] @@ -2149,7 +2149,7 @@ SelectionDisplay = (function() { var curBoxPosition = Vec3.sum(props.position, offset); var color = {red: 255, green: 128, blue: 0}; - if (i >= selectionManager.selections.length - 1) { + if (i >= SelectionManager.selections.length - 1) { color = {red: 255, green: 255, blue: 64}; } @@ -2244,13 +2244,13 @@ SelectionDisplay = (function() { visible: !inModeRotate, solid: true, position: { - x: selectionManager.worldPosition.x, + x: SelectionManager.worldPosition.x, y: grid.getOrigin().y, - z: selectionManager.worldPosition.z + z: SelectionManager.worldPosition.z }, dimensions: { - x: selectionManager.worldDimensions.x, - y: selectionManager.worldDimensions.z + x: SelectionManager.worldDimensions.x, + y: SelectionManager.worldDimensions.z }, rotation: Quat.fromPitchYawRollDegrees(90, 0, 0) }); @@ -2509,7 +2509,7 @@ SelectionDisplay = (function() { } constrainMajorOnly = event.isControl; - var cornerPosition = Vec3.sum(startPosition, Vec3.multiply(-0.5, selectionManager.worldDimensions)); + var cornerPosition = Vec3.sum(startPosition, Vec3.multiply(-0.5, SelectionManager.worldDimensions)); vector = Vec3.subtract( grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly), cornerPosition); @@ -2604,7 +2604,7 @@ SelectionDisplay = (function() { } for (var i = 0; i < SelectionManager.selections.length; i++) { var id = SelectionManager.selections[i]; - var properties = selectionManager.savedProperties[id]; + var properties = SelectionManager.savedProperties[id]; var original = properties.position; var newPosition = Vec3.sum(properties.position, vector); @@ -3088,7 +3088,7 @@ SelectionDisplay = (function() { Vec3.print("Radius stretch: ", vector); } var length = vector.x + vector.y + vector.z; - var props = selectionManager.savedProperties[selectionManager.selections[0]]; + var props = SelectionManager.savedProperties[SelectionManager.selections[0]]; var radius = props.dimensions.z / 2; var originalCutoff = props.cutoff; @@ -3097,7 +3097,7 @@ SelectionDisplay = (function() { var newSize = originalSize + length; var cutoff = Math.atan2(newSize, radius) * 180 / Math.PI; - Entities.editEntity(selectionManager.selections[0], { + Entities.editEntity(SelectionManager.selections[0], { cutoff: cutoff }); @@ -3106,7 +3106,7 @@ SelectionDisplay = (function() { // FUNCTION: RADIUS STRETCH FUNC function radiusStretchFunc(vector, change) { - var props = selectionManager.savedProperties[selectionManager.selections[0]]; + var props = SelectionManager.savedProperties[SelectionManager.selections[0]]; // Find the axis being adjusted var size; @@ -3124,7 +3124,7 @@ SelectionDisplay = (function() { z: size }; - Entities.editEntity(selectionManager.selections[0], { + Entities.editEntity(SelectionManager.selections[0], { dimensions: newDimensions }); @@ -3631,8 +3631,8 @@ SelectionDisplay = (function() { rotationNormal[rotAroundAxis] = 1; // Size the overlays to the current selection size - var diagonal = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - var halfDimensions = Vec3.multiply(selectionManager.worldDimensions, 0.5); + var diagonal = (Vec3.length(SelectionManager.worldDimensions) / 2) * 1.1; + var halfDimensions = Vec3.multiply(SelectionManager.worldDimensions, 0.5); innerRadius = diagonal; outerRadius = diagonal * 1.15; var innerAlpha = 0.2; @@ -3955,7 +3955,7 @@ SelectionDisplay = (function() { return false; } - entityIconOverlayManager.setIconsSelectable(selectionManager.selections, true); + entityIconOverlayManager.setIconsSelectable(SelectionManager.selections, true); var hitTool = grabberTools[ hitOverlayID ]; if (hitTool) { From e9ae2099f3910f5d7b77a6a0af62b7f3ae0e2297 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 4 Oct 2017 20:37:57 -0400 Subject: [PATCH 46/79] [Case 6491] eslint pass: Fixes indent issues. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- .../system/libraries/entitySelectionTool.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 62e265b5fd..647080b742 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2429,7 +2429,7 @@ SelectionDisplay = (function() { var MIN_ELEVATION = 0.02; // largest dimension of object divided by distance to it var elevation = translateXZTool.elevation(pickRay.origin, pick); if (wantDebug) { - print("Start Elevation: " + translateXZTool.startingElevation + ", elevation: " + elevation); + print("Start Elevation: " + translateXZTool.startingElevation + ", elevation: " + elevation); } if ((translateXZTool.startingElevation > 0.0 && elevation < MIN_ELEVATION) || (translateXZTool.startingElevation < 0.0 && elevation > -MIN_ELEVATION)) { @@ -2642,11 +2642,11 @@ SelectionDisplay = (function() { // FUNCTION: VEC 3 MULT var vec3Mult = function(v1, v2) { - return { - x: v1.x * v2.x, - y: v1.y * v2.y, - z: v1.z * v2.z - }; + return { + x: v1.x * v2.x, + y: v1.y * v2.y, + z: v1.z * v2.z + }; }; // FUNCTION: MAKE STRETCH TOOL @@ -2740,8 +2740,7 @@ SelectionDisplay = (function() { deltaPivot3D = Vec3.subtract(centeredRP, scaledPivot3D); var scaledOffsetWorld3D = vec3Mult(initialDimensions, - Vec3.subtract(Vec3.multiply(0.5, Vec3.multiply(-1.0, directionFor3DStretch)), - centeredRP)); + Vec3.subtract(Vec3.multiply(0.5, Vec3.multiply(-1.0, directionFor3DStretch)), centeredRP)); pickRayPosition3D = Vec3.sum(initialPosition, Vec3.multiplyQbyV(rotation, scaledOffsetWorld)); } @@ -2921,8 +2920,8 @@ SelectionDisplay = (function() { } else { newPick = rayPlaneIntersection(pickRay, - pickRayPosition, - planeNormal); + pickRayPosition, + planeNormal); vector = Vec3.subtract(newPick, lastPick); vector = Vec3.multiplyQbyV(Quat.inverse(rotation), vector); From 18d884f6c45c00cc4086fa2472139bd6d82d7afc Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 4 Oct 2017 20:44:47 -0400 Subject: [PATCH 47/79] [Case 6491] eslint pass: Fixes no-multiple-empty-lines issues. * eslint pass using .eslintrc.js Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 647080b742..68cdf91dc1 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2016,7 +2016,6 @@ SelectionDisplay = (function() { }// end of isSingleSelection - Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, rotation: rotation, @@ -2515,7 +2514,6 @@ SelectionDisplay = (function() { cornerPosition); - for (var i = 0; i < SelectionManager.selections.length; i++) { var properties = SelectionManager.savedProperties[SelectionManager.selections[i]]; if (!properties) { @@ -2639,7 +2637,6 @@ SelectionDisplay = (function() { }); - // FUNCTION: VEC 3 MULT var vec3Mult = function(v1, v2) { return { @@ -2677,8 +2674,7 @@ SelectionDisplay = (function() { y: Math.abs(direction.y) > 0 ? 1 : 0, z: Math.abs(direction.z) > 0 ? 1 : 0 }; - - + var numDimensions = mask.x + mask.y + mask.z; @@ -4187,7 +4183,6 @@ SelectionDisplay = (function() { Controller.mouseReleaseEvent.connect(that.mouseReleaseEvent); - return that; }()); From 347645329eaa14071792d032672ec04e82168e17 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Thu, 5 Oct 2017 09:11:02 -0700 Subject: [PATCH 48/79] fixing laser staying on in edit mode --- .../system/controllers/controllerModules/farActionGrabEntity.js | 1 - scripts/system/libraries/entitySelectionTool.js | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index c5b82f75f0..81ffaa4189 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -408,7 +408,6 @@ Script.include("/~/system/libraries/controllers.js"); this.distanceRotating = false; if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { - this.updateLaserPointer(controllerData); this.prepareDistanceRotatingData(controllerData); return makeRunningValues(true, [], []); } else { diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 4df25c41b7..010c86f4d4 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -4076,7 +4076,6 @@ SelectionDisplay = (function() { if (controllerPose.valid && lastControllerPoses[hand].valid) { if (!Vec3.equal(controllerPose.position, lastControllerPoses[hand].position) || !Vec3.equal(controllerPose.rotation, lastControllerPoses[hand].rotation)) { - print("setting controller pose"); that.mouseMoveEvent({}); } } From 601b30f0628aaa2466e59984ecd91ec3c875d654 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 5 Oct 2017 15:31:45 -0700 Subject: [PATCH 49/79] fix flash when switching display modes --- .../display-plugins/OpenGLDisplayPlugin.cpp | 22 ++++++++++--------- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 93e648f441..13abcbadc6 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -564,17 +564,19 @@ void OpenGLDisplayPlugin::updateFrameData() { std::function OpenGLDisplayPlugin::getHUDOperator() { return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { - batch.enableStereo(false); - batch.setPipeline(_hudPipeline); - batch.setResourceTexture(0, hudTexture); - if (isStereo()) { - for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye, getRecommendedRenderSize())); + if (_hudPipeline) { + batch.enableStereo(false); + batch.setPipeline(_hudPipeline); + batch.setResourceTexture(0, hudTexture); + if (isStereo()) { + for_each_eye([&](Eye eye) { + batch.setViewportTransform(eyeViewport(eye, getRecommendedRenderSize())); + batch.draw(gpu::TRIANGLE_STRIP, 4); + }); + } else { + batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); - }); - } else { - batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); - batch.draw(gpu::TRIANGLE_STRIP, 4); + } } }; } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index e5e1295786..053f3171be 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -431,8 +431,8 @@ std::function HmdDisplayPlugin::H updatePipeline(); return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { if (pipeline) { - batch.setPipeline(pipeline); + batch.setInputFormat(format); gpu::BufferView posView(vertices, VERTEX_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::POSITION)._element); gpu::BufferView uvView(vertices, TEXTURE_OFFSET, vertices->getSize(), VERTEX_STRIDE, format->getAttributes().at(gpu::Stream::TEXCOORD)._element); From 707569b23020391c43697d6d51999b8b02671f7c Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 6 Oct 2017 09:50:24 -0400 Subject: [PATCH 50/79] [Case 6491] More efficient version of normalizeDegrees function (details below). Refactoring the original normalizeDegrees function to be more efficient as suggested via: https://github.com/highfidelity/hifi/pull/11338#pullrequestreview-67520585 Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 68cdf91dc1..b6b4b56d5a 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -238,11 +238,8 @@ SelectionManager = (function() { // Normalize degrees to be in the range (-180, 180] function normalizeDegrees(degrees) { - while (degrees > 180) { - degrees -= 360; - } - - while (degrees <= -180) { + degrees = ((degrees + 180) % 360) - 180; + if (degrees < -180) { degrees += 360; } From 2f082d9e86684a791e928750a21863084af47fdf Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 6 Oct 2017 10:11:26 -0400 Subject: [PATCH 51/79] [Case 6491] Fixes issue in normalizeDegrees from last commit (details below). The range of the function is targeting (-180, 180] such that the statement: if (degrees < -180) should be: if (degrees <= -180) to account for degrees being -180. Changes Committed: modified: scripts/system/libraries/entitySelectionTool.js --- scripts/system/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b6b4b56d5a..d36b3f28ee 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -239,7 +239,7 @@ SelectionManager = (function() { // Normalize degrees to be in the range (-180, 180] function normalizeDegrees(degrees) { degrees = ((degrees + 180) % 360) - 180; - if (degrees < -180) { + if (degrees <= -180) { degrees += 360; } From e95ecc3f272a176737b4c42695e66d65546d0685 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 6 Oct 2017 15:30:34 -0700 Subject: [PATCH 52/79] fix missing sensorToWorld matrix --- interface/src/Application.cpp | 1 + interface/src/ui/OverlayConductor.cpp | 1 - interface/src/ui/overlays/Base3DOverlay.cpp | 8 +++----- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 13 ++----------- .../src/display-plugins/OpenGLDisplayPlugin.h | 1 - .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 1 - 6 files changed, 6 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e93e67d5a..2079705bcf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5053,6 +5053,7 @@ void Application::update(float deltaTime) { float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); appRenderArgs._sensorToWorldScale = sensorToWorldScale; + appRenderArgs._sensorToWorld = getMyAvatar()->getSensorToWorldMatrix(); { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); { diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 71aff38032..dbf58c5cbc 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -96,7 +96,6 @@ bool OverlayConductor::updateAvatarHasDriveInput() { void OverlayConductor::centerUI() { // place the overlay at the current hmd position in sensor space auto camMat = cancelOutRollAndPitch(qApp->getHMDSensorPose()); - qDebug() << "OverlayConductor::centerUI" << camMat; qApp->getApplicationCompositor().setModelTransform(Transform(camMat)); } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 6625ae54f7..a34240483b 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -277,10 +277,10 @@ void Base3DOverlay::update(float duration) { // then the correct transform used for rendering is computed in the update transaction and assigned. if (_renderTransformDirty) { auto itemID = getRenderItemID(); - // Capture the render transform value in game loop before - auto latestTransform = evalRenderTransform(); - _renderTransformDirty = false; if (render::Item::isValidID(itemID)) { + // Capture the render transform value in game loop before + auto latestTransform = evalRenderTransform(); + _renderTransformDirty = false; render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID, [latestTransform](Overlay& data) { @@ -290,8 +290,6 @@ void Base3DOverlay::update(float duration) { } }); scene->enqueueTransaction(transaction); - } else { - setRenderTransform(latestTransform); } } } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 13abcbadc6..88aa56cccf 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -570,11 +570,11 @@ std::function OpenGLDisplayPlugin batch.setResourceTexture(0, hudTexture); if (isStereo()) { for_each_eye([&](Eye eye) { - batch.setViewportTransform(eyeViewport(eye, getRecommendedRenderSize())); + batch.setViewportTransform(eyeViewport(eye)); batch.draw(gpu::TRIANGLE_STRIP, 4); }); } else { - batch.setViewportTransform(ivec4(uvec2(0), getRecommendedRenderSize())); + batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize())); batch.draw(gpu::TRIANGLE_STRIP, 4); } } @@ -840,15 +840,6 @@ ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye) const { return ivec4(vpPos, vpSize); } -ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye, uvec2 vpSize) const { - vpSize.x /= 2; - uvec2 vpPos; - if (eye == Eye::Right) { - vpPos.x = vpSize.x; - } - return ivec4(vpPos, vpSize); -} - gpu::gl::GLBackend* OpenGLDisplayPlugin::getGLBackend() { if (!_gpuContext || !_gpuContext->getBackend()) { return nullptr; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 4bb82f3651..ec775aed4c 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -125,7 +125,6 @@ protected: void present(); virtual void swapBuffers(); ivec4 eyeViewport(Eye eye) const; - ivec4 eyeViewport(Eye eye, uvec2 vpSize) const; void render(std::function f); diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index fde9b26779..053f3171be 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -444,7 +444,6 @@ std::function HmdDisplayPlugin::H batch.setUniformBuffer(uniformsLocation, uniformsBuffer); auto compositorHelper = DependencyManager::get(); - qDebug() << "getUITransform" << compositorHelper->getUiTransform(); batch.setModelTransform(compositorHelper->getUiTransform()); batch.setResourceTexture(0, hudTexture); From b4a3ab920450c36949cde73a54d377e307251d39 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 6 Oct 2017 15:46:10 -0700 Subject: [PATCH 53/79] fix debugDeferredLighting --- .../render-utils/src/RenderDeferredTask.cpp | 4 ++-- .../utilities/render/deferredLighting.qml | 23 ++++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index a0bef828fa..45e6fd4ba4 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -186,7 +186,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawZones", zones); } - // Overlays + // Layered Overlays const auto filteredOverlaysOpaque = task.addJob("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT); const auto filteredOverlaysTransparent = task.addJob("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT); const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN(0); @@ -251,7 +251,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren { // Debug the bounds of the rendered Overlay items that are marked drawHUDLayer, still look at the zbuffer task.addJob("DrawOverlayHUDOpaqueBounds", overlaysHUDOpaque); - task.addJob("DrawOverlayHUDOpaqueBounds", overlaysHUDTransparent); + task.addJob("DrawOverlayHUDTransparentBounds", overlaysHUDTransparent); } task.addJob("ToneAndPostRangeTimer", toneAndPostRangeTimer); diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 2254b6d95f..60929d75c0 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -178,15 +178,26 @@ Column { onCheckedChanged: { mainViewTask.getConfig("DrawTransparentBounds")["enabled"] = checked } } CheckBox { - text: "Overlay Opaques" - checked: mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayOpaqueBounds")["enabled"] = checked } + text: "Opaques in Front" + checked: mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontOpaqueBounds")["enabled"] = checked } } CheckBox { - text: "Overlay Transparents" - checked: mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"] - onCheckedChanged: { mainViewTask.getConfig("DrawOverlayTransparentBounds")["enabled"] = checked } + text: "Transparents in Front" + checked: mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayInFrontTransparentBounds")["enabled"] = checked } } + CheckBox { + text: "Opaques in HUD" + checked: mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDOpaqueBounds")["enabled"] = checked } + } + CheckBox { + text: "Transparents in HUD" + checked: mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] + onCheckedChanged: { mainViewTask.getConfig("DrawOverlayHUDTransparentBounds")["enabled"] = checked } + } + } Column { CheckBox { From c45fe1af6c966cb541ae7b3bdd4073e02039b004 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 7 Oct 2017 19:41:43 -0700 Subject: [PATCH 54/79] Fix rendering transform for text3d overlays --- interface/src/ui/overlays/Text3DOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 57e3c32060..2e55a9a471 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -88,6 +88,7 @@ void Text3DOverlay::update(float deltatime) { applyTransformTo(transform); setTransform(transform); } + Parent::update(deltatime); } void Text3DOverlay::render(RenderArgs* args) { From 0f4e7fb53236b7e9cbaf5536e92b93dfdb0b4508 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Oct 2017 18:03:25 -0700 Subject: [PATCH 55/79] workaround for bad physics polling on login --- interface/src/Application.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0fc8c46cdc..f1e1f918e2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5639,10 +5639,10 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { return false; } + AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(0.5f * PHYSICS_READY_RANGE), glm::vec3(PHYSICS_READY_RANGE)); QVector entities; entityTree->withReadLock([&] { - AABox box(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); - entityTree->findEntities(box, entities); + entityTree->findEntities(avatarBox, entities); }); // For reasons I haven't found, we don't necessarily have the full scene when we receive a stats packet. Apply @@ -5662,11 +5662,18 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { bool result = true; foreach (EntityItemPointer entity, entities) { if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); - qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); - // don't break here because we want all the relevant entities to start their downloads - result = false; + // BUG: the findEntities() query above is sometimes returning objects that don't actually overlap + // TODO: investigate and fix findQueries() but in the meantime... + // WORKAROUND: test the overlap of each entity to verify it matters + bool success = false; + AACube entityCube = entity->getQueryAACube(success); + if (success && avatarBox.touches(entityCube)) { + static QString repeatedMessage = + LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); + qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); + // don't break here because we want all the relevant entities to start their downloads + result = false; + } } } return result; From 0bcecdbe668466b09e209c40c3ca70b331f89292 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 5 Oct 2017 11:17:40 -0700 Subject: [PATCH 56/79] be picky when finding nearby entities at login --- interface/src/Application.cpp | 49 +++++++++++++------- libraries/entities/src/EntityTree.cpp | 6 +++ libraries/entities/src/EntityTree.h | 5 ++ libraries/entities/src/EntityTreeElement.cpp | 8 ++++ libraries/entities/src/EntityTreeElement.h | 6 +++ 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f1e1f918e2..835a2fed56 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5639,14 +5639,38 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { return false; } - AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(0.5f * PHYSICS_READY_RANGE), glm::vec3(PHYSICS_READY_RANGE)); + // We don't want to use EntityTree::findEntities(AABox, ...) method because that scan will snarf parented entities + // whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture + // custom filters and use the general-purpose EntityTree::findEntities(filter, ...) QVector entities; entityTree->withReadLock([&] { - entityTree->findEntities(avatarBox, entities); + AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); + + // create two functions that use avatarBox (entityScan and elementScan), the second calls the first + std::function entityScan = [=](EntityItemPointer& entity) { + if (entity->shouldBePhysical()) { + bool success = false; + AABox entityBox = entity->getAABox(success); + // important: bail for entities that cannot supply a valid AABox + return success && avatarBox.touches(entityBox); + } + return false; + }; + std::function elementScan = [&](const OctreeElementPointer& element, void* unused) { + if (element->getAACube().touches(avatarBox)) { + EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); + entityTreeElement->getEntities(entityScan, entities); + return true; + } + return false; + }; + + // Pass the second function to the general-purpose EntityTree::findEntities() + // which will traverse the tree, apply the two filter functions (to element, then to entities) + // as it traverses. The end result will be a list of entities that match. + entityTree->findEntities(elementScan, entities); }); - // For reasons I haven't found, we don't necessarily have the full scene when we receive a stats packet. Apply - // a heuristic to try to decide when we actually know about all of the nearby entities. uint32_t nearbyCount = entities.size(); if (nearbyCount == _nearbyEntitiesCountAtLastPhysicsCheck) { _nearbyEntitiesStabilityCount++; @@ -5662,18 +5686,11 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { bool result = true; foreach (EntityItemPointer entity, entities) { if (entity->shouldBePhysical() && !entity->isReadyToComputeShape()) { - // BUG: the findEntities() query above is sometimes returning objects that don't actually overlap - // TODO: investigate and fix findQueries() but in the meantime... - // WORKAROUND: test the overlap of each entity to verify it matters - bool success = false; - AACube entityCube = entity->getQueryAACube(success); - if (success && avatarBox.touches(entityCube)) { - static QString repeatedMessage = - LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); - qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); - // don't break here because we want all the relevant entities to start their downloads - result = false; - } + static QString repeatedMessage = + LogHandler::getInstance().addRepeatedMessageRegex("Physics disabled until entity loads: .*"); + qCDebug(interfaceapp) << "Physics disabled until entity loads: " << entity->getID() << entity->getName(); + // don't break here because we want all the relevant entities to start their downloads + result = false; } } return result; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index bf37a08386..fa386ae090 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -864,6 +864,12 @@ void EntityTree::findEntities(const ViewFrustum& frustum, QVector& foundEntities) { + recurseTreeWithOperation(elementFilter, nullptr); +} + EntityItemPointer EntityTree::findEntityByID(const QUuid& id) { EntityItemID entityID(id); return findEntityByEntityItemID(entityID); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index d0448f438a..53e36bc7c7 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -165,6 +165,11 @@ public: /// \param foundEntities[out] vector of EntityItemPointer void findEntities(const ViewFrustum& frustum, QVector& foundEntities); + /// finds all entities that match scanOperator + /// \parameter scanOperator function that scans entities that match criteria + /// \parameter foundEntities[out] vector of EntityItemPointer + void findEntities(RecurseOctreeOperation& scanOperator, QVector& foundEntities); + void addNewlyCreatedHook(NewlyCreatedEntityHook* hook); void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook); diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 0c33855a61..2696377028 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -869,6 +869,14 @@ void EntityTreeElement::getEntities(const ViewFrustum& frustum, QVector& foundEntities) { + forEachEntity([&](EntityItemPointer entity) { + if (filter(entity)) { + foundEntities.push_back(entity); + } + }); +} + EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const { EntityItemPointer foundEntity = NULL; withReadLock([&] { diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index c7fb80c330..cafae9941a 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -27,6 +27,7 @@ class EntityTreeElement; using EntityItems = QVector; using EntityTreeElementWeakPointer = std::weak_ptr; using EntityTreeElementPointer = std::shared_ptr; +using EntityItemFilter = std::function; class EntityTreeUpdateArgs { public: @@ -199,6 +200,11 @@ public: /// \param entities[out] vector of non-const EntityItemPointer void getEntities(const ViewFrustum& frustum, QVector& foundEntities); + /// finds all entities that match filter + /// \param filter function that adds matching entities to foundEntities + /// \param entities[out] vector of non-const EntityItemPointer + void getEntities(EntityItemFilter& filter, QVector& foundEntities); + EntityItemPointer getEntityWithID(uint32_t id) const; EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const; void getEntitiesInside(const AACube& box, QVector& foundEntities); From bbde1bcd632767466478fdc001350f7257f5cd80 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 9 Oct 2017 10:42:42 -0700 Subject: [PATCH 57/79] move stuff out of writelock when possible --- interface/src/Application.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 835a2fed56..527e3607f5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5643,20 +5643,18 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { // whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture // custom filters and use the general-purpose EntityTree::findEntities(filter, ...) QVector entities; - entityTree->withReadLock([&] { - AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); - - // create two functions that use avatarBox (entityScan and elementScan), the second calls the first - std::function entityScan = [=](EntityItemPointer& entity) { - if (entity->shouldBePhysical()) { - bool success = false; - AABox entityBox = entity->getAABox(success); - // important: bail for entities that cannot supply a valid AABox - return success && avatarBox.touches(entityBox); - } - return false; - }; - std::function elementScan = [&](const OctreeElementPointer& element, void* unused) { + AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); + // create two functions that use avatarBox (entityScan and elementScan), the second calls the first + std::function entityScan = [=](EntityItemPointer& entity) { + if (entity->shouldBePhysical()) { + bool success = false; + AABox entityBox = entity->getAABox(success); + // important: bail for entities that cannot supply a valid AABox + return success && avatarBox.touches(entityBox); + } + return false; + }; + std::function elementScan = [&](const OctreeElementPointer& element, void* unused) { if (element->getAACube().touches(avatarBox)) { EntityTreeElementPointer entityTreeElement = std::static_pointer_cast(element); entityTreeElement->getEntities(entityScan, entities); @@ -5665,6 +5663,7 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { return false; }; + entityTree->withReadLock([&] { // Pass the second function to the general-purpose EntityTree::findEntities() // which will traverse the tree, apply the two filter functions (to element, then to entities) // as it traverses. The end result will be a list of entities that match. From 3acbd7820b19caa8676f4555fff9fd79bd9ca625 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 6 Oct 2017 17:22:07 -0700 Subject: [PATCH 58/79] build error --- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 8 -------- libraries/render/src/render/Item.cpp | 5 +++++ libraries/render/src/render/Item.h | 8 ++++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 053f3171be..0785226836 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -49,14 +49,6 @@ static const glm::mat4 IDENTITY_MATRIX; //#define LIVE_SHADER_RELOAD 1 extern glm::vec3 getPoint(float yaw, float pitch); -static QString readFile(const QString& filename) { - QFile file(filename); - file.open(QFile::Text | QFile::ReadOnly); - QString result; - result.append(QTextStream(&file).readAll()); - return result; -} - glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const { return CompositorHelper::VIRTUAL_SCREEN_SIZE; } diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp index f0fbbb1973..036c7d3a99 100644 --- a/libraries/render/src/render/Item.cpp +++ b/libraries/render/src/render/Item.cpp @@ -29,6 +29,11 @@ const float Item::Status::Value::CYAN = 180.0f; const float Item::Status::Value::BLUE = 240.0f; const float Item::Status::Value::MAGENTA = 300.0f; +const int Item::LAYER_2D = 0; +const int Item::LAYER_3D = 1; +const int Item::LAYER_3D_FRONT = 2; +const int Item::LAYER_3D_HUD = 3; + void Item::Status::Value::setScale(float scale) { _scale = (std::numeric_limits::max() -1) * 0.5f * (1.0f + std::max(std::min(scale, 1.0f), 0.0f)); } diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 8cdb41de45..2b02db81f9 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -359,10 +359,10 @@ public: // Get the layer where the item belongs. int getLayer() const { return _payload->getLayer(); } - static const int LAYER_2D = 0; - static const int LAYER_3D = 1; - static const int LAYER_3D_FRONT = 2; - static const int LAYER_3D_HUD = 3; + static const int LAYER_2D; + static const int LAYER_3D; + static const int LAYER_3D_FRONT; + static const int LAYER_3D_HUD; // Render call for the item void render(RenderArgs* args) const { _payload->render(args); } From acdd1e32e4080ea1844a07b616e22f4ecb867e22 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 9 Oct 2017 12:11:07 -0700 Subject: [PATCH 59/79] First round --- .../qml/hifi/commerce/checkout/Checkout.qml | 4 +++- .../qml/hifi/commerce/purchases/Purchases.qml | 12 ++++++------ .../resources/qml/hifi/commerce/wallet/Wallet.qml | 4 +++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 09c2f6fa76..38a938c535 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -79,6 +79,8 @@ Rectangle { failureErrorText.text = result.message; root.activeView = "checkoutFailure"; } else { + root.itemHref = result.data.download_url; + console.log("ZRF TEST " + root.itemHref); root.activeView = "checkoutSuccess"; } } @@ -125,7 +127,7 @@ Rectangle { id: notSetUpTimer; interval: 200; onTriggered: { - sendToScript({method: 'checkout_walletNotSetUp'}); + sendToScript({method: 'checkout_walletNotSetUp', itemId: itemId}); } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 990fd348c6..ea32c139d4 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -78,6 +78,10 @@ Rectangle { onInventoryResult: { purchasesReceived = true; + if (root.pendingInventoryReply) { + inventoryTimer.start(); + } + if (result.status !== 'success') { console.log("Failed to get purchases", result.message); } else { @@ -98,10 +102,6 @@ Rectangle { previousPurchasesModel.append(inventoryResult); buildFilteredPurchasesModel(); - - if (root.pendingInventoryReply) { - inventoryTimer.start(); - } } root.pendingInventoryReply = false; @@ -112,7 +112,7 @@ Rectangle { id: notSetUpTimer; interval: 200; onTriggered: { - sendToScript({method: 'checkout_walletNotSetUp'}); + sendToScript({method: 'purchases_walletNotSetUp'}); } } @@ -426,7 +426,7 @@ Rectangle { itemName: title; itemId: id; itemPreviewImageUrl: preview; - itemHref: root_file_url; + itemHref: download_url; purchaseStatus: status; purchaseStatusChanged: statusChanged; itemEdition: model.edition_number; diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 9056d5bed3..9beadd3361 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -176,6 +176,8 @@ Rectangle { commerce.getWalletStatus(); } else if (msg.referrer === 'purchases') { sendToScript({method: 'goToPurchases'}); + } else { + sendToScript({method: 'goToMarketplaceItemPage', itemId: msg.referrer}); } } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; @@ -283,7 +285,7 @@ Rectangle { Connections { onSendSignalToParent: { if (msg.method === "authSuccess") { - root.activeView = "walletHome"; + commerce.getWalletStatus(); } else { sendToScript(msg); } From 733df8391f367b6d779aa0f65d55b4d6f21c1ae3 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 9 Oct 2017 12:17:26 -0700 Subject: [PATCH 60/79] Round 2 --- .../qml/hifi/commerce/checkout/Checkout.qml | 1 - interface/src/commerce/QmlCommerce.cpp | 32 ++-------------- interface/src/commerce/QmlCommerce.h | 7 ---- interface/src/commerce/Wallet.cpp | 38 +++++++++++++++++++ interface/src/commerce/Wallet.h | 13 +++++++ .../scripting/WalletScriptingInterface.cpp | 5 +++ .../src/scripting/WalletScriptingInterface.h | 3 ++ .../ui/overlays/ContextOverlayInterface.cpp | 8 +++- scripts/system/commerce/wallet.js | 5 +++ scripts/system/html/js/marketplacesInject.js | 1 - scripts/system/marketplaces/marketplaces.js | 19 ++++++++-- scripts/system/notifications.js | 5 ++- 12 files changed, 93 insertions(+), 44 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 38a938c535..e2ecf927a5 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -80,7 +80,6 @@ Rectangle { root.activeView = "checkoutFailure"; } else { root.itemHref = result.data.download_url; - console.log("ZRF TEST " + root.itemHref); root.activeView = "checkoutSuccess"; } } diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 9f8847e8c7..ee75bc59e3 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -15,7 +15,6 @@ #include "Ledger.h" #include "Wallet.h" #include -#include "scripting/WalletScriptingInterface.h" HIFI_QML_DEF(QmlCommerce) @@ -29,37 +28,12 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(ledger.data(), &Ledger::historyResult, this, &QmlCommerce::historyResult); connect(wallet.data(), &Wallet::keyFilePathIfExistsResult, this, &QmlCommerce::keyFilePathIfExistsResult); connect(ledger.data(), &Ledger::accountResult, this, &QmlCommerce::accountResult); - connect(ledger.data(), &Ledger::accountResult, this, [&]() { - auto wallet = DependencyManager::get(); - auto walletScriptingInterface = DependencyManager::get(); - uint status; - - if (wallet->getKeyFilePath() == "" || !wallet->getSecurityImage()) { - status = (uint)WalletStatus::WALLET_STATUS_NOT_SET_UP; - } else if (!wallet->walletIsAuthenticatedWithPassphrase()) { - status = (uint)WalletStatus::WALLET_STATUS_NOT_AUTHENTICATED; - } else { - status = (uint)WalletStatus::WALLET_STATUS_READY; - } - - walletScriptingInterface->setWalletStatus(status); - emit walletStatusResult(status); - }); + connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); } void QmlCommerce::getWalletStatus() { - auto walletScriptingInterface = DependencyManager::get(); - uint status; - - if (DependencyManager::get()->isLoggedIn()) { - // This will set account info for the wallet, allowing us to decrypt and display the security image. - account(); - } else { - status = (uint)WalletStatus::WALLET_STATUS_NOT_LOGGED_IN; - emit walletStatusResult(status); - walletScriptingInterface->setWalletStatus(status); - return; - } + auto wallet = DependencyManager::get(); + wallet->getWalletStatus(); } void QmlCommerce::getLoginStatus() { diff --git a/interface/src/commerce/QmlCommerce.h b/interface/src/commerce/QmlCommerce.h index 8e6af6da65..45a5360680 100644 --- a/interface/src/commerce/QmlCommerce.h +++ b/interface/src/commerce/QmlCommerce.h @@ -27,13 +27,6 @@ class QmlCommerce : public OffscreenQmlDialog { public: QmlCommerce(QQuickItem* parent = nullptr); - enum WalletStatus { - WALLET_STATUS_NOT_LOGGED_IN = 0, - WALLET_STATUS_NOT_SET_UP, - WALLET_STATUS_NOT_AUTHENTICATED, - WALLET_STATUS_READY - }; - signals: void walletStatusResult(uint walletStatus); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 079e3a9479..fc16b85439 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -282,9 +282,27 @@ void initializeAESKeys(unsigned char* ivec, unsigned char* ckey, const QByteArra Wallet::Wallet() { auto nodeList = DependencyManager::get(); + auto ledger = DependencyManager::get(); auto& packetReceiver = nodeList->getPacketReceiver(); packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket"); + + connect(ledger.data(), &Ledger::accountResult, this, [&]() { + auto wallet = DependencyManager::get(); + auto walletScriptingInterface = DependencyManager::get(); + uint status; + + if (wallet->getKeyFilePath() == "" || !wallet->getSecurityImage()) { + status = (uint)WalletStatus::WALLET_STATUS_NOT_SET_UP; + } else if (!wallet->walletIsAuthenticatedWithPassphrase()) { + status = (uint)WalletStatus::WALLET_STATUS_NOT_AUTHENTICATED; + } else { + status = (uint)WalletStatus::WALLET_STATUS_READY; + } + + walletScriptingInterface->setWalletStatus(status); + emit walletStatusResult(status); + }); } Wallet::~Wallet() { @@ -682,3 +700,23 @@ bool Wallet::verifyOwnerChallenge(const QByteArray& encryptedText, const QString decryptedText = QString("hello"); return true; } + +void Wallet::account() { + auto ledger = DependencyManager::get(); + ledger->account(); +} + +void Wallet::getWalletStatus() { + auto walletScriptingInterface = DependencyManager::get(); + uint status; + + if (DependencyManager::get()->isLoggedIn()) { + // This will set account info for the wallet, allowing us to decrypt and display the security image. + account(); + } else { + status = (uint)WalletStatus::WALLET_STATUS_NOT_LOGGED_IN; + emit walletStatusResult(status); + walletScriptingInterface->setWalletStatus(status); + return; + } +} diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index acf9f8e45e..38c5299810 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -17,6 +17,7 @@ #include #include #include +#include "scripting/WalletScriptingInterface.h" #include @@ -50,10 +51,20 @@ public: void reset(); + void getWalletStatus(); + enum WalletStatus { + WALLET_STATUS_NOT_LOGGED_IN = 0, + WALLET_STATUS_NOT_SET_UP, + WALLET_STATUS_NOT_AUTHENTICATED, + WALLET_STATUS_READY + }; + signals: void securityImageResult(bool exists); void keyFilePathIfExistsResult(const QString& path); + void walletStatusResult(uint walletStatus); + private slots: void handleChallengeOwnershipPacket(QSharedPointer packet, SharedNodePointer sendingNode); @@ -71,6 +82,8 @@ private: bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen); bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText); + + void account(); }; #endif // hifi_Wallet_h diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 555e9477b0..99fdd5fbde 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -18,6 +18,11 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q WalletScriptingInterface::WalletScriptingInterface() { } +void WalletScriptingInterface::refreshWalletStatus() { + auto wallet = DependencyManager::get(); + wallet->getWalletStatus(); +} + static const QString CHECKOUT_QML_PATH = qApp->applicationDirPath() + "../../../qml/hifi/commerce/checkout/Checkout.qml"; void WalletScriptingInterface::buy(const QString& name, const QString& id, const int& price, const QString& href) { if (QThread::currentThread() != thread()) { diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 31b42094cf..038c580197 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -20,6 +20,7 @@ #include #include #include "Application.h" +#include "commerce/Wallet.h" class CheckoutProxy : public QmlWrapper { Q_OBJECT @@ -36,6 +37,7 @@ class WalletScriptingInterface : public QObject, public Dependency { public: WalletScriptingInterface(); + Q_INVOKABLE void refreshWalletStatus(); Q_INVOKABLE uint getWalletStatus() { return _walletStatus; } void setWalletStatus(const uint& status) { _walletStatus = status; } @@ -43,6 +45,7 @@ public: signals: void walletStatusChanged(); + void walletNotSetup(); private: uint _walletStatus; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 39fd4f9377..8cbb214857 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -41,6 +41,7 @@ ContextOverlayInterface::ContextOverlayInterface() { _entityPropertyFlags += PROP_MARKETPLACE_ID; _entityPropertyFlags += PROP_DIMENSIONS; _entityPropertyFlags += PROP_REGISTRATION_POINT; + _entityPropertyFlags += PROP_CERTIFICATE_ID; auto entityTreeRenderer = DependencyManager::get().data(); connect(entityTreeRenderer, SIGNAL(mousePressOnEntity(const EntityItemID&, const PointerEvent&)), this, SLOT(createOrDestroyContextOverlay(const EntityItemID&, const PointerEvent&))); @@ -176,7 +177,12 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); - return (entityProperties.getMarketplaceID().length() != 0); + Setting::Handle _settingSwitch{ "commerce", false }; + if (_settingSwitch.get()) { + return (entityProperties.getCertificateID().length() != 0); + } else { + return (entityProperties.getMarketplaceID().length() != 0); + } } bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event) { diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 7553ca4eeb..04b67ec14f 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -16,6 +16,8 @@ (function () { // BEGIN LOCAL_SCOPE Script.include("/~/system/libraries/accountUtils.js"); + var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; + // Function Name: onButtonClicked() // // Description: @@ -88,6 +90,9 @@ case 'goToPurchases': tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH); break; + case 'goToMarketplaceItemPage': + tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.itemId, MARKETPLACES_INJECT_SCRIPT_URL); + break; default: print('Unrecognized message from QML:', JSON.stringify(message)); } diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index ded4542c51..41db724c3f 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -334,7 +334,6 @@ $('body').addClass("code-injected"); maybeAddLogInButton(); - maybeAddSetupWalletButton(); changeDropdownMenu(); var purchaseButton = $('#side-info').find('.btn').first(); diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index e94b227a4a..deeae0d299 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -129,6 +129,10 @@ } } + function openWallet() { + tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + } + function setCertificateInfo(currentEntityWithContextOverlay, itemMarketplaceId) { wireEventBridge(true); tablet.sendToQml({ @@ -158,6 +162,7 @@ Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged); ContextOverlay.contextOverlayClicked.connect(setCertificateInfo); GlobalServices.myUsernameChanged.connect(onUsernameChanged); + Wallet.refreshWalletStatus(); function onMessage(message) { @@ -214,7 +219,7 @@ } else if (parsedJsonMessage.type === "LOGIN") { openLoginWindow(); } else if (parsedJsonMessage.type === "WALLET_SETUP") { - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); } else if (parsedJsonMessage.type === "MY_ITEMS") { referrerURL = MARKETPLACE_URL_INITIAL; filterText = ""; @@ -281,16 +286,22 @@ case 'purchases_openWallet': case 'checkout_openWallet': case 'checkout_setUpClicked': - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); break; case 'purchases_walletNotSetUp': - case 'checkout_walletNotSetUp': wireEventBridge(true); tablet.sendToQml({ method: 'updateWalletReferrer', referrer: "purchases" }); - tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH); + openWallet(); + case 'checkout_walletNotSetUp': + wireEventBridge(true); + tablet.sendToQml({ + method: 'updateWalletReferrer', + referrer: message.itemId + }); + openWallet(); break; case 'checkout_cancelClicked': tablet.gotoWebScreen(MARKETPLACE_URL + '/items/' + message.params, MARKETPLACES_INJECT_SCRIPT_URL); diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index ce693b6339..dc0fb1daf9 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -95,13 +95,15 @@ EDIT_ERROR: 4, TABLET: 5, CONNECTION: 6, + WALLET: 7, properties: [ { text: "Snapshot" }, { text: "Level of Detail" }, { text: "Connection Refused" }, { text: "Edit error" }, { text: "Tablet" }, - { text: "Connection" } + { text: "Connection" }, + { text: "Wallet" } ], getTypeFromMenuItem: function (menuItemName) { var type; @@ -691,6 +693,7 @@ Window.notifyEditError = onEditError; Window.notify = onNotify; Tablet.tabletNotification.connect(tabletNotification); + Wallet.walletNotSetup.connect(walletNotSetup); Messages.subscribe(NOTIFICATIONS_MESSAGE_CHANNEL); Messages.messageReceived.connect(onMessageReceived); From 873ae9b9d650244fd1bb303492759c92912b3ca0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 9 Oct 2017 13:36:38 -0700 Subject: [PATCH 61/79] model asks for renderUpdate if animating --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 19da8a77f4..df78bd9439 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1244,6 +1244,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce mapJoints(entity, model->getJointNames()); } animate(entity); + emit requestRenderUpdate(); } } From ee02fa9a91ffb14aa5f04a9f34013f885e9d437f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 9 Oct 2017 13:36:38 -0700 Subject: [PATCH 62/79] model asks for renderUpdate if animating (cherry picked from commit 873ae9b9d650244fd1bb303492759c92912b3ca0) --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 064eacdb35..9120cd1788 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1240,6 +1240,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce mapJoints(entity, model->getJointNames()); } animate(entity); + emit requestRenderUpdate(); } } From 38b95b54031ae9e4bd2a90ce6b4d9d330f1bd520 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 9 Oct 2017 15:07:14 -0700 Subject: [PATCH 63/79] Instructions HTML file and flow --- .../html/commerce/backup_instructions.html | 609 ++++++++++++++++++ .../qml/hifi/commerce/wallet/Help.qml | 8 +- .../qml/hifi/commerce/wallet/Security.qml | 15 +- .../qml/hifi/commerce/wallet/WalletSetup.qml | 19 +- interface/src/commerce/Wallet.cpp | 37 +- 5 files changed, 672 insertions(+), 16 deletions(-) create mode 100644 interface/resources/html/commerce/backup_instructions.html diff --git a/interface/resources/html/commerce/backup_instructions.html b/interface/resources/html/commerce/backup_instructions.html new file mode 100644 index 0000000000..560894e33d --- /dev/null +++ b/interface/resources/html/commerce/backup_instructions.html @@ -0,0 +1,609 @@ + + + + + +Backing Up Your Private Keys | High Fidelity + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

Backing Up Your Private Keys

+
+ + +

What are private keys?

+

A private key is a secret piece of text that is used to prove ownership, unlock confidential information and sign transactions.

+

In High Fidelity, your private keys are used to securely access the contents of your Wallet and Purchases.

+ +
+

Where are my private keys stored?"

+

By default, your private keys are only stored on your hard drive in High Fidelity Interface's AppData directory.

+

Here is the file path of your hifikey - you can browse to it using your file explorer.

+
HIFIKEY_PATH_REPLACEME
+ +
+

How should I make a backup of my private keys?

+

You should backup your .hifikey file above 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.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +

What happens if I lose my passphrase?

+

Your passphrase is used to encrypt your private keys. If you lose your passphrase, you will no longer be able to decrypt your private key file nor have access to the contents of your Wallet or My Purchases.

+

In order to guarantee your privacy, nobody can help you recover your passphrase, including High Fidelity. + +

Please write it down and store it securely.

+

 

+
+ +

Want to learn more?

+

You can find out much more about the blockchain and about commerce in High Fidelity by visiting our Docs site:

+

Visit High Fidelity's Docs

+
+ +
+
+ +
+ + diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index 21548ea788..fb0fd7a76e 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -30,12 +30,14 @@ Item { id: commerce; onKeyFilePathIfExistsResult: { - keyFilePath = path; + root.keyFilePath = path; } } - Component.onCompleted: { - commerce.getKeyFilePathIfExists(); + onVisibleChanged: { + if (visible) { + commerce.getKeyFilePathIfExists(); + } } RalewaySemiBold { diff --git a/interface/resources/qml/hifi/commerce/wallet/Security.qml b/interface/resources/qml/hifi/commerce/wallet/Security.qml index 9b70bb1f71..0f2edbe913 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Security.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Security.qml @@ -25,13 +25,13 @@ Item { HifiConstants { id: hifi; } id: root; - property string keyFilePath: ""; + property string keyFilePath; Hifi.QmlCommerce { id: commerce; onKeyFilePathIfExistsResult: { - keyFilePath = path; + root.keyFilePath = path; } } @@ -232,6 +232,12 @@ Item { anchors.rightMargin: 55; anchors.bottom: parent.bottom; + onVisibleChanged: { + if (visible) { + commerce.getKeyFilePathIfExists(); + } + } + HiFiGlyphs { id: yourPrivateKeysImage; text: hifi.glyphs.walletKey; @@ -320,8 +326,9 @@ Item { height: 40; onClicked: { - Qt.openUrlExternally("https://www.highfidelity.com/"); - Qt.openUrlExternally("file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/'))); + var keyPath = "file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/')); + Qt.openUrlExternally(keyPath + "/backup_instructions.html"); + Qt.openUrlExternally(keyPath); removeHmdContainer.visible = true; removeHmdContainerTimer.start(); } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml index 898cdf0ef2..0075e86bdc 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletSetup.qml @@ -30,6 +30,7 @@ Item { property string lastPage; property bool hasShownSecurityImageTip: false; property string referrer; + property string keyFilePath; Image { anchors.fill: parent; @@ -58,7 +59,7 @@ Item { } onKeyFilePathIfExistsResult: { - keyFilePath.text = path; + root.keyFilePath = path; } } @@ -608,7 +609,7 @@ Item { anchors.fill: parent; RalewaySemiBold { - id: keyFilePathText; + id: keyFilePathHelperText; text: "Private Key File Location:"; size: 18; anchors.top: parent.top; @@ -627,7 +628,7 @@ Item { colorScheme: hifi.colorSchemes.dark; anchors.left: parent.left; anchors.leftMargin: 30; - anchors.top: keyFilePathText.bottom; + anchors.top: keyFilePathHelperText.bottom; anchors.topMargin: 8; height: 24; width: height; @@ -643,11 +644,12 @@ Item { } onClicked: { - Qt.openUrlExternally("file:///" + keyFilePath.text.substring(0, keyFilePath.text.lastIndexOf('/'))); + Qt.openUrlExternally("file:///" + keyFilePath.substring(0, keyFilePath.lastIndexOf('/'))); } } RalewayRegular { - id: keyFilePath; + id: keyFilePathText; + text: root.keyFilePath; size: 18; anchors.top: clipboardButton.top; anchors.left: clipboardButton.right; @@ -670,7 +672,7 @@ Item { id: openInstructionsButton; color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.dark; - anchors.top: keyFilePath.bottom; + anchors.top: keyFilePathText.bottom; anchors.topMargin: 30; anchors.left: parent.left; anchors.leftMargin: 30; @@ -682,8 +684,9 @@ Item { instructions01Container.visible = false; instructions02Container.visible = true; keysReadyPageFinishButton.visible = true; - Qt.openUrlExternally("https://www.highfidelity.com/"); - Qt.openUrlExternally("file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/'))); + var keyPath = "file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/')); + Qt.openUrlExternally(keyPath + "/backup_instructions.html"); + Qt.openUrlExternally(keyPath); } } } diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index fc16b85439..fe73adf487 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -41,6 +41,7 @@ #endif static const char* KEY_FILE = "hifikey"; +static const char* INSTRUCTIONS_FILE = "backup_instructions.html"; static const char* IMAGE_HEADER = "-----BEGIN SECURITY IMAGE-----\n"; static const char* IMAGE_FOOTER = "-----END SECURITY IMAGE-----\n"; @@ -104,6 +105,38 @@ RSA* readKeys(const char* filename) { return key; } +bool writeBackupInstructions() { + QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html"); + QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE); + QFile outputFile(filename); + bool retval = false; + + if (QFile::exists(filename)) + { + QFile::remove(filename); + } + QFile::copy(inputFilename, filename); + + if (QFile::exists(filename) && outputFile.open(QIODevice::ReadWrite)) { + + QByteArray fileData = outputFile.readAll(); + QString text(fileData); + + text.replace(QString("HIFIKEY_PATH_REPLACEME"), keyFilePath()); + + outputFile.seek(0); // go to the beginning of the file + outputFile.write(text.toUtf8()); // write the new text back to the file + + outputFile.close(); // close the file handle. + + retval = true; + qCDebug(commerce) << "wrote html file successfully"; + } else { + qCDebug(commerce) << "failed to open output html file" << filename; + } + return retval; +} + bool writeKeys(const char* filename, RSA* keys) { FILE* fp; bool retval = false; @@ -121,6 +154,8 @@ bool writeKeys(const char* filename, RSA* keys) { QFile(QString(filename)).remove(); return retval; } + + writeBackupInstructions(); retval = true; qCDebug(commerce) << "wrote keys successfully"; @@ -488,7 +523,6 @@ bool Wallet::generateKeyPair() { // TODO: redo this soon -- need error checking and so on writeSecurityImage(_securityImage, keyFilePath()); - emit keyFilePathIfExistsResult(getKeyFilePath()); QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last(); QString key = keyPair.first->toBase64(); _publicKeys.push_back(key); @@ -646,6 +680,7 @@ bool Wallet::writeWallet(const QString& newPassphrase) { QFile(QString(keyFilePath())).remove(); QFile(tempFileName).rename(QString(keyFilePath())); qCDebug(commerce) << "wallet written successfully"; + emit keyFilePathIfExistsResult(getKeyFilePath()); return true; } else { qCDebug(commerce) << "couldn't write security image to temp wallet"; From b81a8a95eab181f794929c2ee9e1baee41435b72 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 9 Oct 2017 15:23:22 -0700 Subject: [PATCH 64/79] Final fixes --- .../resources/qml/hifi/commerce/checkout/Checkout.qml | 6 +++--- interface/src/Application.cpp | 9 ++------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index e2ecf927a5..8d94e284ed 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -115,7 +115,7 @@ Rectangle { } onItemHrefChanged: { - itemIsJson = root.itemHref.indexOf('.json') !== -1; + itemIsJson = root.itemHref.endsWith('.json'); } onItemPriceChanged: { @@ -575,8 +575,8 @@ Rectangle { anchors.right: parent.right; text: "Rez It" onClicked: { - if (urlHandler.canHandleUrl(itemHref)) { - urlHandler.handleUrl(itemHref); + if (urlHandler.canHandleUrl(root.itemHref)) { + urlHandler.handleUrl(root.itemHref); } rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0fc8c46cdc..504e91ff58 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2689,15 +2689,10 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { bool Application::importJSONFromURL(const QString& urlString) { // we only load files that terminate in just .json (not .svo.json and not .ava.json) - // if they come from the High Fidelity Marketplace Assets CDN QUrl jsonURL { urlString }; - if (jsonURL.host().endsWith(MARKETPLACE_CDN_HOSTNAME)) { - emit svoImportRequested(urlString); - return true; - } else { - return false; - } + emit svoImportRequested(urlString); + return true; } bool Application::importSVOFromURL(const QString& urlString) { From e9f4dee56deed6c3b309fef0bcad6308e94967d5 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Tue, 10 Oct 2017 03:39:13 +0100 Subject: [PATCH 65/79] WL 21562 - Fix the error in the Asset Browser --- interface/resources/qml/windows/TabletModalWindow.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/windows/TabletModalWindow.qml b/interface/resources/qml/windows/TabletModalWindow.qml index 05f192f7a7..0c64ce67ce 100644 --- a/interface/resources/qml/windows/TabletModalWindow.qml +++ b/interface/resources/qml/windows/TabletModalWindow.qml @@ -15,7 +15,7 @@ import "." Rectangle { id: modalWindow layer.enabled: true - property var title: "Modal" + property var title: "Model" width: tabletRoot.width height: tabletRoot.height color: "#80000000" From 583b0c521ea734646c67b80f31ec3c7bc3cc5252 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Tue, 10 Oct 2017 03:40:48 +0100 Subject: [PATCH 66/79] Open --- interface/resources/qml/windows/TabletModalWindow.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/windows/TabletModalWindow.qml b/interface/resources/qml/windows/TabletModalWindow.qml index 0c64ce67ce..e21cb6b224 100644 --- a/interface/resources/qml/windows/TabletModalWindow.qml +++ b/interface/resources/qml/windows/TabletModalWindow.qml @@ -15,7 +15,7 @@ import "." Rectangle { id: modalWindow layer.enabled: true - property var title: "Model" + property var title: "Open" width: tabletRoot.width height: tabletRoot.height color: "#80000000" From fc41155ce1be98f42b85b3985541e3947dfc1cae Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 10 Oct 2017 09:17:01 -0700 Subject: [PATCH 67/79] saving work --- .../controllerModules/farActionGrabEntity.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 0ef0e67471..8f6a0be163 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -119,6 +119,7 @@ Script.include("/~/system/libraries/controllers.js"); this.reticleMaxX; this.reticleMinY = MARGIN; this.reticleMaxY; + this.madeDynamic = false; var ACTION_TTL = 15; // seconds @@ -344,6 +345,13 @@ Script.include("/~/system/libraries/controllers.js"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); + if (this.madeDynamic) { + var props = Entities.getEntityProperties(this.grabbedThingID, ["dynamic", "localVelocity"]); + props.dynamic = false; + props.localVelocity = {x: 0, y: 0, z: 0}; + Entities.editEntity(this.grabbedThingID, props); + this.madeDynamic = false; + } this.actionID = null; this.grabbedThingID = null; }; @@ -503,12 +511,19 @@ Script.include("/~/system/libraries/controllers.js"); this.destroyContextOverlay(); } - if (entityIsDistanceGrabbable(targetProps)) { + if (entityIsGrabbable(targetProps)) { + if (!entityIsDistanceGrabbable(targetProps)) { + targetProps.dynamic = true; + Entities.editEntity(entityID, targetProps); + this.madeDynamic = true; + // make distance grabbale + } + if (!this.distanceRotating) { this.grabbedThingID = entityID; this.grabbedDistance = rayPickInfo.distance; } - + if (otherFarGrabModule.grabbedThingID === this.grabbedThingID && otherFarGrabModule.distanceHolding) { this.prepareDistanceRotatingData(controllerData); this.distanceRotate(otherFarGrabModule); From 003395b256303798b8430f8aa0bbf3144333183b Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 10 Oct 2017 09:43:02 -0700 Subject: [PATCH 68/79] removing whitespace --- .../system/controllers/controllerModules/farActionGrabEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 8f6a0be163..4b5a489531 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -523,7 +523,7 @@ Script.include("/~/system/libraries/controllers.js"); this.grabbedThingID = entityID; this.grabbedDistance = rayPickInfo.distance; } - + if (otherFarGrabModule.grabbedThingID === this.grabbedThingID && otherFarGrabModule.distanceHolding) { this.prepareDistanceRotatingData(controllerData); this.distanceRotate(otherFarGrabModule); From 9c120f1194e9994abbfe89257de16466e3485440 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 10 Oct 2017 09:44:13 -0700 Subject: [PATCH 69/79] Update AssetMappingsScriptingInterface to not open file for activity event --- .../src/scripting/AssetMappingsScriptingInterface.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index 2d288a8804..b8fd8f0f0d 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -105,12 +105,8 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping, startedCallback.call(); - QFile file { path }; - int64_t size { 0 }; - if (file.open(QIODevice::ReadOnly)) { - size = file.size(); - file.close(); - } + QFileInfo fileInfo { path }; + int64_t size { fileInfo.size() }; QString extension = ""; auto idx = path.lastIndexOf("."); From d0eb6a3ad090694a2d2735fbaf6e08816d501180 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 10 Oct 2017 09:45:41 -0700 Subject: [PATCH 70/79] remove comments --- .../system/controllers/controllerModules/farActionGrabEntity.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 4b5a489531..1ebed27b0e 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -516,7 +516,6 @@ Script.include("/~/system/libraries/controllers.js"); targetProps.dynamic = true; Entities.editEntity(entityID, targetProps); this.madeDynamic = true; - // make distance grabbale } if (!this.distanceRotating) { From a179df29fbc4d0d0ac506598aac1e1b2aa9de709 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 10 Oct 2017 10:31:40 -0700 Subject: [PATCH 71/79] mouse grab non-dynamic entities --- scripts/system/controllers/grab.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 0e9b8569ae..40b1bfd23b 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -15,12 +15,13 @@ // /* global MyAvatar, Entities, Script, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller, - isInEditMode, HMD */ + isInEditMode, HMD entityIsGrabbable*/ (function() { // BEGIN LOCAL_SCOPE -Script.include("/~/system/libraries/utils.js"); + Script.include("/~/system/libraries/utils.js"); + Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be grabbed var DELAY_FOR_30HZ = 33; // milliseconds @@ -330,9 +331,11 @@ Grabber.prototype.pressEvent = function(event) { return; } - var isDynamic = Entities.getEntityProperties(pickResults.objectID, "dynamic").dynamic; - if (!isDynamic) { - // only grab dynamic objects + var props = Entities.getEntityProperties(pickResults.objectID, ["dynamic", "userData", "locked", "type"]); + var isDynamic = props.dynamic; + var isGrabbable = props.grabbable; + if (!entityIsGrabbable(props)) { + // only grab grabbable objects return; } @@ -350,6 +353,7 @@ Grabber.prototype.pressEvent = function(event) { var entityProperties = Entities.getEntityProperties(clickedEntity); this.startPosition = entityProperties.position; this.lastRotation = entityProperties.rotation; + this.madeDynamic = false; var cameraPosition = Camera.getPosition(); var objectBoundingDiameter = Vec3.length(entityProperties.dimensions); @@ -361,6 +365,11 @@ Grabber.prototype.pressEvent = function(event) { return; } + if (entityIsGrabbable(props) && !isDynamic) { + entityProperties.dynamic = true; + Entities.editEntity(clickedEntity, entityProperties); + this.madeDynamic = true; + } // this.activateEntity(clickedEntity, entityProperties); this.isGrabbing = true; @@ -416,6 +425,14 @@ Grabber.prototype.releaseEvent = function(event) { if (this.actionID) { Entities.deleteAction(this.entityID, this.actionID); } + + if (this.madeDynamic) { + var entityProps = Entities.getEntityProperties(this.entityID, ["dynamic", "localVelocity"]); + entityProps.dynamic = false; + entityProps.localVelocity = {x: 0, y: 0, z: 0}; + Entities.editEntity(this.entityID, entityProps); + } + this.actionID = null; LaserPointers.setRenderState(this.mouseRayEntities, ""); From 8d0d9a159fd35514777f8e22af700662bde1d595 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 10 Oct 2017 10:38:19 -0700 Subject: [PATCH 72/79] Bugfixes --- .../qml/hifi/commerce/wallet/Help.qml | 2 +- interface/src/commerce/Wallet.cpp | 5 + scripts/system/html/js/marketplacesInject.js | 109 ++++++++++-------- scripts/system/marketplaces/marketplaces.js | 25 ++-- 4 files changed, 80 insertions(+), 61 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index fb0fd7a76e..65c06994f8 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -105,7 +105,7 @@ Item { ListElement { isExpanded: false; question: "What is a 'Security Pic'?" - answer: qsTr("Your Security Pic is an encrypted image that you selected during Wallet Setup. It acts as an extra layer of Wallet security.

When you see your Security Pic, you know that your actions and data are securely making use of your private keys.

If you don't see your Security Pic on a page that is asking you for your Wallet passphrase, someone untrustworthy may be trying to gain access to your Wallet.

The Pic is stored on your hard drive inside the same file as your private keys."); + answer: qsTr("Your Security Pic is an encrypted image that you selected during Wallet Setup. It acts as an extra layer of Wallet security.

When you see your Security Pic, you know that your actions and data are securely making use of your private keys.

If you don't see your Security Pic on a page that is asking you for your Wallet passphrase, someone untrustworthy may be trying to gain access to your Wallet.

The encrypted Pic is stored on your hard drive inside the same file as your private keys."); } ListElement { isExpanded: false; diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index fe73adf487..d7227a58f7 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -338,6 +338,11 @@ Wallet::Wallet() { walletScriptingInterface->setWalletStatus(status); emit walletStatusResult(status); }); + + auto accountManager = DependencyManager::get(); + connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { + getWalletStatus(); + }); } Wallet::~Wallet() { diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 41db724c3f..fc16eae8bf 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -26,7 +26,7 @@ var xmlHttpRequest = null; var isPreparing = false; // Explicitly track download request status. - var confirmAllPurchases = false; // Set this to "true" to cause Checkout.qml to popup for all items, even if free + var commerceMode = false; var userIsLoggedIn = false; var walletNeedsSetup = false; @@ -99,7 +99,9 @@ } function maybeAddSetupWalletButton() { - if (userIsLoggedIn && walletNeedsSetup) { + if (!$('body').hasClass("walletsetup-injected") && userIsLoggedIn && walletNeedsSetup) { + $('body').addClass("walletsetup-injected"); + var resultsElement = document.getElementById('results'); var setupWalletElement = document.createElement('div'); setupWalletElement.classList.add("row"); @@ -135,7 +137,8 @@ } function maybeAddLogInButton() { - if (!userIsLoggedIn) { + if (!$('body').hasClass("login-injected") && !userIsLoggedIn) { + $('body').addClass("login-injected"); var resultsElement = document.getElementById('results'); var logInElement = document.createElement('div'); logInElement.classList.add("row"); @@ -300,68 +303,72 @@ } function injectHiFiCode() { - if (!$('body').hasClass("code-injected") && confirmAllPurchases) { - - $('body').addClass("code-injected"); - + if (commerceMode) { maybeAddLogInButton(); maybeAddSetupWalletButton(); - changeDropdownMenu(); - var target = document.getElementById('templated-items'); - // MutationObserver is necessary because the DOM is populated after the page is loaded. - // We're searching for changes to the element whose ID is '#templated-items' - this is - // the element that gets filled in by the AJAX. - var observer = new MutationObserver(function (mutations) { - mutations.forEach(function (mutation) { - injectBuyButtonOnMainPage(); + if (!$('body').hasClass("code-injected")) { + + $('body').addClass("code-injected"); + changeDropdownMenu(); + + var target = document.getElementById('templated-items'); + // MutationObserver is necessary because the DOM is populated after the page is loaded. + // We're searching for changes to the element whose ID is '#templated-items' - this is + // the element that gets filled in by the AJAX. + var observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + injectBuyButtonOnMainPage(); + }); + //observer.disconnect(); }); - //observer.disconnect(); - }); - var config = { attributes: true, childList: true, characterData: true }; - observer.observe(target, config); + var config = { attributes: true, childList: true, characterData: true }; + observer.observe(target, config); - // Try this here in case it works (it will if the user just pressed the "back" button, - // since that doesn't trigger another AJAX request. - injectBuyButtonOnMainPage(); - maybeAddPurchasesButton(); + // Try this here in case it works (it will if the user just pressed the "back" button, + // since that doesn't trigger another AJAX request. + injectBuyButtonOnMainPage(); + maybeAddPurchasesButton(); + } } } function injectHiFiItemPageCode() { - if (!$('body').hasClass("code-injected") && confirmAllPurchases) { - - $('body').addClass("code-injected"); - + if (commerceMode) { maybeAddLogInButton(); - changeDropdownMenu(); - var purchaseButton = $('#side-info').find('.btn').first(); + if (!$('body').hasClass("code-injected")) { - var href = purchaseButton.attr('href'); - purchaseButton.attr('href', '#'); - purchaseButton.css({ - "background": "linear-gradient(#00b4ef, #0093C5)", - "color": "#FFF", - "font-weight": "600", - "padding-bottom": "10px" - }); + $('body').addClass("code-injected"); + changeDropdownMenu(); - var cost = $('.item-cost').text(); + var purchaseButton = $('#side-info').find('.btn').first(); - if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) { - purchaseButton.html('PURCHASE ' + cost); + var href = purchaseButton.attr('href'); + purchaseButton.attr('href', '#'); + purchaseButton.css({ + "background": "linear-gradient(#00b4ef, #0093C5)", + "color": "#FFF", + "font-weight": "600", + "padding-bottom": "10px" + }); + + var cost = $('.item-cost').text(); + + if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) { + purchaseButton.html('PURCHASE ' + cost); + } + + purchaseButton.on('click', function () { + buyButtonClicked(window.location.pathname.split("/")[3], + $('#top-center').find('h1').text(), + $('#creator').find('.value').text(), + cost, + href); + }); + maybeAddPurchasesButton(); } - - purchaseButton.on('click', function () { - buyButtonClicked(window.location.pathname.split("/")[3], - $('#top-center').find('h1').text(), - $('#creator').find('.value').text(), - cost, - href); - }); - maybeAddPurchasesButton(); } } @@ -622,7 +629,7 @@ if (parsedJsonMessage.type === "marketplaces") { if (parsedJsonMessage.action === "commerceSetting") { - confirmAllPurchases = !!parsedJsonMessage.data.commerceMode; + commerceMode = !!parsedJsonMessage.data.commerceMode; userIsLoggedIn = !!parsedJsonMessage.data.userIsLoggedIn; walletNeedsSetup = !!parsedJsonMessage.data.walletNeedsSetup; injectCode(); diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index deeae0d299..bf9822ba19 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -98,6 +98,7 @@ // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { + Wallet.refreshWalletStatus(); var entity = HMD.tabletID; Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); showMarketplace(); @@ -157,11 +158,24 @@ } } + function sendCommerceSettings() { + tablet.emitScriptEvent(JSON.stringify({ + type: "marketplaces", + action: "commerceSetting", + data: { + commerceMode: Settings.getValue("commerce", false), + userIsLoggedIn: Account.loggedIn, + walletNeedsSetup: Wallet.walletStatus === 1 + } + })); + } + marketplaceButton.clicked.connect(onClick); tablet.screenChanged.connect(onScreenChanged); Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged); ContextOverlay.contextOverlayClicked.connect(setCertificateInfo); GlobalServices.myUsernameChanged.connect(onUsernameChanged); + Wallet.walletStatusChanged.connect(sendCommerceSettings); Wallet.refreshWalletStatus(); function onMessage(message) { @@ -203,15 +217,7 @@ canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified }); } else if (parsedJsonMessage.type === "REQUEST_SETTING") { - tablet.emitScriptEvent(JSON.stringify({ - type: "marketplaces", - action: "commerceSetting", - data: { - commerceMode: Settings.getValue("commerce", false), - userIsLoggedIn: Account.loggedIn, - walletNeedsSetup: Wallet.walletStatus === 1 - } - })); + sendCommerceSettings(); } else if (parsedJsonMessage.type === "PURCHASES") { referrerURL = parsedJsonMessage.referrerURL; filterText = ""; @@ -244,6 +250,7 @@ tablet.webEventReceived.disconnect(onMessage); Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged); GlobalServices.myUsernameChanged.disconnect(onUsernameChanged); + Wallet.walletStatusChanged.disconnect(sendCommerceSettings); }); From 013e15c9a2cac45f6256d4a1c101bee396bf696b Mon Sep 17 00:00:00 2001 From: druiz17 Date: Tue, 10 Oct 2017 10:54:56 -0700 Subject: [PATCH 73/79] made requested changes --- .../system/controllers/controllerModules/farActionGrabEntity.js | 2 +- scripts/system/controllers/grab.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 1ebed27b0e..fb380f992b 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -346,7 +346,7 @@ Script.include("/~/system/libraries/controllers.js"); Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); if (this.madeDynamic) { - var props = Entities.getEntityProperties(this.grabbedThingID, ["dynamic", "localVelocity"]); + var props = {}; props.dynamic = false; props.localVelocity = {x: 0, y: 0, z: 0}; Entities.editEntity(this.grabbedThingID, props); diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 40b1bfd23b..2f046cbce3 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -427,7 +427,7 @@ Grabber.prototype.releaseEvent = function(event) { } if (this.madeDynamic) { - var entityProps = Entities.getEntityProperties(this.entityID, ["dynamic", "localVelocity"]); + var entityProps = {}; entityProps.dynamic = false; entityProps.localVelocity = {x: 0, y: 0, z: 0}; Entities.editEntity(this.entityID, entityProps); From cea0f48e5c73e3e98835122f590c5e4e8cade46d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 10 Oct 2017 15:19:09 -0700 Subject: [PATCH 74/79] Fix warnings --- libraries/image/src/image/Image.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libraries/image/src/image/Image.cpp b/libraries/image/src/image/Image.cpp index a2f5f93e9b..58b920da4d 100644 --- a/libraries/image/src/image/Image.cpp +++ b/libraries/image/src/image/Image.cpp @@ -74,9 +74,7 @@ glm::uvec2 rectifyToSparseSize(const glm::uvec2& size) { namespace image { -enum { - QIMAGE_HDR_FORMAT = QImage::Format_RGB30 -}; +QImage::Format QIMAGE_HDR_FORMAT = QImage::Format_RGB30; TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) { switch (type) { @@ -440,10 +438,8 @@ void generateHDRMips(gpu::Texture* texture, const QImage& image, const std::atom auto mipFormat = texture->getStoredMipFormat(); std::function unpackFunc; - nvtt::TextureType textureType = nvtt::TextureType_2D; nvtt::InputFormat inputFormat = nvtt::InputFormat_RGBA_32F; nvtt::WrapMode wrapMode = nvtt::WrapMode_Mirror; - nvtt::RoundMode roundMode = nvtt::RoundMode_None; nvtt::AlphaMode alphaMode = nvtt::AlphaMode_None; nvtt::CompressionOptions compressionOptions; From 026195223a0da05106744fbd1d83e380980c015f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 12:58:37 -0700 Subject: [PATCH 75/79] more correct use of BufferView in GeometryCache --- libraries/render-utils/src/GeometryCache.cpp | 75 ++++++++++++-------- libraries/render-utils/src/GeometryCache.h | 8 +-- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 658eab7210..93f3002fe8 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -84,67 +84,83 @@ std::vector polygon() { } void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices) { + gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - _positionView = gpu::BufferView(vertexBuffer, 0, - vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); - _normalView = gpu::BufferView(vertexBuffer, SHAPE_NORMALS_OFFSET, - vertexBuffer->getSize(), SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); + gpu::Buffer::Size viewSize = vertices.size() * 2 * sizeof(glm::vec3); + + _positionView = gpu::BufferView(vertexBuffer, offset, + viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); + _normalView = gpu::BufferView(vertexBuffer, offset + SHAPE_NORMALS_OFFSET, + viewSize, SHAPE_VERTEX_STRIDE, NORMAL_ELEMENT); } void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices) { - _indices = indexBuffer; + gpu::Buffer::Size offset = indexBuffer->getSize(); if (!indices.empty()) { - _indexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; - _indexCount = indices.size(); - indexBuffer->append(indices); + for (uint32_t i = 0; i < indices.size(); ++i) { + indexBuffer->append((uint16_t)indices[i]); + } } + gpu::Size viewSize = indices.size() * sizeof(uint16_t); + _indicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16); + offset = indexBuffer->getSize(); if (!wireIndices.empty()) { - _wireIndexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; - _wireIndexCount = wireIndices.size(); - indexBuffer->append(wireIndices); + for (uint32_t i = 0; i < wireIndices.size(); ++i) { + indexBuffer->append((uint16_t)wireIndices[i]); + } } + viewSize = wireIndices.size() * sizeof(uint16_t); + _wireIndicesView = gpu::BufferView(indexBuffer, offset, viewSize, gpu::Element::INDEX_UINT16); } void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); - batch.setIndexBuffer(SHAPE_INDEX_TYPE, _indices, 0); + batch.setIndexBuffer(_indicesView); } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { - if (_indexCount) { + gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + if (numIndices > 0) { setupBatch(batch); - batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset); + batch.drawIndexed(gpu::TRIANGLES, numIndices, 0); } } void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { - if (_wireIndexCount) { - setupBatch(batch); - batch.drawIndexed(gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset); + gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + if (numIndices > 0) { + batch.setInputBuffer(gpu::Stream::POSITION, _positionView); + batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setIndexBuffer(_wireIndicesView); + batch.drawIndexed(gpu::LINES, numIndices, 0); } } void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const { - if (_indexCount) { + gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + if (numIndices > 0) { setupBatch(batch); - batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, (gpu::uint32)_indexCount, (gpu::uint32)_indexOffset); + batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, numIndices, 0); } } void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const { - if (_wireIndexCount) { - setupBatch(batch); - batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, (gpu::uint32)_wireIndexCount, (gpu::uint32)_wireIndexOffset); + gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + if (numIndices > 0) { + batch.setInputBuffer(gpu::Stream::POSITION, _positionView); + batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setIndexBuffer(_wireIndicesView); + batch.drawIndexedInstanced((gpu::uint32)count, gpu::LINES, numIndices, 0); } } static const size_t ICOSAHEDRON_TO_SPHERE_TESSELATION_COUNT = 3; size_t GeometryCache::getShapeTriangleCount(Shape shape) { - return _shapes[shape]._indexCount / VERTICES_PER_TRIANGLE; + return _shapes[shape]._indicesView.getNumElements() / VERTICES_PER_TRIANGLE; } size_t GeometryCache::getSphereTriangleCount() { @@ -168,7 +184,6 @@ static IndexPair indexToken(geometry::Index a, geometry::Index b) { template void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; IndexPairs wireSeenIndices; @@ -179,6 +194,7 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& face = shape.faces[f]; // Compute the face normal @@ -219,7 +235,6 @@ void setupFlatShape(GeometryCache::ShapeData& shapeData, const geometry::Solid void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid& shape, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer) { using namespace geometry; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; vertices.reserve(shape.vertices.size() * 2); @@ -236,6 +251,7 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid solidIndices.reserve(faceIndexCount * faceCount); + Index baseVertex = 0; for (size_t f = 0; f < faceCount; f++) { const Face& face = shape.faces[f]; // Create the wire indices for unseen edges @@ -265,7 +281,6 @@ void setupSmoothShape(GeometryCache::ShapeData& shapeData, const geometry::Solid template void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexBuffer, gpu::BufferPointer& indexBuffer, bool isConical = false) { using namespace geometry; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; @@ -286,6 +301,7 @@ void extrudePolygon(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& ver vertices.push_back(vec3(v.x, -0.5f, v.z)); vertices.push_back(vec3(0.0f, -1.0f, 0.0f)); } + Index baseVertex = 0; for (uint32_t i = 2; i < N; i++) { solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + i); @@ -343,7 +359,6 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB // Draw a circle with radius 1/4th the size of the bounding box using namespace geometry; - Index baseVertex = (Index)(vertexBuffer->getSize() / SHAPE_VERTEX_STRIDE); VertexVector vertices; IndexVector solidIndices, wireIndices; const int NUM_CIRCLE_VERTICES = 64; @@ -354,6 +369,7 @@ void drawCircle(GeometryCache::ShapeData& shapeData, gpu::BufferPointer& vertexB vertices.push_back(vec3(0.0f, 0.0f, 0.0f)); } + Index baseVertex = 0; for (uint32_t i = 2; i < NUM_CIRCLE_VERTICES; i++) { solidIndices.push_back(baseVertex + 0); solidIndices.push_back(baseVertex + i); @@ -403,7 +419,6 @@ void GeometryCache::buildShapes() { // Line { - Index baseVertex = (Index)(_shapeVertices->getSize() / SHAPE_VERTEX_STRIDE); ShapeData& shapeData = _shapes[Line]; shapeData.setupVertices(_shapeVertices, VertexVector { vec3(-0.5f, 0.0f, 0.0f), vec3(-0.5f, 0.0f, 0.0f), @@ -411,8 +426,8 @@ void GeometryCache::buildShapes() { }); IndexVector wireIndices; // Only two indices - wireIndices.push_back(0 + baseVertex); - wireIndices.push_back(1 + baseVertex); + wireIndices.push_back(0); + wireIndices.push_back(1); shapeData.setupIndices(_shapeIndices, IndexVector(), wireIndices); } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 288ab363f0..5a437cf5e9 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -339,14 +339,10 @@ public: void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); struct ShapeData { - size_t _indexOffset{ 0 }; - size_t _indexCount{ 0 }; - size_t _wireIndexOffset{ 0 }; - size_t _wireIndexCount{ 0 }; - gpu::BufferView _positionView; gpu::BufferView _normalView; - gpu::BufferPointer _indices; + gpu::BufferView _indicesView; + gpu::BufferView _wireIndicesView; void setupVertices(gpu::BufferPointer& vertexBuffer, const geometry::VertexVector& vertices); void setupIndices(gpu::BufferPointer& indexBuffer, const geometry::IndexVector& indices, const geometry::IndexVector& wireIndices); From 4bf99fe9d2aef8253a627426d3097f66fc8eaeff Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 17:05:54 -0700 Subject: [PATCH 76/79] remove unused variable --- libraries/render-utils/src/GeometryCache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 93f3002fe8..c8fa73947a 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -69,7 +69,6 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); static const gpu::Type SHAPE_INDEX_TYPE = gpu::UINT32; -static const uint SHAPE_INDEX_SIZE = sizeof(gpu::uint32); template std::vector polygon() { From 886422cbef2a2573b5349791a8c28baa11c3b710 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 10 Oct 2017 17:07:17 -0700 Subject: [PATCH 77/79] remove unused variable --- libraries/render-utils/src/GeometryCache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c8fa73947a..c7bc09a5e3 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -68,7 +68,6 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -static const gpu::Type SHAPE_INDEX_TYPE = gpu::UINT32; template std::vector polygon() { From 69b6a8c1639638acf333c9878d177dce33dade0f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 10 Oct 2017 15:22:32 -0700 Subject: [PATCH 78/79] Fix .fst texdir not being followed Although the texdir was being acknowledged and used as the _textureBaseURL inside of the Geometry* classes, it was being overwritten in code meant to handle redirects. Basically, when a geometry resource request is redirected (via ATP, HTTP, etc.), we needed to update the _textureBaseURL to take the new location into account. Previously we were overwriting the _textureBaseURL all the time, even when not being redirected, but this updates it to only be overwritten when the request is redirected. There is at least 1 known case that this does not handle: a .fst with its `texdir` set, that points at an fbx that gets redirected. --- .../src/model-networking/ModelCache.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 2756334a1a..b62ad7b366 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -71,14 +71,14 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { } else { QUrl url = _url.resolved(filename); - QString texdir = mapping.value("texdir").toString(); + QString texdir = mapping.value(TEXDIR_FIELD).toString(); if (!texdir.isNull()) { if (!texdir.endsWith('/')) { texdir += '/'; } _textureBaseUrl = resolveTextureBaseUrl(url, _url.resolved(texdir)); } else { - _textureBaseUrl = _effectiveBaseURL; + _textureBaseUrl = url.resolved(QUrl(".")); } auto animGraphVariant = mapping.value("animGraphUrl"); @@ -241,8 +241,10 @@ private: }; void GeometryDefinitionResource::downloadFinished(const QByteArray& data) { - _url = _effectiveBaseURL; - _textureBaseUrl = _effectiveBaseURL; + if (_url != _effectiveBaseURL) { + _url = _effectiveBaseURL; + _textureBaseUrl = _effectiveBaseURL; + } QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts)); } From d9ba75ca72c0413e98bf6870f45439d24a28facf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 11 Oct 2017 06:07:07 -0700 Subject: [PATCH 79/79] fix warning about implicit cast from 64 to 32 bits --- libraries/render-utils/src/GeometryCache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c7bc09a5e3..cf8e268681 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -120,7 +120,7 @@ void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { - gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_indicesView.getNumElements(); if (numIndices > 0) { setupBatch(batch); batch.drawIndexed(gpu::TRIANGLES, numIndices, 0); @@ -128,7 +128,7 @@ void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { } void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { - gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_wireIndicesView.getNumElements(); if (numIndices > 0) { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); @@ -138,7 +138,7 @@ void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { } void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const { - gpu::Buffer::Size numIndices = _indicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_indicesView.getNumElements(); if (numIndices > 0) { setupBatch(batch); batch.drawIndexedInstanced((gpu::uint32)count, gpu::TRIANGLES, numIndices, 0); @@ -146,7 +146,7 @@ void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) co } void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const { - gpu::Buffer::Size numIndices = _wireIndicesView.getNumElements(); + uint32_t numIndices = (uint32_t)_wireIndicesView.getNumElements(); if (numIndices > 0) { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView);