From f06556ba1245bebcbb11414f63255f5c896b1acc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Apr 2015 14:37:39 -0700 Subject: [PATCH 01/15] migrate the various list to sort the rendering from explicit names to a more generic key based map --- libraries/fbx/src/FBXReader.cpp | 7 +- libraries/render-utils/CMakeLists.txt | 12 + libraries/render-utils/src/Model.cpp | 344 ++++---------------------- libraries/render-utils/src/Model.h | 79 ++---- 4 files changed, 94 insertions(+), 348 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index b9b2f24034..25ea9ef8e1 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1705,7 +1705,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, material._material->setDiffuse(material.diffuse); material._material->setSpecular(material.specular); material._material->setShininess(material.shininess); - material._material->setOpacity(material.opacity); + + if (material.opacity <= 0.0f) { + material._material->setOpacity(1.0f); + } else { + material._material->setOpacity(material.opacity); + } materials.insert(material.id, material); diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index caabff44cf..423e8fcfb6 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -12,4 +12,16 @@ add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) +if (WIN32) + if (USE_NSIGHT) + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif () + endif() +endif (WIN32) + link_hifi_libraries(animation fbx shared gpu) \ No newline at end of file diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index cf6ceaa1f1..53139b788e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -244,13 +244,6 @@ void Model::initJointTransforms() { void Model::init() { if (_renderPipelineLib.empty()) { - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0)); - slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); - slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); - slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3)); - // Vertex shaders auto modelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_vert))); auto modelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_normal_map_vert))); @@ -291,10 +284,24 @@ void Model::init() { RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), modelNormalMapVertex, modelNormalSpecularMapPixel); + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::IS_TRANSLUCENT), modelVertex, modelTranslucentPixel); + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT), + modelNormalMapVertex, modelTranslucentPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT), + modelVertex, modelTranslucentPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT), + modelNormalMapVertex, modelTranslucentPixel); + + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::HAS_LIGHTMAP), modelLightmapVertex, modelLightmapPixel); @@ -310,6 +317,7 @@ void Model::init() { RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel); + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::IS_SKINNED), skinModelVertex, modelPixel); @@ -326,15 +334,29 @@ void Model::init() { RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), skinModelNormalMapVertex, modelNormalSpecularMapPixel); + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT), skinModelVertex, modelTranslucentPixel); + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT), + skinModelNormalMapVertex, modelTranslucentPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT), + skinModelVertex, modelTranslucentPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT), + skinModelNormalMapVertex, modelTranslucentPixel); + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW), modelShadowVertex, modelShadowPixel); + _renderPipelineLib.addRenderPipeline( RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW), skinModelShadowVertex, modelShadowPixel); @@ -1935,55 +1957,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) { } void Model::segregateMeshGroups() { - _meshesTranslucentTangents.clear(); - _meshesTranslucent.clear(); - _meshesTranslucentTangentsSpecular.clear(); - _meshesTranslucentSpecular.clear(); - - _meshesTranslucentTangentsSkinned.clear(); - _meshesTranslucentSkinned.clear(); - _meshesTranslucentTangentsSpecularSkinned.clear(); - _meshesTranslucentSpecularSkinned.clear(); - - _meshesOpaqueTangents.clear(); - _meshesOpaque.clear(); - _meshesOpaqueTangentsSpecular.clear(); - _meshesOpaqueSpecular.clear(); - - _meshesOpaqueTangentsSkinned.clear(); - _meshesOpaqueSkinned.clear(); - _meshesOpaqueTangentsSpecularSkinned.clear(); - _meshesOpaqueSpecularSkinned.clear(); - - _meshesOpaqueLightmapTangents.clear(); - _meshesOpaqueLightmap.clear(); - _meshesOpaqueLightmapTangentsSpecular.clear(); - _meshesOpaqueLightmapSpecular.clear(); - - _unsortedMeshesTranslucentTangents.clear(); - _unsortedMeshesTranslucent.clear(); - _unsortedMeshesTranslucentTangentsSpecular.clear(); - _unsortedMeshesTranslucentSpecular.clear(); - - _unsortedMeshesTranslucentTangentsSkinned.clear(); - _unsortedMeshesTranslucentSkinned.clear(); - _unsortedMeshesTranslucentTangentsSpecularSkinned.clear(); - _unsortedMeshesTranslucentSpecularSkinned.clear(); - - _unsortedMeshesOpaqueTangents.clear(); - _unsortedMeshesOpaque.clear(); - _unsortedMeshesOpaqueTangentsSpecular.clear(); - _unsortedMeshesOpaqueSpecular.clear(); - - _unsortedMeshesOpaqueTangentsSkinned.clear(); - _unsortedMeshesOpaqueSkinned.clear(); - _unsortedMeshesOpaqueTangentsSpecularSkinned.clear(); - _unsortedMeshesOpaqueSpecularSkinned.clear(); - - _unsortedMeshesOpaqueLightmapTangents.clear(); - _unsortedMeshesOpaqueLightmap.clear(); - _unsortedMeshesOpaqueLightmapTangentsSpecular.clear(); - _unsortedMeshesOpaqueLightmapSpecular.clear(); + _renderBuckets.clear(); const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); @@ -2017,201 +1991,19 @@ void Model::segregateMeshGroups() { qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size(); } - if (!hasLightmap) { - if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) { + RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned); - _unsortedMeshesTranslucent.insertMulti(materialID, i); - - } else if (translucentMesh && hasTangents && !hasSpecular && !isSkinned) { - - _unsortedMeshesTranslucentTangents.insertMulti(materialID, i); - - } else if (translucentMesh && hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesTranslucentTangentsSpecular.insertMulti(materialID, i); - - } else if (translucentMesh && !hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesTranslucentSpecular.insertMulti(materialID, i); - - } else if (translucentMesh && hasTangents && !hasSpecular && isSkinned) { - - _unsortedMeshesTranslucentTangentsSkinned.insertMulti(materialID, i); - - } else if (translucentMesh && !hasTangents && !hasSpecular && isSkinned) { - - _unsortedMeshesTranslucentSkinned.insertMulti(materialID, i); - - } else if (translucentMesh && hasTangents && hasSpecular && isSkinned) { - - _unsortedMeshesTranslucentTangentsSpecularSkinned.insertMulti(materialID, i); - - } else if (translucentMesh && !hasTangents && hasSpecular && isSkinned) { - - _unsortedMeshesTranslucentSpecularSkinned.insertMulti(materialID, i); - - } else if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) { - - _unsortedMeshesOpaque.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueTangents.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueTangentsSpecular.insertMulti(materialID, i); - - } else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueSpecular.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && !hasSpecular && isSkinned) { - - _unsortedMeshesOpaqueTangentsSkinned.insertMulti(materialID, i); - - } else if (!translucentMesh && !hasTangents && !hasSpecular && isSkinned) { - - _unsortedMeshesOpaqueSkinned.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && hasSpecular && isSkinned) { - - _unsortedMeshesOpaqueTangentsSpecularSkinned.insertMulti(materialID, i); - - } else if (!translucentMesh && !hasTangents && hasSpecular && isSkinned) { - - _unsortedMeshesOpaqueSpecularSkinned.insertMulti(materialID, i); - } else { - qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???"; - } - } else { - if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueLightmap.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueLightmapTangents.insertMulti(materialID, i); - - } else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueLightmapTangentsSpecular.insertMulti(materialID, i); - - } else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) { - - _unsortedMeshesOpaqueLightmapSpecular.insertMulti(materialID, i); - - } else { - qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???"; - } - } + // reuse or create the bucket corresponding to that key and insert the mesh as unsorted + _renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i); } - foreach(int i, _unsortedMeshesTranslucent) { - _meshesTranslucent.append(i); + for(auto& b : _renderBuckets) { + foreach(auto i, b.second._unsortedMeshes) { + b.second._meshes.append(i); + b.second._unsortedMeshes.clear(); + } } - foreach(int i, _unsortedMeshesTranslucentTangents) { - _meshesTranslucentTangents.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentTangentsSpecular) { - _meshesTranslucentTangentsSpecular.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentSpecular) { - _meshesTranslucentSpecular.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentSkinned) { - _meshesTranslucentSkinned.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentTangentsSkinned) { - _meshesTranslucentTangentsSkinned.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentTangentsSpecularSkinned) { - _meshesTranslucentTangentsSpecularSkinned.append(i); - } - - foreach(int i, _unsortedMeshesTranslucentSpecularSkinned) { - _meshesTranslucentSpecularSkinned.append(i); - } - - foreach(int i, _unsortedMeshesOpaque) { - _meshesOpaque.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueTangents) { - _meshesOpaqueTangents.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueTangentsSpecular) { - _meshesOpaqueTangentsSpecular.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueSpecular) { - _meshesOpaqueSpecular.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueSkinned) { - _meshesOpaqueSkinned.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueTangentsSkinned) { - _meshesOpaqueTangentsSkinned.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueTangentsSpecularSkinned) { - _meshesOpaqueTangentsSpecularSkinned.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueSpecularSkinned) { - _meshesOpaqueSpecularSkinned.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueLightmap) { - _meshesOpaqueLightmap.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueLightmapTangents) { - _meshesOpaqueLightmapTangents.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueLightmapTangentsSpecular) { - _meshesOpaqueLightmapTangentsSpecular.append(i); - } - - foreach(int i, _unsortedMeshesOpaqueLightmapSpecular) { - _meshesOpaqueLightmapSpecular.append(i); - } - - _unsortedMeshesTranslucentTangents.clear(); - _unsortedMeshesTranslucent.clear(); - _unsortedMeshesTranslucentTangentsSpecular.clear(); - _unsortedMeshesTranslucentSpecular.clear(); - - _unsortedMeshesTranslucentTangentsSkinned.clear(); - _unsortedMeshesTranslucentSkinned.clear(); - _unsortedMeshesTranslucentTangentsSpecularSkinned.clear(); - _unsortedMeshesTranslucentSpecularSkinned.clear(); - - _unsortedMeshesOpaqueTangents.clear(); - _unsortedMeshesOpaque.clear(); - _unsortedMeshesOpaqueTangentsSpecular.clear(); - _unsortedMeshesOpaqueSpecular.clear(); - - _unsortedMeshesOpaqueTangentsSkinned.clear(); - _unsortedMeshesOpaqueSkinned.clear(); - _unsortedMeshesOpaqueTangentsSpecularSkinned.clear(); - _unsortedMeshesOpaqueSpecularSkinned.clear(); - - _unsortedMeshesOpaqueLightmapTangents.clear(); - _unsortedMeshesOpaqueLightmap.clear(); - _unsortedMeshesOpaqueLightmapTangentsSpecular.clear(); - _unsortedMeshesOpaqueLightmapSpecular.clear(); - _meshGroupsKnown = true; } @@ -2220,52 +2012,14 @@ QVector* Model::pickMeshList(bool translucent, float alphaThreshold, bool h // depending on which parameters we were called with, pick the correct mesh group to render QVector* whichList = NULL; - if (translucent && !hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesTranslucent; - } else if (translucent && hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesTranslucentTangents; - } else if (translucent && hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesTranslucentTangentsSpecular; - } else if (translucent && !hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesTranslucentSpecular; - } else if (translucent && hasTangents && !hasSpecular && isSkinned) { - whichList = &_meshesTranslucentTangentsSkinned; - } else if (translucent && !hasTangents && !hasSpecular && isSkinned) { - whichList = &_meshesTranslucentSkinned; - } else if (translucent && hasTangents && hasSpecular && isSkinned) { - whichList = &_meshesTranslucentTangentsSpecularSkinned; - } else if (translucent && !hasTangents && hasSpecular && isSkinned) { - whichList = &_meshesTranslucentSpecularSkinned; - } else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesOpaque; - } else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueTangents; - } else if (!translucent && !hasLightmap && hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueTangentsSpecular; - } else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueSpecular; - } else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && isSkinned) { - whichList = &_meshesOpaqueTangentsSkinned; - } else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && isSkinned) { - whichList = &_meshesOpaqueSkinned; - } else if (!translucent && !hasLightmap && hasTangents && hasSpecular && isSkinned) { - whichList = &_meshesOpaqueTangentsSpecularSkinned; - } else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && isSkinned) { - whichList = &_meshesOpaqueSpecularSkinned; + RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned); - } else if (!translucent && hasLightmap && !hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueLightmap; - } else if (!translucent && hasLightmap && hasTangents && !hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueLightmapTangents; - } else if (!translucent && hasLightmap && hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueLightmapTangentsSpecular; - } else if (!translucent && hasLightmap && !hasTangents && hasSpecular && !isSkinned) { - whichList = &_meshesOpaqueLightmapSpecular; - - } else { - qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???"; + auto bucket = _renderBuckets.find(key.getRaw()); + if (bucket != _renderBuckets.end()) { + whichList = &(*bucket).second._meshes; } + return whichList; } @@ -2277,6 +2031,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f auto pipeline = _renderPipelineLib.find(key.getRaw()); if (pipeline == _renderPipelineLib.end()) { qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw(); + locations = 0; return; } @@ -2303,7 +2058,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool int meshPartsRendered = 0; bool pickProgramsNeeded = true; - Locations* locations; + Locations* locations = nullptr; foreach(Model* model, _modelsInScene) { QVector* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned); @@ -2331,20 +2086,19 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl PROFILE_RANGE(__FUNCTION__); int meshPartsRendered = 0; - QVector* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned); - + //Pick the mesh list with the requested render flags + QVector* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned); if (!whichList) { - qCDebug(renderutils) << "unexpected!!! we don't know which list of meshes to render..."; return 0; } QVector& list = *whichList; // If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs - if (list.size() == 0) { + if (list.empty()) { return 0; } - Locations* locations; + Locations* locations = nullptr; pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations); meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index fce5629b8d..9ca817a8e7 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -350,58 +350,6 @@ private: bool _meshGroupsKnown; - QMap _unsortedMeshesTranslucent; - QMap _unsortedMeshesTranslucentTangents; - QMap _unsortedMeshesTranslucentTangentsSpecular; - QMap _unsortedMeshesTranslucentSpecular; - - QMap _unsortedMeshesTranslucentSkinned; - QMap _unsortedMeshesTranslucentTangentsSkinned; - QMap _unsortedMeshesTranslucentTangentsSpecularSkinned; - QMap _unsortedMeshesTranslucentSpecularSkinned; - - QMap _unsortedMeshesOpaque; - QMap _unsortedMeshesOpaqueTangents; - QMap _unsortedMeshesOpaqueTangentsSpecular; - QMap _unsortedMeshesOpaqueSpecular; - - QMap _unsortedMeshesOpaqueSkinned; - QMap _unsortedMeshesOpaqueTangentsSkinned; - QMap _unsortedMeshesOpaqueTangentsSpecularSkinned; - QMap _unsortedMeshesOpaqueSpecularSkinned; - - QMap _unsortedMeshesOpaqueLightmap; - QMap _unsortedMeshesOpaqueLightmapTangents; - QMap _unsortedMeshesOpaqueLightmapTangentsSpecular; - QMap _unsortedMeshesOpaqueLightmapSpecular; - - typedef std::unordered_map> MeshListMap; - MeshListMap _sortedMeshes; - - QVector _meshesTranslucent; - QVector _meshesTranslucentTangents; - QVector _meshesTranslucentTangentsSpecular; - QVector _meshesTranslucentSpecular; - - QVector _meshesTranslucentSkinned; - QVector _meshesTranslucentTangentsSkinned; - QVector _meshesTranslucentTangentsSpecularSkinned; - QVector _meshesTranslucentSpecularSkinned; - - QVector _meshesOpaque; - QVector _meshesOpaqueTangents; - QVector _meshesOpaqueTangentsSpecular; - QVector _meshesOpaqueSpecular; - - QVector _meshesOpaqueSkinned; - QVector _meshesOpaqueTangentsSkinned; - QVector _meshesOpaqueTangentsSpecularSkinned; - QVector _meshesOpaqueSpecularSkinned; - - QVector _meshesOpaqueLightmap; - QVector _meshesOpaqueLightmapTangents; - QVector _meshesOpaqueLightmapTangentsSpecular; - QVector _meshesOpaqueLightmapSpecular; // debug rendering support void renderDebugMeshBoxes(); @@ -490,6 +438,17 @@ private: int getRaw() { return *reinterpret_cast(this); } + + RenderKey( + bool translucent, bool hasLightmap, + bool hasTangents, bool hasSpecular, bool isSkinned) : + RenderKey( (translucent ? IS_TRANSLUCENT : 0) + | (hasLightmap ? HAS_LIGHTMAP : 0) + | (hasTangents ? HAS_TANGENTS : 0) + | (hasSpecular ? HAS_SPECULAR : 0) + | (isSkinned ? IS_SKINNED : 0) + ) {} + RenderKey(RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned) : @@ -527,6 +486,22 @@ private: }; static RenderPipelineLib _renderPipelineLib; + + class RenderBucket { + public: + QVector _meshes; + QMap _unsortedMeshes; + }; + typedef std::unordered_map BaseRenderBucketMap; + class RenderBucketMap : public BaseRenderBucketMap { + public: + typedef RenderKey Key; + + + void addRenderBucket(Key key, RenderBucket& bucket); + }; + RenderBucketMap _renderBuckets; + bool _renderCollisionHull; }; From 23d56f5bd01c78bd8791052282cb199159ec84b2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 16 Apr 2015 14:51:55 -0700 Subject: [PATCH 02/15] Remove current DDE filtering --- interface/src/devices/DdeFaceTracker.cpp | 18 ++++++------------ interface/src/devices/DdeFaceTracker.h | 5 ----- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index a701160198..e596342473 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -156,12 +156,9 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui _browUpRightIndex(18), _mouthSmileLeftIndex(28), _mouthSmileRightIndex(29), - _jawOpenIndex(21), - _previousTranslation(glm::vec3()), - _previousRotation(glm::quat()) + _jawOpenIndex(21) { _coefficients.resize(NUM_FACESHIFT_BLENDSHAPES); - _previousCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES); _blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES); @@ -290,13 +287,11 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { translation -= _referenceTranslation; translation /= LEAN_DAMPING_FACTOR; translation.x *= -1; - _headTranslation = (translation + _previousTranslation) / 2.0f; - _previousTranslation = translation; + _headTranslation = translation; // Compute relative rotation rotation = glm::inverse(_referenceRotation) * rotation; - _headRotation = (rotation + _previousRotation) / 2.0f; - _previousRotation = rotation; + _headRotation = rotation; // Translate DDE coefficients to Faceshift compatible coefficients for (int i = 0; i < NUM_EXPRESSIONS; i += 1) { @@ -305,8 +300,8 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { // Use EyeBlink values to control both EyeBlink and EyeOpen static const float RELAXED_EYE_VALUE = 0.1f; - float leftEye = (_coefficients[_leftBlinkIndex] + _previousCoefficients[_leftBlinkIndex]) / 2.0f; - float rightEye = (_coefficients[_rightBlinkIndex] + _previousCoefficients[_rightBlinkIndex]) / 2.0f; + float leftEye = _coefficients[_leftBlinkIndex]; + float rightEye = _coefficients[_rightBlinkIndex]; if (leftEye > RELAXED_EYE_VALUE) { _coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE; _coefficients[_leftEyeOpenIndex] = 0.0f; @@ -341,8 +336,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { // Scale all coefficients for (int i = 0; i < NUM_EXPRESSIONS; i += 1) { _blendshapeCoefficients[i] - = glm::clamp(DDE_COEFFICIENT_SCALES[i] * (_coefficients[i] + _previousCoefficients[i]) / 2.0f, 0.0f, 1.0f); - _previousCoefficients[i] = _coefficients[i]; + = glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f); } } else { diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index 490020e511..3cea667327 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -100,11 +100,6 @@ private: int _jawOpenIndex; QVector _coefficients; - - // Previous values for simple smoothing - glm::vec3 _previousTranslation; - glm::quat _previousRotation; - QVector _previousCoefficients; }; #endif // hifi_DdeFaceTracker_h \ No newline at end of file From 3e484ee2089b01e2608621b11ea01bf5330d4930 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 16 Apr 2015 15:04:25 -0700 Subject: [PATCH 03/15] Add menu item for enabling DDE filtering --- interface/src/Menu.cpp | 3 +++ interface/src/Menu.h | 1 + 2 files changed, 4 insertions(+) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d50cb48118..bb7d2b5382 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -386,6 +386,8 @@ Menu::Menu() { } #ifdef HAVE_DDE faceTrackingMenu->addSeparator(); + QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFiltering, 0, true); + ddeFiltering->setVisible(false); QAction* ddeFaceTrackerReset = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::ResetDDETracking, Qt::CTRL | Qt::Key_Apostrophe, DependencyManager::get().data(), SLOT(resetTracking())); @@ -991,6 +993,7 @@ void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) { void Menu::setActiveFaceTracker() { #ifdef HAVE_DDE bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression); + Menu::getInstance()->getActionForOption(MenuOption::DDEFiltering)->setVisible(isUsingDDE); Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE); #endif qApp->setActiveFaceTracker(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index f580b9204b..5798ca3a13 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -137,6 +137,7 @@ namespace MenuOption { const QString CopyAddress = "Copy Address to Clipboard"; const QString CopyPath = "Copy Path to Clipboard"; const QString DDEFaceRegression = "DDE Face Regression"; + const QString DDEFiltering = "DDE Filtering"; const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DeleteBookmark = "Delete Bookmark..."; const QString DisableActivityLogger = "Disable Activity Logger"; From c46f21152fa43dba02ee7d6c1d3fad9438e8d5ad Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 16 Apr 2015 15:47:02 -0700 Subject: [PATCH 04/15] Add velocity filtering to DDE head movement Based on filtering code in Faceshift.cpp. --- interface/src/devices/DdeFaceTracker.cpp | 44 ++++++++++++++++++++++-- interface/src/devices/DdeFaceTracker.h | 7 ++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index e596342473..4cbbe28ec2 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -17,6 +17,8 @@ #include #include +#include + #include "DdeFaceTracker.h" #include "FaceshiftConstants.h" #include "InterfaceLogging.h" @@ -267,6 +269,8 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const { void DdeFaceTracker::decodePacket(const QByteArray& buffer) { if(buffer.size() > MIN_PACKET_SIZE) { + bool isFitering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering); + Packet packet; int bytesToCopy = glm::min((int)sizeof(packet), buffer.size()); memset(&packet.name, '\n', MAX_NAME_SIZE + 1); @@ -287,11 +291,36 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { translation -= _referenceTranslation; translation /= LEAN_DAMPING_FACTOR; translation.x *= -1; - _headTranslation = translation; + if (isFitering) { + glm::vec3 linearVelocity = (translation - _lastHeadTranslation) / _averageMessageTime; + const float LINEAR_VELOCITY_FILTER_STRENGTH = 0.3f; + float velocityFilter = glm::clamp(1.0f - glm::length(linearVelocity) * + LINEAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f); + _filteredHeadTranslation = velocityFilter * _filteredHeadTranslation + (1.0f - velocityFilter) * translation; + _lastHeadTranslation = translation; + _headTranslation = _filteredHeadTranslation; + } else { + _headTranslation = translation; + } // Compute relative rotation rotation = glm::inverse(_referenceRotation) * rotation; - _headRotation = rotation; + if (isFitering) { + glm::quat r = rotation * glm::inverse(_headRotation); + float theta = 2 * acos(r.w); + glm::vec3 angularVelocity; + if (theta > EPSILON) { + float rMag = glm::length(glm::vec3(r.x, r.y, r.z)); + angularVelocity = theta / _averageMessageTime * glm::vec3(r.x, r.y, r.z) / rMag; + } else { + angularVelocity = glm::vec3(0, 0, 0); + } + const float ANGULAR_VELOCITY_FILTER_STRENGTH = 0.3f; + _headRotation = safeMix(_headRotation, rotation, glm::clamp(glm::length(angularVelocity) * + ANGULAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f)); + } else { + _headRotation = rotation; + } // Translate DDE coefficients to Faceshift compatible coefficients for (int i = 0; i < NUM_EXPRESSIONS; i += 1) { @@ -339,7 +368,16 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { = glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f); } - } else { + // Calculate average frame time + const float FRAME_AVERAGING_FACTOR = 0.99f; + quint64 usecsNow = usecTimestampNow(); + if (_lastMessageReceived != 0) { + _averageMessageTime = FRAME_AVERAGING_FACTOR * _averageMessageTime + + (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastMessageReceived) / 1000000.0f; + } + _lastMessageReceived = usecsNow; + +} else { qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error"; } _lastReceiveTimestamp = usecTimestampNow(); diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index 3cea667327..261b538d83 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -23,6 +23,8 @@ #include "FaceTracker.h" +const float STARTING_DDE_MESSAGE_TIME = 0.033f; + class DdeFaceTracker : public FaceTracker, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -100,6 +102,11 @@ private: int _jawOpenIndex; QVector _coefficients; + + quint64 _lastMessageReceived = 0; + float _averageMessageTime = STARTING_DDE_MESSAGE_TIME; + glm::vec3 _lastHeadTranslation = glm::vec3(0.0f); + glm::vec3 _filteredHeadTranslation = glm::vec3(0.0f); }; #endif // hifi_DdeFaceTracker_h \ No newline at end of file From d60ee3b6e24590d35c3233338261eec0b7954ac9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 16 Apr 2015 16:28:22 -0700 Subject: [PATCH 05/15] Add velocity filtering to DDE eyelids --- interface/src/devices/DdeFaceTracker.cpp | 21 ++++++++++++++++++--- interface/src/devices/DdeFaceTracker.h | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index 4cbbe28ec2..35bb7a2595 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -269,7 +269,7 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const { void DdeFaceTracker::decodePacket(const QByteArray& buffer) { if(buffer.size() > MIN_PACKET_SIZE) { - bool isFitering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering); + bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering); Packet packet; int bytesToCopy = glm::min((int)sizeof(packet), buffer.size()); @@ -291,7 +291,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { translation -= _referenceTranslation; translation /= LEAN_DAMPING_FACTOR; translation.x *= -1; - if (isFitering) { + if (isFiltering) { glm::vec3 linearVelocity = (translation - _lastHeadTranslation) / _averageMessageTime; const float LINEAR_VELOCITY_FILTER_STRENGTH = 0.3f; float velocityFilter = glm::clamp(1.0f - glm::length(linearVelocity) * @@ -305,7 +305,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { // Compute relative rotation rotation = glm::inverse(_referenceRotation) * rotation; - if (isFitering) { + if (isFiltering) { glm::quat r = rotation * glm::inverse(_headRotation); float theta = 2 * acos(r.w); glm::vec3 angularVelocity; @@ -331,6 +331,21 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { static const float RELAXED_EYE_VALUE = 0.1f; float leftEye = _coefficients[_leftBlinkIndex]; float rightEye = _coefficients[_rightBlinkIndex]; + if (isFiltering) { + const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f; + + float velocity = fabs(leftEye - _lastLeftEyeBlink) / _averageMessageTime; + float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f); + _filteredLeftEyeBlink = velocityFilter * leftEye + (1.0f - velocityFilter) * _filteredLeftEyeBlink; + _lastLeftEyeBlink = leftEye; + leftEye = _filteredLeftEyeBlink; + + velocity = fabs(rightEye - _lastRightEyeBlink) / _averageMessageTime; + velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f); + _filteredRightEyeBlink = velocityFilter * rightEye + (1.0f - velocityFilter) * _filteredRightEyeBlink; + _lastRightEyeBlink = rightEye; + rightEye = _filteredRightEyeBlink; + } if (leftEye > RELAXED_EYE_VALUE) { _coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE; _coefficients[_leftEyeOpenIndex] = 0.0f; diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index 261b538d83..50de9687d2 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -107,6 +107,10 @@ private: float _averageMessageTime = STARTING_DDE_MESSAGE_TIME; glm::vec3 _lastHeadTranslation = glm::vec3(0.0f); glm::vec3 _filteredHeadTranslation = glm::vec3(0.0f); + float _lastLeftEyeBlink = 0.0f; + float _filteredLeftEyeBlink = 0.0f; + float _lastRightEyeBlink = 0.0f; + float _filteredRightEyeBlink = 0.0f; }; #endif // hifi_DdeFaceTracker_h \ No newline at end of file From b5b146b81b26ddcb3e73b18af6a3ecd795f5e0ac Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Apr 2015 17:35:37 -0700 Subject: [PATCH 06/15] Training Team: improving the sun lighting interface to javascript to enable / disable the earthSkyModel, assign explicitely the SUnDirection and getter, and expose a AmbientINtensity to control the amount of the ambient lighting contribution Expose these to javascript --- examples/example/misc/sunLightExample.js | 6 +++ interface/src/Application.cpp | 2 +- libraries/model/src/model/Light.cpp | 4 ++ libraries/model/src/model/Light.h | 6 ++- libraries/model/src/model/Light.slh | 1 + libraries/model/src/model/Stage.cpp | 27 ++++++++--- libraries/model/src/model/Stage.h | 47 ++++++++++++------- .../render-utils/src/DeferredGlobalLight.slh | 6 +-- .../src/DeferredLightingEffect.cpp | 3 +- .../render-utils/src/DeferredLightingEffect.h | 2 +- .../src/SceneScriptingInterface.cpp | 24 ++++++++++ .../src/SceneScriptingInterface.h | 14 ++++++ 12 files changed, 111 insertions(+), 31 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index e6c06bb1ae..55c312881f 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -78,6 +78,12 @@ panel.newSlider("Light Intensity", 0.0, 5, function(value) { return (value).toFixed(2); } ); +panel.newSlider("Light Ambient Intensity", 0.0, 1.0, + function(value) { Scene.setSunAmbientIntensity(value); }, + function() { return Scene.getSunAmbientIntensity(); }, + function(value) { return (value).toFixed(2); } +); + Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); }); Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); }); Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); }); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc24127054..56b5d931e3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3045,7 +3045,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); auto skyStage = DependencyManager::get()->getSkyStage(); - DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity()); + DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); PROFILE_RANGE("DeferredLighting"); diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index ea77412140..e8c01c68aa 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -64,6 +64,10 @@ void Light::setIntensity(float intensity) { editSchema()._intensity = intensity; } +void Light::setAmbientIntensity(float intensity) { + editSchema()._ambientIntensity = intensity; +} + void Light::setMaximumRadius(float radius) { if (radius <= 0.f) { radius = 1.0f; diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 8f6c663668..6b9371a0ee 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -244,6 +244,10 @@ public: void setShowContour(float show); float getShowContour() const { return getSchema()._control.w; } + // If the light has an ambient (Indirect) component, then the Ambientintensity can be used to control its contribution to the lighting + void setAmbientIntensity(float intensity); + float getAmbientIntensity() const { return getSchema()._ambientIntensity; } + // Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light void setAmbientSphere(const SphericalHarmonics& sphere) { _ambientSphere = sphere; } const SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; } @@ -254,7 +258,7 @@ public: public: Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f}; Vec3 _direction{0.0f, 0.0f, -1.0f}; - float _spare0{0.0f}; + float _ambientIntensity{0.0f}; Color _color{1.0f}; float _intensity{1.0f}; Vec4 _attenuation{1.0f}; diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 41c6e075cf..1aaf0e8327 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -27,6 +27,7 @@ vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z vec3 getLightColor(Light l) { return l._color.rgb; } float getLightIntensity(Light l) { return l._color.w; } +float getLightAmbientIntensity(Light l) { return l._direction.w; } float evalLightAttenuation(Light l, float r) { float d = max(r - l._attenuation.x, 0.0); diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index b72aa16497..68c13e5a7c 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -203,6 +203,7 @@ SunSkyStage::SunSkyStage() : _sunLight->setType(Light::SUN); setSunIntensity(1.0f); + setSunAmbientIntensity(0.5f); setSunColor(Vec3(1.0f, 1.0f, 1.0f)); // Default origin location is a special place in the world... @@ -249,12 +250,26 @@ void SunSkyStage::setOriginLocation(float longitude, float latitude, float altit invalidate(); } +void SunSkyStage::setEarthSunModelEnable(bool isEnabled) { + _earthSunModelEnable = isEnabled; + invalidate(); +} + void SunSkyStage::setSunColor(const Vec3& color) { _sunLight->setColor(color); } void SunSkyStage::setSunIntensity(float intensity) { _sunLight->setIntensity(intensity); } +void SunSkyStage::setSunAmbientIntensity(float intensity) { + _sunLight->setAmbientIntensity(intensity); +} + +void SunSkyStage::setSunDirection(const Vec3& direction) { + if (!isEarthSunModelEnabled()) { + _sunLight->setDirection(direction); + } +} // THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun double evalSunDeclinaison(double dayNumber) { @@ -271,19 +286,19 @@ void SunSkyStage::updateGraphicsObject() const { // And update the sunLAtitude as the declinaison depending of the time of the year _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); - Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); - _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); + if (isEarthSunModelEnabled()) { + Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); + _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); - double originAlt = _earthSunModel.getAltitude(); - _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); + double originAlt = _earthSunModel.getAltitude(); + _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); + } static int firstTime = 0; if (firstTime == 0) { firstTime++; gpu::Shader::makeProgram(*(_skyPipeline->getProgram())); - } - } void SunSkyStage::setSkybox(const SkyboxPointer& skybox) { diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 30c96259ca..968d50587a 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -177,38 +177,49 @@ typedef QSharedPointer< Skybox > SkyboxPointer; // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth -class SunSkyStage { +class SunSkyStage : public QObject { + Q_OBJECT public: SunSkyStage(); ~SunSkyStage(); // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] - void setDayTime(float hour); - float getDayTime() const { return _dayTime; } + Q_INVOKABLE void setDayTime(float hour); + Q_INVOKABLE float getDayTime() const { return _dayTime; } // time of the year expressed in day in the range [0, 365] - void setYearTime(unsigned int day); - unsigned int getYearTime() const { return _yearTime; } + Q_INVOKABLE void setYearTime(unsigned int day); + Q_INVOKABLE unsigned int getYearTime() const { return _yearTime; } // Origin orientation used to modify the cardinal axis alignement used. // THe default is north along +Z axis and west along +X axis. this orientation gets added // to the transform stack producing the sun light direction. - void setOriginOrientation(const Quat& orientation); - const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } + Q_INVOKABLE void setOriginOrientation(const Quat& orientation); + Q_INVOKABLE const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] - void setOriginLocation(float longitude, float latitude, float surfaceAltitude); - float getOriginLatitude() const { return _earthSunModel.getLatitude(); } - float getOriginLongitude() const { return _earthSunModel.getLongitude(); } - float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + Q_INVOKABLE void setOriginLocation(float longitude, float latitude, float surfaceAltitude); + Q_INVOKABLE float getOriginLatitude() const { return _earthSunModel.getLatitude(); } + Q_INVOKABLE float getOriginLongitude() const { return _earthSunModel.getLongitude(); } + Q_INVOKABLE float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + + // Enable / disable the effect of the time and location on the sun direction and color + Q_INVOKABLE void setEarthSunModelEnable(bool isEnabled); + Q_INVOKABLE bool isEarthSunModelEnabled() const { return _earthSunModelEnable; } // Sun properties - void setSunColor(const Vec3& color); - const Vec3& getSunColor() const { return getSunLight()->getColor(); } - void setSunIntensity(float intensity); - float getSunIntensity() const { return getSunLight()->getIntensity(); } + Q_INVOKABLE void setSunColor(const Vec3& color); + Q_INVOKABLE const Vec3& getSunColor() const { return getSunLight()->getColor(); } + Q_INVOKABLE void setSunIntensity(float intensity); + Q_INVOKABLE float getSunIntensity() const { return getSunLight()->getIntensity(); } + Q_INVOKABLE void setSunAmbientIntensity(float intensity); + Q_INVOKABLE float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } + // The sun direction is expressed in the world space + Q_INVOKABLE void setSunDirection(const Vec3& direction); + Q_INVOKABLE const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } + LightPointer getSunLight() const { valid(); return _sunLight; } AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; } @@ -223,10 +234,10 @@ protected: gpu::PipelinePointer _skyPipeline; - float _dayTime; - int _yearTime; - + float _dayTime = 12.0f; + int _yearTime = 0; mutable EarthSunModel _earthSunModel; + bool _earthSunModelEnable = true; mutable bool _invalid = true; void invalidate() const { _invalid = true; } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index ecb1f503c7..cbf7c31d1f 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -66,7 +66,7 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 color = diffuse.rgb * getLightColor(light) * 0.5; + vec3 color = diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); @@ -83,7 +83,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec3 fragEyeDir = normalize(fragEyeVector.xyz); vec3 ambientNormal = fragNormal.xyz; - vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, ambientNormal).xyz; + vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * getLightAmbientIntensity(light); vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); @@ -112,7 +112,7 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve vec3 diffuseLight = lightAttenuation * lightmap; // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; + vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); return diffuse * (ambientLight + diffuseLight); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 440f75e32e..bddb1815bf 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -554,11 +554,12 @@ void DeferredLightingEffect::setAmbientLightMode(int preset) { } } -void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity) { +void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity) { auto light = _allocatedLights.front(); light->setDirection(direction); light->setColor(diffuse); light->setIntensity(intensity); + light->setAmbientIntensity(ambientIntensity); } void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 6d0d131029..0d3d370fd4 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -73,7 +73,7 @@ public: // update global lighting void setAmbientLightMode(int preset); - void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity); + void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity); void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; } void setGlobalSkybox(const model::SkyboxPointer& skybox); diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 5a8f591410..0f3818317e 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -62,6 +62,30 @@ float SceneScriptingInterface::getSunIntensity() const { return _skyStage->getSunIntensity(); } +void SceneScriptingInterface::setSunAmbientIntensity(float intensity) { + _skyStage->setSunAmbientIntensity(intensity); +} + +float SceneScriptingInterface::getSunAmbientIntensity() const { + return _skyStage->getSunAmbientIntensity(); +} + +void SceneScriptingInterface::setSunDirection(const glm::vec3& direction) { + _skyStage->setSunDirection(direction); +} + +const glm::vec3& SceneScriptingInterface::getSunDirection() const { + return _skyStage->getSunDirection(); +} + +void SceneScriptingInterface::setStageEarthSunModelEnable(bool isEnabled) { + _skyStage->setEarthSunModelEnable(isEnabled); +} + +bool SceneScriptingInterface::isStageEarthSunModelEnabled() const { + return _skyStage->isEarthSunModelEnabled(); +} + model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 352bc1e78f..83f5a44bb7 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -38,10 +38,24 @@ public: Q_INVOKABLE void setStageYearTime(int day); Q_INVOKABLE int getStageYearTime() const; + Q_INVOKABLE void setStageEarthSunModelEnable(bool isEnabled); + Q_INVOKABLE bool isStageEarthSunModelEnabled() const; + + Q_INVOKABLE void setSunColor(const glm::vec3& color); Q_INVOKABLE const glm::vec3& getSunColor() const; Q_INVOKABLE void setSunIntensity(float intensity); Q_INVOKABLE float getSunIntensity() const; + Q_INVOKABLE void setSunAmbientIntensity(float intensity); + Q_INVOKABLE float getSunAmbientIntensity() const; + + // Only valid if stage Earth Sun model is disabled + Q_INVOKABLE void setSunDirection(const glm::vec3& direction); + + Q_INVOKABLE const glm::vec3& getSunDirection() const; + + + model::SunSkyStagePointer getSkyStage() const; From 1c5c7cc23997fa0bd4e5536fd636e71bedcf8c49 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 16 Apr 2015 17:55:55 -0700 Subject: [PATCH 07/15] faking a checkbox to do a boolean property control --- examples/example/misc/sunLightExample.js | 8 +- examples/utilities/tools/cookies.js | 122 +++++++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 55c312881f..2fe546cd0e 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -72,13 +72,19 @@ function runStageTime() { } Script.setInterval(runStageTime, tickTackPeriod); +panel.newCheckbox("Enable Earth Sun Model", + function(value) { Scene.setStageEarthSunModelEnable((value != 0)); }, + function() { return Scene.isStageEarthSunModelEnabled(); }, + function(value) { return (value); } +); + panel.newSlider("Light Intensity", 0.0, 5, function(value) { Scene.setSunIntensity(value); }, function() { return Scene.getSunIntensity(); }, function(value) { return (value).toFixed(2); } ); -panel.newSlider("Light Ambient Intensity", 0.0, 1.0, +panel.newSlider("Ambient Light Intensity", 0.0, 1.0, function(value) { Scene.setSunAmbientIntensity(value); }, function() { return Scene.getSunAmbientIntensity(); }, function(value) { return (value).toFixed(2); } diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js index 205b19c9f9..49446be234 100755 --- a/examples/utilities/tools/cookies.js +++ b/examples/utilities/tools/cookies.js @@ -118,6 +118,113 @@ Slider = function(x,y,width,thumbSize) { }; } +// The Checkbox class +Checkbox = function(x,y,width,thumbSize) { + + this.thumb = Overlays.addOverlay("text", { + backgroundColor: { red: 255, green: 255, blue: 255 }, + x: x, + y: y, + width: thumbSize, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 1.0, + visible: true + }); + this.background = Overlays.addOverlay("text", { + backgroundColor: { red: 125, green: 125, blue: 255 }, + x: x, + y: y, + width: width, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 0.5, + visible: true + }); + + this.thumbSize = thumbSize; + this.thumbHalfSize = 0.5 * thumbSize; + + this.minThumbX = x + this.thumbHalfSize; + this.maxThumbX = x + width - this.thumbHalfSize; + this.thumbX = this.minThumbX; + + this.minValue = 0.0; + this.maxValue = 1.0; + + this.clickOffsetX = 0; + this.isMoving = false; + + this.updateThumb = function() { + thumbTruePos = this.thumbX - 0.5 * this.thumbSize; + Overlays.editOverlay(this.thumb, { x: thumbTruePos } ); + }; + + this.onMouseMoveEvent = function(event) { + if (this.isMoving) { + newThumbX = event.x - this.clickOffsetX; + if (newThumbX < this.minThumbX) { + newThumbX = this.minThumbX; + } + if (newThumbX > this.maxThumbX) { + newThumbX = this.maxThumbX; + } + this.thumbX = newThumbX; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + }; + + this.onMousePressEvent = function(event) { + this.isMoving = true; + var clickOffset = event.x - this.thumbX; + if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { + this.clickOffsetX = clickOffset; + } else { + this.clickOffsetX = 0; + this.thumbX = event.x; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + + }; + + this.onMouseReleaseEvent = function(event) { + this.isMoving = false; + }; + + // Public members: + + this.setNormalizedValue = function(value) { + if (value < 0.0) { + this.thumbX = this.minThumbX; + } else if (value > 1.0) { + this.thumbX = this.maxThumbX; + } else { + this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX; + } + this.updateThumb(); + }; + this.getNormalizedValue = function() { + return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX); + }; + + this.setValue = function(value) { + var normValue = (value - this.minValue) / (this.maxValue - this.minValue); + this.setNormalizedValue(normValue); + }; + + this.getValue = function() { + return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue; + }; + + this.onValueChanged = function(value) {}; + + this.destroy = function() { + Overlays.deleteOverlay(this.background); + Overlays.deleteOverlay(this.thumb); + }; +} var textFontSize = 16; @@ -252,6 +359,21 @@ Panel = function(x, y) { // print("created Item... slider=" + name); }; + this.newCheckbox = function(name, setValue, getValue, displayValue) { + + var checkboxItem = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + + var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight); + checkbox.onValueChanged = function(value) { checkboxItem.setterFromWidget(value); }; + + + checkboxItem.widget = checkbox; + checkboxItem.setter(getValue()); + this.items[name] = checkboxItem; + this.nextY += rawYDelta; + // print("created Item... slider=" + name); + }; + this.destroy = function() { for (var i in this.items) { this.items[i].destroy(); From c823fcd08381ce2cc5d344de4001e8bbf248fe5f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 17 Apr 2015 10:35:48 -0700 Subject: [PATCH 08/15] Code tidying --- interface/src/devices/DdeFaceTracker.cpp | 14 ++++++++++++-- interface/src/devices/DdeFaceTracker.h | 18 ++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index 35bb7a2595..743b3be780 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -134,6 +134,8 @@ struct Packet { char name[MAX_NAME_SIZE + 1]; }; +const float STARTING_DDE_MESSAGE_TIME = 0.033f; + DdeFaceTracker::DdeFaceTracker() : DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT) { @@ -158,7 +160,15 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui _browUpRightIndex(18), _mouthSmileLeftIndex(28), _mouthSmileRightIndex(29), - _jawOpenIndex(21) + _jawOpenIndex(21), + _lastMessageReceived(0), + _averageMessageTime(STARTING_DDE_MESSAGE_TIME), + _lastHeadTranslation(glm::vec3(0.0f)), + _filteredHeadTranslation(glm::vec3(0.0f)), + _lastLeftEyeBlink(0.0f), + _filteredLeftEyeBlink(0.0f), + _lastRightEyeBlink(0.0f), + _filteredRightEyeBlink(0.0f) { _coefficients.resize(NUM_FACESHIFT_BLENDSHAPES); @@ -392,7 +402,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) { } _lastMessageReceived = usecsNow; -} else { + } else { qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error"; } _lastReceiveTimestamp = usecTimestampNow(); diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index 50de9687d2..aa3e9f3b81 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -23,8 +23,6 @@ #include "FaceTracker.h" -const float STARTING_DDE_MESSAGE_TIME = 0.033f; - class DdeFaceTracker : public FaceTracker, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -103,14 +101,14 @@ private: QVector _coefficients; - quint64 _lastMessageReceived = 0; - float _averageMessageTime = STARTING_DDE_MESSAGE_TIME; - glm::vec3 _lastHeadTranslation = glm::vec3(0.0f); - glm::vec3 _filteredHeadTranslation = glm::vec3(0.0f); - float _lastLeftEyeBlink = 0.0f; - float _filteredLeftEyeBlink = 0.0f; - float _lastRightEyeBlink = 0.0f; - float _filteredRightEyeBlink = 0.0f; + quint64 _lastMessageReceived; + float _averageMessageTime; + glm::vec3 _lastHeadTranslation; + glm::vec3 _filteredHeadTranslation; + float _lastLeftEyeBlink; + float _filteredLeftEyeBlink; + float _lastRightEyeBlink; + float _filteredRightEyeBlink; }; #endif // hifi_DdeFaceTracker_h \ No newline at end of file From 64d17f101a2a73b7107a839a1aa98dd2e411adc3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 17 Apr 2015 10:44:01 -0700 Subject: [PATCH 09/15] obfuscate set access token from AM log --- libraries/networking/src/AccountManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 1f1ada5592..2830a13ca7 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -366,7 +366,7 @@ void AccountManager::setAccessTokenForCurrentAuthURL(const QString& accessToken) OAuthAccessToken newOAuthToken; newOAuthToken.token = accessToken; - qCDebug(networking) << "Setting new account manager access token to" << accessToken; + qCDebug(networking) << "Setting new account manager access token. F2C:" << accessToken.left(2) << "L2C:" << accessToken.right(2); _accountInfo.setAccessToken(newOAuthToken); } From f94fcdab7bdd4bbd2f4a640a0e6208c65be51ebf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 17 Apr 2015 10:44:18 -0700 Subject: [PATCH 10/15] print if DS is using an access token from env --- domain-server/src/DomainServer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 9ce15b7507..d7cd7ec47d 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -302,6 +302,9 @@ bool DomainServer::didSetupAccountManagerWithAccessToken() { << "at keypath metaverse.access_token or in your ENV at key DOMAIN_SERVER_ACCESS_TOKEN"; return false; } + } else { + qDebug() << "Using access token from DOMAIN_SERVER_ACCESS_TOKEN in env. This overrides any access token present" + << " in the user or master config."; } // give this access token to the AccountManager From 6b085ca6684887511b447cd24b0dea059784aa3c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 17 Apr 2015 10:53:04 -0700 Subject: [PATCH 11/15] Move method out of Menu class --- interface/src/Application.cpp | 5 ++++- interface/src/Application.h | 3 ++- interface/src/Menu.cpp | 17 ++++------------- interface/src/Menu.h | 1 - 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc24127054..e3c101d280 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1748,7 +1748,10 @@ void Application::setActiveFaceTracker() { DependencyManager::get()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); #endif #ifdef HAVE_DDE - DependencyManager::get()->setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression)); + bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression); + Menu::getInstance()->getActionForOption(MenuOption::DDEFiltering)->setVisible(isUsingDDE); + Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE); + DependencyManager::get()->setEnabled(isUsingDDE); #endif #ifdef HAVE_VISAGE DependencyManager::get()->updateEnabled(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 833d9a6799..b5b2921844 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -210,7 +210,6 @@ public: bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; } FaceTracker* getActiveFaceTracker(); - void setActiveFaceTracker(); QSystemTrayIcon* getTrayIcon() { return _trayIcon; } ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; } @@ -385,6 +384,8 @@ public slots: void setVSyncEnabled(); void resetSensors(); + void setActiveFaceTracker(); + void aboutApp(); void showEditEntitiesHelp(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index bb7d2b5382..74231b6fe3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -362,25 +362,25 @@ Menu::Menu() { QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking, 0, true, - this, SLOT(setActiveFaceTracker())); + qApp, SLOT(setActiveFaceTracker())); faceTrackerGroup->addAction(noFaceTracker); #ifdef HAVE_FACESHIFT QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift, 0, false, - this, SLOT(setActiveFaceTracker())); + qApp, SLOT(setActiveFaceTracker())); faceTrackerGroup->addAction(faceshiftFaceTracker); #endif #ifdef HAVE_DDE QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFaceRegression, 0, false, - this, SLOT(setActiveFaceTracker())); + qApp, SLOT(setActiveFaceTracker())); faceTrackerGroup->addAction(ddeFaceTracker); #endif #ifdef HAVE_VISAGE QAction* visageFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Visage, 0, false, - this, SLOT(setActiveFaceTracker())); + qApp, SLOT(setActiveFaceTracker())); faceTrackerGroup->addAction(visageFaceTracker); #endif } @@ -989,12 +989,3 @@ void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) { qCDebug(interfaceapp) << "ERROR Menu::visibilityChanged() called with unrecognized value."; } } - -void Menu::setActiveFaceTracker() { -#ifdef HAVE_DDE - bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression); - Menu::getInstance()->getActionForOption(MenuOption::DDEFiltering)->setVisible(isUsingDDE); - Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE); -#endif - qApp->setActiveFaceTracker(); -} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5798ca3a13..ea34664eaa 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -68,7 +68,6 @@ public slots: private slots: void setVisibility(); - void setActiveFaceTracker(); private: static Menu* _instance; From ee480248315e07c91db495674409313f6a446b94 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 17 Apr 2015 11:31:48 -0700 Subject: [PATCH 12/15] Remove uninitialized method reference --- interface/src/devices/DdeFaceTracker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index 743b3be780..13b96dd18f 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -29,9 +29,9 @@ static const QHostAddress DDE_SERVER_ADDR("127.0.0.1"); static const quint16 DDE_SERVER_PORT = 64204; static const quint16 DDE_CONTROL_PORT = 64205; #if defined(Q_OS_WIN) -static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde/dde.exe"; +static const QString DDE_PROGRAM_PATH = "/dde/dde.exe"; #elif defined(Q_OS_MAC) -static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde.app/Contents/MacOS/dde"; +static const QString DDE_PROGRAM_PATH = "/dde.app/Contents/MacOS/dde"; #endif static const QStringList DDE_ARGUMENTS = QStringList() << "--udp=" + DDE_SERVER_ADDR.toString() + ":" + QString::number(DDE_SERVER_PORT) From edb388ed834b2c6ab5b2c22f6fd6f5c5f3429959 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 17 Apr 2015 11:32:05 -0700 Subject: [PATCH 13/15] Fixing the function with no implementation --- libraries/render-utils/src/Model.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 9ca817a8e7..1559e73e61 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -496,9 +496,6 @@ private: class RenderBucketMap : public BaseRenderBucketMap { public: typedef RenderKey Key; - - - void addRenderBucket(Key key, RenderBucket& bucket); }; RenderBucketMap _renderBuckets; From 931c46345ea8c7fda7f3d7d3cd37a5ae94ef6ced Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 17 Apr 2015 14:15:50 -0700 Subject: [PATCH 14/15] Move visibility methods into DiscoverabilityManager --- interface/src/DiscoverabilityManager.cpp | 31 ++++++++++++++++++++- interface/src/DiscoverabilityManager.h | 3 +++ interface/src/Menu.cpp | 34 +++--------------------- interface/src/Menu.h | 5 ---- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index 6622a27145..230f4202c8 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -18,6 +18,7 @@ #include #include "DiscoverabilityManager.h" +#include "Menu.h" const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All; @@ -96,4 +97,32 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov emit discoverabilityModeChanged(discoverabilityMode); } -} \ No newline at end of file +} + +void DiscoverabilityManager::setVisibility() { + Menu* menu = Menu::getInstance(); + + if (menu->isOptionChecked(MenuOption::VisibleToEveryone)) { + this->setDiscoverabilityMode(Discoverability::All); + } else if (menu->isOptionChecked(MenuOption::VisibleToFriends)) { + this->setDiscoverabilityMode(Discoverability::Friends); + } else if (menu->isOptionChecked(MenuOption::VisibleToNoOne)) { + this->setDiscoverabilityMode(Discoverability::None); + } else { + qDebug() << "ERROR DiscoverabilityManager::setVisibility() called with unrecognized value."; + } +} + +void DiscoverabilityManager::visibilityChanged(Discoverability::Mode discoverabilityMode) { + Menu* menu = Menu::getInstance(); + + if (discoverabilityMode == Discoverability::All) { + menu->setIsOptionChecked(MenuOption::VisibleToEveryone, true); + } else if (discoverabilityMode == Discoverability::Friends) { + menu->setIsOptionChecked(MenuOption::VisibleToFriends, true); + } else if (discoverabilityMode == Discoverability::None) { + menu->setIsOptionChecked(MenuOption::VisibleToNoOne, true); + } else { + qDebug() << "ERROR DiscoverabilityManager::visibilityChanged() called with unrecognized value."; + } +} diff --git a/interface/src/DiscoverabilityManager.h b/interface/src/DiscoverabilityManager.h index 9daa9408f8..1b5adcdb5d 100644 --- a/interface/src/DiscoverabilityManager.h +++ b/interface/src/DiscoverabilityManager.h @@ -36,6 +36,9 @@ public slots: Discoverability::Mode getDiscoverabilityMode() { return static_cast(_mode.get()); } void setDiscoverabilityMode(Discoverability::Mode discoverabilityMode); + void setVisibility(); + void visibilityChanged(Discoverability::Mode discoverabilityMode); + signals: void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8d6a1e3184..b07d122aee 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -163,21 +163,21 @@ Menu::Menu() { QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone, 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All, - this, SLOT(setVisibility())); + discoverabilityManager.data(), SLOT(setVisibility())); visibilityGroup->addAction(visibleToEveryone); QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends, 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends, - this, SLOT(setVisibility())); + discoverabilityManager.data(), SLOT(setVisibility())); visibilityGroup->addAction(visibleToFriends); QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne, 0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None, - this, SLOT(setVisibility())); + discoverabilityManager.data(), SLOT(setVisibility())); visibilityGroup->addAction(visibleToNoOne); connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, - this, &Menu::visibilityChanged); + discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged); } addActionToQMenuAndActionHash(toolsMenu, @@ -963,29 +963,3 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) { } return false; }; - -void Menu::setVisibility() { - auto discoverabilityManager = DependencyManager::get(); - - if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToEveryone)) { - discoverabilityManager->setDiscoverabilityMode(Discoverability::All); - } else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToFriends)) { - discoverabilityManager->setDiscoverabilityMode(Discoverability::Friends); - } else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToNoOne)) { - discoverabilityManager->setDiscoverabilityMode(Discoverability::None); - } else { - qCDebug(interfaceapp) << "ERROR Menu::setVisibility() called with unrecognized value."; - } -} - -void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) { - if (discoverabilityMode == Discoverability::All) { - setIsOptionChecked(MenuOption::VisibleToEveryone, true); - } else if (discoverabilityMode == Discoverability::Friends) { - setIsOptionChecked(MenuOption::VisibleToFriends, true); - } else if (discoverabilityMode == Discoverability::None) { - setIsOptionChecked(MenuOption::VisibleToNoOne, true); - } else { - qCDebug(interfaceapp) << "ERROR Menu::visibilityChanged() called with unrecognized value."; - } -} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index ea34664eaa..3d10d20f1b 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -66,9 +66,6 @@ public slots: bool isOptionChecked(const QString& menuOption) const; void setIsOptionChecked(const QString& menuOption, bool isChecked); -private slots: - void setVisibility(); - private: static Menu* _instance; Menu(); @@ -99,8 +96,6 @@ private: int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem); int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition); - void visibilityChanged(Discoverability::Mode discoverabilityMode); - QHash _actionHash; }; From 687ca7fee58bb4dfe780ed51698d132d63630efb Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 17 Apr 2015 19:00:40 -0700 Subject: [PATCH 15/15] Update the cookies.js to be able to edit and test direction and color, validate that the SunDirection and color and on/off is working --- examples/example/misc/sunLightExample.js | 15 +- examples/utilities/tools/cookies.js | 422 ++++++++++++++---- libraries/model/src/model/Light.h | 2 +- libraries/model/src/model/Stage.h | 43 +- .../src/SceneScriptingInterface.cpp | 4 +- .../src/SceneScriptingInterface.h | 4 +- 6 files changed, 364 insertions(+), 126 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 2fe546cd0e..e4826dcfeb 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -41,7 +41,8 @@ panel.newSlider("Year Time", 0, 364, ); panel.newSlider("Day Time", 0, 24, - function(value) { Scene.setStageDayTime(value); }, + + function(value) { Scene.setStageDayTime(value); panel.update("Light Direction"); }, function() { return Scene.getStageDayTime(); }, function(value) { var hour = Math.floor(value); @@ -78,6 +79,12 @@ panel.newCheckbox("Enable Earth Sun Model", function(value) { return (value); } ); +panel.newDirectionBox("Light Direction", + function(value) { Scene.setSunDirection(value); }, + function() { return Scene.getSunDirection(); }, + function(value) { return value.x.toFixed(2) + "," + value.y.toFixed(2) + "," + value.z.toFixed(2); } +); + panel.newSlider("Light Intensity", 0.0, 5, function(value) { Scene.setSunIntensity(value); }, function() { return Scene.getSunIntensity(); }, @@ -90,6 +97,12 @@ panel.newSlider("Ambient Light Intensity", 0.0, 1.0, function(value) { return (value).toFixed(2); } ); +panel.newColorBox("Light Color", + function(value) { Scene.setSunColor(value); }, + function() { return Scene.getSunColor(); }, + function(value) { return (value); } // "(" + value.x + "," = value.y + "," + value.z + ")"; } +); + Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); }); Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); }); Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); }); diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js index 49446be234..0182bf8db0 100755 --- a/examples/utilities/tools/cookies.js +++ b/examples/utilities/tools/cookies.js @@ -12,6 +12,129 @@ // The Slider class Slider = function(x,y,width,thumbSize) { + this.background = Overlays.addOverlay("text", { + backgroundColor: { red: 125, green: 125, blue: 255 }, + x: x, + y: y, + width: width, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 0.5, + visible: true + }); + this.thumb = Overlays.addOverlay("text", { + backgroundColor: { red: 255, green: 255, blue: 255 }, + x: x, + y: y, + width: thumbSize, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 1.0, + visible: true + }); + + + this.thumbSize = thumbSize; + this.thumbHalfSize = 0.5 * thumbSize; + + this.minThumbX = x + this.thumbHalfSize; + this.maxThumbX = x + width - this.thumbHalfSize; + this.thumbX = this.minThumbX; + + this.minValue = 0.0; + this.maxValue = 1.0; + + this.clickOffsetX = 0; + this.isMoving = false; + + this.updateThumb = function() { + thumbTruePos = this.thumbX - 0.5 * this.thumbSize; + Overlays.editOverlay(this.thumb, { x: thumbTruePos } ); + }; + + this.isClickableOverlayItem = function(item) { + return (item == this.thumb) || (item == this.background); + }; + + this.onMouseMoveEvent = function(event) { + if (this.isMoving) { + newThumbX = event.x - this.clickOffsetX; + if (newThumbX < this.minThumbX) { + newThumbX = this.minThumbX; + } + if (newThumbX > this.maxThumbX) { + newThumbX = this.maxThumbX; + } + this.thumbX = newThumbX; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + }; + + this.onMousePressEvent = function(event, clickedOverlay) { + if (!this.isClickableOverlayItem(clickedOverlay)) { + this.isMoving = false; + return; + } + this.isMoving = true; + var clickOffset = event.x - this.thumbX; + if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { + this.clickOffsetX = clickOffset; + } else { + this.clickOffsetX = 0; + this.thumbX = event.x; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + + }; + + this.onMouseReleaseEvent = function(event) { + this.isMoving = false; + }; + + // Public members: + + this.setNormalizedValue = function(value) { + if (value < 0.0) { + this.thumbX = this.minThumbX; + } else if (value > 1.0) { + this.thumbX = this.maxThumbX; + } else { + this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX; + } + this.updateThumb(); + }; + this.getNormalizedValue = function() { + return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX); + }; + + this.setValue = function(value) { + var normValue = (value - this.minValue) / (this.maxValue - this.minValue); + this.setNormalizedValue(normValue); + }; + + this.getValue = function() { + return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue; + }; + + this.onValueChanged = function(value) {}; + + this.destroy = function() { + Overlays.deleteOverlay(this.background); + Overlays.deleteOverlay(this.thumb); + }; + + this.setThumbColor = function(color) { + Overlays.editOverlay(this.thumb, {backgroundColor: { red: color.x*255, green: color.y*255, blue: color.z*255 }}); + }; + this.setBackgroundColor = function(color) { + Overlays.editOverlay(this.background, {backgroundColor: { red: color.x*255, green: color.y*255, blue: color.z*255 }}); + }; +} + +// The Checkbox class +Checkbox = function(x,y,width,thumbSize) { this.thumb = Overlays.addOverlay("text", { backgroundColor: { red: 255, green: 255, blue: 255 }, @@ -52,6 +175,10 @@ Slider = function(x,y,width,thumbSize) { Overlays.editOverlay(this.thumb, { x: thumbTruePos } ); }; + this.isClickableOverlayItem = function(item) { + return item == this.background; + }; + this.onMouseMoveEvent = function(event) { if (this.isMoving) { newThumbX = event.x - this.clickOffsetX; @@ -67,7 +194,11 @@ Slider = function(x,y,width,thumbSize) { } }; - this.onMousePressEvent = function(event) { + this.onMousePressEvent = function(event, clickedOverlay) { + if (this.background != clickedOverlay) { + this.isMoving = false; + return; + } this.isMoving = true; var clickOffset = event.x - this.thumbX; if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { @@ -118,112 +249,166 @@ Slider = function(x,y,width,thumbSize) { }; } -// The Checkbox class -Checkbox = function(x,y,width,thumbSize) { +// The ColorBox class +ColorBox = function(x,y,width,thumbSize) { + var self = this; + + var slideHeight = thumbSize / 3; + var sliderWidth = width; + this.red = new Slider(x, y, width, slideHeight); + this.green = new Slider(x, y + slideHeight, width, slideHeight); + this.blue = new Slider(x, y + 2 * slideHeight, width, slideHeight); + this.red.setBackgroundColor({x: 1, y: 0, z: 0}); + this.green.setBackgroundColor({x: 0, y: 1, z: 0}); + this.blue.setBackgroundColor({x: 0, y: 0, z: 1}); - this.thumb = Overlays.addOverlay("text", { - backgroundColor: { red: 255, green: 255, blue: 255 }, - x: x, - y: y, - width: thumbSize, - height: thumbSize, - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true - }); - this.background = Overlays.addOverlay("text", { - backgroundColor: { red: 125, green: 125, blue: 255 }, - x: x, - y: y, - width: width, - height: thumbSize, - alpha: 1.0, - backgroundAlpha: 0.5, - visible: true - }); - - this.thumbSize = thumbSize; - this.thumbHalfSize = 0.5 * thumbSize; - - this.minThumbX = x + this.thumbHalfSize; - this.maxThumbX = x + width - this.thumbHalfSize; - this.thumbX = this.minThumbX; - - this.minValue = 0.0; - this.maxValue = 1.0; - - this.clickOffsetX = 0; - this.isMoving = false; - - this.updateThumb = function() { - thumbTruePos = this.thumbX - 0.5 * this.thumbSize; - Overlays.editOverlay(this.thumb, { x: thumbTruePos } ); + this.isClickableOverlayItem = function(item) { + return this.red.isClickableOverlayItem(item) + || this.green.isClickableOverlayItem(item) + || this.blue.isClickableOverlayItem(item); }; this.onMouseMoveEvent = function(event) { - if (this.isMoving) { - newThumbX = event.x - this.clickOffsetX; - if (newThumbX < this.minThumbX) { - newThumbX = this.minThumbX; - } - if (newThumbX > this.maxThumbX) { - newThumbX = this.maxThumbX; - } - this.thumbX = newThumbX; - this.updateThumb(); - this.onValueChanged(this.getValue()); - } + this.red.onMouseMoveEvent(event); + this.green.onMouseMoveEvent(event); + this.blue.onMouseMoveEvent(event); }; - this.onMousePressEvent = function(event) { - this.isMoving = true; - var clickOffset = event.x - this.thumbX; - if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { - this.clickOffsetX = clickOffset; - } else { - this.clickOffsetX = 0; - this.thumbX = event.x; - this.updateThumb(); - this.onValueChanged(this.getValue()); + this.onMousePressEvent = function(event, clickedOverlay) { + this.red.onMousePressEvent(event, clickedOverlay); + if (this.red.isMoving) { + return; } + this.green.onMousePressEvent(event, clickedOverlay); + if (this.green.isMoving) { + return; + } + + this.blue.onMousePressEvent(event, clickedOverlay); }; this.onMouseReleaseEvent = function(event) { - this.isMoving = false; + this.red.onMouseReleaseEvent(event); + this.green.onMouseReleaseEvent(event); + this.blue.onMouseReleaseEvent(event); + }; + + this.setterFromWidget = function(value) { + var color = self.getValue(); + self.onValueChanged(color); + self.updateRGBSliders(color); + }; + + this.red.onValueChanged = this.setterFromWidget; + this.green.onValueChanged = this.setterFromWidget; + this.blue.onValueChanged = this.setterFromWidget; + + this.updateRGBSliders = function(color) { + this.red.setThumbColor({x: color.x, y: 0, z: 0}); + this.green.setThumbColor({x: 0, y: color.y, z: 0}); + this.blue.setThumbColor({x: 0, y: 0, z: color.z}); }; // Public members: - - this.setNormalizedValue = function(value) { - if (value < 0.0) { - this.thumbX = this.minThumbX; - } else if (value > 1.0) { - this.thumbX = this.maxThumbX; - } else { - this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX; - } - this.updateThumb(); - }; - this.getNormalizedValue = function() { - return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX); - }; - this.setValue = function(value) { - var normValue = (value - this.minValue) / (this.maxValue - this.minValue); - this.setNormalizedValue(normValue); + this.red.setValue(value.x); + this.green.setValue(value.y); + this.blue.setValue(value.z); + this.updateRGBSliders(value); }; this.getValue = function() { - return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue; + var value = {x:this.red.getValue(), y:this.green.getValue(),z:this.blue.getValue()}; + return value; + }; + + this.destroy = function() { + this.red.destroy(); + this.green.destroy(); + this.blue.destroy(); }; this.onValueChanged = function(value) {}; +} + +// The DirectionBox class +DirectionBox = function(x,y,width,thumbSize) { + var self = this; + + var slideHeight = thumbSize / 2; + var sliderWidth = width; + this.yaw = new Slider(x, y, width, slideHeight); + this.pitch = new Slider(x, y + slideHeight, width, slideHeight); + + this.yaw.setThumbColor({x: 1, y: 0, z: 0}); + this.yaw.minValue = -180; + this.yaw.maxValue = +180; + + this.pitch.setThumbColor({x: 0, y: 0, z: 1}); + this.pitch.minValue = -1; + this.pitch.maxValue = +1; + + this.isClickableOverlayItem = function(item) { + return this.yaw.isClickableOverlayItem(item) + || this.pitch.isClickableOverlayItem(item); + }; + + this.onMouseMoveEvent = function(event) { + this.yaw.onMouseMoveEvent(event); + this.pitch.onMouseMoveEvent(event); + }; + + this.onMousePressEvent = function(event, clickedOverlay) { + this.yaw.onMousePressEvent(event, clickedOverlay); + if (this.yaw.isMoving) { + return; + } + this.pitch.onMousePressEvent(event, clickedOverlay); + }; + + this.onMouseReleaseEvent = function(event) { + this.yaw.onMouseReleaseEvent(event); + this.pitch.onMouseReleaseEvent(event); + }; + + this.setterFromWidget = function(value) { + var yawPitch = self.getValue(); + self.onValueChanged(yawPitch); + }; + + this.yaw.onValueChanged = this.setterFromWidget; + this.pitch.onValueChanged = this.setterFromWidget; + + // Public members: + this.setValue = function(direction) { + var flatXZ = Math.sqrt(direction.x * direction.x + direction.z * direction.z); + if (flatXZ > 0.0) { + var flatX = direction.x / flatXZ; + var flatZ = direction.z / flatXZ; + var yaw = Math.acos(flatX) * 180 / Math.PI; + if (flatZ < 0) { + yaw = -yaw; + } + this.yaw.setValue(yaw); + } + this.pitch.setValue(direction.y); + }; + + this.getValue = function() { + var dirZ = this.pitch.getValue(); + var yaw = this.yaw.getValue() * Math.PI / 180; + var cosY = Math.sqrt(1 - dirZ*dirZ); + var value = {x:cosY * Math.cos(yaw), y:dirZ, z: cosY * Math.sin(yaw)}; + return value; + }; this.destroy = function() { - Overlays.deleteOverlay(this.background); - Overlays.deleteOverlay(this.thumb); + this.yaw.destroy(); + this.pitch.destroy(); }; + + this.onValueChanged = function(value) {}; } var textFontSize = 16; @@ -274,7 +459,12 @@ function PanelItem(name, setter, getter, displayer, x, y, textWidth, valueWidth, }; this.setterFromWidget = function(value) { setter(value); - Overlays.editOverlay(this.value, {text: this.displayer(getter())}); + // ANd loop back the value after the final setter has been called + var value = getter(); + if (this.widget) { + this.widget.setValue(value); + } + Overlays.editOverlay(this.value, {text: this.displayer(value)}); }; @@ -326,9 +516,9 @@ Panel = function(x, y) { for (var i in this.items) { var widget = this.items[i].widget; - if (clickedOverlay == widget.background) { + if (widget.isClickableOverlayItem(clickedOverlay)) { this.activeWidget = widget; - this.activeWidget.onMousePressEvent(event); + this.activeWidget.onMousePressEvent(event, clickedOverlay); // print("clicked... widget=" + i); break; } @@ -344,36 +534,63 @@ Panel = function(x, y) { this.newSlider = function(name, minValue, maxValue, setValue, getValue, displayValue) { - var sliderItem = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); var slider = new Slider(this.widgetX, this.nextY, widgetWidth, rawHeight); slider.minValue = minValue; slider.maxValue = maxValue; - slider.onValueChanged = function(value) { sliderItem.setterFromWidget(value); }; - sliderItem.widget = slider; - sliderItem.setter(getValue()); - this.items[name] = sliderItem; + item.widget = slider; + item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; + item.setter(getValue()); + this.items[name] = item; this.nextY += rawYDelta; // print("created Item... slider=" + name); }; this.newCheckbox = function(name, setValue, getValue, displayValue) { - var checkboxItem = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight); - checkbox.onValueChanged = function(value) { checkboxItem.setterFromWidget(value); }; - - - checkboxItem.widget = checkbox; - checkboxItem.setter(getValue()); - this.items[name] = checkboxItem; + + item.widget = checkbox; + item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; + item.setter(getValue()); + this.items[name] = item; this.nextY += rawYDelta; // print("created Item... slider=" + name); }; + this.newColorBox = function(name, setValue, getValue, displayValue) { + + var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + + var colorBox = new ColorBox(this.widgetX, this.nextY, widgetWidth, rawHeight); + + item.widget = colorBox; + item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; + item.setter(getValue()); + this.items[name] = item; + this.nextY += rawYDelta; + // print("created Item... colorBox=" + name); + }; + + this.newDirectionBox= function(name, setValue, getValue, displayValue) { + + var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + + var directionBox = new DirectionBox(this.widgetX, this.nextY, widgetWidth, rawHeight); + + item.widget = directionBox; + item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; + item.setter(getValue()); + this.items[name] = item; + this.nextY += rawYDelta; + // print("created Item... directionBox=" + name); + }; + this.destroy = function() { for (var i in this.items) { this.items[i].destroy(); @@ -395,6 +612,15 @@ Panel = function(x, y) { } return null; } + + this.update = function(name) { + var item = this.items[name]; + if (item != null) { + return item.setter(item.getter()); + } + return null; + } + }; diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 6b9371a0ee..30e3a8edad 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -265,7 +265,7 @@ public: Vec4 _spot{0.0f, 0.0f, 0.0f, 3.0f}; Vec4 _shadow{0.0f}; - Vec4 _control{0.0f}; + Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f}; Schema() {} }; diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 968d50587a..eca290b852 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -177,48 +177,47 @@ typedef QSharedPointer< Skybox > SkyboxPointer; // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth -class SunSkyStage : public QObject { - Q_OBJECT +class SunSkyStage { public: SunSkyStage(); ~SunSkyStage(); // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] - Q_INVOKABLE void setDayTime(float hour); - Q_INVOKABLE float getDayTime() const { return _dayTime; } + void setDayTime(float hour); + float getDayTime() const { return _dayTime; } // time of the year expressed in day in the range [0, 365] - Q_INVOKABLE void setYearTime(unsigned int day); - Q_INVOKABLE unsigned int getYearTime() const { return _yearTime; } + void setYearTime(unsigned int day); + unsigned int getYearTime() const { return _yearTime; } // Origin orientation used to modify the cardinal axis alignement used. // THe default is north along +Z axis and west along +X axis. this orientation gets added // to the transform stack producing the sun light direction. - Q_INVOKABLE void setOriginOrientation(const Quat& orientation); - Q_INVOKABLE const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } + void setOriginOrientation(const Quat& orientation); + const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] - Q_INVOKABLE void setOriginLocation(float longitude, float latitude, float surfaceAltitude); - Q_INVOKABLE float getOriginLatitude() const { return _earthSunModel.getLatitude(); } - Q_INVOKABLE float getOriginLongitude() const { return _earthSunModel.getLongitude(); } - Q_INVOKABLE float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + void setOriginLocation(float longitude, float latitude, float surfaceAltitude); + float getOriginLatitude() const { return _earthSunModel.getLatitude(); } + float getOriginLongitude() const { return _earthSunModel.getLongitude(); } + float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } // Enable / disable the effect of the time and location on the sun direction and color - Q_INVOKABLE void setEarthSunModelEnable(bool isEnabled); - Q_INVOKABLE bool isEarthSunModelEnabled() const { return _earthSunModelEnable; } + void setEarthSunModelEnable(bool isEnabled); + bool isEarthSunModelEnabled() const { return _earthSunModelEnable; } // Sun properties - Q_INVOKABLE void setSunColor(const Vec3& color); - Q_INVOKABLE const Vec3& getSunColor() const { return getSunLight()->getColor(); } - Q_INVOKABLE void setSunIntensity(float intensity); - Q_INVOKABLE float getSunIntensity() const { return getSunLight()->getIntensity(); } - Q_INVOKABLE void setSunAmbientIntensity(float intensity); - Q_INVOKABLE float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } + void setSunColor(const Vec3& color); + const Vec3& getSunColor() const { return getSunLight()->getColor(); } + void setSunIntensity(float intensity); + float getSunIntensity() const { return getSunLight()->getIntensity(); } + void setSunAmbientIntensity(float intensity); + float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } // The sun direction is expressed in the world space - Q_INVOKABLE void setSunDirection(const Vec3& direction); - Q_INVOKABLE const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } + void setSunDirection(const Vec3& direction); + const Vec3& getSunDirection() const { return getSunLight()->getDirection(); } LightPointer getSunLight() const { valid(); return _sunLight; } AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 0f3818317e..557938c78a 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -50,7 +50,7 @@ void SceneScriptingInterface::setSunColor(const glm::vec3& color) { _skyStage->setSunColor(color); } -const glm::vec3& SceneScriptingInterface::getSunColor() const { +glm::vec3 SceneScriptingInterface::getSunColor() const { return _skyStage->getSunColor(); } @@ -74,7 +74,7 @@ void SceneScriptingInterface::setSunDirection(const glm::vec3& direction) { _skyStage->setSunDirection(direction); } -const glm::vec3& SceneScriptingInterface::getSunDirection() const { +glm::vec3 SceneScriptingInterface::getSunDirection() const { return _skyStage->getSunDirection(); } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 83f5a44bb7..e847b7ff68 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -43,7 +43,7 @@ public: Q_INVOKABLE void setSunColor(const glm::vec3& color); - Q_INVOKABLE const glm::vec3& getSunColor() const; + Q_INVOKABLE glm::vec3 getSunColor() const; Q_INVOKABLE void setSunIntensity(float intensity); Q_INVOKABLE float getSunIntensity() const; Q_INVOKABLE void setSunAmbientIntensity(float intensity); @@ -52,7 +52,7 @@ public: // Only valid if stage Earth Sun model is disabled Q_INVOKABLE void setSunDirection(const glm::vec3& direction); - Q_INVOKABLE const glm::vec3& getSunDirection() const; + Q_INVOKABLE glm::vec3 getSunDirection() const;