From 518f5fe17c3fa6fa46eecf29bec522ea7647a6f4 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 22 Sep 2015 18:21:36 -0700 Subject: [PATCH 001/152] Starting to clean the mesh part of the RenderItem.... --- libraries/fbx/src/FBXReader.h | 2 +- libraries/fbx/src/FBXReader_Mesh.cpp | 28 ++++++------- .../src/model-networking/ModelCache.cpp | 1 + .../src/model-networking/ModelCache.h | 5 +-- libraries/render-utils/src/Model.cpp | 41 ++++++++++++++++--- .../render-utils/src/RenderDeferredTask.cpp | 8 +++- 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3027eb52cc..01c3785086 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -181,7 +181,7 @@ public: unsigned int meshIndex; // the order the meshes appeared in the object file # if USE_MODEL_MESH - model::Mesh _mesh; + model::MeshPointer _mesh; # endif }; diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index c0cf57df58..f3bf3f433d 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -370,19 +370,19 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); if (extracted.mesh.vertices.size() == 0) { - extracted.mesh._mesh = model::Mesh(); + extracted.mesh._mesh; qCDebug(modelformat) << "buildModelMesh failed -- no vertices, url = " << url; return; } FBXMesh& fbxMesh = extracted.mesh; - model::Mesh mesh; + model::MeshPointer mesh(new model::Mesh()); // Grab the vertices in a buffer auto vb = std::make_shared(); vb->setData(extracted.mesh.vertices.size() * sizeof(glm::vec3), (const gpu::Byte*) extracted.mesh.vertices.data()); gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - mesh.setVertexBuffer(vbv); + mesh->setVertexBuffer(vbv); // evaluate all attribute channels sizes int normalsSize = fbxMesh.normals.size() * sizeof(glm::vec3); @@ -414,37 +414,37 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (gpu::Byte*) fbxMesh.clusterWeights.constData()); if (normalsSize) { - mesh.addAttribute(gpu::Stream::NORMAL, + mesh->addAttribute(gpu::Stream::NORMAL, model::BufferView(attribBuffer, normalsOffset, normalsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (tangentsSize) { - mesh.addAttribute(gpu::Stream::TANGENT, + mesh->addAttribute(gpu::Stream::TANGENT, model::BufferView(attribBuffer, tangentsOffset, tangentsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (colorsSize) { - mesh.addAttribute(gpu::Stream::COLOR, + mesh->addAttribute(gpu::Stream::COLOR, model::BufferView(attribBuffer, colorsOffset, colorsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB))); } if (texCoordsSize) { - mesh.addAttribute(gpu::Stream::TEXCOORD, + mesh->addAttribute(gpu::Stream::TEXCOORD, model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } if (texCoords1Size) { - mesh.addAttribute(gpu::Stream::TEXCOORD1, + mesh->addAttribute(gpu::Stream::TEXCOORD1, model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } if (clusterIndicesSize) { - mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); } if (clusterWeightsSize) { - mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); } @@ -457,7 +457,6 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } if (! totalIndices) { - extracted.mesh._mesh = model::Mesh(); qCDebug(modelformat) << "buildModelMesh failed -- no indices, url = " << url; return; } @@ -489,21 +488,20 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } gpu::BufferView ibv(ib, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ)); - mesh.setIndexBuffer(ibv); + mesh->setIndexBuffer(ibv); if (parts.size()) { auto pb = std::make_shared(); pb->setData(parts.size() * sizeof(model::Mesh::Part), (const gpu::Byte*) parts.data()); gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW)); - mesh.setPartBuffer(pbv); + mesh->setPartBuffer(pbv); } else { - extracted.mesh._mesh = model::Mesh(); qCDebug(modelformat) << "buildModelMesh failed -- no parts, url = " << url; return; } // model::Box box = - mesh.evalPartBound(0); + mesh->evalPartBound(0); extracted.mesh._mesh = mesh; } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index a66fda624d..71d225a43a 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -269,6 +269,7 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas auto textureCache = DependencyManager::get(); NetworkMesh* networkMesh = new NetworkMesh(); + networkMesh->_mesh = mesh._mesh; int totalIndices = 0; bool checkForTexcoordLightmap = false; diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 1110d36e3e..4067bed122 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -191,15 +191,14 @@ public: /// The state associated with a single mesh. class NetworkMesh { public: + model::MeshPointer _mesh; + gpu::BufferPointer _indexBuffer; gpu::BufferPointer _vertexBuffer; gpu::BufferStreamPointer _vertexStream; gpu::Stream::FormatPointer _vertexFormat; - - int getTranslucentPartCount(const FBXMesh& fbxMesh) const; - bool isPartTranslucent(const FBXMesh& fbxMesh, int partIndex) const; }; #endif // hifi_GeometryCache_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7cf965951b..a374f9acb8 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -754,6 +754,16 @@ public: int meshIndex; int partIndex; int _shapeID; + + render::Item::Bound getBound() const { + if (_isBoundInvalid) { + model->getPartBounds(meshIndex, partIndex); + _isBoundInvalid = false; + } + return _bound; + } + mutable render::Item::Bound _bound; + mutable bool _isBoundInvalid = true; }; namespace render { @@ -780,7 +790,7 @@ namespace render { template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { if (payload) { - return payload->model->getPartBounds(payload->meshIndex, payload->partIndex); + return payload->getBound(); // model->getPartBounds(payload->meshIndex, payload->partIndex); } return render::Item::Bound(); } @@ -1486,6 +1496,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape const FBXMesh& mesh = geometry.meshes.at(meshIndex); const MeshState& state = _meshStates.at(meshIndex); + auto drawMesh = networkMesh._mesh; + + auto drawMaterialKey = material->getKey(); bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); @@ -1541,7 +1554,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape return; // FIXME! } - batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + // Assign index buffer: + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { // sanity check @@ -1574,10 +1589,21 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape batch.setModelTransform(_transforms[0]); if (mesh.blendshapes.isEmpty()) { - batch.setInputFormat(networkMesh._vertexFormat); - batch.setInputStream(0, *networkMesh._vertexStream); + batch.setInputFormat((drawMesh->getVertexFormat())); + auto inputStream = drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + + // batch.setInputFormat(networkMesh._vertexFormat); + // batch.setInputStream(0, *networkMesh._vertexStream); } else { + /* batch.setInputFormat((drawMesh->getVertexFormat())); + auto inputStream = drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + */ batch.setInputFormat(networkMesh._vertexFormat); + batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); batch.setInputStream(2, *networkMesh._vertexStream); @@ -1702,9 +1728,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape } } - batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); - batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + auto& drawPart = drawMesh->getPartBuffer().get(); + batch.drawIndexed(model::Mesh::topologyToPrimitive(drawPart._topology), drawPart._numIndices, drawPart._startIndex); +/* batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); + batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + */ if (args) { const int INDICES_PER_TRIANGLE = 3; args->_details._trianglesRendered += part.mergedTrianglesIndicesCount / INDICES_PER_TRIANGLE; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 137294c5b6..0094a3c3a1 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -189,8 +189,12 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); - args->_context->render((*args->_batch)); - args->_batch = nullptr; + { + PerformanceTimer perfTimer("DrawOpaqueDeferred::run::renderBatch"); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } } void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { From 6aa9ef991013d620fd95170a05ccf8fee2fb61a6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 20:51:25 -0700 Subject: [PATCH 002/152] first cut at migrating animation settings into a property group --- .../entities/src/EntityItemProperties.cpp | 83 ++++++++++--------- libraries/entities/src/EntityItemProperties.h | 22 +++-- libraries/entities/src/ModelEntityItem.cpp | 54 ++++++------ libraries/entities/src/ModelEntityItem.h | 12 ++- .../entities/src/ParticleEffectEntityItem.cpp | 56 ++++++++----- .../entities/src/ParticleEffectEntityItem.h | 11 ++- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 8 files changed, 145 insertions(+), 96 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index b92ea34827..ea80b27877 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -64,10 +64,10 @@ CONSTRUCT_PROPERTY(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), CONSTRUCT_PROPERTY(alphaFinish, ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH), CONSTRUCT_PROPERTY(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), -CONSTRUCT_PROPERTY(animationURL, ""), -CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS), -CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), -CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), +//CONSTRUCT_PROPERTY(animationURL, ""), +//CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS), +//CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), +//CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), CONSTRUCT_PROPERTY(registrationPoint, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT), CONSTRUCT_PROPERTY(angularVelocity, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY), CONSTRUCT_PROPERTY(angularDamping, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING), @@ -79,8 +79,8 @@ CONSTRUCT_PROPERTY(exponent, 0.0f), CONSTRUCT_PROPERTY(cutoff, ENTITY_ITEM_DEFAULT_CUTOFF), CONSTRUCT_PROPERTY(locked, ENTITY_ITEM_DEFAULT_LOCKED), CONSTRUCT_PROPERTY(textures, ""), -CONSTRUCT_PROPERTY(animationSettings, "{\"firstFrame\":0,\"fps\":30,\"frameIndex\":0,\"hold\":false," - "\"lastFrame\":100000,\"loop\":false,\"running\":false,\"startAutomatically\":false}"), +//CONSTRUCT_PROPERTY(animationSettings, "{\"firstFrame\":0,\"fps\":30,\"frameIndex\":0,\"hold\":false," +// "\"lastFrame\":100000,\"loop\":false,\"running\":false,\"startAutomatically\":false}"), CONSTRUCT_PROPERTY(userData, ENTITY_ITEM_DEFAULT_USER_DATA), CONSTRUCT_PROPERTY(simulationOwner, SimulationOwner()), CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT), @@ -167,11 +167,13 @@ void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const _naturalPosition = max - halfDimension; } +/* bool EntityItemProperties::animationSettingsChanged() const { return _animationSettingsChanged; } void EntityItemProperties::setAnimationSettings(const QString& value) { + // the animations setting is a JSON string that may contain various animation settings. // if it includes fps, frameIndex, or running, those values will be parsed out and // will over ride the regular animation settings @@ -223,6 +225,7 @@ QString EntityItemProperties::getAnimationSettings() const { QString jsonByteString(jsonByteArray); return jsonByteString; } +*/ void EntityItemProperties::setCreated(QDateTime &v) { _created = v.toMSecsSinceEpoch() * 1000; // usec per msec @@ -355,11 +358,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, animationURL); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SETTINGS, animationSettings); + //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, animationURL); + //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying); + //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); + //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS); + //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SETTINGS, animationSettings); CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible); CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint); CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity); @@ -519,7 +522,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models only if (_type == EntityTypes::Model) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, animationURL); + //COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, animationURL); } if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { @@ -534,10 +537,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models & Particles if (_type == EntityTypes::Model || _type == EntityTypes::ParticleEffect) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, animationIsPlaying); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, animationFPS); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); - COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_SETTINGS, animationSettings, getAnimationSettings()); + //COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, animationIsPlaying); + //COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, animationFPS); + //COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); + //COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_SETTINGS, animationSettings, getAnimationSettings()); } // Lights only @@ -673,11 +676,11 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL); - COPY_PROPERTY_FROM_QSCRIPTVALUE(animationURL, QString, setAnimationURL); - COPY_PROPERTY_FROM_QSCRIPTVALUE(animationIsPlaying, bool, setAnimationIsPlaying); - COPY_PROPERTY_FROM_QSCRIPTVALUE(animationFPS, float, setAnimationFPS); - COPY_PROPERTY_FROM_QSCRIPTVALUE(animationFrameIndex, float, setAnimationFrameIndex); - COPY_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, QString, setAnimationSettings); + //COPY_PROPERTY_FROM_QSCRIPTVALUE(animationURL, QString, setAnimationURL); + //COPY_PROPERTY_FROM_QSCRIPTVALUE(animationIsPlaying, bool, setAnimationIsPlaying); + //COPY_PROPERTY_FROM_QSCRIPTVALUE(animationFPS, float, setAnimationFPS); + //COPY_PROPERTY_FROM_QSCRIPTVALUE(animationFrameIndex, float, setAnimationFrameIndex); + //COPY_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, QString, setAnimationSettings); COPY_PROPERTY_FROM_QSCRIPTVALUE(glowLevel, float, setGlowLevel); COPY_PROPERTY_FROM_QSCRIPTVALUE(localRenderAlpha, float, setLocalRenderAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE(ignoreForCollisions, bool, setIgnoreForCollisions); @@ -1087,12 +1090,12 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem if (properties.getType() == EntityTypes::Model) { APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, properties.getModelURL()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, properties.getAnimationURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, properties.getAnimationURL()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType())); } @@ -1105,10 +1108,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::ParticleEffect) { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); + //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan()); @@ -1377,12 +1380,12 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int if (properties.getType() == EntityTypes::Model) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_URL, QString, setModelURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_URL, QString, setAnimationURL); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_URL, QString, setAnimationURL); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); } @@ -1395,10 +1398,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::ParticleEffect) { - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); @@ -1534,11 +1537,13 @@ void EntityItemProperties::markAllChanged() { _alphaChanged = true; _modelURLChanged = true; _compoundShapeURLChanged = true; + /* _animationURLChanged = true; _animationIsPlayingChanged = true; _animationFrameIndexChanged = true; _animationFPSChanged = true; _animationSettingsChanged = true; + */ _glowLevelChanged = true; _localRenderAlphaChanged = true; _isSpotlightChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 55be145d85..29249d35e3 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -29,6 +29,7 @@ #include #include +#include "AnimationPropertyGroup.h" #include "AtmospherePropertyGroup.h" #include "EntityItemID.h" #include "EntityItemPropertiesMacros.h" @@ -115,10 +116,13 @@ public: DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString); DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); + /* DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, AnimationURL, animationURL, QString); DEFINE_PROPERTY(PROP_ANIMATION_FPS, AnimationFPS, animationFPS, float); DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, AnimationFrameIndex, animationFrameIndex, float); DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, AnimationIsPlaying, animationIsPlaying, bool); + //DEFINE_PROPERTY_REF_WITH_SETTER_AND_GETTER(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString); + */ DEFINE_PROPERTY_REF(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3); DEFINE_PROPERTY_REF(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3); DEFINE_PROPERTY(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float); @@ -130,7 +134,6 @@ public: DEFINE_PROPERTY(PROP_CUTOFF, Cutoff, cutoff, float); DEFINE_PROPERTY(PROP_LOCKED, Locked, locked, bool); DEFINE_PROPERTY_REF(PROP_TEXTURES, Textures, textures, QString); - DEFINE_PROPERTY_REF_WITH_SETTER_AND_GETTER(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString); DEFINE_PROPERTY_REF(PROP_USER_DATA, UserData, userData, QString); DEFINE_PROPERTY_REF(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner); DEFINE_PROPERTY_REF(PROP_TEXT, Text, text, QString); @@ -169,6 +172,7 @@ public: DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup); DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup); DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup); + DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup); DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString); DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float); DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector); @@ -200,7 +204,7 @@ public: bool containsBoundsProperties() const { return (_positionChanged || _dimensionsChanged); } bool containsPositionChange() const { return _positionChanged; } bool containsDimensionsChange() const { return _dimensionsChanged; } - bool containsAnimationSettingsChange() const { return _animationSettingsChanged; } + bool containsAnimationSettingsChange() const { return false; /*_animationSettingsChanged;*/ } // FIXME float getGlowLevel() const { return _glowLevel; } float getLocalRenderAlpha() const { return _localRenderAlpha; } @@ -297,9 +301,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { if (properties.containsPositionChange()) { debug << " position:" << properties.getPosition() << "in meters" << "\n"; } - if (properties.containsAnimationSettingsChange()) { - debug << " animationSettings:" << properties.getAnimationSettings() << "\n"; - } + //if (properties.containsAnimationSettingsChange()) { + // debug << " animationSettings:" << properties.getAnimationSettings() << "\n"; + //} DEBUG_PROPERTY_IF_CHANGED(debug, properties, Dimensions, dimensions, "in meters"); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters"); @@ -326,10 +330,10 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaFinish, alphaFinish, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ModelURL, modelURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CompoundShapeURL, compoundShapeURL, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationURL, animationURL, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFPS, animationFPS, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFrameIndex, animationFrameIndex, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationIsPlaying, animationIsPlaying, ""); + //DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationURL, animationURL, ""); + //DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFPS, animationFPS, ""); + //DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFrameIndex, animationFrameIndex, ""); + //DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationIsPlaying, animationIsPlaying, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, RegistrationPoint, registrationPoint, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AngularVelocity, angularVelocity, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AngularDamping, angularDamping, ""); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 70747937d8..61b10d69e8 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -49,14 +49,12 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationURL, getAnimationURL); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationIsPlaying, getAnimationIsPlaying); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFrameIndex, getAnimationFrameIndex); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS); COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationSettings, getAnimationSettings); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); + + _animationProperties.getProperties(properties); + return properties; } @@ -67,14 +65,11 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL); SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationURL, setAnimationURL); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationIsPlaying, setAnimationIsPlaying); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationSettings, setAnimationSettings); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); + bool somethingChangedInStage = _animationProperties.setProperties(properties); + if (somethingChanged) { bool wantDebug = false; if (wantDebug) { @@ -113,9 +108,11 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, float animationFPS = getAnimationFPS(); float animationFrameIndex = getAnimationFrameIndex(); bool animationIsPlaying = getAnimationIsPlaying(); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + } if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { if (animationIsPlaying != getAnimationIsPlaying()) { @@ -130,9 +127,22 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, } READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + } else { + int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData); + + bytesRead += bytesFromAnimation; + dataAt += bytesFromAnimation; + + // FIXME -- we need to actually get the property values out of the _animationProperties + // and use them for our AnimationLoop + } + READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); + return bytesRead; } @@ -142,13 +152,9 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& requestedProperties += PROP_MODEL_URL; requestedProperties += PROP_COMPOUND_SHAPE_URL; - requestedProperties += PROP_ANIMATION_URL; - requestedProperties += PROP_ANIMATION_FPS; - requestedProperties += PROP_ANIMATION_FRAME_INDEX; - requestedProperties += PROP_ANIMATION_PLAYING; - requestedProperties += PROP_ANIMATION_SETTINGS; requestedProperties += PROP_TEXTURES; requestedProperties += PROP_SHAPE_TYPE; + requestedProperties += _animationProperties.getEntityProperties(params); return requestedProperties; } @@ -166,12 +172,12 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getAnimationURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getAnimationFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getAnimationFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getAnimationIsPlaying()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, getAnimationSettings()); + + // FIXME - we probably need to make sure the _animationProperties has the latest data from the AnimationLoop + _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); + APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index bf6d7a9785..c00766dfbe 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -79,6 +79,11 @@ public: // model related properties void setModelURL(const QString& url) { _modelURL = url; } virtual void setCompoundShapeURL(const QString& url); + + + // Animation related items... + const AnimationPropertyGroup& getAnimationProperties() const { return _animationProperties; } + void setAnimationURL(const QString& url); static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value); @@ -134,9 +139,14 @@ protected: QString _compoundShapeURL; quint64 _lastAnimated; - QString _animationURL; + AnimationPropertyGroup _animationProperties; AnimationLoop _animationLoop; + + // FIXME - delete these + QString _animationURL; QString _animationSettings; + + QString _textures; ShapeType _shapeType = SHAPE_TYPE_NONE; diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 9d11dff55a..8b75bf29dd 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -168,11 +168,11 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationIsPlaying, getAnimationIsPlaying); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFrameIndex, getAnimationFrameIndex); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS); + //COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationIsPlaying, getAnimationIsPlaying); + //COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFrameIndex, getAnimationFrameIndex); + //COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS); COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationSettings, getAnimationSettings); + //COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationSettings, getAnimationSettings); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); @@ -208,11 +208,11 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationIsPlaying, setAnimationIsPlaying); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS); + //SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationIsPlaying, setAnimationIsPlaying); + //SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex); + //SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS); SET_ENTITY_PROPERTY_FROM_PROPERTIES(glowLevel, setGlowLevel); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationSettings, setAnimationSettings); + //SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationSettings, setAnimationSettings); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan); @@ -268,9 +268,11 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch float animationFPS = getAnimationFPS(); float animationFrameIndex = getAnimationFrameIndex(); bool animationIsPlaying = getAnimationIsPlaying(); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + } if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { if (animationIsPlaying != getAnimationIsPlaying()) { @@ -283,7 +285,20 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { setAnimationFrameIndex(animationFrameIndex); } - READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); + } + else { + int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData); + + bytesRead += bytesFromAnimation; + dataAt += bytesFromAnimation; + + // FIXME -- we need to actually get the property values out of the _animationProperties + // and use them for our AnimationLoop + } + READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); @@ -348,10 +363,6 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_COLOR; - requestedProperties += PROP_ANIMATION_FPS; - requestedProperties += PROP_ANIMATION_FRAME_INDEX; - requestedProperties += PROP_ANIMATION_PLAYING; - requestedProperties += PROP_ANIMATION_SETTINGS; requestedProperties += PROP_SHAPE_TYPE; requestedProperties += PROP_MAX_PARTICLES; requestedProperties += PROP_LIFESPAN; @@ -380,11 +391,13 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_AZIMUTH_START; requestedProperties += PROP_AZIMUTH_FINISH; + requestedProperties += _animationProperties.getEntityProperties(params); + return requestedProperties; } void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, - EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, @@ -393,10 +406,11 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getAnimationFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getAnimationFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getAnimationIsPlaying()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, getAnimationSettings()); + + // FIXME - we probably need to make sure the _animationProperties has the latest data from the AnimationLoop + _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, + propertyFlags, propertiesDidntFit, propertyCount, appendState); + APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan()); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 74d39aa4af..4e37165b55 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -31,7 +31,7 @@ public: virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, - EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, @@ -91,6 +91,9 @@ public: virtual void debugDump() const; + + const AnimationPropertyGroup& getAnimationProperties() const { return _animationProperties; } + static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value); void setAnimationSettings(const QString& value); @@ -245,9 +248,15 @@ protected: float _radiusStart = DEFAULT_RADIUS_START; float _radiusFinish = DEFAULT_RADIUS_FINISH; float _radiusSpread = DEFAULT_RADIUS_SPREAD; + + quint64 _lastAnimated; + AnimationPropertyGroup _animationProperties; AnimationLoop _animationLoop; + + // FIXME - remove this QString _animationSettings; + QString _textures = DEFAULT_TEXTURES; bool _texturesChangedFlag = false; ShapeType _shapeType = SHAPE_TYPE_NONE; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a8cf743686..bdf6f8c524 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,7 +38,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER; + return VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP; default: return 14; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 9f3c5950a2..25a99d65f7 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -141,5 +141,6 @@ const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; +const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 45; #endif // hifi_PacketHeaders_h From 9fc684edf0692e6198757ef64bcc3331c1e5e27f Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 20:51:37 -0700 Subject: [PATCH 003/152] first cut at migrating animation settings into a property group --- .../entities/src/AnimationPropertyGroup.cpp | 210 ++++++++++++++++++ .../entities/src/AnimationPropertyGroup.h | 83 +++++++ .../entities/src/EntityItemProperties.cpp | 7 - libraries/entities/src/EntityPropertyFlags.h | 6 + 4 files changed, 299 insertions(+), 7 deletions(-) create mode 100644 libraries/entities/src/AnimationPropertyGroup.cpp create mode 100644 libraries/entities/src/AnimationPropertyGroup.h diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp new file mode 100644 index 0000000000..bc2dc61601 --- /dev/null +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -0,0 +1,210 @@ +// +// AnimationPropertyGroup.cpp +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "AnimationPropertyGroup.h" +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +AnimationPropertyGroup::AnimationPropertyGroup() { + //_url = QString(); +} + +void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); +} + +void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); +} + +void AnimationPropertyGroup::debugDump() const { + qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; + qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); +} + +bool AnimationPropertyGroup::appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + + return true; +} + + +bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, FrameIndex); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_PLAYING, Running); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LOOP, Loop); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically); + + processedBytes += bytesRead; + + return true; +} + +void AnimationPropertyGroup::markAllChanged() { + _urlChanged = true; + _fpsChanged = true; + _frameIndexChanged = true; + _runningChanged = true; +} + +EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, frameIndex); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, running); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LOOP, loop); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically); + + return changedProperties; +} + +void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); +} + +bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); + + return somethingChanged; +} + +EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_ANIMATION_URL; + requestedProperties += PROP_ANIMATION_FPS; + requestedProperties += PROP_ANIMATION_FRAME_INDEX; + requestedProperties += PROP_ANIMATION_PLAYING; + requestedProperties += PROP_ANIMATION_LOOP; + requestedProperties += PROP_ANIMATION_FIRST_FRAME; + requestedProperties += PROP_ANIMATION_LAST_FRAME; + requestedProperties += PROP_ANIMATION_HOLD; + requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY; + + return requestedProperties; +} + +void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); +} + +int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + + return bytesRead; +} diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h new file mode 100644 index 0000000000..d931684e9e --- /dev/null +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -0,0 +1,83 @@ +// +// AnimationPropertyGroup.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 2015/9/30. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimationPropertyGroup_h +#define hifi_AnimationPropertyGroup_h + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +#include +#include + + +class AnimationPropertyGroup : public PropertyGroup { +public: + AnimationPropertyGroup(); + virtual ~AnimationPropertyGroup() {} + + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); + virtual void debugDump() const; + + virtual bool appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes); + virtual void markAllChanged(); + virtual EntityPropertyFlags getChangedProperties() const; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties); + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + + DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString); + DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float); + DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, FrameIndex, frameIndex, float); + DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool); // was animationIsPlaying + DEFINE_PROPERTY(PROP_ANIMATION_LOOP, Loop, loop, bool); // was animationSettings.loop + DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float); // was animationSettings.firstFrame + DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float); // was animationSettings.lastFrame + DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool); // was animationSettings.hold + DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically +}; + +#endif // hifi_AnimationPropertyGroup_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ea80b27877..d29b1d6a46 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1537,13 +1537,6 @@ void EntityItemProperties::markAllChanged() { _alphaChanged = true; _modelURLChanged = true; _compoundShapeURLChanged = true; - /* - _animationURLChanged = true; - _animationIsPlayingChanged = true; - _animationFrameIndexChanged = true; - _animationFPSChanged = true; - _animationSettingsChanged = true; - */ _glowLevelChanged = true; _localRenderAlphaChanged = true; _isSpotlightChanged = true; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 71215a5596..849e3e3a61 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -143,6 +143,12 @@ enum EntityPropertyList { PROP_AZIMUTH_START, PROP_AZIMUTH_FINISH, + PROP_ANIMATION_LOOP, + PROP_ANIMATION_FIRST_FRAME, + PROP_ANIMATION_LAST_FRAME, + PROP_ANIMATION_HOLD, + PROP_ANIMATION_START_AUTOMATICALLY, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, From d7ee41cc2326f4ade5115c8bc009aca4d1cf636e Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 20:51:37 -0700 Subject: [PATCH 004/152] first cut at migrating animation settings into a property group --- .../entities/src/AnimationPropertyGroup.cpp | 210 ++++++++++++++++++ .../entities/src/AnimationPropertyGroup.h | 83 +++++++ .../entities/src/EntityItemProperties.cpp | 37 +-- libraries/entities/src/EntityPropertyFlags.h | 6 + 4 files changed, 310 insertions(+), 26 deletions(-) create mode 100644 libraries/entities/src/AnimationPropertyGroup.cpp create mode 100644 libraries/entities/src/AnimationPropertyGroup.h diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp new file mode 100644 index 0000000000..bc2dc61601 --- /dev/null +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -0,0 +1,210 @@ +// +// AnimationPropertyGroup.cpp +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 12/4/13. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "AnimationPropertyGroup.h" +#include "EntityItemProperties.h" +#include "EntityItemPropertiesMacros.h" + +AnimationPropertyGroup::AnimationPropertyGroup() { + //_url = QString(); +} + +void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); +} + +void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); +} + +void AnimationPropertyGroup::debugDump() const { + qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; + qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); +} + +bool AnimationPropertyGroup::appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + + return true; +} + + +bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) { + + int bytesRead = 0; + bool overwriteLocalData = true; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, FrameIndex); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_PLAYING, Running); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LOOP, Loop); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically); + + processedBytes += bytesRead; + + return true; +} + +void AnimationPropertyGroup::markAllChanged() { + _urlChanged = true; + _fpsChanged = true; + _frameIndexChanged = true; + _runningChanged = true; +} + +EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { + EntityPropertyFlags changedProperties; + + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, frameIndex); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, running); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LOOP, loop); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_START_AUTOMATICALLY, startAutomatically); + + return changedProperties; +} + +void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); +} + +bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { + bool somethingChanged = false; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); + + return somethingChanged; +} + +EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const { + EntityPropertyFlags requestedProperties; + + requestedProperties += PROP_ANIMATION_URL; + requestedProperties += PROP_ANIMATION_FPS; + requestedProperties += PROP_ANIMATION_FRAME_INDEX; + requestedProperties += PROP_ANIMATION_PLAYING; + requestedProperties += PROP_ANIMATION_LOOP; + requestedProperties += PROP_ANIMATION_FIRST_FRAME; + requestedProperties += PROP_ANIMATION_LAST_FRAME; + requestedProperties += PROP_ANIMATION_HOLD; + requestedProperties += PROP_ANIMATION_START_AUTOMATICALLY; + + return requestedProperties; +} + +void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const { + + bool successPropertyFits = true; + + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); +} + +int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + + int bytesRead = 0; + const unsigned char* dataAt = data; + + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + + return bytesRead; +} diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h new file mode 100644 index 0000000000..d931684e9e --- /dev/null +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -0,0 +1,83 @@ +// +// AnimationPropertyGroup.h +// libraries/entities/src +// +// Created by Brad Hefta-Gaub on 2015/9/30. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimationPropertyGroup_h +#define hifi_AnimationPropertyGroup_h + +#include + +#include "PropertyGroup.h" +#include "EntityItemPropertiesMacros.h" + +class EntityItemProperties; +class EncodeBitstreamParams; +class OctreePacketData; +class EntityTreeElementExtraEncodeData; +class ReadBitstreamToTreeParams; + +#include +#include + + +class AnimationPropertyGroup : public PropertyGroup { +public: + AnimationPropertyGroup(); + virtual ~AnimationPropertyGroup() {} + + // EntityItemProperty related helpers + virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; + virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); + virtual void debugDump() const; + + virtual bool appentToEditPacket(OctreePacketData* packetData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes); + virtual void markAllChanged(); + virtual EntityPropertyFlags getChangedProperties() const; + + // EntityItem related helpers + // methods for getting/setting all properties of an entity + virtual void getProperties(EntityItemProperties& propertiesOut) const; + + /// returns true if something changed + virtual bool setProperties(const EntityItemProperties& properties); + + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; + + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, + EntityPropertyFlags& requestedProperties, + EntityPropertyFlags& propertyFlags, + EntityPropertyFlags& propertiesDidntFit, + int& propertyCount, + OctreeElement::AppendState& appendState) const; + + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + ReadBitstreamToTreeParams& args, + EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + + DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString); + DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float); + DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, FrameIndex, frameIndex, float); + DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool); // was animationIsPlaying + DEFINE_PROPERTY(PROP_ANIMATION_LOOP, Loop, loop, bool); // was animationSettings.loop + DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float); // was animationSettings.firstFrame + DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float); // was animationSettings.lastFrame + DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool); // was animationSettings.hold + DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically +}; + +#endif // hifi_AnimationPropertyGroup_h diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ea80b27877..d98169fade 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -30,6 +30,7 @@ #include "LineEntityItem.h" #include "PolyLineEntityItem.h" +AnimationPropertyGroup EntityItemProperties::_staticAnimation; AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere; SkyboxPropertyGroup EntityItemProperties::_staticSkybox; StagePropertyGroup EntityItemProperties::_staticStage; @@ -1090,13 +1091,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem if (properties.getType() == EntityTypes::Model) { APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, properties.getModelURL()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, properties.getAnimationURL()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType())); + + _staticAnimation.setProperties(properties); + _staticAnimation.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); } if (properties.getType() == EntityTypes::Light) { @@ -1108,10 +1107,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::ParticleEffect) { - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, properties.getAnimationFPS()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, properties.getAnimationFrameIndex()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, properties.getAnimationIsPlaying()); - //APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, properties.getAnimationSettings()); + _staticAnimation.setProperties(properties); + _staticAnimation.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan()); @@ -1380,13 +1378,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int if (properties.getType() == EntityTypes::Model) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_URL, QString, setModelURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_URL, QString, setAnimationURL); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); + + properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); } if (properties.getType() == EntityTypes::Light) { @@ -1398,12 +1393,9 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::ParticleEffect) { - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FPS, float, setAnimationFPS); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - //READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); + properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); @@ -1537,13 +1529,6 @@ void EntityItemProperties::markAllChanged() { _alphaChanged = true; _modelURLChanged = true; _compoundShapeURLChanged = true; - /* - _animationURLChanged = true; - _animationIsPlayingChanged = true; - _animationFrameIndexChanged = true; - _animationFPSChanged = true; - _animationSettingsChanged = true; - */ _glowLevelChanged = true; _localRenderAlphaChanged = true; _isSpotlightChanged = true; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 71215a5596..849e3e3a61 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -143,6 +143,12 @@ enum EntityPropertyList { PROP_AZIMUTH_START, PROP_AZIMUTH_FINISH, + PROP_ANIMATION_LOOP, + PROP_ANIMATION_FIRST_FRAME, + PROP_ANIMATION_LAST_FRAME, + PROP_ANIMATION_HOLD, + PROP_ANIMATION_START_AUTOMATICALLY, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, From aca25bd76ef016e15612225f7b177c1321e06995 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 1 Oct 2015 11:05:16 -0700 Subject: [PATCH 005/152] connect up AnimationPropertyGroup to AnimationLoop --- .../example/entities/animatedModelExample.js | 19 +- libraries/animation/src/AnimationLoop.cpp | 23 +- libraries/animation/src/AnimationLoop.h | 24 +- .../entities/src/AnimationPropertyGroup.cpp | 237 +++++++++++++----- .../entities/src/AnimationPropertyGroup.h | 18 +- .../entities/src/AtmospherePropertyGroup.cpp | 2 +- .../entities/src/AtmospherePropertyGroup.h | 2 +- .../entities/src/EntityItemProperties.cpp | 28 +-- libraries/entities/src/EntityItemProperties.h | 4 +- .../entities/src/EntityItemPropertiesMacros.h | 12 + libraries/entities/src/ModelEntityItem.cpp | 35 +-- .../entities/src/ParticleEffectEntityItem.cpp | 6 +- libraries/entities/src/PropertyGroup.h | 2 +- .../entities/src/SkyboxPropertyGroup.cpp | 2 +- libraries/entities/src/SkyboxPropertyGroup.h | 2 +- libraries/entities/src/StagePropertyGroup.cpp | 2 +- libraries/entities/src/StagePropertyGroup.h | 2 +- 17 files changed, 285 insertions(+), 135 deletions(-) diff --git a/examples/example/entities/animatedModelExample.js b/examples/example/entities/animatedModelExample.js index af2fab05a0..47bca9cfb0 100644 --- a/examples/example/entities/animatedModelExample.js +++ b/examples/example/entities/animatedModelExample.js @@ -37,8 +37,12 @@ var originalProperties = { modelURL: "http://public.highfidelity.io/cozza13/club/dragon/dragon.fbx", rotation: rotation, - animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", - animationIsPlaying: true, + //animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", + //animationIsPlaying: true, + animationSettings: { + url: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", + running: true + } }; var modelID = Entities.addEntity(originalProperties); @@ -99,13 +103,18 @@ function moveModel(deltaTime) { if (somethingChanged) { var newProperties = { - animationIsPlaying: isPlaying, - animationFPS: animationFPS, + //animationIsPlaying: isPlaying, + //animationFPS: animationFPS, + animationSettings: { + running: isPlaying, + fps: animationFPS + } }; if (resetFrame) { print("resetting the frame!"); - newProperties.animationFrameIndex = 0; + //newProperties.animationFrameIndex = 0; + newProperties.animationSettings.frameIndex = 0; resetFrame = false; } diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index a2a27170c2..6ad724922e 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -14,16 +14,17 @@ const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f; -AnimationLoop::AnimationLoop() : - _fps(30.0f), - _loop(false), - _hold(false), - _startAutomatically(false), - _firstFrame(0.0f), - _lastFrame(MAXIMUM_POSSIBLE_FRAME), - _running(false), - _frameIndex(0.0f), - _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME) +AnimationLoop::AnimationLoop() +/*: +_fps(30.0f), +_loop(false), +_hold(false), +_startAutomatically(false), +_firstFrame(0.0f), +_lastFrame(MAXIMUM_POSSIBLE_FRAME), +_running(false), +_frameIndex(0.0f), +_maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME)*/ { } @@ -89,7 +90,7 @@ void AnimationLoop::setRunning(bool running) { _running = running; // If we just set running to true, then also reset the frame to the first frame - if (running) { + if (running && _resetOnRunning) { // move back to the beginning _frameIndex = _firstFrame; } diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 02161544ba..3c6079d967 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -41,7 +41,12 @@ public: void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); } float getLastFrame() const { return _lastFrame; } + /// by default the AnimationLoop will always reset to the first frame on any call to setRunning + /// this is not desirable in the case of entities with animations, if you don't want the reset + /// to happen then call this method with false; + void setResetOnRunning(bool resetOnRunning) { _resetOnRunning = resetOnRunning; } void setRunning(bool running); + bool getRunning() const { return _running; } bool isRunning() const { return _running; } void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); } @@ -55,15 +60,16 @@ public: void simulate(float deltaTime); private: - float _fps; - bool _loop; - bool _hold; - bool _startAutomatically; - float _firstFrame; - float _lastFrame; - bool _running; - float _frameIndex; - float _maxFrameIndexHint; + float _fps = 30.0f; + bool _loop = false; + bool _hold = false; + bool _startAutomatically = false; + float _firstFrame = 0.0f; + float _lastFrame = MAXIMUM_POSSIBLE_FRAME; + bool _running = false; + float _frameIndex = 0.0f; + float _maxFrameIndexHint = MAXIMUM_POSSIBLE_FRAME; + bool _resetOnRunning = false; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index bc2dc61601..a93becd7fb 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -11,6 +11,8 @@ #include +#include + #include "AnimationPropertyGroup.h" #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" @@ -20,27 +22,51 @@ AnimationPropertyGroup::AnimationPropertyGroup() { } void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, Running, running); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, AnimationSettings, animationSettings, URL, url); + + if (_animationLoop) { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically, _animationLoop->getFPS); + } else { + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically); + } } void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, setFrameIndex); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, url, QString, setURL); + + if (_animationLoop) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, _animationLoop->setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, _animationLoop->setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, running, bool, _animationLoop->setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, loop, bool, _animationLoop->setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, firstFrame, float, _animationLoop->setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, _animationLoop->setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, _animationLoop->setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, _animationLoop->setStartAutomatically); + } else { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, running, bool, setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, loop, bool, setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, firstFrame, float, setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, setStartAutomatically); + } } void AnimationPropertyGroup::debugDump() const { @@ -48,7 +74,7 @@ void AnimationPropertyGroup::debugDump() const { qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); } -bool AnimationPropertyGroup::appentToEditPacket(OctreePacketData* packetData, +bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, @@ -58,14 +84,25 @@ bool AnimationPropertyGroup::appentToEditPacket(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + if (_animationLoop) { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); + } else { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + } return true; } @@ -77,14 +114,25 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF bool overwriteLocalData = true; READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + if (_animationLoop) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); + } else { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + } DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); @@ -125,29 +173,55 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { } void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, getFrameIndex); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, URL, getURL); + + if (_animationLoop) { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FPS, _animationLoop->getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FrameIndex, _animationLoop->getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Running, _animationLoop->getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Loop, _animationLoop->getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FirstFrame, _animationLoop->getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, LastFrame, _animationLoop->getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Hold, _animationLoop->getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, StartAutomatically, _animationLoop->getStartAutomatically); + } else { + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FPS, getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FrameIndex, getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Running, getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Loop, getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FirstFrame, getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, LastFrame, getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, StartAutomatically, getStartAutomatically); + } } bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, setFrameIndex); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, URL, url, setURL); + + if (_animationLoop) { + qDebug() << "AnimationPropertyGroup::setProperties() -- apply new properties to our associated AnimationLoop"; + + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FPS, fps, _animationLoop->setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FrameIndex, frameIndex, _animationLoop->setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Running, running, _animationLoop->setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Loop, loop, _animationLoop->setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FirstFrame, firstFrame, _animationLoop->setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, LastFrame, lastFrame, _animationLoop->setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Hold, hold, _animationLoop->setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); + } else { + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FPS, fps, setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FrameIndex, frameIndex, setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Running, running, setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Loop, loop, setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FirstFrame, firstFrame, setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, LastFrame, lastFrame, setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, StartAutomatically, startAutomatically, setStartAutomatically); + } return somethingChanged; } @@ -179,14 +253,25 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + if (_animationLoop) { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + } else { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); + } } int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, @@ -197,14 +282,28 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); - READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + if (_animationLoop) { + // apply new properties to our associated AnimationLoop + qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, _animationLoop->setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); + } else { + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame); + READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold); + READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); + } + return bytesRead; } diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index d931684e9e..a26975a83c 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -9,6 +9,16 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + +// FIXME - TODO +// 1) make EntityItemProperties support old versions of animation properties +// DONE - 2) rename the group animationSettings +// 3) make sure that setting properties and reading from stream actually set the animationLoop object properly +// 4) test it! +// 5) update all scripts +// 6) remove all remnants of old member variables +// 7) research and remove animation settings from Particle Effect + #ifndef hifi_AnimationPropertyGroup_h #define hifi_AnimationPropertyGroup_h @@ -22,6 +32,7 @@ class EncodeBitstreamParams; class OctreePacketData; class EntityTreeElementExtraEncodeData; class ReadBitstreamToTreeParams; +class AnimationLoop; #include #include @@ -37,7 +48,7 @@ public: virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; - virtual bool appentToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, @@ -78,6 +89,11 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float); // was animationSettings.lastFrame DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool); // was animationSettings.hold DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically + +public: + void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } +private: + AnimationLoop* _animationLoop = nullptr; }; #endif // hifi_AnimationPropertyGroup_h diff --git a/libraries/entities/src/AtmospherePropertyGroup.cpp b/libraries/entities/src/AtmospherePropertyGroup.cpp index f8117dbb62..676a214b81 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.cpp +++ b/libraries/entities/src/AtmospherePropertyGroup.cpp @@ -63,7 +63,7 @@ void AtmospherePropertyGroup::debugDump() const { qDebug() << " Has Stars:" << getHasStars() << " has changed:" << hasStarsChanged(); } -bool AtmospherePropertyGroup::appentToEditPacket(OctreePacketData* packetData, +bool AtmospherePropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/AtmospherePropertyGroup.h b/libraries/entities/src/AtmospherePropertyGroup.h index c4b50822fa..715b923feb 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.h +++ b/libraries/entities/src/AtmospherePropertyGroup.h @@ -57,7 +57,7 @@ public: virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; - virtual bool appentToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index b5bd032949..5c4c89a465 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -30,7 +30,7 @@ #include "LineEntityItem.h" #include "PolyLineEntityItem.h" -AnimationPropertyGroup EntityItemProperties::_staticAnimation; +AnimationPropertyGroup EntityItemProperties::_staticAnimationSettings; AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere; SkyboxPropertyGroup EntityItemProperties::_staticSkybox; StagePropertyGroup EntityItemProperties::_staticStage; @@ -430,7 +430,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID); CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); - changedProperties += _animation.getChangedProperties(); + changedProperties += _animationSettings.getChangedProperties(); changedProperties += _atmosphere.getChangedProperties(); changedProperties += _skybox.getChangedProperties(); changedProperties += _stage.getChangedProperties(); @@ -537,7 +537,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models & Particles if (_type == EntityTypes::Model || _type == EntityTypes::ParticleEffect) { - _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + _animationSettings.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); } @@ -740,7 +740,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool //COPY_PROPERTY_FROM_QSCRIPTVALUE(simulationOwner, ???, setSimulatorPriority); } - _animation.copyFromScriptValue(object, _defaultSettings); + _animationSettings.copyFromScriptValue(object, _defaultSettings); _atmosphere.copyFromScriptValue(object, _defaultSettings); _skybox.copyFromScriptValue(object, _defaultSettings); _stage.copyFromScriptValue(object, _defaultSettings); @@ -1096,8 +1096,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType())); - _staticAnimation.setProperties(properties); - _staticAnimation.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + _staticAnimationSettings.setProperties(properties); + _staticAnimationSettings.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); } if (properties.getType() == EntityTypes::Light) { @@ -1109,8 +1109,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::ParticleEffect) { - _staticAnimation.setProperties(properties); - _staticAnimation.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + _staticAnimationSettings.setProperties(properties); + _staticAnimationSettings.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); @@ -1146,7 +1146,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, properties.getKeyLightDirection()); _staticStage.setProperties(properties); - _staticStage.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState ); + _staticStage.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)properties.getShapeType()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL()); @@ -1154,10 +1154,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)properties.getBackgroundMode()); _staticAtmosphere.setProperties(properties); - _staticAtmosphere.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState ); + _staticAtmosphere.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); _staticSkybox.setProperties(properties); - _staticSkybox.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState ); + _staticSkybox.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); } if (properties.getType() == EntityTypes::PolyVox) { @@ -1383,7 +1383,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); - properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + properties.getAnimationSettings().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); } if (properties.getType() == EntityTypes::Light) { @@ -1395,7 +1395,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::ParticleEffect) { - properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + properties.getAnimationSettings().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); @@ -1583,7 +1583,7 @@ void EntityItemProperties::markAllChanged() { _backgroundModeChanged = true; - _animation.markAllChanged(); + _animationSettings.markAllChanged(); _atmosphere.markAllChanged(); _skybox.markAllChanged(); _stage.markAllChanged(); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index c8bf0836d5..82095b6b71 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -165,7 +165,7 @@ public: DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup); DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup); DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup); - DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup); + DEFINE_PROPERTY_GROUP(AnimationSettings, animationSettings, AnimationPropertyGroup); DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString); DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float); DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector); @@ -373,7 +373,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, YPNeighborID, yPNeighborID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZPNeighborID, zPNeighborID, ""); - properties.getAnimation().debugDump(); + properties.getAnimationSettings().debugDump(); properties.getAtmosphere().debugDump(); properties.getSkybox().debugDump(); properties.getStage().debugDump(); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 731e49b388..6b2a21ddf5 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -131,6 +131,18 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) properties.setProperty(#g, groupProperties); \ } +#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(X,G,g,P,p,M) \ + if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ + (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ + QScriptValue groupProperties = properties.property(#g); \ + if (!groupProperties.isValid()) { \ + groupProperties = engine->newObject(); \ + } \ + QScriptValue V = convertScriptValue(engine, M()); \ + groupProperties.setProperty(#p, V); \ + properties.setProperty(#g, groupProperties); \ + } + #define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \ if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \ (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 738d28f026..de06fecd81 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -41,6 +41,9 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI _jointMappingCompleted = false; _lastKnownFrameIndex = -1; _color[0] = _color[1] = _color[2] = 0; + + _animationProperties.associateWithAnimationLoop(&_animationLoop); + _animationLoop.setResetOnRunning(false); } EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { @@ -107,39 +110,39 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, // Because we're using AnimationLoop which will reset the frame index if you change it's running state // we want to read these values in the order they appear in the buffer, but call our setters in an // order that allows AnimationLoop to preserve the correct frame rate. - float animationFPS = getAnimationFPS(); - float animationFrameIndex = getAnimationFrameIndex(); - bool animationIsPlaying = getAnimationIsPlaying(); if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + float animationFPS = getAnimationFPS(); + float animationFrameIndex = getAnimationFrameIndex(); + bool animationIsPlaying = getAnimationIsPlaying(); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { - if (animationIsPlaying != getAnimationIsPlaying()) { - setAnimationIsPlaying(animationIsPlaying); + if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { + if (animationIsPlaying != getAnimationIsPlaying()) { + setAnimationIsPlaying(animationIsPlaying); + } + } + if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) { + setAnimationFPS(animationFPS); + } + if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { + setAnimationFrameIndex(animationFrameIndex); } - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) { - setAnimationFPS(animationFPS); - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { - setAnimationFrameIndex(animationFrameIndex); } READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); } else { + // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() + // will automatically read into the animation loop int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); bytesRead += bytesFromAnimation; dataAt += bytesFromAnimation; - - // FIXME -- we need to actually get the property values out of the _animationProperties - // and use them for our AnimationLoop } READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 5bf2369cd5..496d0d437f 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -103,11 +103,15 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _particleMaxBound(glm::vec3(1.0f, 1.0f, 1.0f)), - _particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) { + _particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) +{ _type = EntityTypes::ParticleEffect; setColor(DEFAULT_COLOR); setProperties(properties); + + _animationProperties.associateWithAnimationLoop(&_animationLoop); + _animationLoop.setResetOnRunning(false); } ParticleEffectEntityItem::~ParticleEffectEntityItem() { diff --git a/libraries/entities/src/PropertyGroup.h b/libraries/entities/src/PropertyGroup.h index f780907896..4069e7be02 100644 --- a/libraries/entities/src/PropertyGroup.h +++ b/libraries/entities/src/PropertyGroup.h @@ -59,7 +59,7 @@ public: virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) = 0; virtual void debugDump() const { } - virtual bool appentToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/SkyboxPropertyGroup.cpp b/libraries/entities/src/SkyboxPropertyGroup.cpp index 624a382d55..261e050387 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.cpp +++ b/libraries/entities/src/SkyboxPropertyGroup.cpp @@ -36,7 +36,7 @@ void SkyboxPropertyGroup::debugDump() const { qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); } -bool SkyboxPropertyGroup::appentToEditPacket(OctreePacketData* packetData, +bool SkyboxPropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/SkyboxPropertyGroup.h b/libraries/entities/src/SkyboxPropertyGroup.h index 25d982cbe7..995c87e1db 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.h +++ b/libraries/entities/src/SkyboxPropertyGroup.h @@ -37,7 +37,7 @@ public: virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; - virtual bool appentToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/StagePropertyGroup.cpp b/libraries/entities/src/StagePropertyGroup.cpp index fb27f9a464..a8b7705a73 100644 --- a/libraries/entities/src/StagePropertyGroup.cpp +++ b/libraries/entities/src/StagePropertyGroup.cpp @@ -76,7 +76,7 @@ void StagePropertyGroup::debugDump() const { qDebug() << " _automaticHourDay:" << _automaticHourDay; } -bool StagePropertyGroup::appentToEditPacket(OctreePacketData* packetData, +bool StagePropertyGroup::appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, diff --git a/libraries/entities/src/StagePropertyGroup.h b/libraries/entities/src/StagePropertyGroup.h index 32eb3462a3..0f1cbf5a89 100644 --- a/libraries/entities/src/StagePropertyGroup.h +++ b/libraries/entities/src/StagePropertyGroup.h @@ -37,7 +37,7 @@ public: virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings); virtual void debugDump() const; - virtual bool appentToEditPacket(OctreePacketData* packetData, + virtual bool appendToEditPacket(OctreePacketData* packetData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, From 91a27e3adf1b4d79ecc2825a04004f57a9dde4e5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 1 Oct 2015 13:29:07 -0700 Subject: [PATCH 006/152] get animation to actually run again --- libraries/animation/src/AnimationLoop.cpp | 6 +- .../src/RenderableModelEntityItem.cpp | 1 + .../entities/src/AnimationPropertyGroup.cpp | 50 ++++++++++++---- .../entities/src/AnimationPropertyGroup.h | 5 +- libraries/entities/src/ModelEntityItem.cpp | 58 ++++--------------- libraries/entities/src/ModelEntityItem.h | 20 +++---- 6 files changed, 66 insertions(+), 74 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 6ad724922e..f6c414c1d7 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -14,8 +14,7 @@ const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f; -AnimationLoop::AnimationLoop() -/*: +AnimationLoop::AnimationLoop() : _fps(30.0f), _loop(false), _hold(false), @@ -24,7 +23,7 @@ _firstFrame(0.0f), _lastFrame(MAXIMUM_POSSIBLE_FRAME), _running(false), _frameIndex(0.0f), -_maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME)*/ +_maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME) { } @@ -85,6 +84,7 @@ void AnimationLoop::setStartAutomatically(bool startAutomatically) { } void AnimationLoop::setRunning(bool running) { + qDebug() << "AnimationLoop::setRunning() new running:" << running << "old _running:" << _running; // don't do anything if the new value is the same as the value we already have if (_running != running) { _running = running; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c978fab012..15cea8b432 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -269,6 +269,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (_model) { // handle animations.. if (hasAnimation()) { + if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); mapJoints(modelJointNames); diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index a93becd7fb..da7d309316 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -17,22 +17,35 @@ #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" -AnimationPropertyGroup::AnimationPropertyGroup() { - //_url = QString(); + +AnimationPropertyGroup::AnimationPropertyGroup() : +CONSTRUCT_PROPERTY(fps, 30.0f), +CONSTRUCT_PROPERTY(running, false), +CONSTRUCT_PROPERTY(loop, true), +CONSTRUCT_PROPERTY(firstFrame, 0.0f), +CONSTRUCT_PROPERTY(lastFrame, AnimationLoop::MAXIMUM_POSSIBLE_FRAME), +CONSTRUCT_PROPERTY(hold, false), +CONSTRUCT_PROPERTY(startAutomatically, false) +{ + static const QString DEFAULT_URL; + + _url = DEFAULT_URL; } void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, AnimationSettings, animationSettings, URL, url); + //qDebug() << "AnimationPropertyGroup::copyToScriptValue() url:" << getURL(); + if (_animationLoop) { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps, _animationLoop->getFPS); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running, _animationLoop->getRunning); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop, _animationLoop->getLoop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame, _animationLoop->getFirstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame, _animationLoop->getLastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold, _animationLoop->getHold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); } else { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex); @@ -48,6 +61,8 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, url, QString, setURL); + //qDebug() << "AnimationPropertyGroup::copyFromScriptValue() url:" << getURL(); + if (_animationLoop) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, _animationLoop->setFPS); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, _animationLoop->setFrameIndex); @@ -84,6 +99,9 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); + + //qDebug() << "AnimationPropertyGroup::appendToEditPacket() url:" << getURL(); + if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); @@ -114,6 +132,9 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF bool overwriteLocalData = true; READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + + //qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() url:" << getURL(); + if (_animationLoop) { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); @@ -175,6 +196,8 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, URL, getURL); + //qDebug() << "AnimationPropertyGroup::getProperties() url:" << getURL(); + if (_animationLoop) { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FPS, _animationLoop->getFPS); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FrameIndex, _animationLoop->getFrameIndex); @@ -201,8 +224,10 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, URL, url, setURL); + //qDebug() << "AnimationPropertyGroup::setProperties() url:" << getURL(); + if (_animationLoop) { - qDebug() << "AnimationPropertyGroup::setProperties() -- apply new properties to our associated AnimationLoop"; + //qDebug() << "AnimationPropertyGroup::setProperties() -- apply new properties to our associated AnimationLoop"; SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FPS, fps, _animationLoop->setFPS); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FrameIndex, frameIndex, _animationLoop->setFrameIndex); @@ -252,6 +277,8 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En bool successPropertyFits = true; + //qDebug() << "AnimationPropertyGroup::appendSubclassData() url:" << getURL(); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); @@ -282,9 +309,12 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); + + //qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() url:" << getURL(); + if (_animationLoop) { // apply new properties to our associated AnimationLoop - qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; + //qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index a26975a83c..2c04303482 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -91,7 +91,10 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically public: - void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } + void associateWithAnimationLoop(AnimationLoop* animationLoop) { + qDebug() << "associateWithAnimationLoop() this:" << this << "animationLoop:" << animationLoop; + _animationLoop = animationLoop; + } private: AnimationLoop* _animationLoop = nullptr; }; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index de06fecd81..5e4e1e534b 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -35,15 +35,15 @@ EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const E ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : EntityItem(entityItemID) { + _animationProperties.associateWithAnimationLoop(&_animationLoop); + _animationLoop.setResetOnRunning(false); + _type = EntityTypes::Model; setProperties(properties); _lastAnimated = usecTimestampNow(); _jointMappingCompleted = false; _lastKnownFrameIndex = -1; _color[0] = _color[1] = _color[2] = 0; - - _animationProperties.associateWithAnimationLoop(&_animationLoop); - _animationLoop.setResetOnRunning(false); } EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { @@ -62,6 +62,8 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP } bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID(); + bool somethingChanged = false; somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class @@ -215,7 +217,7 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { return; } - AnimationPointer myAnimation = getAnimation(_animationURL); + AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); if (myAnimation && myAnimation->isLoaded()) { QStringList animationJointNames = myAnimation->getJointNames(); @@ -236,7 +238,7 @@ const QVector& ModelEntityItem::getAnimationFrame(bool& newFrame) { return _lastKnownFrameData; } - AnimationPointer myAnimation = getAnimation(_animationURL); // FIXME: this could be optimized + AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); // FIXME: this could be optimized if (myAnimation && myAnimation->isLoaded()) { const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy @@ -282,6 +284,7 @@ void ModelEntityItem::update(const quint64& now) { if (getAnimationIsPlaying()) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; _lastAnimated = now; + qDebug() << "ModelEntityItem::update() calling _animationLoop.simulate(deltaTime);"; _animationLoop.simulate(deltaTime); } else { _lastAnimated = now; @@ -334,7 +337,7 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { void ModelEntityItem::setAnimationURL(const QString& url) { _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; - _animationURL = url; + _animationProperties.setURL(url); } void ModelEntityItem::setAnimationFrameIndex(float value) { @@ -411,7 +414,7 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { setAnimationStartAutomatically(startAutomatically); } - _animationSettings = value; + //_animationSettings = value; _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; } @@ -425,47 +428,6 @@ void ModelEntityItem::setAnimationFPS(float value) { _animationLoop.setFPS(value); } -QString ModelEntityItem::getAnimationSettings() const { - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and - // will over ride the regular animation settings - QString value = _animationSettings; - - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - - QVariant fpsValue(getAnimationFPS()); - settingsMap["fps"] = fpsValue; - - QVariant frameIndexValue(getAnimationFrameIndex()); - settingsMap["frameIndex"] = frameIndexValue; - - QVariant runningValue(getAnimationIsPlaying()); - settingsMap["running"] = runningValue; - - QVariant firstFrameValue(getAnimationFirstFrame()); - settingsMap["firstFrame"] = firstFrameValue; - - QVariant lastFrameValue(getAnimationLastFrame()); - settingsMap["lastFrame"] = lastFrameValue; - - QVariant loopValue(getAnimationLoop()); - settingsMap["loop"] = loopValue; - - QVariant holdValue(getAnimationHold()); - settingsMap["hold"] = holdValue; - - QVariant startAutomaticallyValue(getAnimationStartAutomatically()); - settingsMap["startAutomatically"] = startAutomaticallyValue; - - settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap); - QJsonDocument newDocument(settingsAsJsonObject); - QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact); - QString jsonByteString(jsonByteArray); - return jsonByteString; -} - // virtual bool ModelEntityItem::shouldBePhysical() const { return EntityItem::shouldBePhysical() && getShapeType() != SHAPE_TYPE_NONE; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index c00766dfbe..c8b2d072bb 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -65,10 +65,6 @@ public: static const QString DEFAULT_COMPOUND_SHAPE_URL; const QString& getCompoundShapeURL() const { return _compoundShapeURL; } - bool hasAnimation() const { return !_animationURL.isEmpty(); } - static const QString DEFAULT_ANIMATION_URL; - const QString& getAnimationURL() const { return _animationURL; } - void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); } void setColor(const xColor& value) { _color[RED_INDEX] = value.red; @@ -84,10 +80,13 @@ public: // Animation related items... const AnimationPropertyGroup& getAnimationProperties() const { return _animationProperties; } + bool hasAnimation() const { return !_animationProperties.getURL().isEmpty(); } + static const QString DEFAULT_ANIMATION_URL; + const QString& getAnimationURL() const { return _animationProperties.getURL(); } void setAnimationURL(const QString& url); + static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value); - void setAnimationSettings(const QString& value); static const bool DEFAULT_ANIMATION_IS_PLAYING; void setAnimationIsPlaying(bool value); @@ -117,7 +116,6 @@ public: bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } - QString getAnimationSettings() const; static const QString DEFAULT_TEXTURES; const QString& getTextures() const { return _textures; } @@ -126,7 +124,10 @@ public: virtual bool shouldBePhysical() const; static void cleanupLoadedAnimations(); - + +private: + void setAnimationSettings(const QString& value); // only called for old bitstream format + protected: QVector _lastKnownFrameData; int _lastKnownFrameIndex; @@ -142,11 +143,6 @@ protected: AnimationPropertyGroup _animationProperties; AnimationLoop _animationLoop; - // FIXME - delete these - QString _animationURL; - QString _animationSettings; - - QString _textures; ShapeType _shapeType = SHAPE_TYPE_NONE; From 815c4c69afd3975ef5789f7e508b049438bd6bcb Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 1 Oct 2015 14:52:28 -0700 Subject: [PATCH 007/152] support for legacy properties --- .../entities/src/AnimationPropertyGroup.cpp | 24 +++++++--- .../entities/src/AnimationPropertyGroup.h | 2 +- .../entities/src/EntityItemProperties.cpp | 46 ------------------- libraries/entities/src/ModelEntityItem.cpp | 19 +------- 4 files changed, 21 insertions(+), 70 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index da7d309316..a75404e316 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -17,8 +17,8 @@ #include "EntityItemProperties.h" #include "EntityItemPropertiesMacros.h" - AnimationPropertyGroup::AnimationPropertyGroup() : +CONSTRUCT_PROPERTY(url, QString{}), CONSTRUCT_PROPERTY(fps, 30.0f), CONSTRUCT_PROPERTY(running, false), CONSTRUCT_PROPERTY(loop, true), @@ -27,9 +27,6 @@ CONSTRUCT_PROPERTY(lastFrame, AnimationLoop::MAXIMUM_POSSIBLE_FRAME), CONSTRUCT_PROPERTY(hold, false), CONSTRUCT_PROPERTY(startAutomatically, false) { - static const QString DEFAULT_URL; - - _url = DEFAULT_URL; } void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { @@ -40,7 +37,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire if (_animationLoop) { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps, _animationLoop->getFPS); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running, _animationLoop->getRunning); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, AnimationSettings, animationSettings, Running, running, _animationLoop->getRunning); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop, _animationLoop->getLoop); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame, _animationLoop->getFirstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame, _animationLoop->getLastFrame); @@ -49,7 +46,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire } else { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, AnimationSettings, animationSettings, Running, running); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame); @@ -59,8 +56,12 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire } void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, url, QString, setURL); + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); + //qDebug() << "AnimationPropertyGroup::copyFromScriptValue() url:" << getURL(); if (_animationLoop) { @@ -72,6 +73,12 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, _animationLoop->setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, _animationLoop->setHold); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, _animationLoop->setStartAutomatically); + + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, _animationLoop->setRunning, _animationLoop->getRunning); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setFrameIndex, _animationLoop->getFrameIndex); + } else { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, setFPS); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, setFrameIndex); @@ -81,6 +88,11 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, setLastFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, setHold); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, setStartAutomatically); + + // legacy property support + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setFrameIndex, getFrameIndex); } } diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 2c04303482..4502a7c36b 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -13,7 +13,7 @@ // FIXME - TODO // 1) make EntityItemProperties support old versions of animation properties // DONE - 2) rename the group animationSettings -// 3) make sure that setting properties and reading from stream actually set the animationLoop object properly +// DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly // 4) test it! // 5) update all scripts // 6) remove all remnants of old member variables diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 5c4c89a465..d0cedbfe37 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -65,10 +65,6 @@ CONSTRUCT_PROPERTY(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), CONSTRUCT_PROPERTY(alphaFinish, ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH), CONSTRUCT_PROPERTY(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), -//CONSTRUCT_PROPERTY(animationURL, ""), -//CONSTRUCT_PROPERTY(animationFPS, ModelEntityItem::DEFAULT_ANIMATION_FPS), -//CONSTRUCT_PROPERTY(animationFrameIndex, ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), -//CONSTRUCT_PROPERTY(animationIsPlaying, ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), CONSTRUCT_PROPERTY(registrationPoint, ENTITY_ITEM_DEFAULT_REGISTRATION_POINT), CONSTRUCT_PROPERTY(angularVelocity, ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY), CONSTRUCT_PROPERTY(angularDamping, ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING), @@ -80,8 +76,6 @@ CONSTRUCT_PROPERTY(exponent, 0.0f), CONSTRUCT_PROPERTY(cutoff, ENTITY_ITEM_DEFAULT_CUTOFF), CONSTRUCT_PROPERTY(locked, ENTITY_ITEM_DEFAULT_LOCKED), CONSTRUCT_PROPERTY(textures, ""), -//CONSTRUCT_PROPERTY(animationSettings, "{\"firstFrame\":0,\"fps\":30,\"frameIndex\":0,\"hold\":false," -// "\"lastFrame\":100000,\"loop\":false,\"running\":false,\"startAutomatically\":false}"), CONSTRUCT_PROPERTY(userData, ENTITY_ITEM_DEFAULT_USER_DATA), CONSTRUCT_PROPERTY(simulationOwner, SimulationOwner()), CONSTRUCT_PROPERTY(text, TextEntityItem::DEFAULT_TEXT), @@ -169,10 +163,6 @@ void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const } /* -bool EntityItemProperties::animationSettingsChanged() const { - return _animationSettingsChanged; -} - void EntityItemProperties::setAnimationSettings(const QString& value) { // the animations setting is a JSON string that may contain various animation settings. @@ -200,32 +190,6 @@ void EntityItemProperties::setAnimationSettings(const QString& value) { _animationSettings = value; _animationSettingsChanged = true; } - -QString EntityItemProperties::getAnimationSettings() const { - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and - // will over ride the regular animation settings - QString value = _animationSettings; - - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - - QVariant fpsValue(getAnimationFPS()); - settingsMap["fps"] = fpsValue; - - QVariant frameIndexValue(getAnimationFrameIndex()); - settingsMap["frameIndex"] = frameIndexValue; - - QVariant runningValue(getAnimationIsPlaying()); - settingsMap["running"] = runningValue; - - settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap); - QJsonDocument newDocument(settingsAsJsonObject); - QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact); - QString jsonByteString(jsonByteArray); - return jsonByteString; -} */ void EntityItemProperties::setCreated(QDateTime &v) { @@ -359,11 +323,6 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); - //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, animationURL); - //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying); - //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); - //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS); - //CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SETTINGS, animationSettings); CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible); CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint); CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity); @@ -824,10 +783,6 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString); ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); - ADD_PROPERTY_TO_MAP(PROP_ANIMATION_URL, AnimationURL, animationURL, QString); - ADD_PROPERTY_TO_MAP(PROP_ANIMATION_FPS, AnimationFPS, animationFPS, float); - ADD_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, AnimationFrameIndex, animationFrameIndex, float); - ADD_PROPERTY_TO_MAP(PROP_ANIMATION_PLAYING, AnimationIsPlaying, animationIsPlaying, bool); ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float); @@ -839,7 +794,6 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_CUTOFF, Cutoff, cutoff, float); ADD_PROPERTY_TO_MAP(PROP_LOCKED, Locked, locked, bool); ADD_PROPERTY_TO_MAP(PROP_TEXTURES, Textures, textures, QString); - ADD_PROPERTY_TO_MAP(PROP_ANIMATION_SETTINGS, AnimationSettings, animationSettings, QString); ADD_PROPERTY_TO_MAP(PROP_USER_DATA, UserData, userData, QString); ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner); ADD_PROPERTY_TO_MAP(PROP_TEXT, Text, text, QString); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 5e4e1e534b..9c0024ff79 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -113,35 +113,20 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, // we want to read these values in the order they appear in the buffer, but call our setters in an // order that allows AnimationLoop to preserve the correct frame rate. if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - float animationFPS = getAnimationFPS(); - float animationFrameIndex = getAnimationFrameIndex(); - bool animationIsPlaying = getAnimationIsPlaying(); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - - if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { - if (animationIsPlaying != getAnimationIsPlaying()) { - setAnimationIsPlaying(animationIsPlaying); - } - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) { - setAnimationFPS(animationFPS); - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { - setAnimationFrameIndex(animationFrameIndex); - } } READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); } else { // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() // will automatically read into the animation loop int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData); bytesRead += bytesFromAnimation; dataAt += bytesFromAnimation; From b8ea83099afa841ce0140ba898167545fe496c1d Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 21:13:22 -0700 Subject: [PATCH 008/152] Debuggging --- libraries/fbx/src/FBXReader_Mesh.cpp | 1 + libraries/render-utils/src/Model.cpp | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index f3bf3f433d..21b51245cb 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -480,6 +480,7 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } model::Mesh::Part triPart(indexNum, part.triangleIndices.size(), 0, model::Mesh::TRIANGLES); if (triPart._numIndices) { + parts.push_back(triPart); ib->setSubData(offset, part.triangleIndices.size() * sizeof(int), (gpu::Byte*) part.triangleIndices.constData()); offset += part.triangleIndices.size() * sizeof(int); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 3a4d83f68d..c7649d27ed 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1527,7 +1527,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape } // Assign index buffer: - batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + // batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { @@ -1561,6 +1561,10 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape batch.setModelTransform(_transforms[0]); if (mesh.blendshapes.isEmpty()) { + // Assign index buffer: + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + batch.setInputFormat((drawMesh->getVertexFormat())); auto inputStream = drawMesh->makeBufferStream(); @@ -1569,16 +1573,18 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape // batch.setInputFormat(networkMesh._vertexFormat); // batch.setInputStream(0, *networkMesh._vertexStream); } else { - /* batch.setInputFormat((drawMesh->getVertexFormat())); + return; + batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + batch.setInputFormat((drawMesh->getVertexFormat())); auto inputStream = drawMesh->makeBufferStream(); batch.setInputStream(0, inputStream); - */ - batch.setInputFormat(networkMesh._vertexFormat); + + /* batch.setInputFormat(networkMesh._vertexFormat); batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); - batch.setInputStream(2, *networkMesh._vertexStream); + batch.setInputStream(2, *networkMesh._vertexStream);*/ } if (mesh.colors.isEmpty()) { From cf2693e7121afd8b23d20bed35783f38dea38cf6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 08:31:22 -0700 Subject: [PATCH 009/152] working fistFrame lastFrame --- libraries/animation/src/AnimationLoop.cpp | 2 - libraries/animation/src/AnimationLoop.h | 8 +- .../entities/src/AnimationPropertyGroup.cpp | 220 ++++++++++++------ .../entities/src/AnimationPropertyGroup.h | 12 +- .../entities/src/EntityItemProperties.cpp | 52 +---- libraries/entities/src/EntityItemProperties.h | 4 +- .../entities/src/EntityItemPropertiesMacros.h | 12 + libraries/entities/src/ModelEntityItem.cpp | 1 - 8 files changed, 192 insertions(+), 119 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index f6c414c1d7..7f559dd257 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -70,7 +70,6 @@ void AnimationLoop::simulate(float deltaTime) { // wrap within the the desired range if (_frameIndex < startFrameIndex) { _frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex); - } else if (_frameIndex > endFrameIndex) { _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); } @@ -84,7 +83,6 @@ void AnimationLoop::setStartAutomatically(bool startAutomatically) { } void AnimationLoop::setRunning(bool running) { - qDebug() << "AnimationLoop::setRunning() new running:" << running << "old _running:" << _running; // don't do anything if the new value is the same as the value we already have if (_running != running) { _running = running; diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 3c6079d967..c906ba530f 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -35,10 +35,14 @@ public: void setStartAutomatically(bool startAutomatically); bool getStartAutomatically() const { return _startAutomatically; } - void setFirstFrame(float firstFrame) { _firstFrame = glm::clamp(firstFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); } + void setFirstFrame(float firstFrame) { _firstFrame = glm::clamp(firstFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); + //qDebug() << "AnimationLoop::setFirstFrame() firstFrame:" << firstFrame << "_firstFrame:" << _firstFrame; + } float getFirstFrame() const { return _firstFrame; } - void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); } + void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); + //qDebug() << "AnimationLoop::setLastFrame() lastFrame:" << lastFrame<< "_lastFrame:" << _lastFrame; + } float getLastFrame() const { return _lastFrame; } /// by default the AnimationLoop will always reset to the first frame on any call to setRunning diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index a75404e316..47733c205d 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include @@ -30,49 +31,50 @@ CONSTRUCT_PROPERTY(startAutomatically, false) } void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, AnimationSettings, animationSettings, URL, url); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); //qDebug() << "AnimationPropertyGroup::copyToScriptValue() url:" << getURL(); if (_animationLoop) { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, AnimationSettings, animationSettings, Running, running, _animationLoop->getRunning); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop, _animationLoop->getLoop); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame, _animationLoop->getFirstFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame, _animationLoop->getLastFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold, _animationLoop->getHold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, Animation, animation, Running, running, _animationLoop->getRunning); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop, _animationLoop->getLoop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame, _animationLoop->getLastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold, _animationLoop->getHold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); } else { - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, AnimationSettings, animationSettings, FPS, fps); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, AnimationSettings, animationSettings, FrameIndex, frameIndex); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, AnimationSettings, animationSettings, Running, running); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, AnimationSettings, animationSettings, Loop, loop); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, AnimationSettings, animationSettings, FirstFrame, firstFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, AnimationSettings, animationSettings, LastFrame, lastFrame); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, AnimationSettings, animationSettings, Hold, hold); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, AnimationSettings, animationSettings, StartAutomatically, startAutomatically); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, Animation, animation, Running, running); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically); } } void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, url, QString, setURL); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, url, QString, setURL); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); + COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(animationSettings, QString, setFromOldAnimationSettings); //qDebug() << "AnimationPropertyGroup::copyFromScriptValue() url:" << getURL(); if (_animationLoop) { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, _animationLoop->setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, _animationLoop->setFrameIndex); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, running, bool, _animationLoop->setRunning); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, loop, bool, _animationLoop->setLoop); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, firstFrame, float, _animationLoop->setFirstFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, _animationLoop->setLastFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, _animationLoop->setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, _animationLoop->setStartAutomatically); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, _animationLoop->setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, _animationLoop->setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, _animationLoop->setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, _animationLoop->setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, _animationLoop->setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, _animationLoop->setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, _animationLoop->setStartAutomatically); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); @@ -80,14 +82,14 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setFrameIndex, _animationLoop->getFrameIndex); } else { - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, fps, float, setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, frameIndex, float, setFrameIndex); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, running, bool, setRunning); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, loop, bool, setLoop); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, firstFrame, float, setFirstFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, lastFrame, float, setLastFrame); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, hold, bool, setHold); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animationSettings, startAutomatically, bool, setStartAutomatically); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, startAutomatically, bool, setStartAutomatically); // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); @@ -96,6 +98,88 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo } } +void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { + + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() value:" << value; + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, frameIndex, or running, those values will be parsed out and + // will over ride the regular animation settings + + float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); + float frameIndex = _animationLoop ? _animationLoop->getFrameIndex() : getFrameIndex(); + bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); + float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); + float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); + bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); + bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); + bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + + if (settingsMap.contains("fps")) { + fps = settingsMap["fps"].toFloat(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had fps:" << fps; + } + + if (settingsMap.contains("frameIndex")) { + frameIndex = settingsMap["frameIndex"].toFloat(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had frameIndex"; + } + + if (settingsMap.contains("running")) { + running = settingsMap["running"].toBool(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had running"; + } + + if (settingsMap.contains("firstFrame")) { + frameIndex = settingsMap["firstFrame"].toFloat(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had firstFrame"; + } + + if (settingsMap.contains("lastFrame")) { + frameIndex = settingsMap["lastFrame"].toFloat(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had lastFrame"; + } + + if (settingsMap.contains("loop")) { + running = settingsMap["loop"].toBool(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had loop"; + } + + if (settingsMap.contains("hold")) { + running = settingsMap["hold"].toBool(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had hold"; + } + + if (settingsMap.contains("startAutomatically")) { + running = settingsMap["startAutomatically"].toBool(); + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had startAutomatically"; + } + + if (_animationLoop) { + _animationLoop->setFPS(fps); + _animationLoop->setFrameIndex(frameIndex); + _animationLoop->setRunning(running); + _animationLoop->setFirstFrame(firstFrame); + _animationLoop->setLastFrame(lastFrame); + _animationLoop->setLoop(loop); + _animationLoop->setHold(hold); + _animationLoop->setStartAutomatically(startAutomatically); + } else { + setFPS(fps); + setFrameIndex(frameIndex); + setRunning(running); + setFirstFrame(firstFrame); + setLastFrame(lastFrame); + setLoop(loop); + setHold(hold); + setStartAutomatically(startAutomatically); + } +} + + void AnimationPropertyGroup::debugDump() const { qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); @@ -206,58 +290,58 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { } void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, URL, getURL); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); //qDebug() << "AnimationPropertyGroup::getProperties() url:" << getURL(); if (_animationLoop) { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FPS, _animationLoop->getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FrameIndex, _animationLoop->getFrameIndex); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Running, _animationLoop->getRunning); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Loop, _animationLoop->getLoop); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FirstFrame, _animationLoop->getFirstFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, LastFrame, _animationLoop->getLastFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Hold, _animationLoop->getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, StartAutomatically, _animationLoop->getStartAutomatically); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, _animationLoop->getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, _animationLoop->getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, _animationLoop->getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, _animationLoop->getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, _animationLoop->getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, _animationLoop->getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically); } else { - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FPS, getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FrameIndex, getFrameIndex); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Running, getRunning); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Loop, getLoop); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, FirstFrame, getFirstFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, LastFrame, getLastFrame); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, Hold, getHold); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(AnimationSettings, StartAutomatically, getStartAutomatically); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, getStartAutomatically); } } bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) { bool somethingChanged = false; - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, URL, url, setURL); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); //qDebug() << "AnimationPropertyGroup::setProperties() url:" << getURL(); if (_animationLoop) { //qDebug() << "AnimationPropertyGroup::setProperties() -- apply new properties to our associated AnimationLoop"; - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FPS, fps, _animationLoop->setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FrameIndex, frameIndex, _animationLoop->setFrameIndex); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Running, running, _animationLoop->setRunning); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Loop, loop, _animationLoop->setLoop); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FirstFrame, firstFrame, _animationLoop->setFirstFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, LastFrame, lastFrame, _animationLoop->setLastFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Hold, hold, _animationLoop->setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, _animationLoop->setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, _animationLoop->setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, _animationLoop->setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, _animationLoop->setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, _animationLoop->setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, _animationLoop->setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); } else { - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FPS, fps, setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FrameIndex, frameIndex, setFrameIndex); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Running, running, setRunning); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Loop, loop, setLoop); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, FirstFrame, firstFrame, setFirstFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, LastFrame, lastFrame, setLastFrame); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, Hold, hold, setHold); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(AnimationSettings, StartAutomatically, startAutomatically, setStartAutomatically); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } return somethingChanged; diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 4502a7c36b..75ba146266 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -11,12 +11,15 @@ // FIXME - TODO -// 1) make EntityItemProperties support old versions of animation properties +// DONE - 1) make EntityItemProperties support old versions of animation properties // DONE - 2) rename the group animationSettings // DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly // 4) test it! +// a) toybox/windmill +// b) toybox "put me down" doll +// c) asana bugs about animations // 5) update all scripts -// 6) remove all remnants of old member variables +// DONE - 6) remove all remnants of old member variables // 7) research and remove animation settings from Particle Effect #ifndef hifi_AnimationPropertyGroup_h @@ -95,7 +98,10 @@ public: qDebug() << "associateWithAnimationLoop() this:" << this << "animationLoop:" << animationLoop; _animationLoop = animationLoop; } -private: + +protected: + void setFromOldAnimationSettings(const QString& value); + AnimationLoop* _animationLoop = nullptr; }; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d0cedbfe37..a1b191bc0c 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -30,7 +30,7 @@ #include "LineEntityItem.h" #include "PolyLineEntityItem.h" -AnimationPropertyGroup EntityItemProperties::_staticAnimationSettings; +AnimationPropertyGroup EntityItemProperties::_staticAnimation; AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere; SkyboxPropertyGroup EntityItemProperties::_staticSkybox; StagePropertyGroup EntityItemProperties::_staticStage; @@ -162,36 +162,6 @@ void EntityItemProperties::calculateNaturalPosition(const glm::vec3& min, const _naturalPosition = max - halfDimension; } -/* -void EntityItemProperties::setAnimationSettings(const QString& value) { - - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and - // will over ride the regular animation settings - - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - if (settingsMap.contains("fps")) { - float fps = settingsMap["fps"].toFloat(); - setAnimationFPS(fps); - } - - if (settingsMap.contains("frameIndex")) { - float frameIndex = settingsMap["frameIndex"].toFloat(); - setAnimationFrameIndex(frameIndex); - } - - if (settingsMap.contains("running")) { - bool running = settingsMap["running"].toBool(); - setAnimationIsPlaying(running); - } - - _animationSettings = value; - _animationSettingsChanged = true; -} -*/ - void EntityItemProperties::setCreated(QDateTime &v) { _created = v.toMSecsSinceEpoch() * 1000; // usec per msec } @@ -389,7 +359,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID); CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID); - changedProperties += _animationSettings.getChangedProperties(); + changedProperties += _animation.getChangedProperties(); changedProperties += _atmosphere.getChangedProperties(); changedProperties += _skybox.getChangedProperties(); changedProperties += _stage.getChangedProperties(); @@ -496,7 +466,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models & Particles if (_type == EntityTypes::Model || _type == EntityTypes::ParticleEffect) { - _animationSettings.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); + _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); } @@ -699,7 +669,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool //COPY_PROPERTY_FROM_QSCRIPTVALUE(simulationOwner, ???, setSimulatorPriority); } - _animationSettings.copyFromScriptValue(object, _defaultSettings); + _animation.copyFromScriptValue(object, _defaultSettings); _atmosphere.copyFromScriptValue(object, _defaultSettings); _skybox.copyFromScriptValue(object, _defaultSettings); _stage.copyFromScriptValue(object, _defaultSettings); @@ -1050,8 +1020,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType())); - _staticAnimationSettings.setProperties(properties); - _staticAnimationSettings.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + _staticAnimation.setProperties(properties); + _staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); } if (properties.getType() == EntityTypes::Light) { @@ -1063,8 +1033,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::ParticleEffect) { - _staticAnimationSettings.setProperties(properties); - _staticAnimationSettings.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + _staticAnimation.setProperties(properties); + _staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); @@ -1337,7 +1307,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType); - properties.getAnimationSettings().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); } if (properties.getType() == EntityTypes::Light) { @@ -1349,7 +1319,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::ParticleEffect) { - properties.getAnimationSettings().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); + properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); @@ -1537,7 +1507,7 @@ void EntityItemProperties::markAllChanged() { _backgroundModeChanged = true; - _animationSettings.markAllChanged(); + _animation.markAllChanged(); _atmosphere.markAllChanged(); _skybox.markAllChanged(); _stage.markAllChanged(); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 82095b6b71..c8bf0836d5 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -165,7 +165,7 @@ public: DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup); DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup); DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup); - DEFINE_PROPERTY_GROUP(AnimationSettings, animationSettings, AnimationPropertyGroup); + DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup); DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString); DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float); DEFINE_PROPERTY_REF(LINE_POINTS, LinePoints, linePoints, QVector); @@ -373,7 +373,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, YPNeighborID, yPNeighborID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ZPNeighborID, zPNeighborID, ""); - properties.getAnimationSettings().debugDump(); + properties.getAnimation().debugDump(); properties.getAtmosphere().debugDump(); properties.getSkybox().debugDump(); properties.getStage().debugDump(); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 6b2a21ddf5..8e0b968fcb 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -289,6 +289,18 @@ inline xColor xColor_convertFromScriptValue(const QScriptValue& v, bool& isValid }\ } +#define COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(P, T, S) \ +{ \ + QScriptValue V = object.property(#P); \ + if (V.isValid()) { \ + bool isValid = false; \ + T newValue = T##_convertFromScriptValue(V, isValid); \ + if (isValid && (_defaultSettings)) { \ + S(newValue); \ + } \ + }\ +} + #define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(G, P, T, S) \ { \ QScriptValue G = object.property(#G); \ diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 9c0024ff79..55911b213b 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -269,7 +269,6 @@ void ModelEntityItem::update(const quint64& now) { if (getAnimationIsPlaying()) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; _lastAnimated = now; - qDebug() << "ModelEntityItem::update() calling _animationLoop.simulate(deltaTime);"; _animationLoop.simulate(deltaTime); } else { _lastAnimated = now; From 51887a76e1c28b54519a608744ceac417ecb0260 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 2 Oct 2015 11:02:19 -0700 Subject: [PATCH 010/152] refactoring lights to fix problem with piling up --- examples/toys/lightSwitch.js | 1 + examples/toys/masterReset.js | 150 +++++++++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 examples/toys/lightSwitch.js diff --git a/examples/toys/lightSwitch.js b/examples/toys/lightSwitch.js new file mode 100644 index 0000000000..932e773797 --- /dev/null +++ b/examples/toys/lightSwitch.js @@ -0,0 +1 @@ +print("HEY THERE") \ No newline at end of file diff --git a/examples/toys/masterReset.js b/examples/toys/masterReset.js index 72e2d73729..a4fb40bc1a 100644 --- a/examples/toys/masterReset.js +++ b/examples/toys/masterReset.js @@ -8,7 +8,7 @@ /*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ //per script -/*global deleteAllToys, createAllToys, createGates, createPingPongBallGun, createFire, createPottedPlant, createCombinedArmChair, createBasketballHoop, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ +/*global deleteAllToys, createAllToys, createGates, createPingPongBallGun, createFire, createPottedPlant, createCombinedArmChair, createBasketballHoop, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLights */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); @@ -89,7 +89,7 @@ function createAllToys() { createFire(); // //Handles toggling of all sconce lights - createLightSwitches(); + createLights(); @@ -98,7 +98,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function(entity) { + entities.forEach(function (entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -252,9 +252,9 @@ function createFlashlight(position) { } -function createLightSwitches() { +function createLights() { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; - var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); + var scriptURL = Script.resolvePath("lightSwitch.js"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -278,12 +278,63 @@ function createLightSwitches() { z: 0.16242524981498718 } }); - setEntityCustomData(resetKey, lightSwitchHall, { resetMe: true }); - scriptURL = Script.resolvePath("lightSwitchGarage.js?v1"); + var sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.75, + y: 496.24, + z: 511.13 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(resetKey, sconceLight1, { + resetMe: true, + lightType: "Sconce Light", + on: true + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 540.1, + y: 496.24, + z: 505.57 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(resetKey, sconceLight2, { + resetMe: true, + lightType: "Sconce Light", + state: true + }); var lightSwitchGarage = Entities.addEntity({ type: "Model", @@ -312,6 +363,91 @@ function createLightSwitches() { resetMe: true }); + + var sconceLight3 = Entities.addEntity({ + type: "Light", + position: { + x: 545.49468994140625, + y: 496.24026489257812, + z: 500.63516235351562 + }, + + name: "Sconce 3 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + + + setEntityCustomData(resetKey, sconceLight3, { + resetMe: true, + lightType: "Sconce Light", + on: true + }); + + var sconceLight4 = Entities.addEntity({ + type: "Light", + position: { + x: 550.90399169921875, + y: 496.24026489257812, + z: 507.90237426757812 + }, + name: "Sconce 4 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(resetKey, sconceLight4, { + resetMe: true, + lightType: "Sconce Light", + on: true + }); + + var sconceLight5 = Entities.addEntity({ + type: "Light", + position: { + x: 548.407958984375, + y: 496.24026489257812, + z: 509.5504150390625 + }, + name: "Sconce 5 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(resetKey, sconceLight5, { + resetMe: true, + lightType: "Sconce Light", + on: true + }); + } function createDice() { From 2533bfd2ad9a949ec6cb64756f8659df5b87f708 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Fri, 2 Oct 2015 11:30:56 -0700 Subject: [PATCH 011/152] initial --- examples/toys/createKnockoverBlocks.js | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/toys/createKnockoverBlocks.js diff --git a/examples/toys/createKnockoverBlocks.js b/examples/toys/createKnockoverBlocks.js new file mode 100644 index 0000000000..b5fe22ca73 --- /dev/null +++ b/examples/toys/createKnockoverBlocks.js @@ -0,0 +1,47 @@ +// +// createKnockoverBlocks.js +// +// Created by James B. Pollack on 9/29/2015 +// Copyright 2015 High Fidelity, Inc. +// +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ + +var blockDimensions={ + x:0.12, + y:0.25, + z:0.50 +}; + +var centerPosition = { + x: + y: + z: +}; + + +var sideBlock1_position = { + x: + y: + z: +}; + + + +var sideBlock2_position = { + x: + y: + z: +}; + + +var sideBlock1_rotation = Quat.fromPitchYawRollDegrees(); +var sideBlock2_rotation = Quat.fromPitchYawRollDegrees(); +var topBlock_rotation = Quat.fromPitchYawRollDegrees(); + +var sideBlock1 = Entities.addEntity(); +var sideBlock2 = Entities.addEntity(); +var topBlock = Entities.addEntity(); +var ground = Entities.addEntity(); \ No newline at end of file From 4b62048fb143b6e6a188fc64fd083b0f88d897ae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 2 Oct 2015 12:12:36 -0700 Subject: [PATCH 012/152] more light changes --- examples/toys/lightSwitch.js | 53 +++++- unpublishedScripts/masterReset.js | 297 +++++++++++++++--------------- 2 files changed, 201 insertions(+), 149 deletions(-) diff --git a/examples/toys/lightSwitch.js b/examples/toys/lightSwitch.js index 932e773797..18c6d26185 100644 --- a/examples/toys/lightSwitch.js +++ b/examples/toys/lightSwitch.js @@ -1 +1,52 @@ -print("HEY THERE") \ No newline at end of file +// +// lightSwitch.js.js +// examples/entityScripts +// +// Created by Eric Levin on 10/2/15. +// Copyright 2015 High Fidelity, Inc. +// +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ +//per script + +/*global LightSwitch */ + +(function () { + + var LightSwitch = function () { + this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); + print("SHNUUUUR") + + }; + + LightSwitch.prototype = { + + clickReleaseOnEntity: function (entityID, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.toggleLights(); + }, + + toggleLights: function () { + print("TOGGLE LIGHTS"); + }, + + startNearGrabNonColliding: function () { + this.toggleLights(); + }, + + preload: function (entityID) { + this.entityID = entityID; + //The light switch is static, so just cache its position once + this.position = Entities.getEntityProperties(this.entityID, "position").position; + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new LightSwitch(); +}()); \ No newline at end of file diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index fe29d8a8de..40cce2582c 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -106,155 +106,10 @@ function deleteAllToys() { }); } -function createFire() { - - - var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); - - var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 - }); - - - var fire = Entities.addEntity({ - type: "ParticleEffect", - name: "fire", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.45, - y: 494.82, - z: 502.05 - }, - emitRate: 100, - colorStart: { - red: 70, - green: 70, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - radiusSpread: 0.01, - radiusStart: 0.02, - radiusEnd: 0.001, - particleRadius: 0.05, - radiusFinish: 0.0, - emitOrientation: myOrientation, - emitSpeed: 0.3, - speedSpread: 0.1, - alphaStart: 0.05, - alpha: 0.1, - alphaFinish: 0.05, - emitDimensions: { - x: 1, - y: 1, - z: 0.1 - }, - polarFinish: 0.1, - emitAcceleration: { - x: 0.0, - y: 0.0, - z: 0.0 - }, - accelerationSpread: { - x: 0.1, - y: 0.01, - z: 0.1 - }, - lifespan: 1 - }); - - - setEntityCustomData(resetKey, fire, { - resetMe: true - }); -} - - -function createCat(position) { - var scriptURL = Script.resolvePath("../examples/toys/cat.js"); - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; - var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ - running: true, - }); - var cat = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "cat", - script: scriptURL, - animationURL: animationURL, - animationSettings: animationSettings, - position: position, - rotation: { - w: 0.35020983219146729, - x: -4.57763671875e-05, - y: 0.93664455413818359, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.15723302960395813, - y: 0.50762706995010376, - z: 0.90716040134429932 - }, - }); - - setEntityCustomData(resetKey, cat, { - resetMe: true - }); -} - -function createFlashlight(position) { - var scriptURL = Script.resolvePath('../examples/toys/flashlight/flashlight.js'); - var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; - - var flashlight = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - name: "flashlight", - script: scriptURL, - position: position, - dimensions: { - x: 0.08, - y: 0.30, - z: 0.08 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - shapeType: 'box', - }); - - setEntityCustomData(resetKey, flashlight, { - resetMe: true - }); - -} - function createLights() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; - var scriptURL = Script.resolvePath("../examples/toys/lightSwitchHall.js"); + var scriptURL = Script.resolvePath("../examples/toys/lightSwitch.js"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -450,6 +305,152 @@ function createLights() { } + +function createFire() { + + + var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); + + var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 + }); + + + var fire = Entities.addEntity({ + type: "ParticleEffect", + name: "fire", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.45, + y: 494.82, + z: 502.05 + }, + emitRate: 100, + colorStart: { + red: 70, + green: 70, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + radiusSpread: 0.01, + radiusStart: 0.02, + radiusEnd: 0.001, + particleRadius: 0.05, + radiusFinish: 0.0, + emitOrientation: myOrientation, + emitSpeed: 0.3, + speedSpread: 0.1, + alphaStart: 0.05, + alpha: 0.1, + alphaFinish: 0.05, + emitDimensions: { + x: 1, + y: 1, + z: 0.1 + }, + polarFinish: 0.1, + emitAcceleration: { + x: 0.0, + y: 0.0, + z: 0.0 + }, + accelerationSpread: { + x: 0.1, + y: 0.01, + z: 0.1 + }, + lifespan: 1 + }); + + + setEntityCustomData(resetKey, fire, { + resetMe: true + }); +} + + +function createCat(position) { + var scriptURL = Script.resolvePath("../examples/toys/cat.js"); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; + var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; + var animationSettings = JSON.stringify({ + running: true, + }); + var cat = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "cat", + script: scriptURL, + animationURL: animationURL, + animationSettings: animationSettings, + position: position, + rotation: { + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, + }); + + setEntityCustomData(resetKey, cat, { + resetMe: true + }); +} + +function createFlashlight(position) { + var scriptURL = Script.resolvePath('../examples/toys/flashlight/flashlight.js'); + var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; + + var flashlight = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "flashlight", + script: scriptURL, + position: position, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, + shapeType: 'box', + }); + + setEntityCustomData(resetKey, flashlight, { + resetMe: true + }); + +} + function createDice() { var diceProps = { type: "Model", @@ -967,4 +968,4 @@ function cleanup() { if (shouldDeleteOnEndScript) { Script.scriptEnding.connect(cleanup); -} +} \ No newline at end of file From edb485cb0f2ccac6c5f6533bc398611639b48a50 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 2 Oct 2015 12:24:41 -0700 Subject: [PATCH 013/152] working on getting the Model payload to use model::Mesh --- libraries/fbx/src/FBXReader_Mesh.cpp | 25 +++++++++++++++---------- libraries/gpu/src/gpu/Stream.cpp | 13 +++++++++++++ libraries/gpu/src/gpu/Stream.h | 4 +++- libraries/render-utils/src/Model.cpp | 15 +++++++++------ 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 21b51245cb..299968d663 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -415,29 +415,34 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { if (normalsSize) { mesh->addAttribute(gpu::Stream::NORMAL, - model::BufferView(attribBuffer, normalsOffset, normalsSize, - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); + model::BufferView(attribBuffer, normalsOffset, normalsSize, + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (tangentsSize) { mesh->addAttribute(gpu::Stream::TANGENT, - model::BufferView(attribBuffer, tangentsOffset, tangentsSize, - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); + model::BufferView(attribBuffer, tangentsOffset, tangentsSize, + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (colorsSize) { mesh->addAttribute(gpu::Stream::COLOR, - model::BufferView(attribBuffer, colorsOffset, colorsSize, - gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB))); + model::BufferView(attribBuffer, colorsOffset, colorsSize, + gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB))); } if (texCoordsSize) { mesh->addAttribute(gpu::Stream::TEXCOORD, - model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, - gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); + model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, + gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } if (texCoords1Size) { + mesh->addAttribute( gpu::Stream::TEXCOORD1, + model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, + gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); + } else if (texCoordsSize) { mesh->addAttribute(gpu::Stream::TEXCOORD1, - model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, - gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); + model::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, + gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } + if (clusterIndicesSize) { mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 61150ab90e..183f2137fb 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -92,3 +92,16 @@ void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset _offsets.push_back(offset); _strides.push_back(stride); } + +BufferStream BufferStream::makeRangedStream(uint32 offset, uint32 count) const { + if ((offset < _buffers.size())) { + auto rangeSize = std::min(count, (uint32)(_buffers.size() - offset)); + BufferStream newStream; + newStream._buffers.insert(newStream._buffers.begin(), _buffers.begin() + offset, _buffers.begin() + offset + rangeSize); + newStream._offsets.insert(newStream._offsets.begin(), _offsets.begin() + offset, _offsets.begin() + offset + rangeSize); + newStream._strides.insert(newStream._strides.begin(), _strides.begin() + offset, _strides.begin() + offset + rangeSize); + return newStream; + } + + return BufferStream(); +} diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 420aa50f72..53509c1033 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -139,7 +139,9 @@ public: const Buffers& getBuffers() const { return _buffers; } const Offsets& getOffsets() const { return _offsets; } const Strides& getStrides() const { return _strides; } - uint8 getNumBuffers() const { return _buffers.size(); } + uint32 getNumBuffers() const { return _buffers.size(); } + + BufferStream makeRangedStream(uint32 offset, uint32 count = -1) const; protected: Buffers _buffers; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index c7649d27ed..872592a9a4 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1573,14 +1573,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape // batch.setInputFormat(networkMesh._vertexFormat); // batch.setInputStream(0, *networkMesh._vertexStream); } else { - return; - batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); - batch.setInputFormat((drawMesh->getVertexFormat())); - auto inputStream = drawMesh->makeBufferStream(); + batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + batch.setInputFormat((drawMesh->getVertexFormat())); - batch.setInputStream(0, inputStream); + batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); + batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); + + auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2); - /* batch.setInputFormat(networkMesh._vertexFormat); + batch.setInputStream(2, inputStream); + + /* batch.setInputFormat(networkMesh._vertexFormat); batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); From b27396606b512c2878be69db61074b902d87d385 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 12:34:46 -0700 Subject: [PATCH 014/152] fix first run --- libraries/animation/src/AnimationLoop.cpp | 31 ++++++++++++++--------- libraries/animation/src/AnimationLoop.h | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 7f559dd257..6062d71f9c 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -15,15 +15,17 @@ const float AnimationLoop::MAXIMUM_POSSIBLE_FRAME = 100000.0f; AnimationLoop::AnimationLoop() : -_fps(30.0f), -_loop(false), -_hold(false), -_startAutomatically(false), -_firstFrame(0.0f), -_lastFrame(MAXIMUM_POSSIBLE_FRAME), -_running(false), -_frameIndex(0.0f), -_maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME) + _fps(30.0f), + _loop(false), + _hold(false), + _startAutomatically(false), + _firstFrame(0.0f), + _lastFrame(MAXIMUM_POSSIBLE_FRAME), + _running(false), + _frameIndex(0.0f), + _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME), + _resetOnRunning(false), + _firstRun(true) { } @@ -35,7 +37,9 @@ AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : _firstFrame(animationDetails.firstFrame), _lastFrame(animationDetails.lastFrame), _running(animationDetails.running), - _frameIndex(animationDetails.frameIndex) + _frameIndex(animationDetails.frameIndex), + _resetOnRunning(false), + _firstRun(true) { } @@ -48,7 +52,9 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati _firstFrame(firstFrame), _lastFrame(lastFrame), _running(running), - _frameIndex(frameIndex) + _frameIndex(frameIndex), + _resetOnRunning(false), + _firstRun(true) { } @@ -88,9 +94,10 @@ void AnimationLoop::setRunning(bool running) { _running = running; // If we just set running to true, then also reset the frame to the first frame - if (running && _resetOnRunning) { + if (running && (_resetOnRunning || _firstRun)) { // move back to the beginning _frameIndex = _firstFrame; + _firstRun = false; } } } diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index c906ba530f..ae5a88fdbd 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -74,6 +74,7 @@ private: float _frameIndex = 0.0f; float _maxFrameIndexHint = MAXIMUM_POSSIBLE_FRAME; bool _resetOnRunning = false; + bool _firstRun = true; }; #endif // hifi_AnimationLoop_h From 98e8b3083df063d26e373db9d0a40aa04bf8cac0 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 13:04:02 -0700 Subject: [PATCH 015/152] comment --- libraries/entities/src/AnimationPropertyGroup.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 75ba146266..0dbf6d1615 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -15,12 +15,13 @@ // DONE - 2) rename the group animationSettings // DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly // 4) test it! -// a) toybox/windmill +// a) toybox/windmill // b) toybox "put me down" doll // c) asana bugs about animations // 5) update all scripts // DONE - 6) remove all remnants of old member variables // 7) research and remove animation settings from Particle Effect +// 8) make sure animations start properly when entering a domain... with previously running animations #ifndef hifi_AnimationPropertyGroup_h #define hifi_AnimationPropertyGroup_h From a34e1d85a500e5a65bbb5f93d50570fb9bfb9c2e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 17 Sep 2015 16:10:01 +0200 Subject: [PATCH 016/152] Close current packet fix --- libraries/networking/src/udt/PacketList.cpp | 2 +- tools/udt-test/src/UDTTest.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index 53edfb32f1..64ae8f54db 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -105,7 +105,7 @@ std::unique_ptr PacketList::createPacketWithExtendedHeader() { } void PacketList::closeCurrentPacket(bool shouldSendEmpty) { - if (shouldSendEmpty && !_currentPacket) { + if (shouldSendEmpty && !_currentPacket && _packets.empty()) { _currentPacket = createPacketWithExtendedHeader(); } diff --git a/tools/udt-test/src/UDTTest.cpp b/tools/udt-test/src/UDTTest.cpp index d57ff7a874..32ab1780e0 100644 --- a/tools/udt-test/src/UDTTest.cpp +++ b/tools/udt-test/src/UDTTest.cpp @@ -282,7 +282,7 @@ void UDTTest::sendPacket() { packetList->write(randomPaddedData); } - packetList->closeCurrentPacket(false); + packetList->closeCurrentPacket(); _totalQueuedBytes += packetList->getDataSize(); _totalQueuedPackets += packetList->getNumPackets(); From 3a61e6b6a3a0ad206fc61a3d181b8da7edeb8fdf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 17 Sep 2015 16:27:31 +0200 Subject: [PATCH 017/152] Coding standart for locks --- libraries/networking/src/udt/SendQueue.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index ac6c8238e8..d814dfdcdc 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -230,13 +230,12 @@ void SendQueue::overrideNAKListFromPacket(ControlPacket& packet) { } void SendQueue::handshakeACK() { - std::unique_lock locker { _handshakeMutex }; - - _hasReceivedHandshakeACK = true; - - // unlock the mutex and notify on the handshake ACK condition - locker.unlock(); + { + std::unique_lock locker { _handshakeMutex }; + _hasReceivedHandshakeACK = true; + } + // Notify on the handshake ACK condition _handshakeACKCondition.notify_one(); } From a4d383b38499e479ad14a7c105e5fe990da922c7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 17 Sep 2015 16:29:34 +0200 Subject: [PATCH 018/152] Check handshake separately --- libraries/networking/src/udt/SendQueue.cpp | 65 ++++++++++------------ libraries/networking/src/udt/SendQueue.h | 2 + 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index d814dfdcdc..45caec3aa9 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -229,6 +229,22 @@ void SendQueue::overrideNAKListFromPacket(ControlPacket& packet) { _emptyCondition.notify_one(); } +void SendQueue::sendHandshake() { + std::unique_lock handshakeLock { _handshakeMutex }; + if (!_hasReceivedHandshakeACK) { + // we haven't received a handshake ACK from the client, send another now + static const auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, 0); + _socket->writeBasePacket(*handshakePacket, _destination); + + // we wait for the ACK or the re-send interval to expire + static const auto HANDSHAKE_RESEND_INTERVAL = std::chrono::milliseconds(100); + _handshakeACKCondition.wait_for(handshakeLock, HANDSHAKE_RESEND_INTERVAL); + + // Once we're here we've either received the handshake ACK or it's going to be time to re-send a handshake. + // Either way let's continue processing - no packets will be sent if no handshake ACK has been received. + } +} + void SendQueue::handshakeACK() { { std::unique_lock locker { _handshakeMutex }; @@ -286,44 +302,21 @@ void SendQueue::run() { _state = State::Running; + // Wait for handshake to be complete + while (_state == State::Running && !_hasReceivedHandshakeACK) { + sendHandshake(); + QCoreApplication::processEvents(); + } + while (_state == State::Running) { // Record how long the loop takes to execute - auto loopStartTimestamp = p_high_resolution_clock::now(); - - std::unique_lock handshakeLock { _handshakeMutex }; - - if (!_hasReceivedHandshakeACK) { - // we haven't received a handshake ACK from the client - // if it has been at least 100ms since we last sent a handshake, send another now - - static const auto HANDSHAKE_RESEND_INTERVAL_MS = std::chrono::milliseconds(100); - - // hold the time of last send in a static - static auto lastSendHandshake = p_high_resolution_clock::now() - HANDSHAKE_RESEND_INTERVAL_MS; - - if (p_high_resolution_clock::now() - lastSendHandshake >= HANDSHAKE_RESEND_INTERVAL_MS) { - - // it has been long enough since last handshake, send another - static auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, 0); - _socket->writeBasePacket(*handshakePacket, _destination); - - lastSendHandshake = p_high_resolution_clock::now(); - } - - // we wait for the ACK or the re-send interval to expire - _handshakeACKCondition.wait_until(handshakeLock, p_high_resolution_clock::now() + HANDSHAKE_RESEND_INTERVAL_MS); - - // Once we're here we've either received the handshake ACK or it's going to be time to re-send a handshake. - // Either way let's continue processing - no packets will be sent if no handshake ACK has been received. - } - - handshakeLock.unlock(); + const auto loopStartTimestamp = p_high_resolution_clock::now(); bool sentAPacket = maybeResendPacket(); // if we didn't find a packet to re-send AND we think we can fit a new packet on the wire // (this is according to the current flow window size) then we send out a new packet - if (_hasReceivedHandshakeACK && !sentAPacket) { + if (!sentAPacket) { if (seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) <= _flowWindowSize) { sentAPacket = maybeSendNewPacket(); } @@ -337,7 +330,7 @@ void SendQueue::run() { return; } - if (_hasReceivedHandshakeACK && !sentAPacket) { + if (!sentAPacket) { // check if it is time to break this connection // that will be the case if we have had 16 timeouts since hearing back from the client, and it has been @@ -430,13 +423,11 @@ void SendQueue::run() { } } - auto loopEndTimestamp = p_high_resolution_clock::now(); + const auto loopEndTimestamp = p_high_resolution_clock::now(); // sleep as long as we need until next packet send, if we can - auto timeToSleep = (loopStartTimestamp + std::chrono::microseconds(_packetSendPeriod)) - loopEndTimestamp; - if (timeToSleep > timeToSleep.zero()) { - std::this_thread::sleep_for(timeToSleep); - } + const auto timeToSleep = (loopStartTimestamp + std::chrono::microseconds(_packetSendPeriod)) - loopEndTimestamp; + std::this_thread::sleep_for(timeToSleep); } } diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index 88b6b045b0..80e0195455 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -87,6 +87,8 @@ private: SendQueue(SendQueue& other) = delete; SendQueue(SendQueue&& other) = delete; + void sendHandshake(); + void sendPacket(const Packet& packet); void sendNewPacketAndAddToSentList(std::unique_ptr newPacket, SequenceNumber sequenceNumber); From eb8b37309d82d1cbbd5c51a9cf529d557778f981 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 17 Sep 2015 17:22:24 +0200 Subject: [PATCH 019/152] Use lock_guard when possible --- libraries/networking/src/udt/SendQueue.cpp | 39 ++++++++++------------ 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 45caec3aa9..1e7206c1ee 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -191,12 +191,10 @@ void SendQueue::nak(SequenceNumber start, SequenceNumber end) { _timeoutExpiryCount = 0; _lastReceiverResponse = uint64_t(QDateTime::currentMSecsSinceEpoch()); - std::unique_lock nakLocker(_naksLock); - - _naks.insert(start, end); - - // unlock the locked mutex before we notify - nakLocker.unlock(); + { + std::lock_guard nakLocker(_naksLock); + _naks.insert(start, end); + } // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for losses to re-send _emptyCondition.notify_one(); @@ -207,24 +205,23 @@ void SendQueue::overrideNAKListFromPacket(ControlPacket& packet) { _timeoutExpiryCount = 0; _lastReceiverResponse = uint64_t(QDateTime::currentMSecsSinceEpoch()); - std::unique_lock nakLocker(_naksLock); - _naks.clear(); - - SequenceNumber first, second; - while (packet.bytesLeftToRead() >= (qint64)(2 * sizeof(SequenceNumber))) { - packet.readPrimitive(&first); - packet.readPrimitive(&second); + { + std::lock_guard nakLocker(_naksLock); + _naks.clear(); - if (first == second) { - _naks.append(first); - } else { - _naks.append(first, second); + SequenceNumber first, second; + while (packet.bytesLeftToRead() >= (qint64)(2 * sizeof(SequenceNumber))) { + packet.readPrimitive(&first); + packet.readPrimitive(&second); + + if (first == second) { + _naks.append(first); + } else { + _naks.append(first, second); + } } } - // unlock the mutex before we notify - nakLocker.unlock(); - // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for losses to re-send _emptyCondition.notify_one(); } @@ -247,7 +244,7 @@ void SendQueue::sendHandshake() { void SendQueue::handshakeACK() { { - std::unique_lock locker { _handshakeMutex }; + std::lock_guard locker { _handshakeMutex }; _hasReceivedHandshakeACK = true; } From b0fe8535fdee0129503262c3187b68ddbe1dbf8e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 21 Sep 2015 17:17:29 +0200 Subject: [PATCH 020/152] Release _sendQueue before cleanup --- libraries/networking/src/udt/Connection.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index e8b22f6ab8..d7b851fcf4 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -52,15 +52,14 @@ Connection::~Connection() { } void Connection::stopSendQueue() { - if (_sendQueue) { + if (auto sendQueue = _sendQueue.release()) { // grab the send queue thread so we can wait on it - QThread* sendQueueThread = _sendQueue->thread(); + QThread* sendQueueThread = sendQueue->thread(); // tell the send queue to stop and be deleted - _sendQueue->stop(); - _sendQueue->deleteLater(); - _sendQueue.release(); + sendQueue->stop(); + sendQueue->deleteLater(); // since we're stopping the send queue we should consider our handshake ACK not receieved _hasReceivedHandshakeACK = false; From 290a0e573d34e888b6fd3e942b051f45fdcffe8f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 21 Sep 2015 18:49:15 +0200 Subject: [PATCH 021/152] House cleaning --- libraries/networking/src/udt/Connection.cpp | 9 +++++---- libraries/networking/src/udt/LossList.h | 1 + libraries/networking/src/udt/SendQueue.cpp | 15 +++++++-------- libraries/networking/src/udt/SendQueue.h | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index d7b851fcf4..e8b22f6ab8 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -52,14 +52,15 @@ Connection::~Connection() { } void Connection::stopSendQueue() { - if (auto sendQueue = _sendQueue.release()) { + if (_sendQueue) { // grab the send queue thread so we can wait on it - QThread* sendQueueThread = sendQueue->thread(); + QThread* sendQueueThread = _sendQueue->thread(); // tell the send queue to stop and be deleted - sendQueue->stop(); - sendQueue->deleteLater(); + _sendQueue->stop(); + _sendQueue->deleteLater(); + _sendQueue.release(); // since we're stopping the send queue we should consider our handshake ACK not receieved _hasReceivedHandshakeACK = false; diff --git a/libraries/networking/src/udt/LossList.h b/libraries/networking/src/udt/LossList.h index f0f2b92988..3921364872 100644 --- a/libraries/networking/src/udt/LossList.h +++ b/libraries/networking/src/udt/LossList.h @@ -37,6 +37,7 @@ public: void remove(SequenceNumber start, SequenceNumber end); int getLength() const { return _length; } + bool isEmpty() const { return _length == 0; } SequenceNumber getFirstSequenceNumber() const; SequenceNumber popFirstSequenceNumber(); diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 1e7206c1ee..de056b6850 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -50,10 +50,10 @@ private: }; std::unique_ptr SendQueue::create(Socket* socket, HifiSockAddr destination) { - auto queue = std::unique_ptr(new SendQueue(socket, destination)); - Q_ASSERT_X(socket, "SendQueue::create", "Must be called with a valid Socket*"); + auto queue = std::unique_ptr(new SendQueue(socket, destination)); + // Setup queue private thread QThread* thread = new QThread; thread->setObjectName("Networking: SendQueue " + destination.objectName()); // Name thread for easier debug @@ -66,8 +66,6 @@ std::unique_ptr SendQueue::create(Socket* socket, HifiSockAddr destin // Move queue to private thread and start it queue->moveToThread(thread); - thread->start(); - return std::move(queue); } @@ -75,7 +73,6 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : _socket(socket), _destination(dest) { - } void SendQueue::queuePacket(std::unique_ptr packet) { @@ -178,7 +175,7 @@ void SendQueue::ack(SequenceNumber ack) { { // remove any sequence numbers equal to or lower than this ACK in the loss list std::lock_guard nakLocker(_naksLock); - if (_naks.getLength() > 0 && _naks.getFirstSequenceNumber() <= ack) { + if (!_naks.isEmpty() && _naks.getFirstSequenceNumber() <= ack) { _naks.remove(_naks.getFirstSequenceNumber(), ack); } } @@ -302,7 +299,9 @@ void SendQueue::run() { // Wait for handshake to be complete while (_state == State::Running && !_hasReceivedHandshakeACK) { sendHandshake(); - QCoreApplication::processEvents(); + + // Keep processing events + QCoreApplication::sendPostedEvents(this); } while (_state == State::Running) { @@ -486,7 +485,7 @@ bool SendQueue::maybeResendPacket() { std::unique_lock naksLocker(_naksLock); - if (_naks.getLength() > 0) { + if (!_naks.isEmpty()) { // pull the sequence number we need to re-send SequenceNumber resendNumber = _naks.popFirstSequenceNumber(); naksLocker.unlock(); diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index 80e0195455..39d18a544d 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -111,7 +111,7 @@ private: MessageNumber _currentMessageNumber { 0 }; SequenceNumber _currentSequenceNumber; // Last sequence number sent out - std::atomic _atomicCurrentSequenceNumber { 0 };// Atomic for last sequence number sent out + std::atomic _atomicCurrentSequenceNumber { 0 }; // Atomic for last sequence number sent out std::atomic _packetSendPeriod { 0 }; // Interval between two packet send event in microseconds, set from CC std::atomic _state { State::NotStarted }; From 709dab6beb6e5fe24efe4741f47d5ae85eefd1c7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 22 Sep 2015 15:11:17 +0200 Subject: [PATCH 022/152] Release send queue before cleanup --- libraries/networking/src/udt/Connection.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index e8b22f6ab8..d7b851fcf4 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -52,15 +52,14 @@ Connection::~Connection() { } void Connection::stopSendQueue() { - if (_sendQueue) { + if (auto sendQueue = _sendQueue.release()) { // grab the send queue thread so we can wait on it - QThread* sendQueueThread = _sendQueue->thread(); + QThread* sendQueueThread = sendQueue->thread(); // tell the send queue to stop and be deleted - _sendQueue->stop(); - _sendQueue->deleteLater(); - _sendQueue.release(); + sendQueue->stop(); + sendQueue->deleteLater(); // since we're stopping the send queue we should consider our handshake ACK not receieved _hasReceivedHandshakeACK = false; From 732ad410804414ef5514bf9218a21c3c6cdee4d5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 22 Sep 2015 15:12:36 +0200 Subject: [PATCH 023/152] Introduce PacketQueue --- libraries/networking/src/udt/PacketList.h | 1 + libraries/networking/src/udt/PacketQueue.cpp | 71 ++++ libraries/networking/src/udt/PacketQueue.h | 53 +++ libraries/networking/src/udt/SendQueue.cpp | 341 ++++++++----------- libraries/networking/src/udt/SendQueue.h | 9 +- 5 files changed, 266 insertions(+), 209 deletions(-) create mode 100644 libraries/networking/src/udt/PacketQueue.cpp create mode 100644 libraries/networking/src/udt/PacketQueue.h diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index 7978e77ad7..c873e53711 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -70,6 +70,7 @@ protected: private: friend class ::LimitedNodeList; + friend class PacketQueue; friend class SendQueue; friend class Socket; diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp new file mode 100644 index 0000000000..f5c1b4a9a0 --- /dev/null +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -0,0 +1,71 @@ +// +// PacketQueue.cpp +// libraries/networking/src/udt +// +// Created by Clement on 9/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "PacketQueue.h" + +#include "Packet.h" +#include "PacketList.h" + +using namespace udt; + + +MessageNumber PacketQueue::getNextMessageNumber() { + static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; + _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; + return _currentMessageNumber; +} + +bool PacketQueue::isEmpty() const { + LockGuard locker(_packetsLock); + return _packets.empty(); +} + +PacketQueue::PacketPointer PacketQueue::takeFront() { + LockGuard locker(_packetsLock); + if (!_packets.empty()) { + auto packet = std::move(_packets.front()); + _packets.pop_front(); + return std::move(packet); + } + + return PacketPointer(); +} + +void PacketQueue::queuePacket(PacketPointer packet) { + LockGuard locker(_packetsLock); + _packets.push_back(std::move(packet)); +} + +void PacketQueue::queuePacketList(PacketListPointer packetList) { + Q_ASSERT(packetList->_packets.size() > 0); + + auto messageNumber = getNextMessageNumber(); + auto markPacket = [&messageNumber](const PacketPointer& packet, Packet::PacketPosition position) { + packet->setPacketPosition(position); + packet->writeMessageNumber(messageNumber); + }; + + if (packetList->_packets.size() == 1) { + markPacket(packetList->_packets.front(), Packet::PacketPosition::ONLY); + } else { + const auto second = ++packetList->_packets.begin(); + const auto last = --packetList->_packets.end(); + std::for_each(second, last, [&](const PacketPointer& packet) { + markPacket(packet, Packet::PacketPosition::MIDDLE); + }); + + markPacket(packetList->_packets.front(), Packet::PacketPosition::FIRST); + markPacket(packetList->_packets.back(), Packet::PacketPosition::LAST); + } + + LockGuard locker(_packetsLock); + _packets.splice(_packets.end(), packetList->_packets); +} \ No newline at end of file diff --git a/libraries/networking/src/udt/PacketQueue.h b/libraries/networking/src/udt/PacketQueue.h new file mode 100644 index 0000000000..b305e9b560 --- /dev/null +++ b/libraries/networking/src/udt/PacketQueue.h @@ -0,0 +1,53 @@ +// +// PacketQueue.h +// libraries/networking/src/udt +// +// Created by Clement on 9/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_PacketQueue_h +#define hifi_PacketQueue_h + +#include +#include +#include + +namespace udt { + +class Packet; +class PacketList; + +using MessageNumber = uint32_t; + +class PacketQueue { + using Mutex = std::recursive_mutex; + using LockGuard = std::lock_guard; + using PacketPointer = std::unique_ptr; + using PacketListPointer = std::unique_ptr; + using PacketList = std::list; + +public: + void queuePacket(PacketPointer packet); + void queuePacketList(PacketListPointer packetList); + + bool isEmpty() const; + PacketPointer takeFront(); + + MessageNumber getNextMessageNumber(); + Mutex& getLock() { return _packetsLock; } + +private: + MessageNumber _currentMessageNumber { 0 }; + + mutable Mutex _packetsLock; // Protects the packets to be sent list. + PacketList _packets; // List of packets to be sent +}; + +} + + +#endif // hifi_PacketQueue_h \ No newline at end of file diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index de056b6850..44fa51bca8 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -30,7 +30,7 @@ using namespace udt; class DoubleLock { public: - DoubleLock(std::mutex& mutex1, std::mutex& mutex2) : _mutex1(mutex1), _mutex2(mutex2) { } + DoubleLock(std::recursive_mutex& mutex1, std::mutex& mutex2) : _mutex1(mutex1), _mutex2(mutex2) { } DoubleLock(const DoubleLock&) = delete; DoubleLock& operator=(const DoubleLock&) = delete; @@ -45,7 +45,7 @@ public: void unlock() { _mutex1.unlock(); _mutex2.unlock(); } private: - std::mutex& _mutex1; + std::recursive_mutex& _mutex1; std::mutex& _mutex2; }; @@ -76,17 +76,10 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : } void SendQueue::queuePacket(std::unique_ptr packet) { - { - std::unique_lock locker(_packetsLock); - - _packets.push_back(std::move(packet)); - - // unlock the mutex before we notify - locker.unlock(); - - // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets - _emptyCondition.notify_one(); - } + _packets.queuePacket(std::move(packet)); + + // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets + _emptyCondition.notify_one(); if (!this->thread()->isRunning() && _state == State::NotStarted) { this->thread()->start(); @@ -94,46 +87,10 @@ void SendQueue::queuePacket(std::unique_ptr packet) { } void SendQueue::queuePacketList(std::unique_ptr packetList) { - Q_ASSERT(packetList->_packets.size() > 0); - - { - auto messageNumber = getNextMessageNumber(); - - if (packetList->_packets.size() == 1) { - auto& packet = packetList->_packets.front(); - - packet->setPacketPosition(Packet::PacketPosition::ONLY); - packet->writeMessageNumber(messageNumber); - } else { - bool haveMarkedFirstPacket = false; - auto end = packetList->_packets.end(); - auto lastElement = --packetList->_packets.end(); - for (auto it = packetList->_packets.begin(); it != end; ++it) { - auto& packet = *it; - - if (!haveMarkedFirstPacket) { - packet->setPacketPosition(Packet::PacketPosition::FIRST); - haveMarkedFirstPacket = true; - } else if (it == lastElement) { - packet->setPacketPosition(Packet::PacketPosition::LAST); - } else { - packet->setPacketPosition(Packet::PacketPosition::MIDDLE); - } - - packet->writeMessageNumber(messageNumber); - } - } - - std::unique_lock locker(_packetsLock); - - _packets.splice(_packets.end(), packetList->_packets); - - // unlock the mutex so we can notify - locker.unlock(); - - // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets - _emptyCondition.notify_one(); - } + _packets.queuePacketList(std::move(packetList)); + + // call notify_one on the condition_variable_any in case the send thread is sleeping waiting for packets + _emptyCondition.notify_one(); if (!this->thread()->isRunning() && _state == State::NotStarted) { this->thread()->start(); @@ -144,10 +101,8 @@ void SendQueue::stop() { _state = State::Stopped; - // in case we're waiting to send another handshake, release the condition_variable now so we cleanup sooner + // Notify all conditions in case we're waiting somewhere _handshakeACKCondition.notify_one(); - - // in case the empty condition is waiting for packets/loss release it now so that the queue is cleaned up _emptyCondition.notify_one(); } @@ -254,12 +209,6 @@ SequenceNumber SendQueue::getNextSequenceNumber() { return _currentSequenceNumber; } -uint32_t SendQueue::getNextMessageNumber() { - static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; - _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; - return _currentMessageNumber; -} - void SendQueue::sendNewPacketAndAddToSentList(std::unique_ptr newPacket, SequenceNumber sequenceNumber) { // write the sequence number and send the packet newPacket->writeSequenceNumber(sequenceNumber); @@ -313,167 +262,67 @@ void SendQueue::run() { // if we didn't find a packet to re-send AND we think we can fit a new packet on the wire // (this is according to the current flow window size) then we send out a new packet if (!sentAPacket) { - if (seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) <= _flowWindowSize) { - sentAPacket = maybeSendNewPacket(); - } + sentAPacket = maybeSendNewPacket(); } // since we're a while loop, give the thread a chance to process events - QCoreApplication::sendPostedEvents(this, 0); + QCoreApplication::sendPostedEvents(this); // we just processed events so check now if we were just told to stop - if (_state != State::Running) { - return; + // If the send queue has been innactive, skip the sleep for + // Either _isRunning will have been set to false and we'll break + // Or something happened and we'll keep going + if (_state != State::Running || isInactive(sentAPacket)) { + continue; } - if (!sentAPacket) { - // check if it is time to break this connection - - // that will be the case if we have had 16 timeouts since hearing back from the client, and it has been - // at least 5 seconds - - static const int NUM_TIMEOUTS_BEFORE_INACTIVE = 16; - static const int MIN_SECONDS_BEFORE_INACTIVE_MS = 5 * 1000; - - auto sinceEpochNow = QDateTime::currentMSecsSinceEpoch(); - - if (_timeoutExpiryCount >= NUM_TIMEOUTS_BEFORE_INACTIVE - && (sinceEpochNow - _lastReceiverResponse) > MIN_SECONDS_BEFORE_INACTIVE_MS) { - // If the flow window has been full for over CONSIDER_INACTIVE_AFTER, - // then signal the queue is inactive and return so it can be cleaned up - -#ifdef UDT_CONNECTION_DEBUG - qCDebug(networking) << "SendQueue to" << _destination << "reached" << NUM_TIMEOUTS_BEFORE_INACTIVE << "timeouts" - << "and 10s before receiving any ACK/NAK and is now inactive. Stopping."; -#endif - - deactivate(); - - return; - } else { - // During our processing above we didn't send any packets - - // If that is still the case we should use a condition_variable_any to sleep until we have data to handle. - // To confirm that the queue of packets and the NAKs list are still both empty we'll need to use the DoubleLock - DoubleLock doubleLock(_packetsLock, _naksLock); - - if (doubleLock.try_lock()) { - // The packets queue and loss list mutexes are now both locked - check if they're still both empty - - if (_packets.empty() && _naks.getLength() == 0) { - if (uint32_t(_lastACKSequenceNumber) == uint32_t(_currentSequenceNumber)) { - // we've sent the client as much data as we have (and they've ACKed it) - // either wait for new data to send or 5 seconds before cleaning up the queue - static const auto EMPTY_QUEUES_INACTIVE_TIMEOUT = std::chrono::seconds(5); - - // use our condition_variable_any to wait - auto cvStatus = _emptyCondition.wait_for(doubleLock, EMPTY_QUEUES_INACTIVE_TIMEOUT); - - // we have the double lock again - Make sure to unlock it - doubleLock.unlock(); - - if (cvStatus == std::cv_status::timeout) { -#ifdef UDT_CONNECTION_DEBUG - qCDebug(networking) << "SendQueue to" << _destination << "has been empty for" - << EMPTY_QUEUES_INACTIVE_TIMEOUT.count() - << "seconds and receiver has ACKed all packets." - << "The queue is now inactive and will be stopped."; -#endif - - deactivate(); - - return; - } - } else { - // We think the client is still waiting for data (based on the sequence number gap) - // Let's wait either for a response from the client or until the estimated timeout - auto waitDuration = std::chrono::microseconds(_estimatedTimeout); - - // use our condition_variable_any to wait - auto cvStatus = _emptyCondition.wait_for(doubleLock, waitDuration); - - if (cvStatus == std::cv_status::timeout) { - // increase the number of timeouts - ++_timeoutExpiryCount; - - if (SequenceNumber(_lastACKSequenceNumber) < _currentSequenceNumber) { - // after a timeout if we still have sent packets that the client hasn't ACKed we - // add them to the loss list - - // Note that thanks to the DoubleLock we have the _naksLock right now - _naks.append(SequenceNumber(_lastACKSequenceNumber) + 1, _currentSequenceNumber); - } - } - - // we have the double lock again - Make sure to unlock it - doubleLock.unlock(); - - // skip to the next iteration - continue; - } - } else { - // we got the try_lock but failed the other conditionals so we need to unlock - doubleLock.unlock(); - } - } - } - } - - const auto loopEndTimestamp = p_high_resolution_clock::now(); - // sleep as long as we need until next packet send, if we can + const auto loopEndTimestamp = p_high_resolution_clock::now(); const auto timeToSleep = (loopStartTimestamp + std::chrono::microseconds(_packetSendPeriod)) - loopEndTimestamp; std::this_thread::sleep_for(timeToSleep); } } bool SendQueue::maybeSendNewPacket() { - // we didn't re-send a packet, so time to send a new one - std::unique_lock locker(_packetsLock); - - if (_packets.size() > 0) { - SequenceNumber nextNumber = getNextSequenceNumber(); + if (seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) <= _flowWindowSize) { + // we didn't re-send a packet, so time to send a new one - // grab the first packet we will send - std::unique_ptr firstPacket; - firstPacket.swap(_packets.front()); - _packets.pop_front(); - std::unique_ptr secondPacket; - bool shouldSendPairTail = false; - - if (((uint32_t) nextNumber & 0xF) == 0) { - // the first packet is the first in a probe pair - every 16 (rightmost 16 bits = 0) packets - // pull off a second packet if we can before we unlock - shouldSendPairTail = true; + if (!_packets.isEmpty()) { + SequenceNumber nextNumber = getNextSequenceNumber(); - if (_packets.size() > 0) { - secondPacket.swap(_packets.front()); - _packets.pop_front(); + // grab the first packet we will send + std::unique_ptr firstPacket = _packets.takeFront(); + + std::unique_ptr secondPacket; + bool shouldSendPairTail = false; + + if (((uint32_t) nextNumber & 0xF) == 0) { + // the first packet is the first in a probe pair - every 16 (rightmost 16 bits = 0) packets + // pull off a second packet if we can before we unlock + shouldSendPairTail = true; + + secondPacket = _packets.takeFront(); } + + // definitely send the first packet + sendNewPacketAndAddToSentList(move(firstPacket), nextNumber); + + // do we have a second in a pair to send as well? + if (secondPacket) { + sendNewPacketAndAddToSentList(move(secondPacket), getNextSequenceNumber()); + } else if (shouldSendPairTail) { + // we didn't get a second packet to send in the probe pair + // send a control packet of type ProbePairTail so the receiver can still do + // proper bandwidth estimation + static auto pairTailPacket = ControlPacket::create(ControlPacket::ProbeTail); + _socket->writeBasePacket(*pairTailPacket, _destination); + } + + // We sent our packet(s), return here + return true; } - - // unlock the packets, we're done pulling - locker.unlock(); - - // definitely send the first packet - sendNewPacketAndAddToSentList(move(firstPacket), nextNumber); - - // do we have a second in a pair to send as well? - if (secondPacket) { - sendNewPacketAndAddToSentList(move(secondPacket), getNextSequenceNumber()); - } else if (shouldSendPairTail) { - // we didn't get a second packet to send in the probe pair - // send a control packet of type ProbePairTail so the receiver can still do - // proper bandwidth estimation - static auto pairTailPacket = ControlPacket::create(ControlPacket::ProbeTail); - _socket->writeBasePacket(*pairTailPacket, _destination); - } - - // We sent our packet(s), return here - return true; } - // No packets were sent return false; } @@ -524,6 +373,92 @@ bool SendQueue::maybeResendPacket() { return false; } +bool SendQueue::isInactive(bool sentAPacket) { + if (!sentAPacket) { + // check if it is time to break this connection + + // that will be the case if we have had 16 timeouts since hearing back from the client, and it has been + // at least 5 seconds + static const int NUM_TIMEOUTS_BEFORE_INACTIVE = 16; + static const int MIN_SECONDS_BEFORE_INACTIVE_MS = 5 * 1000; + if (_timeoutExpiryCount >= NUM_TIMEOUTS_BEFORE_INACTIVE && + (QDateTime::currentMSecsSinceEpoch() - _lastReceiverResponse) > MIN_SECONDS_BEFORE_INACTIVE_MS) { + // If the flow window has been full for over CONSIDER_INACTIVE_AFTER, + // then signal the queue is inactive and return so it can be cleaned up + +#ifdef UDT_CONNECTION_DEBUG + qCDebug(networking) << "SendQueue to" << _destination << "reached" << NUM_TIMEOUTS_BEFORE_INACTIVE << "timeouts" + << "and 5s before receiving any ACK/NAK and is now inactive. Stopping."; +#endif + + deactivate(); + + return true; + } + + // During our processing above we didn't send any packets + + // If that is still the case we should use a condition_variable_any to sleep until we have data to handle. + // To confirm that the queue of packets and the NAKs list are still both empty we'll need to use the DoubleLock + DoubleLock doubleLock(_packets.getLock(), _naksLock); + std::unique_lock locker(doubleLock, std::try_to_lock); + + if (locker.owns_lock() && _packets.isEmpty() && _naks.isEmpty()) { + // The packets queue and loss list mutexes are now both locked and they're both empty + + if (uint32_t(_lastACKSequenceNumber) == uint32_t(_currentSequenceNumber)) { + // we've sent the client as much data as we have (and they've ACKed it) + // either wait for new data to send or 5 seconds before cleaning up the queue + static const auto EMPTY_QUEUES_INACTIVE_TIMEOUT = std::chrono::seconds(5); + + // use our condition_variable_any to wait + auto cvStatus = _emptyCondition.wait_for(locker, EMPTY_QUEUES_INACTIVE_TIMEOUT); + + // we have the lock again - Make sure to unlock it + locker.unlock(); + + if (cvStatus == std::cv_status::timeout) { +#ifdef UDT_CONNECTION_DEBUG + qCDebug(networking) << "SendQueue to" << _destination << "has been empty for" + << EMPTY_QUEUES_INACTIVE_TIMEOUT.count() + << "seconds and receiver has ACKed all packets." + << "The queue is now inactive and will be stopped."; +#endif + + // Deactivate queue + deactivate(); + return true; + } + } else { + // We think the client is still waiting for data (based on the sequence number gap) + // Let's wait either for a response from the client or until the estimated timeout + auto waitDuration = std::chrono::microseconds(_estimatedTimeout); + + // use our condition_variable_any to wait + auto cvStatus = _emptyCondition.wait_for(locker, waitDuration); + + if (cvStatus == std::cv_status::timeout) { + // increase the number of timeouts + ++_timeoutExpiryCount; + + if (SequenceNumber(_lastACKSequenceNumber) < _currentSequenceNumber) { + // after a timeout if we still have sent packets that the client hasn't ACKed we + // add them to the loss list + + // Note that thanks to the DoubleLock we have the _naksLock right now + _naks.append(SequenceNumber(_lastACKSequenceNumber) + 1, _currentSequenceNumber); + } + } + + // skip to the next iteration + return true; + } + } + } + + return false; +} + void SendQueue::deactivate() { // this queue is inactive - emit that signal and stop the while emit queueInactive(); diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index 39d18a544d..96de12a971 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -28,6 +28,7 @@ #include "../HifiSockAddr.h" #include "Constants.h" +#include "PacketQueue.h" #include "SequenceNumber.h" #include "LossList.h" @@ -38,8 +39,6 @@ class ControlPacket; class Packet; class PacketList; class Socket; - -using MessageNumber = uint32_t; class SendQueue : public QObject { Q_OBJECT @@ -95,21 +94,19 @@ private: bool maybeSendNewPacket(); // Figures out what packet to send next bool maybeResendPacket(); // Determines whether to resend a packet and which one + bool isInactive(bool sentAPacket); void deactivate(); // makes the queue inactive and cleans it up // Increments current sequence number and return it SequenceNumber getNextSequenceNumber(); - MessageNumber getNextMessageNumber(); - mutable std::mutex _packetsLock; // Protects the packets to be sent list. - std::list> _packets; // List of packets to be sent + PacketQueue _packets; Socket* _socket { nullptr }; // Socket to send packet on HifiSockAddr _destination; // Destination addr std::atomic _lastACKSequenceNumber { 0 }; // Last ACKed sequence number - MessageNumber _currentMessageNumber { 0 }; SequenceNumber _currentSequenceNumber; // Last sequence number sent out std::atomic _atomicCurrentSequenceNumber { 0 }; // Atomic for last sequence number sent out From 91c779ddd8055b4c5d7762a9c0e82ed31af383c7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 22 Sep 2015 15:37:57 +0200 Subject: [PATCH 024/152] Templatized DoubleLock --- libraries/networking/src/udt/PacketQueue.cpp | 2 +- libraries/networking/src/udt/PacketQueue.h | 4 ++-- libraries/networking/src/udt/SendQueue.cpp | 12 ++++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index f5c1b4a9a0..13002745bd 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -17,7 +17,7 @@ using namespace udt; -MessageNumber PacketQueue::getNextMessageNumber() { +PacketQueue::MessageNumber PacketQueue::getNextMessageNumber() { static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; return _currentMessageNumber; diff --git a/libraries/networking/src/udt/PacketQueue.h b/libraries/networking/src/udt/PacketQueue.h index b305e9b560..4bd0feeb25 100644 --- a/libraries/networking/src/udt/PacketQueue.h +++ b/libraries/networking/src/udt/PacketQueue.h @@ -28,7 +28,7 @@ class PacketQueue { using LockGuard = std::lock_guard; using PacketPointer = std::unique_ptr; using PacketListPointer = std::unique_ptr; - using PacketList = std::list; + using PacketContainer = std::list; public: void queuePacket(PacketPointer packet); @@ -44,7 +44,7 @@ private: MessageNumber _currentMessageNumber { 0 }; mutable Mutex _packetsLock; // Protects the packets to be sent list. - PacketList _packets; // List of packets to be sent + PacketContainer _packets; // List of packets to be sent }; } diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 44fa51bca8..aa37c8f23b 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -28,9 +28,12 @@ using namespace udt; +template class DoubleLock { public: - DoubleLock(std::recursive_mutex& mutex1, std::mutex& mutex2) : _mutex1(mutex1), _mutex2(mutex2) { } + using Lock = std::unique_lock>; + + DoubleLock(Mutex1& mutex1, Mutex2& mutex2) : _mutex1(mutex1), _mutex2(mutex2) { } DoubleLock(const DoubleLock&) = delete; DoubleLock& operator=(const DoubleLock&) = delete; @@ -45,8 +48,8 @@ public: void unlock() { _mutex1.unlock(); _mutex2.unlock(); } private: - std::recursive_mutex& _mutex1; - std::mutex& _mutex2; + Mutex1& _mutex1; + Mutex2& _mutex2; }; std::unique_ptr SendQueue::create(Socket* socket, HifiSockAddr destination) { @@ -400,8 +403,9 @@ bool SendQueue::isInactive(bool sentAPacket) { // If that is still the case we should use a condition_variable_any to sleep until we have data to handle. // To confirm that the queue of packets and the NAKs list are still both empty we'll need to use the DoubleLock + using DoubleLock = DoubleLock; DoubleLock doubleLock(_packets.getLock(), _naksLock); - std::unique_lock locker(doubleLock, std::try_to_lock); + DoubleLock::Lock locker(doubleLock, std::try_to_lock); if (locker.owns_lock() && _packets.isEmpty() && _naks.isEmpty()) { // The packets queue and loss list mutexes are now both locked and they're both empty From f1a9aba70448d8915c90b913e732ea31597ac17c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 22 Sep 2015 18:06:47 +0200 Subject: [PATCH 025/152] Magic number --- libraries/networking/src/udt/Packet.cpp | 7 ++++--- libraries/networking/src/udt/Packet.h | 4 ++-- libraries/networking/src/udt/PacketQueue.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 56c65e0657..0582ef6487 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -124,7 +124,8 @@ static const uint32_t RELIABILITY_BIT_MASK = uint32_t(1) << (SEQUENCE_NUMBER_BIT static const uint32_t MESSAGE_BIT_MASK = uint32_t(1) << (SEQUENCE_NUMBER_BITS - 3); static const uint32_t BIT_FIELD_MASK = CONTROL_BIT_MASK | RELIABILITY_BIT_MASK | MESSAGE_BIT_MASK; -static const uint32_t PACKET_POSITION_MASK = uint32_t(0x03) << 30; +static const uint8_t PACKET_POSITION_OFFSET = 30; +static const uint32_t PACKET_POSITION_MASK = uint32_t(0x03) << PACKET_POSITION_OFFSET; static const uint32_t MESSAGE_NUMBER_MASK = ~PACKET_POSITION_MASK; void Packet::readHeader() const { @@ -139,7 +140,7 @@ void Packet::readHeader() const { if (_isPartOfMessage) { MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1; _messageNumber = *messageNumberAndBitField & MESSAGE_NUMBER_MASK; - _packetPosition = static_cast(*messageNumberAndBitField >> 30); + _packetPosition = static_cast(*messageNumberAndBitField >> PACKET_POSITION_OFFSET); } } @@ -164,6 +165,6 @@ void Packet::writeHeader() const { MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1; *messageNumberAndBitField = _messageNumber; - *messageNumberAndBitField |= _packetPosition << 30; + *messageNumberAndBitField |= _packetPosition << PACKET_POSITION_OFFSET; } } diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h index 565fc24616..6bf7c569aa 100644 --- a/libraries/networking/src/udt/Packet.h +++ b/libraries/networking/src/udt/Packet.h @@ -28,7 +28,7 @@ public: // NOTE: The SequenceNumber is only actually 29 bits to leave room for a bit field using SequenceNumberAndBitField = uint32_t; - // NOTE: The MessageNumber is only actually 29 bits to leave room for a bit field + // NOTE: The MessageNumber is only actually 30 bits to leave room for a bit field using MessageNumber = uint32_t; using MessageNumberAndBitField = uint32_t; @@ -83,7 +83,7 @@ private: // Simple holders to prevent multiple reading and bitwise ops mutable bool _isReliable { false }; mutable bool _isPartOfMessage { false }; - mutable SequenceNumber _sequenceNumber; + mutable SequenceNumber _sequenceNumber { 0 }; mutable PacketPosition _packetPosition { PacketPosition::ONLY }; mutable MessageNumber _messageNumber { 0 }; }; diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index 13002745bd..f5c1b4a9a0 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -17,7 +17,7 @@ using namespace udt; -PacketQueue::MessageNumber PacketQueue::getNextMessageNumber() { +MessageNumber PacketQueue::getNextMessageNumber() { static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; return _currentMessageNumber; From 8cecb95bf265d3c1454c175244d327919e37246d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 22 Sep 2015 18:49:56 +0200 Subject: [PATCH 026/152] Use array for stats --- libraries/networking/src/udt/ConnectionStats.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/udt/ConnectionStats.h b/libraries/networking/src/udt/ConnectionStats.h index e04a836ca8..8163ed5250 100644 --- a/libraries/networking/src/udt/ConnectionStats.h +++ b/libraries/networking/src/udt/ConnectionStats.h @@ -13,7 +13,7 @@ #define hifi_ConnectionStats_h #include -#include +#include namespace udt { @@ -42,7 +42,7 @@ public: }; // construct a vector for the events of the size of our Enum - default value is zero - std::vector events = std::vector((int) Event::NumEvents, 0); + std::array events {{ 0 }}; // packet counts and sizes int sentPackets { 0 }; From 02536a5ab9dd9647559067277d346d0558add013 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 14:17:01 -0700 Subject: [PATCH 027/152] remove animationSettings from particles, add isEmitting --- examples/entityScripts/portal.js | 6 +- .../example/entities/animatedModelExample.js | 31 ++- examples/example/entities/butterflies.js | 13 +- examples/example/entities/particlesTest.js | 17 +- examples/fireworks.js | 11 +- examples/html/entityProperties.html | 20 +- examples/libraries/entityPropertyDialogBox.js | 34 +-- examples/particleDance.js | 11 +- examples/particle_explorer/main.js | 5 +- .../particle_explorer/particleExplorer.js | 13 +- examples/particles.js | 8 +- examples/toys/breakdanceCore.js | 10 +- examples/toys/grenade.js | 13 +- examples/toys/sprayPaintCan.js | 9 +- libraries/animation/src/AnimationLoop.h | 30 ++- .../src/RenderableModelEntityItem.cpp | 1 - .../entities/src/AnimationPropertyGroup.h | 10 +- .../entities/src/EntityItemProperties.cpp | 11 +- libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityPropertyFlags.h | 4 + .../entities/src/ParticleEffectEntityItem.cpp | 211 ++---------------- .../entities/src/ParticleEffectEntityItem.h | 44 +--- unpublishedScripts/masterReset.js | 20 +- 23 files changed, 134 insertions(+), 400 deletions(-) diff --git a/examples/entityScripts/portal.js b/examples/entityScripts/portal.js index 4e2ec6ddaf..879c1f9197 100644 --- a/examples/entityScripts/portal.js +++ b/examples/entityScripts/portal.js @@ -32,8 +32,7 @@ this.leaveEntity = function(entityID) { Entities.editEntity(entityID, { - animationURL: animationURL, - animationSettings: '{ "frameIndex": 1, "running": false }' + animation: { url: animationURL, frameIndex: 1, running: false } }); playSound(); @@ -41,8 +40,7 @@ this.hoverEnterEntity = function(entityID) { Entities.editEntity(entityID, { - animationURL: animationURL, - animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }' + animation: { url: animationURL, fps: 24, firstFrame: 1, lastFrame: 25, frameIndex: 1, running: true, hold: true } }); }; }) \ No newline at end of file diff --git a/examples/example/entities/animatedModelExample.js b/examples/example/entities/animatedModelExample.js index 47bca9cfb0..6c97671463 100644 --- a/examples/example/entities/animatedModelExample.js +++ b/examples/example/entities/animatedModelExample.js @@ -18,7 +18,15 @@ var stopAfter = moveUntil + 100; var pitch = 0.0; var yaw = 0.0; var roll = 0.0; -var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll) +var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll); + +var animationSettings = JSON.stringify({ + loop: true, + running: true, + fps: 30, + firstFrame: 10, + lastFrame: 20, +}); var originalProperties = { type: "Model", @@ -37,12 +45,21 @@ var originalProperties = { modelURL: "http://public.highfidelity.io/cozza13/club/dragon/dragon.fbx", rotation: rotation, - //animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", + + + animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", + animationSettings: animationSettings, //animationIsPlaying: true, - animationSettings: { + /* + animation: { url: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", - running: true + running: true, + fps: 30, + firstFrame: 10, + lastFrame: 20, + loop: true } + */ }; var modelID = Entities.addEntity(originalProperties); @@ -105,7 +122,7 @@ function moveModel(deltaTime) { var newProperties = { //animationIsPlaying: isPlaying, //animationFPS: animationFPS, - animationSettings: { + animation: { running: isPlaying, fps: animationFPS } @@ -114,7 +131,7 @@ function moveModel(deltaTime) { if (resetFrame) { print("resetting the frame!"); //newProperties.animationFrameIndex = 0; - newProperties.animationSettings.frameIndex = 0; + newProperties.animation.frameIndex = 0; resetFrame = false; } @@ -124,7 +141,7 @@ function moveModel(deltaTime) { // register the call back so it fires before each data send -Script.update.connect(moveModel); +//Script.update.connect(moveModel); Script.scriptEnding.connect(function () { diff --git a/examples/example/entities/butterflies.js b/examples/example/entities/butterflies.js index 8b02cf5768..2eac9d6258 100644 --- a/examples/example/entities/butterflies.js +++ b/examples/example/entities/butterflies.js @@ -85,8 +85,17 @@ function addButterfly() { damping: 0.00001, dimensions: dimensions, color: color, - animationURL: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx", - animationSettings: "{\"firstFrame\":0,\"fps\":" + newFrameRate + ",\"frameIndex\":0,\"hold\":false,\"lastFrame\":10000,\"loop\":true,\"running\":true,\"startAutomatically\":false}", + animation: { + url: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx", + firstFrame: 0, + fps: newFrameRate, + frameIndex: 0, + hold: false, + lastFrame: 10000, + loop: true, + running: true, + startAutomatically:false + }, modelURL: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx" }; butterflies.push(Entities.addEntity(properties)); diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index bfa4a47ffb..a2bbdbd9d0 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -43,7 +43,7 @@ speedSpread: 0.0, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, radiusSpread: 0.0, - animationIsPlaying: true + isEmitting: true }); break; case 1: @@ -195,7 +195,7 @@ polarFinish: 0.0, azimuthStart: -PI, azimuthFinish: PI, - animationIsPlaying: false + isEmitting: false }); Entities.editEntity(box, { visible: true @@ -210,15 +210,7 @@ function setUp() { var boxPoint, - spawnPoint, - animation = { - fps: 30, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 30, - loop: true - }; + spawnPoint; boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { x: 0.0, y: -0.5, z: 0.0 }); @@ -265,8 +257,7 @@ lifespan: 5.0, visible: false, locked: false, - animationSettings: animation, - animationIsPlaying: false, + isEmitting: false, lifetime: 3600 // 1 hour; just in case }); diff --git a/examples/fireworks.js b/examples/fireworks.js index 3485b1687f..610db389ba 100644 --- a/examples/fireworks.js +++ b/examples/fireworks.js @@ -117,15 +117,6 @@ Rocket = function(point, colorPalette) { } }); - this.animationSettings = JSON.stringify({ - fps: 40, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 20, - loop: false - }); - this.direction = { x: randFloat(-0.4, 0.4), y: 1.0, @@ -170,7 +161,7 @@ Rocket.prototype.explode = function(position) { print(JSON.stringify(color)); this.bursts.push(Entities.addEntity({ type: "ParticleEffect", - animationSettings: this.animationSettings, + isEmitting: true, position: position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: this.emitRate, diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 268a2fb7f2..40b94c2eb2 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -282,7 +282,6 @@ var elModelAnimationPlaying = document.getElementById("property-model-animation-playing"); var elModelAnimationFPS = document.getElementById("property-model-animation-fps"); var elModelAnimationFrame = document.getElementById("property-model-animation-frame"); - var elModelAnimationSettings = document.getElementById("property-model-animation-settings"); var elModelTextures = document.getElementById("property-model-textures"); var elModelOriginalTextures = document.getElementById("property-model-original-textures"); @@ -506,11 +505,10 @@ elModelURL.value = properties.modelURL; elShapeType.value = properties.shapeType; elCompoundShapeURL.value = properties.compoundShapeURL; - elModelAnimationURL.value = properties.animationURL; - elModelAnimationPlaying.checked = properties.animationIsPlaying; - elModelAnimationFPS.value = properties.animationFPS; - elModelAnimationFrame.value = properties.animationFrameIndex; - elModelAnimationSettings.value = properties.animationSettings; + elModelAnimationURL.value = properties.animation.url; + elModelAnimationPlaying.checked = properties.animation.running; + elModelAnimationFPS.value = properties.animation.fps; + elModelAnimationFrame.value = properties.animation.frameIndex; elModelTextures.value = properties.textures; elModelOriginalTextures.value = properties.originalTextures; } else if (properties.type == "Web") { @@ -756,11 +754,11 @@ elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL')); elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType')); elCompoundShapeURL.addEventListener('change', createEmitTextPropertyUpdateFunction('compoundShapeURL')); - elModelAnimationURL.addEventListener('change', createEmitTextPropertyUpdateFunction('animationURL')); - elModelAnimationPlaying.addEventListener('change', createEmitCheckedPropertyUpdateFunction('animationIsPlaying')); - elModelAnimationFPS.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFPS')); - elModelAnimationFrame.addEventListener('change', createEmitNumberPropertyUpdateFunction('animationFrameIndex')); - elModelAnimationSettings.addEventListener('change', createEmitTextPropertyUpdateFunction('animationSettings')); + + elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url')); + elModelAnimationPlaying.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation','running')); + elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','fps')); + elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','frameIndex')); elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text')); diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index 49231ca7c1..a9e2e05445 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -27,7 +27,6 @@ EntityPropertyDialogBox = (function () { var editModelID = -1; var previousAnimationIsPlaying; var previousAnimationFrameIndex; - var previousAnimationSettings; that.cleanup = function () { }; @@ -56,18 +55,15 @@ EntityPropertyDialogBox = (function () { index++; array.push({ label: "Compound Shape URL:", value: properties.compoundShapeURL }); index++; - array.push({ label: "Animation URL:", value: properties.animationURL }); + array.push({ label: "Animation URL:", value: properties.animation.url }); index++; - array.push({ label: "Animation is playing:", type: "checkbox", value: properties.animationIsPlaying }); - previousAnimationIsPlaying = properties.animationIsPlaying; + array.push({ label: "Animation is playing:", type: "checkbox", value: properties.animation.running }); + previousAnimationIsPlaying = properties.animation.running; index++; - array.push({ label: "Animation FPS:", value: properties.animationFPS }); + array.push({ label: "Animation FPS:", value: properties.animation.fps }); index++; - array.push({ label: "Animation Frame:", value: properties.animationFrameIndex }); - previousAnimationFrameIndex = properties.animationFrameIndex; - index++; - array.push({ label: "Animation Settings:", value: properties.animationSettings }); - previousAnimationSettings = properties.animationSettings; + array.push({ label: "Animation Frame:", value: properties.animation.frameIndex }); + previousAnimationFrameIndex = properties.animation.frameIndex; index++; array.push({ label: "Textures:", value: properties.textures }); index++; @@ -312,30 +308,24 @@ EntityPropertyDialogBox = (function () { properties.modelURL = array[index++].value; properties.shapeType = array[index++].value; properties.compoundShapeURL = array[index++].value; - properties.animationURL = array[index++].value; + properties.animation.url = array[index++].value; var newAnimationIsPlaying = array[index++].value; if (previousAnimationIsPlaying != newAnimationIsPlaying) { - properties.animationIsPlaying = newAnimationIsPlaying; + properties.animation.running = newAnimationIsPlaying; } else { - delete properties.animationIsPlaying; + delete properties.animation.running; } - properties.animationFPS = array[index++].value; + properties.animation.fps = array[index++].value; var newAnimationFrameIndex = array[index++].value; if (previousAnimationFrameIndex != newAnimationFrameIndex) { - properties.animationFrameIndex = newAnimationFrameIndex; + properties.animation.frameIndex = newAnimationFrameIndex; } else { - delete properties.animationFrameIndex; + delete properties.animation.frameIndex; } - var newAnimationSettings = array[index++].value; - if (previousAnimationSettings != newAnimationSettings) { - properties.animationSettings = newAnimationSettings; - } else { - delete properties.animationSettings; - } properties.textures = array[index++].value; index++; // skip textureNames label } diff --git a/examples/particleDance.js b/examples/particleDance.js index 6b1f84bb8e..9a0c1fc521 100644 --- a/examples/particleDance.js +++ b/examples/particleDance.js @@ -51,15 +51,6 @@ this.emitRate = randInt(80, 120); this.emitStrength = randInt(4.0, 6.0); - this.animationSettings = JSON.stringify({ - fps: 10, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 50, - loop: true - }); - this.direction = { x: randFloat(-0.3, 0.3), y: 1.0, @@ -85,7 +76,7 @@ var color = colorPalette[colorIndex]; this.emitters.push(Entities.addEntity({ type: "ParticleEffect", - animationSettings: this.animationSettings, + isEmitting: true, position: this.point, textures: TEXTURE_PATH, emitRate: this.emitRate, diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 4be8168407..32ec12b640 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -72,10 +72,7 @@ var keysToIgnore = [ 'marketplaceID', 'collisionSoundURL', 'shapeType', - 'animationSettings', - 'animationFrameIndex', - 'animationIsPlaying', - 'animationFPS', + 'isEmitting', 'sittingPoints', 'originalTextures' ]; diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index 6f03eb3c61..16c75e18c6 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -55,15 +55,7 @@ var particleProperties; function setUp() { var boxPoint, - spawnPoint, - animation = { - fps: 30, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 30, - loop: true - }; + spawnPoint; boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { @@ -138,8 +130,7 @@ function setUp() { lifespan: 5.0, visible: false, locked: false, - animationSettings: animation, - animationIsPlaying: true, + isEmitting: true, lifetime: 3600 // 1 hour; just in case }); diff --git a/examples/particles.js b/examples/particles.js index def21704d1..adfed2cf11 100644 --- a/examples/particles.js +++ b/examples/particles.js @@ -29,17 +29,11 @@ // constructor function TestFx(color, emitDirection, emitRate, emitStrength, blinkRate) { - var animationSettings = JSON.stringify({ fps: 30, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 30, - loop: true }); var PI = 3.141593; var DEG_TO_RAD = PI / 180.0; this.entity = Entities.addEntity({ type: "ParticleEffect", - animationSettings: animationSettings, + isEmitting: true, position: spawnPoint, dimensions: {x: 2, y: 2, z: 2}, emitSpeed: 5, diff --git a/examples/toys/breakdanceCore.js b/examples/toys/breakdanceCore.js index 6a69e8d35a..655e55dfc6 100644 --- a/examples/toys/breakdanceCore.js +++ b/examples/toys/breakdanceCore.js @@ -384,13 +384,14 @@ function createOverlays() { } var TEMPORARY_LIFETIME = 60; -var ANIMATION_SETTINGS = JSON.stringify({ +var ANIMATION_SETTINGS = { + url: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx", fps: 30, running: true, loop: true, firstFrame: 1, lastFrame: 10000 -}); +}; var NATURAL_DIMENSIONS = { x: 1.63, y: 1.67, z: 0.31 }; var DIMENSIONS = Vec3.multiply(NATURAL_DIMENSIONS, 0.3); @@ -407,8 +408,7 @@ function createPuppet(model, location) { type: "Model", modelURL: model, registrationPoint: { x: 0.5, y: 0, z: 0.5 }, - animationURL: "http://s3.amazonaws.com/hifi-public/animations/Breakdancing/breakdance_ready.fbx", - animationSettings: ANIMATION_SETTINGS, + animation: ANIMATION_SETTINGS, position: location, ignoreForCollisions: true, dimensions: DIMENSIONS, @@ -558,7 +558,7 @@ breakdanceUpdate = function(deltaTime) { var props = Entities.getEntityProperties(puppetEntityID); //print("puppetEntityID:" + puppetEntityID + "age:"+props.age); Entities.editEntity(puppetEntityID, { - animationURL: poses[poseValue].animation, + animation: { url: poses[poseValue].animation }, lifetime: TEMPORARY_LIFETIME + props.age // renew lifetime }); } diff --git a/examples/toys/grenade.js b/examples/toys/grenade.js index c6a9c5bdeb..7b987b1091 100644 --- a/examples/toys/grenade.js +++ b/examples/toys/grenade.js @@ -33,15 +33,6 @@ var originalPosition = null; var isGrenade = false; var isBurning = false; -var animationSettings = JSON.stringify({ - running: true, - loop: true - }); -var explodeAnimationSettings = JSON.stringify({ - running: true, - loop: false - }); - var GRAVITY = -9.8; var TIME_TO_EXPLODE = 2500; var DISTANCE_IN_FRONT_OF_ME = 1.0; @@ -85,7 +76,7 @@ function update() { // Create fuse particles particles = Entities.addEntity({ type: "ParticleEffect", - animationSettings: animationSettings, + isEmitting: true, position: newProperties.position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: 100, @@ -142,7 +133,7 @@ function boom() { Audio.playSound(boomSound, audioOptions); Entities.addEntity({ type: "ParticleEffect", - animationSettings: explodeAnimationSettings, + isEmitting: true, position: properties.position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: 200, diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index e0aeb19995..b67224b976 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -62,20 +62,13 @@ this.enableStream = function() { var position = Entities.getEntityProperties(this.entityId, "position").position; - var animationSettings = JSON.stringify({ - fps: 30, - loop: true, - firstFrame: 1, - lastFrame: 10000, - running: true - }); var PI = 3.141593; var DEG_TO_RAD = PI / 180.0; this.paintStream = Entities.addEntity({ type: "ParticleEffect", name: "streamEffect", - animationSettings: animationSettings, + isEmitting: true, position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", emitSpeed: 3, diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index ae5a88fdbd..eb58774223 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -35,14 +35,10 @@ public: void setStartAutomatically(bool startAutomatically); bool getStartAutomatically() const { return _startAutomatically; } - void setFirstFrame(float firstFrame) { _firstFrame = glm::clamp(firstFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); - //qDebug() << "AnimationLoop::setFirstFrame() firstFrame:" << firstFrame << "_firstFrame:" << _firstFrame; - } + void setFirstFrame(float firstFrame) { _firstFrame = glm::clamp(firstFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); } float getFirstFrame() const { return _firstFrame; } - void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); - //qDebug() << "AnimationLoop::setLastFrame() lastFrame:" << lastFrame<< "_lastFrame:" << _lastFrame; - } + void setLastFrame(float lastFrame) { _lastFrame = glm::clamp(lastFrame, 0.0f, MAXIMUM_POSSIBLE_FRAME); } float getLastFrame() const { return _lastFrame; } /// by default the AnimationLoop will always reset to the first frame on any call to setRunning @@ -64,17 +60,17 @@ public: void simulate(float deltaTime); private: - float _fps = 30.0f; - bool _loop = false; - bool _hold = false; - bool _startAutomatically = false; - float _firstFrame = 0.0f; - float _lastFrame = MAXIMUM_POSSIBLE_FRAME; - bool _running = false; - float _frameIndex = 0.0f; - float _maxFrameIndexHint = MAXIMUM_POSSIBLE_FRAME; - bool _resetOnRunning = false; - bool _firstRun = true; + float _fps; + bool _loop; + bool _hold; + bool _startAutomatically; + float _firstFrame; + float _lastFrame; + bool _running; + float _frameIndex; + float _maxFrameIndexHint; + bool _resetOnRunning; + bool _firstRun; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 15cea8b432..c978fab012 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -269,7 +269,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (_model) { // handle animations.. if (hasAnimation()) { - if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); mapJoints(modelJointNames); diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 0dbf6d1615..9219bb3065 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -18,9 +18,10 @@ // a) toybox/windmill // b) toybox "put me down" doll // c) asana bugs about animations -// 5) update all scripts +// +// DONE - 5) update all scripts // DONE - 6) remove all remnants of old member variables -// 7) research and remove animation settings from Particle Effect +// DONE - 7) research and remove animation settings from Particle Effect // 8) make sure animations start properly when entering a domain... with previously running animations #ifndef hifi_AnimationPropertyGroup_h @@ -95,10 +96,7 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically public: - void associateWithAnimationLoop(AnimationLoop* animationLoop) { - qDebug() << "associateWithAnimationLoop() this:" << this << "animationLoop:" << animationLoop; - _animationLoop = animationLoop; - } + void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } protected: void setFromOldAnimationSettings(const QString& value); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index eaa21fed12..8b4d4660bf 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -453,6 +453,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models only if (_type == EntityTypes::Model) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL); + _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); } if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { @@ -466,7 +467,6 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool // Models & Particles if (_type == EntityTypes::Model || _type == EntityTypes::ParticleEffect) { - _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); } @@ -621,6 +621,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(shapeType, ShapeType); COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); + COPY_PROPERTY_FROM_QSCRIPTVALUE(isEmitting, bool, setIsEmitting); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); COPY_PROPERTY_FROM_QSCRIPTVALUE(speedSpread, float, setSpeedSpread); @@ -773,6 +774,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType); ADD_PROPERTY_TO_MAP(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); ADD_PROPERTY_TO_MAP(PROP_LIFESPAN, Lifespan, lifespan, float); + ADD_PROPERTY_TO_MAP(PROP_EMITTING_PARTICLES, IsEmitting, isEmitting, bool); ADD_PROPERTY_TO_MAP(PROP_EMIT_RATE, EmitRate, emitRate, float); ADD_PROPERTY_TO_MAP(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, glm::vec3); @@ -1033,12 +1035,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } if (properties.getType() == EntityTypes::ParticleEffect) { - _staticAnimation.setProperties(properties); - _staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); - APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan()); + APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, properties.getIsEmitting()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, properties.getEmitRate()); APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, properties.getEmitSpeed()); APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, properties.getSpeedSpread()); @@ -1319,11 +1319,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int } if (properties.getType() == EntityTypes::ParticleEffect) { - properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMITTING_PARTICLES, bool, setIsEmitting); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index c8bf0836d5..a12328e438 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -136,6 +136,7 @@ public: DEFINE_PROPERTY_REF_ENUM(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType); DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float); + DEFINE_PROPERTY(PROP_EMITTING_PARTICLES, IsEmitting, isEmitting, bool); DEFINE_PROPERTY(PROP_EMIT_RATE, EmitRate, emitRate, float); DEFINE_PROPERTY(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, float); DEFINE_PROPERTY(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, float); @@ -339,6 +340,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ShapeType, shapeType, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MaxParticles, maxParticles, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifespan, lifespan, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, IsEmitting, isEmitting, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRate, emitRate, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitSpeed, emitSpeed, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, SpeedSpread, speedSpread, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 849e3e3a61..d70a5c9616 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -194,6 +194,10 @@ enum EntityPropertyList { // other properties which will never overlap with each other. PROP_SOURCE_URL = PROP_MODEL_URL, + // Aliases/Piggyback properties for Particle Emmitter. These properties intentionally reuse the enum values for + // other properties which will never overlap with each other. + PROP_EMITTING_PARTICLES = PROP_ANIMATION_PLAYING, + // WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above }; diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index e52d9d0b5d..6023db56e1 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -52,9 +52,9 @@ const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = DEFAULT_ALPHA; const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = DEFAULT_ALPHA; -const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; -const bool ParticleEffectEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; -const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; +//const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; +//const bool ParticleEffectEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; +//const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; @@ -83,9 +83,8 @@ EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID // our non-pure virtual subclass for now... ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : EntityItem(entityItemID), - _lastAnimated(usecTimestampNow()), - _animationLoop(), - _animationSettings(), + _lastSimulated(usecTimestampNow()), + _isEmitting(true), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), @@ -109,9 +108,6 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _type = EntityTypes::ParticleEffect; setColor(DEFAULT_COLOR); setProperties(properties); - - _animationProperties.associateWithAnimationLoop(&_animationLoop); - _animationLoop.setResetOnRunning(false); } ParticleEffectEntityItem::~ParticleEffectEntityItem() { @@ -176,6 +172,7 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(isEmitting, getIsEmitting); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitSpeed, getEmitSpeed); COPY_ENTITY_PROPERTY_TO_PROPERTIES(speedSpread, getSpeedSpread); @@ -200,8 +197,6 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); - _animationProperties.getProperties(properties); - return properties; } @@ -214,6 +209,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(isEmitting, setIsEmitting); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRate, setEmitRate); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitSpeed, setEmitSpeed); SET_ENTITY_PROPERTY_FROM_PROPERTIES(speedSpread, setSpeedSpread); @@ -238,10 +234,6 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); - bool somethingChangedInAnimations = _animationProperties.setProperties(properties); - - somethingChanged = somethingChanged || somethingChangedInAnimations; - if (somethingChanged) { bool wantDebug = false; if (wantDebug) { @@ -267,38 +259,11 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch // Because we're using AnimationLoop which will reset the frame index if you change it's running state // we want to read these values in the order they appear in the buffer, but call our setters in an // order that allows AnimationLoop to preserve the correct frame rate. - float animationFPS = getAnimationFPS(); - float animationFrameIndex = getAnimationFrameIndex(); - bool animationIsPlaying = getAnimationIsPlaying(); if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - } - - if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { - if (animationIsPlaying != getAnimationIsPlaying()) { - setAnimationIsPlaying(animationIsPlaying); - } - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) { - setAnimationFPS(animationFPS); - } - if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { - setAnimationFrameIndex(animationFrameIndex); - } - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); - } - else { - int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); - - bytesRead += bytesFromAnimation; - dataAt += bytesFromAnimation; - - // FIXME -- we need to actually get the property values out of the _animationProperties - // and use them for our AnimationLoop + SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float); + SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float); + SKIP_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool); + SKIP_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString); } READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); @@ -393,8 +358,6 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_AZIMUTH_START; requestedProperties += PROP_AZIMUTH_FINISH; - requestedProperties += _animationProperties.getEntityProperties(params); - return requestedProperties; } @@ -408,11 +371,6 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); - - // FIXME - we probably need to make sure the _animationProperties has the latest data from the AnimationLoop - _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, - propertyFlags, propertiesDidntFit, propertyCount, appendState); - APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan()); @@ -442,9 +400,10 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, getAzimuthFinish()); } -bool ParticleEffectEntityItem::isAnimatingSomething() const { - // keep animating if there are particles still alive. - return (getAnimationIsPlaying() || getLivingParticleCount() > 0) && getAnimationFPS() != 0.0f; +bool ParticleEffectEntityItem::isEmittingParticles() const { + // keep emitting if there are particles still alive. + //return (getAnimationIsPlaying() || getLivingParticleCount() > 0) && getAnimationFPS() != 0.0f; + return (getLivingParticleCount() > 0); } bool ParticleEffectEntityItem::needsToCallUpdate() const { @@ -453,15 +412,10 @@ bool ParticleEffectEntityItem::needsToCallUpdate() const { void ParticleEffectEntityItem::update(const quint64& now) { - float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; - _lastAnimated = now; + float deltaTime = (float)(now - _lastSimulated) / (float)USECS_PER_SECOND; + _lastSimulated = now; - // only advance the frame index if we're playing - if (getAnimationIsPlaying()) { - _animationLoop.simulate(deltaTime); - } - - if (isAnimatingSomething()) { + if (isEmittingParticles()) { stepSimulation(deltaTime); } @@ -484,131 +438,6 @@ void ParticleEffectEntityItem::updateShapeType(ShapeType type) { } } -void ParticleEffectEntityItem::setAnimationFrameIndex(float value) { -#ifdef WANT_DEBUG - if (isAnimatingSomething()) { - qCDebug(entities) << "ParticleEffectEntityItem::setAnimationFrameIndex()"; - qCDebug(entities) << " value:" << value; - qCDebug(entities) << " was:" << _animationLoop.getFrameIndex(); - } -#endif - _animationLoop.setFrameIndex(value); -} - -void ParticleEffectEntityItem::setAnimationSettings(const QString& value) { - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and - // will over ride the regular animation settings - - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - if (settingsMap.contains("fps")) { - float fps = settingsMap["fps"].toFloat(); - setAnimationFPS(fps); - } - - if (settingsMap.contains("frameIndex")) { - float frameIndex = settingsMap["frameIndex"].toFloat(); -#ifdef WANT_DEBUG - if (isAnimatingSomething()) { - qCDebug(entities) << "ParticleEffectEntityItem::setAnimationSettings() calling setAnimationFrameIndex()..."; - qCDebug(entities) << " settings:" << value; - qCDebug(entities) << " settingsMap[frameIndex]:" << settingsMap["frameIndex"]; - qCDebug(entities, " frameIndex: %20.5f", frameIndex); - } -#endif - - setAnimationFrameIndex(frameIndex); - } - - if (settingsMap.contains("running")) { - bool running = settingsMap["running"].toBool(); - if (running != getAnimationIsPlaying()) { - setAnimationIsPlaying(running); - } - } - - if (settingsMap.contains("firstFrame")) { - float firstFrame = settingsMap["firstFrame"].toFloat(); - setAnimationFirstFrame(firstFrame); - } - - if (settingsMap.contains("lastFrame")) { - float lastFrame = settingsMap["lastFrame"].toFloat(); - setAnimationLastFrame(lastFrame); - } - - if (settingsMap.contains("loop")) { - bool loop = settingsMap["loop"].toBool(); - setAnimationLoop(loop); - } - - if (settingsMap.contains("hold")) { - bool hold = settingsMap["hold"].toBool(); - setAnimationHold(hold); - } - - if (settingsMap.contains("startAutomatically")) { - bool startAutomatically = settingsMap["startAutomatically"].toBool(); - setAnimationStartAutomatically(startAutomatically); - } - - _animationSettings = value; - _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; -} - -void ParticleEffectEntityItem::setAnimationIsPlaying(bool value) { - _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; - _animationLoop.setRunning(value); -} - -void ParticleEffectEntityItem::setAnimationFPS(float value) { - _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; - _animationLoop.setFPS(value); -} - -QString ParticleEffectEntityItem::getAnimationSettings() const { - // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and - // will over ride the regular animation settings - QString value = _animationSettings; - - QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); - QJsonObject settingsAsJsonObject = settingsAsJson.object(); - QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - - QVariant fpsValue(getAnimationFPS()); - settingsMap["fps"] = fpsValue; - - QVariant frameIndexValue(getAnimationFrameIndex()); - settingsMap["frameIndex"] = frameIndexValue; - - QVariant runningValue(getAnimationIsPlaying()); - settingsMap["running"] = runningValue; - - QVariant firstFrameValue(getAnimationFirstFrame()); - settingsMap["firstFrame"] = firstFrameValue; - - QVariant lastFrameValue(getAnimationLastFrame()); - settingsMap["lastFrame"] = lastFrameValue; - - QVariant loopValue(getAnimationLoop()); - settingsMap["loop"] = loopValue; - - QVariant holdValue(getAnimationHold()); - settingsMap["hold"] = holdValue; - - QVariant startAutomaticallyValue(getAnimationStartAutomatically()); - settingsMap["startAutomatically"] = startAutomaticallyValue; - - settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap); - QJsonDocument newDocument(settingsAsJsonObject); - QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact); - QString jsonByteString(jsonByteArray); - return jsonByteString; -} - void ParticleEffectEntityItem::updateRadius(quint32 index, float age) { _particleRadiuses[index] = Interpolate::interpolate3Points(_radiusStarts[index], _radiusMiddles[index], _radiusFinishes[index], age); @@ -669,8 +498,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } } - // emit new particles, but only if animation is playing - if (getAnimationIsPlaying()) { + // emit new particles, but only if we are emmitting + if (isEmittingParticles()) { float timeLeftInFrame = deltaTime; while (_timeUntilNextEmit < timeLeftInFrame) { diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index cb2e80a1be..44cfb76a02 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -91,33 +91,9 @@ public: virtual void debugDump() const; - - const AnimationPropertyGroup& getAnimationProperties() const { return _animationProperties; } - - static const float DEFAULT_ANIMATION_FRAME_INDEX; - void setAnimationFrameIndex(float value); - void setAnimationSettings(const QString& value); - - static const bool DEFAULT_ANIMATION_IS_PLAYING; - void setAnimationIsPlaying(bool value); - - static const float DEFAULT_ANIMATION_FPS; - void setAnimationFPS(float value); - - void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); } - bool getAnimationLoop() const { return _animationLoop.getLoop(); } - - void setAnimationHold(bool hold) { _animationLoop.setHold(hold); } - bool getAnimationHold() const { return _animationLoop.getHold(); } - - void setAnimationStartAutomatically(bool startAutomatically) { _animationLoop.setStartAutomatically(startAutomatically); } - bool getAnimationStartAutomatically() const { return _animationLoop.getStartAutomatically(); } - - void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); } - float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); } - - void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } - float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } + bool isEmittingParticles() const; /// emitting enabled, and there are particles alive + bool getIsEmitting() const { return _isEmitting; } + void setIsEmitting(bool isEmitting) { _isEmitting = isEmitting; } static const quint32 DEFAULT_MAX_PARTICLES; void setMaxParticles(quint32 maxParticles); @@ -195,12 +171,6 @@ public: void computeAndUpdateDimensions(); - - bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } - float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } - float getAnimationFPS() const { return _animationLoop.getFPS(); } - QString getAnimationSettings() const; - static const QString DEFAULT_TEXTURES; const QString& getTextures() const { return _textures; } void setTextures(const QString& textures) { @@ -250,12 +220,8 @@ protected: float _radiusSpread = DEFAULT_RADIUS_SPREAD; - quint64 _lastAnimated; - AnimationPropertyGroup _animationProperties; - AnimationLoop _animationLoop; - - // FIXME - remove this - QString _animationSettings; + quint64 _lastSimulated; + bool _isEmitting; QString _textures = DEFAULT_TEXTURES; bool _texturesChangedFlag = false; diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index d6759e2b48..f08d62e087 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -112,19 +112,10 @@ function createFire() { var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); - var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 - }); - - var fire = Entities.addEntity({ type: "ParticleEffect", name: "fire", - animationSettings: animationSettings, + isEmitting: true, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", position: { x: 551.45, @@ -187,17 +178,16 @@ function createFire() { function createCat(position) { var scriptURL = Script.resolvePath("../examples/toys/cat.js"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; - var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ + var animationSettings = { + url: "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx", running: true, - }); + }; var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "cat", script: scriptURL, - animationURL: animationURL, - animationSettings: animationSettings, + animation: animationSettings, position: position, rotation: { w: 0.35020983219146729, From c3fc6f4f79c5e1c128f9cff6e1f6da848ae6253e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 23 Sep 2015 17:32:12 +0200 Subject: [PATCH 028/152] Add message part to Packet --- libraries/networking/src/udt/Packet.cpp | 12 ++++++++-- libraries/networking/src/udt/Packet.h | 17 ++++++++------- libraries/networking/src/udt/PacketList.cpp | 18 +++++++++++++++ libraries/networking/src/udt/PacketList.h | 23 +++++++++++--------- libraries/networking/src/udt/PacketQueue.cpp | 21 +----------------- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 0582ef6487..ebcf4baafd 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -15,7 +15,7 @@ using namespace udt; int Packet::localHeaderSize(bool isPartOfMessage) { return sizeof(Packet::SequenceNumberAndBitField) + - (isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) : 0); + (isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) + sizeof(MessagePart) : 0); } int Packet::totalHeaderSize(bool isPartOfMessage) { @@ -109,9 +109,11 @@ Packet& Packet::operator=(Packet&& other) { return *this; } -void Packet::writeMessageNumber(MessageNumber messageNumber) { +void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart) { _isPartOfMessage = true; _messageNumber = messageNumber; + _packetPosition = position; + _messagePart = messagePart; writeHeader(); } @@ -141,6 +143,9 @@ void Packet::readHeader() const { MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1; _messageNumber = *messageNumberAndBitField & MESSAGE_NUMBER_MASK; _packetPosition = static_cast(*messageNumberAndBitField >> PACKET_POSITION_OFFSET); + + MessagePart* messagePart = messageNumberAndBitField + 1; + _messagePart = *messagePart; } } @@ -166,5 +171,8 @@ void Packet::writeHeader() const { MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1; *messageNumberAndBitField = _messageNumber; *messageNumberAndBitField |= _packetPosition << PACKET_POSITION_OFFSET; + + MessagePart* messagePart = messageNumberAndBitField + 1; + *messagePart = _messagePart; } } diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h index 6bf7c569aa..71fb22eb98 100644 --- a/libraries/networking/src/udt/Packet.h +++ b/libraries/networking/src/udt/Packet.h @@ -31,6 +31,7 @@ public: // NOTE: The MessageNumber is only actually 30 bits to leave room for a bit field using MessageNumber = uint32_t; using MessageNumberAndBitField = uint32_t; + using MessagePart = uint32_t; // Use same size as MessageNumberAndBitField so we can use the enum with bitwise operations enum PacketPosition : MessageNumberAndBitField { @@ -55,14 +56,13 @@ public: bool isPartOfMessage() const { return _isPartOfMessage; } bool isReliable() const { return _isReliable; } - SequenceNumber getSequenceNumber() const { return _sequenceNumber; } - - MessageNumber getMessageNumber() const { return _messageNumber; } - - void setPacketPosition(PacketPosition position) { _packetPosition = position; } - PacketPosition getPacketPosition() const { return _packetPosition; } - void writeMessageNumber(MessageNumber messageNumber); + SequenceNumber getSequenceNumber() const { return _sequenceNumber; } + MessageNumber getMessageNumber() const { return _messageNumber; } + PacketPosition getPacketPosition() const { return _packetPosition; } + MessagePart getMessagePart() const { return _messagePart; } + + void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart); void writeSequenceNumber(SequenceNumber sequenceNumber) const; protected: @@ -84,8 +84,9 @@ private: mutable bool _isReliable { false }; mutable bool _isPartOfMessage { false }; mutable SequenceNumber _sequenceNumber { 0 }; - mutable PacketPosition _packetPosition { PacketPosition::ONLY }; mutable MessageNumber _messageNumber { 0 }; + mutable PacketPosition _packetPosition { PacketPosition::ONLY }; + mutable MessagePart _messagePart { 0 }; }; } // namespace udt diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index 64ae8f54db..8f6a65abc9 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -132,6 +132,24 @@ QByteArray PacketList::getMessage() { return data; } +void PacketList::preparePackets(MessageNumber messageNumber) { + Q_ASSERT(_packets.size() > 0); + + if (_packets.size() == 1) { + _packets.front()->writeMessageNumber(messageNumber, Packet::PacketPosition::ONLY, 0); + } else { + const auto second = ++_packets.begin(); + const auto last = --_packets.end(); + Packet::MessagePart messagePart = 0; + std::for_each(second, last, [&](const PacketPointer& packet) { + packet->writeMessageNumber(messageNumber, Packet::PacketPosition::MIDDLE, ++messagePart); + }); + + _packets.front()->writeMessageNumber(messageNumber, Packet::PacketPosition::FIRST, 0); + _packets.back()->writeMessageNumber(messageNumber, Packet::PacketPosition::LAST, ++messagePart); + } +} + qint64 PacketList::writeData(const char* data, qint64 maxSize) { auto sizeRemaining = maxSize; diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index c873e53711..5337094d1f 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -28,28 +28,29 @@ class Packet; class PacketList : public QIODevice { Q_OBJECT public: + using MessageNumber = uint32_t; + using PacketPointer = std::unique_ptr; + static std::unique_ptr create(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false); static std::unique_ptr fromReceivedPackets(std::list>&& packets); + PacketType getType() const { return _packetType; } bool isReliable() const { return _isReliable; } bool isOrdered() const { return _isOrdered; } + int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); } + size_t getDataSize() const; + size_t getMessageSize() const; + QByteArray getMessage(); + + QByteArray getExtendedHeader() const { return _extendedHeader; } + void startSegment(); void endSegment(); - PacketType getType() const { return _packetType; } - int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); } - - QByteArray getExtendedHeader() const { return _extendedHeader; } - - size_t getDataSize() const; - size_t getMessageSize() const; - void closeCurrentPacket(bool shouldSendEmpty = false); - QByteArray getMessage(); - // QIODevice virtual functions virtual bool isSequential() const { return false; } virtual qint64 size() const { return getDataSize(); } @@ -60,6 +61,8 @@ public: protected: PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false); PacketList(PacketList&& other); + + void preparePackets(MessageNumber messageNumber); virtual qint64 writeData(const char* data, qint64 maxSize); // Not implemented, added an assert so that it doesn't get used by accident diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index f5c1b4a9a0..48d5982eb3 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -45,26 +45,7 @@ void PacketQueue::queuePacket(PacketPointer packet) { } void PacketQueue::queuePacketList(PacketListPointer packetList) { - Q_ASSERT(packetList->_packets.size() > 0); - - auto messageNumber = getNextMessageNumber(); - auto markPacket = [&messageNumber](const PacketPointer& packet, Packet::PacketPosition position) { - packet->setPacketPosition(position); - packet->writeMessageNumber(messageNumber); - }; - - if (packetList->_packets.size() == 1) { - markPacket(packetList->_packets.front(), Packet::PacketPosition::ONLY); - } else { - const auto second = ++packetList->_packets.begin(); - const auto last = --packetList->_packets.end(); - std::for_each(second, last, [&](const PacketPointer& packet) { - markPacket(packet, Packet::PacketPosition::MIDDLE); - }); - - markPacket(packetList->_packets.front(), Packet::PacketPosition::FIRST); - markPacket(packetList->_packets.back(), Packet::PacketPosition::LAST); - } + packetList->preparePackets(getNextMessageNumber()); LockGuard locker(_packetsLock); _packets.splice(_packets.end(), packetList->_packets); From 7007d9f22380727ca67cbf7f4b2aa6cafe95d6e9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 23 Sep 2015 17:32:52 +0200 Subject: [PATCH 029/152] Use message part to check recieved packet list --- libraries/networking/src/udt/Connection.cpp | 39 +++++++-------------- libraries/networking/src/udt/Connection.h | 9 ++--- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index d7b851fcf4..c8264a6737 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -857,37 +857,22 @@ void PendingReceivedMessage::enqueuePacket(std::unique_ptr packet) { "PendingReceivedMessage::enqueuePacket", "called with a packet that is not part of a message"); - if (_isComplete) { - qCDebug(networking) << "UNEXPECTED: Received packet for a message that is already complete"; - return; - } - - auto sequenceNumber = packet->getSequenceNumber(); - - if (packet->getPacketPosition() == Packet::PacketPosition::FIRST) { - _hasFirstSequenceNumber = true; - _firstSequenceNumber = sequenceNumber; - } else if (packet->getPacketPosition() == Packet::PacketPosition::LAST) { - _hasLastSequenceNumber = true; - _lastSequenceNumber = sequenceNumber; - } else if (packet->getPacketPosition() == Packet::PacketPosition::ONLY) { - _hasFirstSequenceNumber = true; - _hasLastSequenceNumber = true; - _firstSequenceNumber = sequenceNumber; - _lastSequenceNumber = sequenceNumber; + if (packet->getPacketPosition() == Packet::PacketPosition::LAST || + packet->getPacketPosition() == Packet::PacketPosition::ONLY) { + _hasLastPacket = true; + _numPackets = packet->getMessagePart() + 1; } // Insert into the packets list in sorted order. Because we generally expect to receive packets in order, begin // searching from the end of the list. - auto it = find_if(_packets.rbegin(), _packets.rend(), - [&](const std::unique_ptr& packet) { return sequenceNumber > packet->getSequenceNumber(); }); + auto messagePart = packet->getMessagePart(); + auto it = std::find_if(_packets.rbegin(), _packets.rend(), + [&](const std::unique_ptr& value) { return messagePart >= value->getMessagePart(); }); - _packets.insert(it.base(), std::move(packet)); - - if (_hasFirstSequenceNumber && _hasLastSequenceNumber) { - auto numPackets = udt::seqlen(_firstSequenceNumber, _lastSequenceNumber); - if (uint64_t(numPackets) == _packets.size()) { - _isComplete = true; - } + if (it != _packets.rend() && ((*it)->getMessagePart() == messagePart)) { + qCDebug(networking) << "PendingReceivedMessage::enqueuePacket: This is a duplicate packet"; + return; } + + _packets.insert(it.base(), std::move(packet)); } diff --git a/libraries/networking/src/udt/Connection.h b/libraries/networking/src/udt/Connection.h index 13756c12f9..7f9978c326 100644 --- a/libraries/networking/src/udt/Connection.h +++ b/libraries/networking/src/udt/Connection.h @@ -37,16 +37,13 @@ class Socket; class PendingReceivedMessage { public: void enqueuePacket(std::unique_ptr packet); - bool isComplete() const { return _isComplete; } + bool isComplete() const { return _hasLastPacket && _numPackets == _packets.size(); } std::list> _packets; private: - bool _isComplete { false }; - bool _hasFirstSequenceNumber { false }; - bool _hasLastSequenceNumber { false }; - SequenceNumber _firstSequenceNumber; - SequenceNumber _lastSequenceNumber; + bool _hasLastPacket { false }; + unsigned int _numPackets { 0 }; }; class Connection : public QObject { From 3db99f50e5980b2d6e811396749f5a3916352e46 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 23 Sep 2015 18:54:13 +0200 Subject: [PATCH 030/152] Change takeFront name --- libraries/networking/src/udt/PacketQueue.cpp | 2 +- libraries/networking/src/udt/PacketQueue.h | 2 +- libraries/networking/src/udt/SendQueue.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index 48d5982eb3..088908200d 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -28,7 +28,7 @@ bool PacketQueue::isEmpty() const { return _packets.empty(); } -PacketQueue::PacketPointer PacketQueue::takeFront() { +PacketQueue::PacketPointer PacketQueue::takePacket() { LockGuard locker(_packetsLock); if (!_packets.empty()) { auto packet = std::move(_packets.front()); diff --git a/libraries/networking/src/udt/PacketQueue.h b/libraries/networking/src/udt/PacketQueue.h index 4bd0feeb25..a687ccf0bc 100644 --- a/libraries/networking/src/udt/PacketQueue.h +++ b/libraries/networking/src/udt/PacketQueue.h @@ -35,7 +35,7 @@ public: void queuePacketList(PacketListPointer packetList); bool isEmpty() const; - PacketPointer takeFront(); + PacketPointer takePacket(); MessageNumber getNextMessageNumber(); Mutex& getLock() { return _packetsLock; } diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index aa37c8f23b..2354bfa377 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -295,7 +295,7 @@ bool SendQueue::maybeSendNewPacket() { SequenceNumber nextNumber = getNextSequenceNumber(); // grab the first packet we will send - std::unique_ptr firstPacket = _packets.takeFront(); + std::unique_ptr firstPacket = _packets.takePacket(); std::unique_ptr secondPacket; bool shouldSendPairTail = false; @@ -305,7 +305,7 @@ bool SendQueue::maybeSendNewPacket() { // pull off a second packet if we can before we unlock shouldSendPairTail = true; - secondPacket = _packets.takeFront(); + secondPacket = _packets.takePacket(); } // definitely send the first packet From 48ff912dd2cba806444d4b5135c45d8c22585bbf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 13:08:04 +0200 Subject: [PATCH 031/152] Use one channel per packet list --- libraries/networking/src/udt/PacketQueue.cpp | 42 +++++++++++++++----- libraries/networking/src/udt/PacketQueue.h | 16 +++++--- libraries/networking/src/udt/SendQueue.cpp | 1 + 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index 088908200d..d0110852cd 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -11,12 +11,10 @@ #include "PacketQueue.h" -#include "Packet.h" #include "PacketList.h" using namespace udt; - MessageNumber PacketQueue::getNextMessageNumber() { static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; @@ -25,28 +23,50 @@ MessageNumber PacketQueue::getNextMessageNumber() { bool PacketQueue::isEmpty() const { LockGuard locker(_packetsLock); - return _packets.empty(); + // Only the main channel and it is empty + return (_channels.size() == 1) && _channels.front().empty(); } PacketQueue::PacketPointer PacketQueue::takePacket() { LockGuard locker(_packetsLock); - if (!_packets.empty()) { - auto packet = std::move(_packets.front()); - _packets.pop_front(); - return std::move(packet); + if (isEmpty()) { + return PacketPointer(); } - return PacketPointer(); + // Find next non empty channel + if (_channels[nextIndex()].empty()) { + nextIndex(); + } + auto& channel = _channels[_currentIndex]; + Q_ASSERT(!channel.empty()); + + // Take front packet + auto packet = std::move(channel.front()); + channel.pop_front(); + + // Remove now empty channel (Don't remove the main channel) + if (channel.empty() && _currentIndex != 0) { + channel.swap(_channels.back()); + _channels.pop_back(); + --_currentIndex; + } + + return std::move(packet); +} + +unsigned int PacketQueue::nextIndex() { + _currentIndex = ++_currentIndex % _channels.size(); + return _currentIndex; } void PacketQueue::queuePacket(PacketPointer packet) { LockGuard locker(_packetsLock); - _packets.push_back(std::move(packet)); + _channels.front().push_back(std::move(packet)); } void PacketQueue::queuePacketList(PacketListPointer packetList) { packetList->preparePackets(getNextMessageNumber()); LockGuard locker(_packetsLock); - _packets.splice(_packets.end(), packetList->_packets); -} \ No newline at end of file + _channels.push_back(std::move(packetList->_packets)); +} diff --git a/libraries/networking/src/udt/PacketQueue.h b/libraries/networking/src/udt/PacketQueue.h index a687ccf0bc..f3d925af30 100644 --- a/libraries/networking/src/udt/PacketQueue.h +++ b/libraries/networking/src/udt/PacketQueue.h @@ -13,12 +13,14 @@ #define hifi_PacketQueue_h #include +#include #include #include +#include "Packet.h" + namespace udt { -class Packet; class PacketList; using MessageNumber = uint32_t; @@ -28,7 +30,8 @@ class PacketQueue { using LockGuard = std::lock_guard; using PacketPointer = std::unique_ptr; using PacketListPointer = std::unique_ptr; - using PacketContainer = std::list; + using Channel = std::list; + using Channels = std::vector; public: void queuePacket(PacketPointer packet); @@ -37,14 +40,17 @@ public: bool isEmpty() const; PacketPointer takePacket(); - MessageNumber getNextMessageNumber(); Mutex& getLock() { return _packetsLock; } private: + MessageNumber getNextMessageNumber(); + unsigned int nextIndex(); + MessageNumber _currentMessageNumber { 0 }; - mutable Mutex _packetsLock; // Protects the packets to be sent list. - PacketContainer _packets; // List of packets to be sent + mutable Mutex _packetsLock; // Protects the packets to be sent. + Channels _channels { 1 }; // One channel per packet list + unsigned int _currentIndex { 0 }; }; } diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 2354bfa377..6ba947553a 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -296,6 +296,7 @@ bool SendQueue::maybeSendNewPacket() { // grab the first packet we will send std::unique_ptr firstPacket = _packets.takePacket(); + Q_ASSERT(firstPacket); std::unique_ptr secondPacket; bool shouldSendPairTail = false; From 1f07ba46d02965f89da2be1c9f9a88baf9f53887 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 15:00:55 +0200 Subject: [PATCH 032/152] Fix in-class initialization for windows build --- libraries/networking/src/udt/ConnectionStats.h | 14 ++++++++++---- libraries/networking/src/udt/PacketQueue.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/ConnectionStats.h b/libraries/networking/src/udt/ConnectionStats.h index 8163ed5250..84cd6b2486 100644 --- a/libraries/networking/src/udt/ConnectionStats.h +++ b/libraries/networking/src/udt/ConnectionStats.h @@ -20,9 +20,6 @@ namespace udt { class ConnectionStats { public: struct Stats { - std::chrono::microseconds startTime; - std::chrono::microseconds endTime; - enum Event { SentACK, ReceivedACK, @@ -41,8 +38,14 @@ public: NumEvents }; + using microseconds = std::chrono::microseconds; + using Events = std::array; + + microseconds startTime; + microseconds endTime; + // construct a vector for the events of the size of our Enum - default value is zero - std::array events {{ 0 }}; + Events events; // packet counts and sizes int sentPackets { 0 }; @@ -66,6 +69,9 @@ public: int rtt { 0 }; int congestionWindowSize { 0 }; int packetSendPeriod { 0 }; + + // TODO: Remove once Win build supports brace initialization: `Events events {{ 0 }};` + Stats() { events.fill(0); } }; ConnectionStats(); diff --git a/libraries/networking/src/udt/PacketQueue.h b/libraries/networking/src/udt/PacketQueue.h index f3d925af30..69784fd8db 100644 --- a/libraries/networking/src/udt/PacketQueue.h +++ b/libraries/networking/src/udt/PacketQueue.h @@ -49,7 +49,7 @@ private: MessageNumber _currentMessageNumber { 0 }; mutable Mutex _packetsLock; // Protects the packets to be sent. - Channels _channels { 1 }; // One channel per packet list + Channels _channels = Channels(1); // One channel per packet list + Main channel unsigned int _currentIndex { 0 }; }; From 1e56d0c99bdf927c92a3c71266f88415d5328d9c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 18:15:10 +0200 Subject: [PATCH 033/152] Add parenthesis to quiet gcc warning --- libraries/networking/src/udt/PacketQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index d0110852cd..1c104e1427 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -55,7 +55,7 @@ PacketQueue::PacketPointer PacketQueue::takePacket() { } unsigned int PacketQueue::nextIndex() { - _currentIndex = ++_currentIndex % _channels.size(); + _currentIndex = (++_currentIndex) % _channels.size(); return _currentIndex; } From f5f349e13aa1b914dccc90399204c1e502174d44 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 18:24:34 +0200 Subject: [PATCH 034/152] Bumped packet version numbers --- libraries/networking/src/udt/PacketHeaders.cpp | 7 ++----- libraries/networking/src/udt/PacketHeaders.h | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index ca75a86158..1aa9e90f99 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,12 +38,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER; - case PacketType::AvatarData: - case PacketType::BulkAvatarData: - return 15; + return VERSION_ENTITIES_PROTOCOL_CHANNELS; default: - return 14; + return 16; } } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 9f3c5950a2..febb997047 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -141,5 +141,6 @@ const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; +const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45; #endif // hifi_PacketHeaders_h From 86a3825a5a6caa0dd4088af4f8b0d20582b05c9c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 14:50:59 -0700 Subject: [PATCH 035/152] tweak --- libraries/entities/src/AnimationPropertyGroup.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 9219bb3065..fa12d8f279 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -47,6 +47,7 @@ class AnimationPropertyGroup : public PropertyGroup { public: AnimationPropertyGroup(); virtual ~AnimationPropertyGroup() {} + void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } // EntityItemProperty related helpers virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const; @@ -95,9 +96,6 @@ public: DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool); // was animationSettings.hold DEFINE_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, StartAutomatically, startAutomatically, bool); // was animationSettings.startAutomatically -public: - void associateWithAnimationLoop(AnimationLoop* animationLoop) { _animationLoop = animationLoop; } - protected: void setFromOldAnimationSettings(const QString& value); From e6e60e5e7a1b607c3b52f9d9d8fc1e34a28429b3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 2 Oct 2015 15:58:32 -0700 Subject: [PATCH 036/152] Lights should now only be created once at start of running reset master script, no matter how many people there are in the room --- examples/toys/lightSwitch.js | 56 ++++++-- examples/toys/lightSwitchGarage.js | 202 ----------------------------- examples/toys/lightSwitchHall.js | 179 ------------------------- unpublishedScripts/masterReset.js | 68 ++++++---- 4 files changed, 89 insertions(+), 416 deletions(-) delete mode 100644 examples/toys/lightSwitchGarage.js delete mode 100644 examples/toys/lightSwitchHall.js diff --git a/examples/toys/lightSwitch.js b/examples/toys/lightSwitch.js index 18c6d26185..9a23a3b6d4 100644 --- a/examples/toys/lightSwitch.js +++ b/examples/toys/lightSwitch.js @@ -16,12 +16,12 @@ /*global LightSwitch */ (function () { + var utilitiesScript = Script.resolvePath("../libraries/utils.js"); + Script.include(utilitiesScript); - var LightSwitch = function () { + LightSwitch = function () { this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - print("SHNUUUUR") - - }; + } LightSwitch.prototype = { @@ -32,21 +32,57 @@ this.toggleLights(); }, - toggleLights: function () { - print("TOGGLE LIGHTS"); - }, - startNearGrabNonColliding: function () { this.toggleLights(); }, + toggleLights: function () { + var lightData = getEntityCustomData(this.resetKey, this.entityID, {}); + var on = lightData.on; + var lightType = lightData.type; + + var lights = Entities.findEntities(this.position, 20); + lights.forEach(function (light) { + var type = getEntityCustomData(this.resetKey, light, {}).type; + if (type === lightType) { + Entities.editEntity(light, { + visible: on + }); + } + }); + + this.flipSwitch(); + + setEntityCustomData(this.resetKey, this.entityID, { + on: !on + type: lightType, + resetMe: true + }); + }, + + flipSwitch: function () { + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + }, preload: function (entityID) { this.entityID = entityID; + this.resetKey = "resetMe"; //The light switch is static, so just cache its position once this.position = Entities.getEntityProperties(this.entityID, "position").position; - }, + this.lightType = getEntityCustomData(this.resetKey, this.entityID, {}).type; + } }; // entity scripts always need to return a newly constructed object of our type return new LightSwitch(); -}()); \ No newline at end of file +}); \ No newline at end of file diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js deleted file mode 100644 index 19d33117df..0000000000 --- a/examples/toys/lightSwitchGarage.js +++ /dev/null @@ -1,202 +0,0 @@ -// -// lightSwitchGarage.js.js -// examples/entityScripts -// -// Created by Eric Levin on 9/21/15. -// Copyright 2015 High Fidelity, Inc. -// -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - - var _this; - - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - LightSwitchGarage = function() { - _this = this; - - this.lightStateKey = "lightStateKey"; - this.resetKey = "resetMe"; - - this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - - }; - - LightSwitchGarage.prototype = { - - clickReleaseOnEntity: function(entityID, mouseEvent) { - if (!mouseEvent.isLeftButton) { - return; - } - this.toggleLights(); - }, - - startNearGrabNonColliding: function() { - this.toggleLights(); - }, - - toggleLights: function() { - var defaultLightData = { - on: false - }; - var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - if (lightState.on === true) { - this.clearLights(); - } else if (lightState.on === false) { - this.createLights(); - } - - this.flipLights(); - - Audio.playSound(this.switchSound, { - volume: 0.5, - position: this.position - }); - - }, - - clearLights: function() { - var entities = Entities.findEntities(MyAvatar.position, 100); - var self = this; - entities.forEach(function(entity) { - var resetData = getEntityCustomData(self.resetKey, entity, {}) - if (resetData.resetMe === true && resetData.lightType === "Sconce Light Garage") { - Entities.deleteEntity(entity); - } - }); - - setEntityCustomData(this.lightStateKey, this.entityID, { - on: false - }); - }, - - createLights: function() { - - var sconceLight3 = Entities.addEntity({ - type: "Light", - position: { - x: 545.49468994140625, - y: 496.24026489257812, - z: 500.63516235351562 - }, - - name: "Sconce 3 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight3, { - resetMe: true, - lightType: "Sconce Light Garage" - }); - - var sconceLight4 = Entities.addEntity({ - type: "Light", - position: { - x: 550.90399169921875, - y: 496.24026489257812, - z: 507.90237426757812 - }, - name: "Sconce 4 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight4, { - resetMe: true, - lightType: "Sconce Light Garage" - }); - - var sconceLight5 = Entities.addEntity({ - type: "Light", - position: { - x: 548.407958984375, - y: 496.24026489257812, - z: 509.5504150390625 - }, - name: "Sconce 5 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight5, { - resetMe: true, - lightType: "Sconce Light Garage" - }); - - setEntityCustomData(this.lightStateKey, this.entityID, { - on: true - }); - }, - - flipLights: function() { - // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); - - }, - - preload: function(entityID) { - this.entityID = entityID; - - //The light switch is static, so just cache its position once - this.position = Entities.getEntityProperties(this.entityID, "position").position; - var defaultLightData = { - on: false - }; - var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - - //If light is off, then we create two new lights- at the position of the sconces - if (lightState.on === false) { - this.createLights(); - this.flipLights(); - } - //If lights are on, do nothing! - }, - }; - - // entity scripts always need to return a newly constructed object of our type - return new LightSwitchGarage(); -}) diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js deleted file mode 100644 index e1093311f9..0000000000 --- a/examples/toys/lightSwitchHall.js +++ /dev/null @@ -1,179 +0,0 @@ -// -// lightSwitchHall.js -// examples/entityScripts -// -// Created by Eric Levin on 9/21/15. -// Copyright 2015 High Fidelity, Inc. -// -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - - var _this; - - - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - LightSwitchHall = function() { - _this = this; - - this.lightStateKey = "lightStateKey"; - this.resetKey = "resetMe"; - - this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - }; - - LightSwitchHall.prototype = { - - clickReleaseOnEntity: function(entityId, mouseEvent) { - if (!mouseEvent.isLeftButton) { - return; - } - this.toggleLights(); - }, - - startNearGrabNonColliding: function() { - this.toggleLights(); - }, - - toggleLights: function() { - var defaultLightData = { - on: false - }; - var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - if (lightState.on === true) { - this.clearLights(); - } else if (lightState.on === false) { - this.createLights(); - } - - // flip model to give illusion of light switch being flicked - this.flipLights(); - - Audio.playSound(this.switchSound, { - volume: 0.5, - position: this.position - }); - - }, - - clearLights: function() { - var entities = Entities.findEntities(MyAvatar.position, 100); - var self = this; - entities.forEach(function(entity) { - var resetData = getEntityCustomData(self.resetKey, entity, {}) - if (resetData.resetMe === true && resetData.lightType === "Sconce Light Hall") { - Entities.deleteEntity(entity); - } - }); - - setEntityCustomData(this.lightStateKey, this.entityID, { - on: false - }); - }, - - createLights: function() { - var sconceLight1 = Entities.addEntity({ - type: "Light", - position: { - x: 543.75, - y: 496.24, - z: 511.13 - }, - name: "Sconce 1 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight1, { - resetMe: true, - lightType: "Sconce Light Hall" - }); - - var sconceLight2 = Entities.addEntity({ - type: "Light", - position: { - x: 540.1, - y: 496.24, - z: 505.57 - }, - name: "Sconce 2 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight2, { - resetMe: true, - lightType: "Sconce Light Hall" - }); - - setEntityCustomData(this.lightStateKey, this.entityID, { - on: true - }); - - }, - - flipLights: function() { - // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); - - }, - - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - preload: function(entityID) { - this.entityID = entityID; - - //The light switch is static, so just cache its position once - this.position = Entities.getEntityProperties(this.entityID, "position").position; - var defaultLightData = { - on: false - }; - var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - - //If light is off, then we create two new lights- at the position of the sconces - if (lightState.on === false) { - this.createLights(); - this.flipLights(); - - } - //If lights are on, do nothing! - }, - }; - - // entity scripts always need to return a newly constructed object of our type - return new LightSwitchHall(); -}) diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 40cce2582c..5f93218dcb 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -111,6 +111,20 @@ function createLights() { var scriptURL = Script.resolvePath("../examples/toys/lightSwitch.js"); + var rotation = { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + var lightSwitchHall = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -121,12 +135,7 @@ function createLights() { y: 495.67999267578125, z: 511.00564575195312 }, - rotation: { - w: 0.63280689716339111, - x: 0.63280689716339111, - y: -0.31551080942153931, - z: 0.31548023223876953 - }, + rotation: rotation, dimensions: { x: 0.10546875, y: 0.032372996211051941, @@ -134,7 +143,9 @@ function createLights() { } }); setEntityCustomData(resetKey, lightSwitchHall, { - resetMe: true + resetMe: true, + on: true, + type: "Hall Light" }); var sconceLight1 = Entities.addEntity({ @@ -160,8 +171,7 @@ function createLights() { setEntityCustomData(resetKey, sconceLight1, { resetMe: true, - lightType: "Sconce Light", - on: true + type: "Hall Light", }); var sconceLight2 = Entities.addEntity({ @@ -187,26 +197,35 @@ function createLights() { setEntityCustomData(resetKey, sconceLight2, { resetMe: true, - lightType: "Sconce Light", - state: true + type: "Hall Light", }); + + rotation = { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }; + axis = { + x: 0, + y: 1, + z: 0 + }; + dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + var lightSwitchGarage = Entities.addEntity({ type: "Model", modelURL: modelURL, - name: "Light Switch Garage", + name: "Garage", script: scriptURL, position: { x: 545.62, y: 495.68, z: 500.21 }, - rotation: { - w: 0.20082402229309082, - x: 0.20082402229309082, - y: -0.67800414562225342, - z: 0.67797362804412842 - }, + rotation: rotation, dimensions: { x: 0.10546875, y: 0.032372996211051941, @@ -215,7 +234,9 @@ function createLights() { }); setEntityCustomData(resetKey, lightSwitchGarage, { - resetMe: true + resetMe: true, + on: true, + type: "Garage Light" }); @@ -245,8 +266,7 @@ function createLights() { setEntityCustomData(resetKey, sconceLight3, { resetMe: true, - lightType: "Sconce Light", - on: true + type: "Garage Light", }); var sconceLight4 = Entities.addEntity({ @@ -272,8 +292,7 @@ function createLights() { setEntityCustomData(resetKey, sconceLight4, { resetMe: true, - lightType: "Sconce Light", - on: true + type: "Garage Light", }); var sconceLight5 = Entities.addEntity({ @@ -299,8 +318,7 @@ function createLights() { setEntityCustomData(resetKey, sconceLight5, { resetMe: true, - lightType: "Sconce Light", - on: true + type: "Garage Light", }); } From 1ac1fcaf6958bfe380f96d605f2900a3aa091a50 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 2 Oct 2015 16:17:54 -0700 Subject: [PATCH 037/152] Light switches work properly now; no extra lights --- examples/toys/lightSwitch.js | 18 +++++++++++------- unpublishedScripts/masterReset.js | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/examples/toys/lightSwitch.js b/examples/toys/lightSwitch.js index 9a23a3b6d4..9494db4479 100644 --- a/examples/toys/lightSwitch.js +++ b/examples/toys/lightSwitch.js @@ -16,10 +16,11 @@ /*global LightSwitch */ (function () { + var _this; var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); - LightSwitch = function () { + _this = this; this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); } @@ -38,23 +39,27 @@ toggleLights: function () { var lightData = getEntityCustomData(this.resetKey, this.entityID, {}); - var on = lightData.on; + var on = !lightData.on; var lightType = lightData.type; var lights = Entities.findEntities(this.position, 20); lights.forEach(function (light) { - var type = getEntityCustomData(this.resetKey, light, {}).type; - if (type === lightType) { + var type = getEntityCustomData(_this.resetKey, light, {}).type; + if (type === lightType && JSON.stringify(light) !== JSON.stringify(_this.entityID)) { Entities.editEntity(light, { visible: on }); + } }); - this.flipSwitch(); + Audio.playSound(this.switchSound, { + volume: 0.5, + position: this.position + }); setEntityCustomData(this.resetKey, this.entityID, { - on: !on + on: on, type: lightType, resetMe: true }); @@ -79,7 +84,6 @@ this.resetKey = "resetMe"; //The light switch is static, so just cache its position once this.position = Entities.getEntityProperties(this.entityID, "position").position; - this.lightType = getEntityCustomData(this.resetKey, this.entityID, {}).type; } }; diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 5f93218dcb..9f4543dc8f 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -218,7 +218,7 @@ function createLights() { var lightSwitchGarage = Entities.addEntity({ type: "Model", modelURL: modelURL, - name: "Garage", + name: "Light Switch Garage", script: scriptURL, position: { x: 545.62, From 38a66bc9153498f17fe0f7b8f1e61666f853bd99 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 2 Oct 2015 16:53:13 -0700 Subject: [PATCH 038/152] syntax fixes --- examples/toys/lightSwitch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/lightSwitch.js b/examples/toys/lightSwitch.js index 9494db4479..5c47108c94 100644 --- a/examples/toys/lightSwitch.js +++ b/examples/toys/lightSwitch.js @@ -1,5 +1,5 @@ // -// lightSwitch.js.js +// lightSwitch.js // examples/entityScripts // // Created by Eric Levin on 10/2/15. @@ -22,7 +22,7 @@ LightSwitch = function () { _this = this; this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - } + }; LightSwitch.prototype = { From f618a2adfa3375a1d3d6dc62df5679df96056394 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 17:06:32 -0700 Subject: [PATCH 039/152] gak - get streaming working again --- libraries/animation/src/AnimationLoop.cpp | 13 ++--- libraries/animation/src/AnimationLoop.h | 1 - .../entities/src/AnimationPropertyGroup.cpp | 47 +++++++++++-------- .../entities/src/EntityItemProperties.cpp | 1 + libraries/entities/src/ModelEntityItem.cpp | 22 +++++++-- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 6062d71f9c..cd360a79a7 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -24,8 +24,7 @@ AnimationLoop::AnimationLoop() : _running(false), _frameIndex(0.0f), _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME), - _resetOnRunning(false), - _firstRun(true) + _resetOnRunning(false) { } @@ -38,8 +37,7 @@ AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : _lastFrame(animationDetails.lastFrame), _running(animationDetails.running), _frameIndex(animationDetails.frameIndex), - _resetOnRunning(false), - _firstRun(true) + _resetOnRunning(false) { } @@ -53,8 +51,7 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati _lastFrame(lastFrame), _running(running), _frameIndex(frameIndex), - _resetOnRunning(false), - _firstRun(true) + _resetOnRunning(false) { } @@ -94,10 +91,10 @@ void AnimationLoop::setRunning(bool running) { _running = running; // If we just set running to true, then also reset the frame to the first frame - if (running && (_resetOnRunning || _firstRun)) { + if (running && (_resetOnRunning)) { // move back to the beginning + qDebug() << "resetting _frameIndex:" << _frameIndex << "to _firstFrame:" << _firstFrame; _frameIndex = _firstFrame; - _firstRun = false; } } } diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index eb58774223..6c3df659dc 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -70,7 +70,6 @@ private: float _frameIndex; float _maxFrameIndexHint; bool _resetOnRunning; - bool _firstRun; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 47733c205d..653cf4c4f8 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -100,7 +100,8 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() value:" << value; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() url:" << getURL() << "value:" << value; + // the animations setting is a JSON string that may contain various animation settings. // if it includes fps, frameIndex, or running, those values will be parsed out and // will over ride the regular animation settings @@ -125,37 +126,37 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { if (settingsMap.contains("frameIndex")) { frameIndex = settingsMap["frameIndex"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had frameIndex"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had frameIndex:" << frameIndex; } if (settingsMap.contains("running")) { running = settingsMap["running"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had running"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had running:" << running; } if (settingsMap.contains("firstFrame")) { frameIndex = settingsMap["firstFrame"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had firstFrame"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had firstFrame:" << firstFrame; } if (settingsMap.contains("lastFrame")) { frameIndex = settingsMap["lastFrame"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had lastFrame"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had lastFrame:" << lastFrame; } if (settingsMap.contains("loop")) { running = settingsMap["loop"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had loop"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had loop:" << loop; } if (settingsMap.contains("hold")) { running = settingsMap["hold"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had hold"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had hold:" << hold; } if (settingsMap.contains("startAutomatically")) { running = settingsMap["startAutomatically"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had startAutomatically"; + qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had startAutomatically:" << startAutomatically; } if (_animationLoop) { @@ -182,7 +183,9 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { void AnimationPropertyGroup::debugDump() const { qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; - qDebug() << " URL:" << getURL() << " has changed:" << urlChanged(); + qDebug() << " url:" << getURL() << " has changed:" << urlChanged(); + qDebug() << " fps:" << getFPS() << " has changed:" << fpsChanged(); + qDebug() << "frameIndex:" << getFrameIndex() << " has changed:" << frameIndexChanged(); } bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, @@ -377,15 +380,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); if (_animationLoop) { - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); - } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); @@ -395,6 +389,16 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); } + else { + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); + } } int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, @@ -410,7 +414,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char if (_animationLoop) { // apply new properties to our associated AnimationLoop - //qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; + qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); @@ -420,6 +424,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { + qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- NO AnimationLoop store locally"; READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); @@ -430,6 +435,10 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } + if (_animationLoop) { + qDebug() << "_animationLoop->isRunning():" << _animationLoop->isRunning(); + } + return bytesRead; } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8b4d4660bf..cdd6c5b2ca 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -176,6 +176,7 @@ void EntityItemProperties::debugDump() const { qCDebug(entities) << " _modelURL=" << _modelURL; qCDebug(entities) << " _compoundShapeURL=" << _compoundShapeURL; + getAnimation().debugDump(); getAtmosphere().debugDump(); getSkybox().debugDump(); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index e2111fb9c1..f7b4e014db 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -49,6 +49,8 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class + //qDebug() << "ModelEntityItem::getProperties() id:" << getEntityItemID(); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL); @@ -58,6 +60,8 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP _animationProperties.getProperties(properties); + //properties.debugDump(); + return properties; } @@ -73,7 +77,11 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "modelURL:" << getModelURL(); + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "calling _animationProperties.setProperties()"; bool somethingChangedInAnimations = _animationProperties.setProperties(properties); + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "AFTER _animationProperties.setProperties() running:" << _animationLoop.getRunning(); + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "AFTER _animationProperties.setProperties() frameIndex:" << _animationLoop.getFrameIndex(); somethingChanged = somethingChanged || somethingChangedInAnimations; @@ -102,17 +110,15 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); if (args.bitstreamVersion < VERSION_ENTITIES_HAS_COLLISION_MODEL) { setCompoundShapeURL(""); - } else if (args.bitstreamVersion == VERSION_ENTITIES_HAS_COLLISION_MODEL) { - READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); } else { READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); } - READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setAnimationURL); // Because we're using AnimationLoop which will reset the frame index if you change it's running state // we want to read these values in the order they appear in the buffer, but call our setters in an // order that allows AnimationLoop to preserve the correct frame rate. if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { + READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setAnimationURL); READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); @@ -135,6 +141,9 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); + qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer()"; + debugDump(); + return bytesRead; } @@ -278,7 +287,9 @@ void ModelEntityItem::update(const quint64& now) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; _lastAnimated = now; _animationLoop.simulate(deltaTime); - } else { + //qDebug() << "ModelEntityItem::update() id:" << getEntityItemID() << "frameIndex:" << _animationLoop.getFrameIndex(); + } + else { _lastAnimated = now; } EntityItem::update(now); // let our base class handle it's updates... @@ -290,7 +301,8 @@ void ModelEntityItem::debugDump() const { qCDebug(entities) << " position:" << getPosition(); qCDebug(entities) << " dimensions:" << getDimensions(); qCDebug(entities) << " model URL:" << getModelURL(); - qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); + qCDebug(entities) << " _animationLoop.isRunning():" << _animationLoop.isRunning(); + //qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); } void ModelEntityItem::updateShapeType(ShapeType type) { From 68dc30360322f4b375ebfcda87f40a792789a3ad Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 17:12:03 -0700 Subject: [PATCH 040/152] remove debug --- .../entities/src/AnimationPropertyGroup.cpp | 42 +------------------ libraries/entities/src/ModelEntityItem.cpp | 22 +--------- 2 files changed, 2 insertions(+), 62 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 653cf4c4f8..7108f3a4cd 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -33,8 +33,6 @@ CONSTRUCT_PROPERTY(startAutomatically, false) void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); - //qDebug() << "AnimationPropertyGroup::copyToScriptValue() url:" << getURL(); - if (_animationLoop) { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex, _animationLoop->getFPS); @@ -64,8 +62,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationURL, QString, setURL, getURL); COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(animationSettings, QString, setFromOldAnimationSettings); - //qDebug() << "AnimationPropertyGroup::copyFromScriptValue() url:" << getURL(); - if (_animationLoop) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, _animationLoop->setFPS); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, _animationLoop->setFrameIndex); @@ -99,9 +95,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo } void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { - - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() url:" << getURL() << "value:" << value; - // the animations setting is a JSON string that may contain various animation settings. // if it includes fps, frameIndex, or running, those values will be parsed out and // will over ride the regular animation settings @@ -121,42 +114,34 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { if (settingsMap.contains("fps")) { fps = settingsMap["fps"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had fps:" << fps; } if (settingsMap.contains("frameIndex")) { frameIndex = settingsMap["frameIndex"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had frameIndex:" << frameIndex; } if (settingsMap.contains("running")) { running = settingsMap["running"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had running:" << running; } if (settingsMap.contains("firstFrame")) { frameIndex = settingsMap["firstFrame"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had firstFrame:" << firstFrame; } if (settingsMap.contains("lastFrame")) { frameIndex = settingsMap["lastFrame"].toFloat(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had lastFrame:" << lastFrame; } if (settingsMap.contains("loop")) { running = settingsMap["loop"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had loop:" << loop; } if (settingsMap.contains("hold")) { running = settingsMap["hold"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had hold:" << hold; } if (settingsMap.contains("startAutomatically")) { running = settingsMap["startAutomatically"].toBool(); - qDebug() << "AnimationPropertyGroup::setFromOldAnimationSettings() had startAutomatically:" << startAutomatically; } if (_animationLoop) { @@ -198,9 +183,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); - - //qDebug() << "AnimationPropertyGroup::appendToEditPacket() url:" << getURL(); - if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); @@ -232,8 +214,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - //qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() url:" << getURL(); - if (_animationLoop) { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); @@ -294,9 +274,6 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) const { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); - - //qDebug() << "AnimationPropertyGroup::getProperties() url:" << getURL(); - if (_animationLoop) { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, _animationLoop->getFPS); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, _animationLoop->getFrameIndex); @@ -322,12 +299,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie bool somethingChanged = false; SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); - - //qDebug() << "AnimationPropertyGroup::setProperties() url:" << getURL(); - if (_animationLoop) { - //qDebug() << "AnimationPropertyGroup::setProperties() -- apply new properties to our associated AnimationLoop"; - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, _animationLoop->setFPS); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, _animationLoop->setFrameIndex); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, _animationLoop->setRunning); @@ -376,8 +348,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En bool successPropertyFits = true; - //qDebug() << "AnimationPropertyGroup::appendSubclassData() url:" << getURL(); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); @@ -388,8 +358,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, _animationLoop->getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); - } - else { + } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); @@ -410,11 +379,8 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); - //qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() url:" << getURL(); - if (_animationLoop) { // apply new properties to our associated AnimationLoop - qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- apply new properties to our associated AnimationLoop"; READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); @@ -424,7 +390,6 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, _animationLoop->setHold); READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { - qDebug() << "AnimationPropertyGroup::readEntitySubclassDataFromBuffer() -- NO AnimationLoop store locally"; READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); @@ -435,10 +400,5 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } - if (_animationLoop) { - qDebug() << "_animationLoop->isRunning():" << _animationLoop->isRunning(); - } - - return bytesRead; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index f7b4e014db..ef8ddbead6 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -48,26 +48,17 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class - - //qDebug() << "ModelEntityItem::getProperties() id:" << getEntityItemID(); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(modelURL, getModelURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType); - _animationProperties.getProperties(properties); - - //properties.debugDump(); - return properties; } bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID(); - bool somethingChanged = false; somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class @@ -77,12 +68,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "modelURL:" << getModelURL(); - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "calling _animationProperties.setProperties()"; bool somethingChangedInAnimations = _animationProperties.setProperties(properties); - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "AFTER _animationProperties.setProperties() running:" << _animationLoop.getRunning(); - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << "AFTER _animationProperties.setProperties() frameIndex:" << _animationLoop.getFrameIndex(); - somethingChanged = somethingChanged || somethingChangedInAnimations; if (somethingChanged) { @@ -140,10 +126,6 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); - - qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer()"; - debugDump(); - return bytesRead; } @@ -287,9 +269,7 @@ void ModelEntityItem::update(const quint64& now) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; _lastAnimated = now; _animationLoop.simulate(deltaTime); - //qDebug() << "ModelEntityItem::update() id:" << getEntityItemID() << "frameIndex:" << _animationLoop.getFrameIndex(); - } - else { + } else { _lastAnimated = now; } EntityItem::update(now); // let our base class handle it's updates... From eb9078bda5cdfac683b6a04102235440952ee4ba Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 17:27:45 -0700 Subject: [PATCH 041/152] cleanup --- .../entities/src/AnimationPropertyGroup.h | 6 +++-- libraries/entities/src/ModelEntityItem.cpp | 23 +------------------ libraries/entities/src/ModelEntityItem.h | 8 +------ .../entities/src/ParticleEffectEntityItem.cpp | 7 +++--- 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index fa12d8f279..5541e49840 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -15,14 +15,16 @@ // DONE - 2) rename the group animationSettings // DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly // 4) test it! -// a) toybox/windmill +// DONE - a) toybox/windmill // b) toybox "put me down" doll // c) asana bugs about animations // // DONE - 5) update all scripts // DONE - 6) remove all remnants of old member variables // DONE - 7) research and remove animation settings from Particle Effect -// 8) make sure animations start properly when entering a domain... with previously running animations +// DONE - 8) make sure animations start properly when entering a domain... with previously running animations +// 9) test particles!!! +// #ifndef hifi_AnimationPropertyGroup_h #define hifi_AnimationPropertyGroup_h diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index ef8ddbead6..a23279a72f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -22,11 +22,6 @@ const QString ModelEntityItem::DEFAULT_MODEL_URL = QString(""); const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString(""); -const QString ModelEntityItem::DEFAULT_ANIMATION_URL = QString(""); -const float ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; -const bool ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; -const float ModelEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; - EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { return std::make_shared(entityID, properties); @@ -157,7 +152,6 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); - // FIXME - we probably need to make sure the _animationProperties has the latest data from the AnimationLoop _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); @@ -281,8 +275,7 @@ void ModelEntityItem::debugDump() const { qCDebug(entities) << " position:" << getPosition(); qCDebug(entities) << " dimensions:" << getDimensions(); qCDebug(entities) << " model URL:" << getModelURL(); - qCDebug(entities) << " _animationLoop.isRunning():" << _animationLoop.isRunning(); - //qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); + qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); } void ModelEntityItem::updateShapeType(ShapeType type) { @@ -324,19 +317,6 @@ void ModelEntityItem::setAnimationURL(const QString& url) { _animationProperties.setURL(url); } -void ModelEntityItem::setAnimationFrameIndex(float value) { -#ifdef WANT_DEBUG - if (isAnimatingSomething()) { - qCDebug(entities) << "ModelEntityItem::setAnimationFrameIndex()"; - qCDebug(entities) << " value:" << value; - qCDebug(entities) << " was:" << _animationLoop.getFrameIndex(); - qCDebug(entities) << " model URL:" << getModelURL(); - qCDebug(entities) << " animation URL:" << getAnimationURL(); - } -#endif - _animationLoop.setFrameIndex(value); -} - void ModelEntityItem::setAnimationSettings(const QString& value) { // the animations setting is a JSON string that may contain various animation settings. // if it includes fps, frameIndex, or running, those values will be parsed out and @@ -398,7 +378,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { setAnimationStartAutomatically(startAutomatically); } - //_animationSettings = value; _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index b677de22cc..66f102fe7a 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -81,17 +81,11 @@ public: const AnimationPropertyGroup& getAnimationProperties() const { return _animationProperties; } bool hasAnimation() const { return !_animationProperties.getURL().isEmpty(); } - static const QString DEFAULT_ANIMATION_URL; const QString& getAnimationURL() const { return _animationProperties.getURL(); } void setAnimationURL(const QString& url); - static const float DEFAULT_ANIMATION_FRAME_INDEX; - void setAnimationFrameIndex(float value); - - static const bool DEFAULT_ANIMATION_IS_PLAYING; + void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); } void setAnimationIsPlaying(bool value); - - static const float DEFAULT_ANIMATION_FPS; void setAnimationFPS(float value); void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 6023db56e1..421565fc84 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -52,9 +52,6 @@ const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = DEFAULT_ALPHA; const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = DEFAULT_ALPHA; -//const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; -//const bool ParticleEffectEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; -//const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; @@ -264,6 +261,8 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float); SKIP_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool); SKIP_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString); + } else { + READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting); } READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); @@ -333,6 +332,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_SHAPE_TYPE; requestedProperties += PROP_MAX_PARTICLES; requestedProperties += PROP_LIFESPAN; + requestedProperties += PROP_EMITTING_PARTICLES; requestedProperties += PROP_EMIT_RATE; requestedProperties += PROP_EMIT_ACCELERATION; requestedProperties += PROP_ACCELERATION_SPREAD; @@ -371,6 +371,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor()); + APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, getIsEmitting()); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan()); From edaa8f998a340384ca3319d21f0d29520e41f87a Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 2 Oct 2015 18:12:16 -0700 Subject: [PATCH 042/152] Migrating to the new mesh for rendering and having problems with multi part mesh --- libraries/fbx/src/FBXReader.h | 1 + libraries/fbx/src/FBXReader_Mesh.cpp | 72 ++++++++--- libraries/gpu/src/gpu/GLBackendInput.cpp | 2 +- .../src/model-networking/ModelCache.cpp | 119 ------------------ .../src/model-networking/ModelCache.h | 4 +- libraries/render-utils/src/Model.cpp | 52 ++++---- 6 files changed, 87 insertions(+), 163 deletions(-) diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index ab0bfeacf1..3bb0545e78 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -123,6 +123,7 @@ class FBXMeshPart { public: QVector quadIndices; // original indices from the FBX mesh + QVector quadTrianglesIndices; // original indices from the FBX mesh of the quad converted has triangles QVector triangleIndices; // original indices from the FBX mesh mutable gpu::BufferPointer mergedTrianglesIndicesBuffer; // both the quads and the triangles merged into a single set of triangles diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 299968d663..2754fc5d67 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -348,6 +348,28 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn appendIndex(data, part.quadIndices, beginIndex++); appendIndex(data, part.quadIndices, beginIndex++); appendIndex(data, part.quadIndices, beginIndex++); + + int quadStartIndex = part.quadIndices.size() - 4; + int i0 = part.quadIndices[quadStartIndex + 0]; + int i1 = part.quadIndices[quadStartIndex + 1]; + int i2 = part.quadIndices[quadStartIndex + 2]; + int i3 = part.quadIndices[quadStartIndex + 3]; + + // Sam's recommended triangle slices + // Triangle tri1 = { v0, v1, v3 }; + // Triangle tri2 = { v1, v2, v3 }; + // NOTE: Random guy on the internet's recommended triangle slices + // Triangle tri1 = { v0, v1, v2 }; + // Triangle tri2 = { v2, v3, v0 }; + + part.quadTrianglesIndices.append(i0); + part.quadTrianglesIndices.append(i1); + part.quadTrianglesIndices.append(i3); + + part.quadTrianglesIndices.append(i1); + part.quadTrianglesIndices.append(i2); + part.quadTrianglesIndices.append(i3); + } else { for (int nextIndex = beginIndex + 1;; ) { appendIndex(data, part.triangleIndices, beginIndex); @@ -369,11 +391,22 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); + unsigned int totalSourceIndices = 0; + foreach(const FBXMeshPart& part, extracted.mesh.parts) { + totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); + } + + if (!totalSourceIndices) { + qCDebug(modelformat) << "buildModelMesh failed -- no indices, url = " << url; + return; + } + if (extracted.mesh.vertices.size() == 0) { extracted.mesh._mesh; qCDebug(modelformat) << "buildModelMesh failed -- no vertices, url = " << url; return; } + FBXMesh& fbxMesh = extracted.mesh; model::MeshPointer mesh(new model::Mesh()); @@ -456,9 +489,8 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { unsigned int totalIndices = 0; - foreach(const FBXMeshPart& part, extracted.mesh.parts) { - totalIndices += (part.quadIndices.size() + part.triangleIndices.size()); + totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); } if (! totalIndices) { @@ -473,24 +505,34 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { int offset = 0; std::vector< model::Mesh::Part > parts; - + if (extracted.mesh.parts.size() > 1) { + indexNum = 0; + } foreach(const FBXMeshPart& part, extracted.mesh.parts) { - model::Mesh::Part quadPart(indexNum, part.quadIndices.size(), 0, model::Mesh::QUADS); - if (quadPart._numIndices) { - parts.push_back(quadPart); - ib->setSubData(offset, part.quadIndices.size() * sizeof(int), - (gpu::Byte*) part.quadIndices.constData()); - offset += part.quadIndices.size() * sizeof(int); - indexNum += part.quadIndices.size(); + model::Mesh::Part modelPart(indexNum, 0, 0, model::Mesh::TRIANGLES); + if (part.quadTrianglesIndices.size()) { + + + ib->setSubData( offset, + part.quadTrianglesIndices.size() * sizeof(int), + (gpu::Byte*) part.quadTrianglesIndices.constData()); + offset += part.quadTrianglesIndices.size() * sizeof(int); + indexNum += part.quadTrianglesIndices.size(); + modelPart._numIndices += part.quadTrianglesIndices.size(); } - model::Mesh::Part triPart(indexNum, part.triangleIndices.size(), 0, model::Mesh::TRIANGLES); - if (triPart._numIndices) { - parts.push_back(triPart); - ib->setSubData(offset, part.triangleIndices.size() * sizeof(int), - (gpu::Byte*) part.triangleIndices.constData()); + // model::Mesh::Part triPart(indexNum, part.triangleIndices.size(), 0, model::Mesh::TRIANGLES); + + if (part.triangleIndices.size()) { + // parts.push_back(triPart); + ib->setSubData( offset, + part.triangleIndices.size() * sizeof(int), + (gpu::Byte*) part.triangleIndices.constData()); offset += part.triangleIndices.size() * sizeof(int); indexNum += part.triangleIndices.size(); + modelPart._numIndices += part.triangleIndices.size(); } + + parts.push_back(modelPart); } gpu::BufferView ibv(ib, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ)); diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index a70e91d7fa..5cdcf0adc6 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -315,7 +315,7 @@ void GLBackend::do_setIndirectBuffer(Batch& batch, uint32 paramOffset) { glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferID(*buffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); } } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index d8b53420a4..c7d3523496 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -266,126 +266,9 @@ void NetworkGeometry::modelRequestError(QNetworkReply::NetworkError error) { } static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBaseUrl) { - auto textureCache = DependencyManager::get(); NetworkMesh* networkMesh = new NetworkMesh(); networkMesh->_mesh = mesh._mesh; - int totalIndices = 0; - //bool checkForTexcoordLightmap = false; - - - - // process network parts - foreach (const FBXMeshPart& part, mesh.parts) { - totalIndices += (part.quadIndices.size() + part.triangleIndices.size()); - } - - // initialize index buffer - { - networkMesh->_indexBuffer = std::make_shared(); - networkMesh->_indexBuffer->resize(totalIndices * sizeof(int)); - int offset = 0; - foreach(const FBXMeshPart& part, mesh.parts) { - networkMesh->_indexBuffer->setSubData(offset, part.quadIndices.size() * sizeof(int), - (gpu::Byte*) part.quadIndices.constData()); - offset += part.quadIndices.size() * sizeof(int); - networkMesh->_indexBuffer->setSubData(offset, part.triangleIndices.size() * sizeof(int), - (gpu::Byte*) part.triangleIndices.constData()); - offset += part.triangleIndices.size() * sizeof(int); - } - } - - // initialize vertex buffer - { - networkMesh->_vertexBuffer = std::make_shared(); - // if we don't need to do any blending, the positions/normals can be static - if (mesh.blendshapes.isEmpty()) { - int normalsOffset = mesh.vertices.size() * sizeof(glm::vec3); - int tangentsOffset = normalsOffset + mesh.normals.size() * sizeof(glm::vec3); - int colorsOffset = tangentsOffset + mesh.tangents.size() * sizeof(glm::vec3); - int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3); - int texCoords1Offset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2); - int clusterIndicesOffset = texCoords1Offset + mesh.texCoords1.size() * sizeof(glm::vec2); - int clusterWeightsOffset = clusterIndicesOffset + mesh.clusterIndices.size() * sizeof(glm::vec4); - - networkMesh->_vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4)); - - networkMesh->_vertexBuffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.vertices.constData()); - networkMesh->_vertexBuffer->setSubData(normalsOffset, mesh.normals.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.normals.constData()); - networkMesh->_vertexBuffer->setSubData(tangentsOffset, - mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData()); - networkMesh->_vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData()); - networkMesh->_vertexBuffer->setSubData(texCoordsOffset, - mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData()); - networkMesh->_vertexBuffer->setSubData(texCoords1Offset, - mesh.texCoords1.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords1.constData()); - networkMesh->_vertexBuffer->setSubData(clusterIndicesOffset, - mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData()); - networkMesh->_vertexBuffer->setSubData(clusterWeightsOffset, - mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData()); - - // otherwise, at least the cluster indices/weights can be static - networkMesh->_vertexStream = std::make_shared(); - networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, 0, sizeof(glm::vec3)); - if (mesh.normals.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, normalsOffset, sizeof(glm::vec3)); - if (mesh.tangents.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, tangentsOffset, sizeof(glm::vec3)); - if (mesh.colors.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3)); - if (mesh.texCoords.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2)); - if (mesh.texCoords1.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoords1Offset, sizeof(glm::vec2)); - if (mesh.clusterIndices.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4)); - if (mesh.clusterWeights.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4)); - - int channelNum = 0; - networkMesh->_vertexFormat = std::make_shared(); - networkMesh->_vertexFormat->setAttribute(gpu::Stream::POSITION, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - if (mesh.normals.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB)); - if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - if (mesh.texCoords1.size()) { - networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - // } else if (checkForTexcoordLightmap && mesh.texCoords.size()) { - } else if (mesh.texCoords.size()) { - // need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel - networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - } - if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW)); - if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW)); - } - else { - int colorsOffset = mesh.tangents.size() * sizeof(glm::vec3); - int texCoordsOffset = colorsOffset + mesh.colors.size() * sizeof(glm::vec3); - int clusterIndicesOffset = texCoordsOffset + mesh.texCoords.size() * sizeof(glm::vec2); - int clusterWeightsOffset = clusterIndicesOffset + mesh.clusterIndices.size() * sizeof(glm::vec4); - - networkMesh->_vertexBuffer->resize(clusterWeightsOffset + mesh.clusterWeights.size() * sizeof(glm::vec4)); - networkMesh->_vertexBuffer->setSubData(0, mesh.tangents.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.tangents.constData()); - networkMesh->_vertexBuffer->setSubData(colorsOffset, mesh.colors.size() * sizeof(glm::vec3), (gpu::Byte*) mesh.colors.constData()); - networkMesh->_vertexBuffer->setSubData(texCoordsOffset, - mesh.texCoords.size() * sizeof(glm::vec2), (gpu::Byte*) mesh.texCoords.constData()); - networkMesh->_vertexBuffer->setSubData(clusterIndicesOffset, - mesh.clusterIndices.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterIndices.constData()); - networkMesh->_vertexBuffer->setSubData(clusterWeightsOffset, - mesh.clusterWeights.size() * sizeof(glm::vec4), (gpu::Byte*) mesh.clusterWeights.constData()); - - networkMesh->_vertexStream = std::make_shared(); - if (mesh.tangents.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, 0, sizeof(glm::vec3)); - if (mesh.colors.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, colorsOffset, sizeof(glm::vec3)); - if (mesh.texCoords.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, texCoordsOffset, sizeof(glm::vec2)); - if (mesh.clusterIndices.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterIndicesOffset, sizeof(glm::vec4)); - if (mesh.clusterWeights.size()) networkMesh->_vertexStream->addBuffer(networkMesh->_vertexBuffer, clusterWeightsOffset, sizeof(glm::vec4)); - - int channelNum = 0; - networkMesh->_vertexFormat = std::make_shared(); - networkMesh->_vertexFormat->setAttribute(gpu::Stream::POSITION, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - if (mesh.normals.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::NORMAL, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - if (mesh.tangents.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - if (mesh.colors.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB)); - if (mesh.texCoords.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - if (mesh.clusterIndices.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW)); - if (mesh.clusterWeights.size()) networkMesh->_vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW)); - } - } return networkMesh; } @@ -394,8 +277,6 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const auto textureCache = DependencyManager::get(); NetworkMaterial* networkMaterial = new NetworkMaterial(); - //bool checkForTexcoordLightmap = false; - networkMaterial->_material = material._material; if (!material.diffuseTexture.filename.isEmpty()) { diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 4067bed122..b53ea18874 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -193,12 +193,12 @@ class NetworkMesh { public: model::MeshPointer _mesh; - gpu::BufferPointer _indexBuffer; +/* gpu::BufferPointer _indexBuffer; gpu::BufferPointer _vertexBuffer; gpu::BufferStreamPointer _vertexStream; gpu::Stream::FormatPointer _vertexFormat; -}; +*/}; #endif // hifi_GeometryCache_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 872592a9a4..44484131d9 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -759,17 +759,27 @@ public: int partIndex; int _shapeID; - render::Item::Bound getBound() const { - if (_isBoundInvalid) { - model->getPartBounds(meshIndex, partIndex); - _isBoundInvalid = false; - } - return _bound; - } + // Render Item interface + render::Item::Bound getBound() const; + void render(RenderArgs* args) const; + + mutable render::Item::Bound _bound; mutable bool _isBoundInvalid = true; }; + +render::Item::Bound MeshPartPayload::getBound() const { + if (_isBoundInvalid) { + model->getPartBounds(meshIndex, partIndex); + _isBoundInvalid = false; + } + return _bound; +} +void MeshPartPayload::render(RenderArgs* args) const { + return model->renderPart(args, meshIndex, partIndex, _shapeID); +} + namespace render { template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { if (!payload->model->isVisible()) { @@ -794,14 +804,12 @@ namespace render { template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { if (payload) { - return payload->getBound(); // model->getPartBounds(payload->meshIndex, payload->partIndex); + return payload->getBound(); } return render::Item::Bound(); } template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { - if (args) { - return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, payload->_shapeID); - } + return payload->render(args); } /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { @@ -1560,20 +1568,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape } batch.setModelTransform(_transforms[0]); + auto drawPart = drawMesh->getPartBuffer().get(partIndex); + if (mesh.blendshapes.isEmpty()) { - // Assign index buffer: batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); - + batch.setInputFormat((drawMesh->getVertexFormat())); auto inputStream = drawMesh->makeBufferStream(); batch.setInputStream(0, inputStream); - - // batch.setInputFormat(networkMesh._vertexFormat); - // batch.setInputStream(0, *networkMesh._vertexStream); } else { - batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((drawMesh->getVertexFormat())); batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); @@ -1582,12 +1587,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2); batch.setInputStream(2, inputStream); - - /* batch.setInputFormat(networkMesh._vertexFormat); - - batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); - batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); - batch.setInputStream(2, *networkMesh._vertexStream);*/ } if (mesh.colors.isEmpty()) { @@ -1712,8 +1711,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape { PerformanceTimer perfTimer("batch.drawIndexed()"); - batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); - batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + // part.getMergedTriangles(); + // part.mergedTrianglesIndicesCount; + batch.drawIndexed(gpu::TRIANGLES, drawPart._numIndices, drawPart._startIndex); } /* batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); From accdd8c86afd57ad97a681882e35a14d89db804e Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 2 Oct 2015 19:15:24 -0700 Subject: [PATCH 043/152] add animation properties to edit properties --- examples/html/entityProperties.html | 46 +++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 40b94c2eb2..5743d65ed0 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -282,6 +282,11 @@ var elModelAnimationPlaying = document.getElementById("property-model-animation-playing"); var elModelAnimationFPS = document.getElementById("property-model-animation-fps"); var elModelAnimationFrame = document.getElementById("property-model-animation-frame"); + var elModelAnimationFirstFrame = document.getElementById("property-model-animation-first-frame"); + var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame"); + var elModelAnimationLoop = document.getElementById("property-model-animation-loop"); + var elModelAnimationHold = document.getElementById("property-model-animation-hold"); + var elModelAnimationStartAutomatically = document.getElementById("property-model-animation-start-automatically"); var elModelTextures = document.getElementById("property-model-textures"); var elModelOriginalTextures = document.getElementById("property-model-original-textures"); @@ -509,6 +514,11 @@ elModelAnimationPlaying.checked = properties.animation.running; elModelAnimationFPS.value = properties.animation.fps; elModelAnimationFrame.value = properties.animation.frameIndex; + elModelAnimationFirstFrame.value = properties.animation.firstFrame; + elModelAnimationLastFrame.value = properties.animation.lastFrame; + elModelAnimationLoop.checked = properties.animation.loop; + elModelAnimationHold.checked = properties.animation.hold; + elModelAnimationStartAutomatically.checked = properties.animation.startAutomatically; elModelTextures.value = properties.textures; elModelOriginalTextures.value = properties.originalTextures; } else if (properties.type == "Web") { @@ -758,7 +768,13 @@ elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url')); elModelAnimationPlaying.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation','running')); elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','fps')); - elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','frameIndex')); + elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'frameIndex')); + elModelAnimationFirstFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'firstFrame')); + elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame')); + elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop')); + elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold')); + elModelAnimationStartAutomatically.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'startAutomatically')); + elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text')); @@ -1278,11 +1294,35 @@
-
Animation Settings
+
Animation First Frame
- +
+
+
Animation Last Frame
+
+ +
+
+
+ Animation Loop + + + +
+
+ Animation Hold + + + +
+
+ Animation Start Automatically + + + +
Textures
From 2720e6ddf4b0bec61ef44ca0410aaaaf3ce4e5c7 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 3 Oct 2015 08:00:33 -0700 Subject: [PATCH 044/152] debug running property --- .../entities/src/AnimationPropertyGroup.cpp | 39 +++++++++++++++++++ .../entities/src/AnimationPropertyGroup.h | 6 ++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 7108f3a4cd..29b134235a 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -92,6 +92,13 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setFrameIndex, getFrameIndex); } + + if (_animationLoop) { + qDebug() << "copyFromScriptValue() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "copyFromScriptValue() running:" << getRunning(); + } + } void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { @@ -203,6 +210,13 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } + if (_animationLoop) { + qDebug() << "appendToEditPacket() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "appendToEditPacket() running:" << getRunning(); + } + + return true; } @@ -246,6 +260,12 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF processedBytes += bytesRead; + if (_animationLoop) { + qDebug() << "decodeFromEditPacket() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "decodeFromEditPacket() running:" << getRunning(); + } + return true; } @@ -319,6 +339,12 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } + if (_animationLoop) { + qDebug() << "setProperties() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "setProperties() running:" << getRunning(); + } + return somethingChanged; } @@ -368,6 +394,13 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } + + if (_animationLoop) { + qDebug() << "appendSubclassData() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "appendSubclassData() running:" << getRunning(); + } + } int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, @@ -400,5 +433,11 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } + if (_animationLoop) { + qDebug() << "readEntitySubclassDataFromBuffer() running:" << _animationLoop->getRunning(); + } else { + qDebug() << "readEntitySubclassDataFromBuffer() running:" << getRunning(); + } + return bytesRead; } diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 5541e49840..5612c1a99e 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -16,14 +16,16 @@ // DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly // 4) test it! // DONE - a) toybox/windmill -// b) toybox "put me down" doll +// DONE - b) toybox "put me down" doll // c) asana bugs about animations +// d) spray paint can (particles) +// e) grenade // // DONE - 5) update all scripts // DONE - 6) remove all remnants of old member variables // DONE - 7) research and remove animation settings from Particle Effect // DONE - 8) make sure animations start properly when entering a domain... with previously running animations -// 9) test particles!!! +// 9) debug running property // #ifndef hifi_AnimationPropertyGroup_h From 8befade007bd18c47db4ee3487e6828fe6f0bd88 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sun, 4 Oct 2015 15:08:35 +0200 Subject: [PATCH 045/152] expose position and orientation of HMD to Javascript. - HMD.orientation - HMD.position --- interface/src/scripting/HMDScriptingInterface.cpp | 14 ++++++++++++++ interface/src/scripting/HMDScriptingInterface.h | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 68ac511eaf..4629ff5917 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -57,3 +57,17 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* conte float HMDScriptingInterface::getIPD() const { return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); } + +glm::vec3 HMDScriptingInterface::getPosition() const { + if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + return glm::vec3(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()[3]); + } + return glm::vec3(); +} + +glm::quat HMDScriptingInterface::getOrientation() const { + if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + return glm::quat_cast(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()); + } + return glm::quat(); +} diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 82b444abaa..1ac524d7f1 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -20,6 +20,8 @@ class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) + Q_PROPERTY(glm::vec3 position READ getPosition) + Q_PROPERTY(glm::quat orientation READ getOrientation) Q_PROPERTY(float ipd READ getIPD) public: static HMDScriptingInterface& getInstance(); @@ -36,6 +38,12 @@ private: bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } float getIPD() const; + // Get the position of the HMD + glm::vec3 getPosition() const; + + // Get the orientation of the HMD + glm::quat getOrientation() const; + bool getHUDLookAtPosition3D(glm::vec3& result) const; }; From 6f86b0f5507a2dab8e43e07d620a767f5a5ff832 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 4 Oct 2015 15:23:17 -0700 Subject: [PATCH 046/152] particle fixes --- examples/particles.js | 9 +++++---- libraries/entities/src/ParticleEffectEntityItem.cpp | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/particles.js b/examples/particles.js index adfed2cf11..a46baf2dea 100644 --- a/examples/particles.js +++ b/examples/particles.js @@ -11,7 +11,7 @@ gravity: { x: 0, y: 0, z: 0 }, visible: true, locked: false, - lifetime: 6000 }); + lifetime: 6000}); var self = this; this.timer = Script.setInterval(function () { var colorProp = { color: { red: Math.random() * 255, @@ -36,7 +36,8 @@ isEmitting: true, position: spawnPoint, dimensions: {x: 2, y: 2, z: 2}, - emitSpeed: 5, + emitSpeed: 0.05, + maxParticles: 2, speedSpread: 2, polarFinish: 30 * DEG_TO_RAD, emitAcceleration: {x: 0, y: -9.8, z: 0}, @@ -52,8 +53,8 @@ this.timer = Script.setInterval(function () { // flip is playing state self.isPlaying = !self.isPlaying; - var animProp = { animationIsPlaying: self.isPlaying }; - Entities.editEntity(self.entity, animProp); + var emittingProp = { isEmitting: self.isPlaying }; + Entities.editEntity(self.entity, emittingProp); }, (1 / blinkRate) * 1000); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 421565fc84..ace0edb0e1 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -403,8 +403,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, bool ParticleEffectEntityItem::isEmittingParticles() const { // keep emitting if there are particles still alive. - //return (getAnimationIsPlaying() || getLivingParticleCount() > 0) && getAnimationFPS() != 0.0f; - return (getLivingParticleCount() > 0); + return (getIsEmitting() || getLivingParticleCount() > 0); } bool ParticleEffectEntityItem::needsToCallUpdate() const { From 48416262a1fcaaeeb4ea70a357423cba6b6c71b6 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 4 Oct 2015 18:31:19 -0700 Subject: [PATCH 047/152] Migrated the FBXReader mesh code to use excusively the Model::mesh and use them directly for rendering in the ModelPartPayload, fixed a bug in the indexBUffer offset value used in drawIndexed and drawIndexedInstanced --- libraries/fbx/src/FBXReader.cpp | 72 ---------------------------- libraries/fbx/src/FBXReader.h | 22 ++++----- libraries/fbx/src/FBXReader_Mesh.cpp | 22 +++------ libraries/gpu/src/gpu/GLBackend.cpp | 14 ++++-- libraries/gpu/src/gpu/GLBackend.h | 2 +- libraries/render-utils/src/Model.cpp | 9 +--- 6 files changed, 28 insertions(+), 113 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index d6ec59499d..9dd5030244 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -264,78 +264,6 @@ void appendModelIDs(const QString& parentID, const QMultiHash& } } - -gpu::BufferPointer FBXMeshPart::getMergedTriangles() const { - // if we've been asked for our triangulation of the original quads, but we don't yet have them - // then create them now. - if (!mergedTrianglesAvailable) { - mergedTrianglesAvailable = true; - - mergedTrianglesIndicesBuffer = std::make_shared(); - - // QVector quadIndices; // original indices from the FBX mesh - QVector mergedTrianglesIndices; // triangle versions of quads converted when first needed - const int INDICES_PER_ORIGINAL_TRIANGLE = 3; - const int INDICES_PER_ORIGINAL_QUAD = 4; - const int INDICES_PER_TRIANGULATED_QUAD = 6; - int numberOfQuads = quadIndices.size() / INDICES_PER_ORIGINAL_QUAD; - int numberOfTriangles = triangleIndices.size() / INDICES_PER_ORIGINAL_TRIANGLE; - int mergedNumberOfIndices = (numberOfQuads * INDICES_PER_TRIANGULATED_QUAD) + triangleIndices.size(); - - // resized our merged indices to be enough room for our triangulated quads and our original triangles - mergedTrianglesIndices.resize(mergedNumberOfIndices); - - int originalIndex = 0; - int triangulatedIndex = 0; - - // triangulate our quads - for (int fromQuad = 0; fromQuad < numberOfQuads; fromQuad++) { - int i0 = quadIndices[originalIndex + 0]; - int i1 = quadIndices[originalIndex + 1]; - int i2 = quadIndices[originalIndex + 2]; - int i3 = quadIndices[originalIndex + 3]; - - // Sam's recommended triangle slices - // Triangle tri1 = { v0, v1, v3 }; - // Triangle tri2 = { v1, v2, v3 }; - // NOTE: Random guy on the internet's recommended triangle slices - // Triangle tri1 = { v0, v1, v2 }; - // Triangle tri2 = { v2, v3, v0 }; - - mergedTrianglesIndices[triangulatedIndex + 0] = i0; - mergedTrianglesIndices[triangulatedIndex + 1] = i1; - mergedTrianglesIndices[triangulatedIndex + 2] = i3; - - mergedTrianglesIndices[triangulatedIndex + 3] = i1; - mergedTrianglesIndices[triangulatedIndex + 4] = i2; - mergedTrianglesIndices[triangulatedIndex + 5] = i3; - - originalIndex += INDICES_PER_ORIGINAL_QUAD; - triangulatedIndex += INDICES_PER_TRIANGULATED_QUAD; - } - - // add our original triangs - originalIndex = 0; - for (int fromTriangle = 0; fromTriangle < numberOfTriangles; fromTriangle++) { - int i0 = triangleIndices[originalIndex + 0]; - int i1 = triangleIndices[originalIndex + 1]; - int i2 = triangleIndices[originalIndex + 2]; - - mergedTrianglesIndices[triangulatedIndex + 0] = i0; - mergedTrianglesIndices[triangulatedIndex + 1] = i1; - mergedTrianglesIndices[triangulatedIndex + 2] = i2; - - originalIndex += INDICES_PER_ORIGINAL_TRIANGLE; - triangulatedIndex += INDICES_PER_ORIGINAL_TRIANGLE; - } - - mergedTrianglesIndicesCount = mergedNumberOfIndices; - mergedTrianglesIndicesBuffer->append(mergedNumberOfIndices * sizeof(quint32), (gpu::Byte*)mergedTrianglesIndices.data()); - - } - return mergedTrianglesIndicesBuffer; -} - FBXBlendshape extractBlendshape(const FBXNode& object) { FBXBlendshape blendshape; foreach (const FBXNode& data, object.children) { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3bb0545e78..d317205909 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -123,28 +123,22 @@ class FBXMeshPart { public: QVector quadIndices; // original indices from the FBX mesh - QVector quadTrianglesIndices; // original indices from the FBX mesh of the quad converted has triangles + QVector quadTrianglesIndices; // original indices from the FBX mesh of the quad converted as triangles QVector triangleIndices; // original indices from the FBX mesh - mutable gpu::BufferPointer mergedTrianglesIndicesBuffer; // both the quads and the triangles merged into a single set of triangles QString materialID; - - mutable bool mergedTrianglesAvailable = false; - mutable int mergedTrianglesIndicesCount = 0; - - gpu::BufferPointer getMergedTriangles() const; }; class FBXMaterial { public: FBXMaterial() {}; - FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor, - const glm::vec2& emissiveParams, float shininess, float opacity) : - diffuseColor(diffuseColor), - specularColor(specularColor), - emissiveColor(emissiveColor), - emissiveParams(emissiveParams), - shininess(shininess), + FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor, + const glm::vec2& emissiveParams, float shininess, float opacity) : + diffuseColor(diffuseColor), + specularColor(specularColor), + emissiveColor(emissiveColor), + emissiveParams(emissiveParams), + shininess(shininess), opacity(opacity) {} glm::vec3 diffuseColor{ 1.0f }; diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 2754fc5d67..411f477a84 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -362,12 +362,12 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn // Triangle tri1 = { v0, v1, v2 }; // Triangle tri2 = { v2, v3, v0 }; - part.quadTrianglesIndices.append(i0); - part.quadTrianglesIndices.append(i1); - part.quadTrianglesIndices.append(i3); - - part.quadTrianglesIndices.append(i1); - part.quadTrianglesIndices.append(i2); + part.quadTrianglesIndices.append(i0); + part.quadTrianglesIndices.append(i1); + part.quadTrianglesIndices.append(i2); + + part.quadTrianglesIndices.append(i1); + part.quadTrianglesIndices.append(i2); part.quadTrianglesIndices.append(i3); } else { @@ -386,8 +386,6 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn return data.extracted; } - -#if USE_MODEL_MESH void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); @@ -402,7 +400,6 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } if (extracted.mesh.vertices.size() == 0) { - extracted.mesh._mesh; qCDebug(modelformat) << "buildModelMesh failed -- no vertices, url = " << url; return; } @@ -510,9 +507,8 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } foreach(const FBXMeshPart& part, extracted.mesh.parts) { model::Mesh::Part modelPart(indexNum, 0, 0, model::Mesh::TRIANGLES); + if (part.quadTrianglesIndices.size()) { - - ib->setSubData( offset, part.quadTrianglesIndices.size() * sizeof(int), (gpu::Byte*) part.quadTrianglesIndices.constData()); @@ -520,10 +516,8 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { indexNum += part.quadTrianglesIndices.size(); modelPart._numIndices += part.quadTrianglesIndices.size(); } - // model::Mesh::Part triPart(indexNum, part.triangleIndices.size(), 0, model::Mesh::TRIANGLES); if (part.triangleIndices.size()) { - // parts.push_back(triPart); ib->setSubData( offset, part.triangleIndices.size() * sizeof(int), (gpu::Byte*) part.triangleIndices.constData()); @@ -553,5 +547,3 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { extracted.mesh._mesh = mesh; } -#endif // USE_MODEL_MESH - diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index b1e63a18bd..37135ccd98 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -319,8 +319,11 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) { uint32 startIndex = batch._params[paramOffset + 0]._uint; GLenum glType = _elementTypeToGLType[_input._indexBufferType]; + + auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; + GLvoid* indexBufferByteOffset = reinterpret_cast(startIndex * typeByteSize + _input._indexBufferOffset); - glDrawElements(mode, numIndices, glType, reinterpret_cast(startIndex + _input._indexBufferOffset)); + glDrawElements(mode, numIndices, glType, indexBufferByteOffset); (void) CHECK_GL_ERROR(); } @@ -353,10 +356,13 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { uint32 startInstance = batch._params[paramOffset + 0]._uint; GLenum glType = _elementTypeToGLType[_input._indexBufferType]; + auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; + GLvoid* indexBufferByteOffset = reinterpret_cast(startIndex * typeByteSize + _input._indexBufferOffset); + #if (GPU_INPUT_PROFILE == GPU_CORE_43) - glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, reinterpret_cast(startIndex + _input._indexBufferOffset), numInstances, 0, startInstance); + glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); #else - glDrawElementsInstanced(mode, numIndices, glType, reinterpret_cast(startIndex + _input._indexBufferOffset), numInstances); + glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, numInstances); Q_UNUSED(startInstance); #endif (void)CHECK_GL_ERROR(); @@ -389,7 +395,7 @@ void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, uint32 paramOffset) { uint commandCount = batch._params[paramOffset + 0]._uint; GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint]; GLenum indexType = _elementTypeToGLType[_input._indexBufferType]; - + glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast(_input._indirectBufferOffset), commandCount, _input._indirectBufferStride); #else // FIXME implement the slow path diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index f12cda827a..e01dbcd0dc 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -286,7 +286,7 @@ protected: BufferPointer _indexBuffer; Offset _indexBufferOffset; Type _indexBufferType; - + BufferPointer _indirectBuffer; Offset _indirectBufferOffset{ 0 }; Offset _indirectBufferStride{ 0 }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 44484131d9..a1ded35ba0 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1711,17 +1711,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape { PerformanceTimer perfTimer("batch.drawIndexed()"); - // part.getMergedTriangles(); - // part.mergedTrianglesIndicesCount; - batch.drawIndexed(gpu::TRIANGLES, drawPart._numIndices, drawPart._startIndex); + batch.drawIndexed(gpu::TRIANGLES, drawPart._numIndices, drawPart._startIndex); } -/* batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); - batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); - */ if (args) { const int INDICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += part.mergedTrianglesIndicesCount / INDICES_PER_TRIANGLE; + args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE; } } From 1799322c672faf946e2bab3e9d25e213fbd9bc5e Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 4 Oct 2015 18:46:35 -0700 Subject: [PATCH 048/152] Fix typos introduce in previous commit about the Quad to triangle indexing and remove dead code in model.cpp --- libraries/fbx/src/FBXReader_Mesh.cpp | 2 +- libraries/render-utils/src/Model.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 411f477a84..c88eaf4137 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -364,7 +364,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn part.quadTrianglesIndices.append(i0); part.quadTrianglesIndices.append(i1); - part.quadTrianglesIndices.append(i2); + part.quadTrianglesIndices.append(i3); part.quadTrianglesIndices.append(i1); part.quadTrianglesIndices.append(i2); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 276ad7a17a..d2fbbc1e43 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1546,9 +1546,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape return; // FIXME! } - // Assign index buffer: - // batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { // sanity check @@ -1610,8 +1607,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape return; } - const FBXMeshPart& part = mesh.parts.at(partIndex); - #ifdef WANT_DEBUG if (material == nullptr) { From fd232b7d3269e7c40a35d1b9011e01e63803c0ec Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 4 Oct 2015 22:27:48 -0700 Subject: [PATCH 049/152] ONe more file to deal with the Model rendering --- libraries/render-utils/src/Model.cpp | 76 +------------------ .../render-utils/src/ModelRenderPayload.cpp | 55 ++++++++++++++ .../render-utils/src/ModelRenderPayload.h | 68 +++++++++++++++++ 3 files changed, 124 insertions(+), 75 deletions(-) create mode 100644 libraries/render-utils/src/ModelRenderPayload.cpp create mode 100644 libraries/render-utils/src/ModelRenderPayload.h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index d2fbbc1e43..cb7b2b4b0c 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -20,13 +20,12 @@ #include #include #include -#include -#include #include "AbstractViewStateInterface.h" #include "AnimationHandle.h" #include "DeferredLightingEffect.h" #include "Model.h" +#include "ModelRenderPayload.h" #include "model_vert.h" #include "model_shadow_vert.h" @@ -744,79 +743,6 @@ void Model::renderSetup(RenderArgs* args) { } } - -class MeshPartPayload { -public: - MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : - model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) { } - - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - Model* model; - QUrl url; - int meshIndex; - int partIndex; - int _shapeID; - - // Render Item interface - render::Item::Bound getBound() const; - void render(RenderArgs* args) const; - - - mutable render::Item::Bound _bound; - mutable bool _isBoundInvalid = true; -}; - - -render::Item::Bound MeshPartPayload::getBound() const { - if (_isBoundInvalid) { - model->getPartBounds(meshIndex, partIndex); - _isBoundInvalid = false; - } - return _bound; -} -void MeshPartPayload::render(RenderArgs* args) const { - return model->renderPart(args, meshIndex, partIndex, _shapeID); -} - -namespace render { - template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { - if (!payload->model->isVisible()) { - return ItemKey::Builder().withInvisible().build(); - } - auto geometry = payload->model->getGeometry(); - if (!geometry.isNull()) { - auto drawMaterial = geometry->getShapeMaterial(payload->_shapeID); - if (drawMaterial) { - auto matKey = drawMaterial->_material->getKey(); - if (matKey.isTransparent() || matKey.isTransparentMap()) { - return ItemKey::Builder::transparentShape(); - } else { - return ItemKey::Builder::opaqueShape(); - } - } - } - - // Return opaque for lack of a better idea - return ItemKey::Builder::opaqueShape(); - } - - template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { - if (payload) { - return payload->getBound(); - } - return render::Item::Bound(); - } - template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { - return payload->render(args); - } - - /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { - return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex); - }*/ -} - void Model::setVisibleInScene(bool newValue, std::shared_ptr scene) { if (_isVisible != newValue) { _isVisible = newValue; diff --git a/libraries/render-utils/src/ModelRenderPayload.cpp b/libraries/render-utils/src/ModelRenderPayload.cpp new file mode 100644 index 0000000000..c8961c0c4f --- /dev/null +++ b/libraries/render-utils/src/ModelRenderPayload.cpp @@ -0,0 +1,55 @@ +// +// ModelRenderPayload.cpp +// interface/src/renderer +// +// Created by Sam Gateau on 10/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ModelRenderPayload.h" + +#include "Model.h" + +using namespace render; + +MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : + model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) +{ +} + +render::ItemKey MeshPartPayload::getKey() const { + if (!model->isVisible()) { + return ItemKey::Builder().withInvisible().build(); + } + auto geometry = model->getGeometry(); + if (!geometry.isNull()) { + auto drawMaterial = geometry->getShapeMaterial(_shapeID); + if (drawMaterial) { + auto matKey = drawMaterial->_material->getKey(); + if (matKey.isTransparent() || matKey.isTransparentMap()) { + return ItemKey::Builder::transparentShape(); + } else { + return ItemKey::Builder::opaqueShape(); + } + } + } + + // Return opaque for lack of a better idea + return ItemKey::Builder::opaqueShape(); +} + +render::Item::Bound MeshPartPayload::getBound() const { + if (_isBoundInvalid) { + model->getPartBounds(meshIndex, partIndex); + _isBoundInvalid = false; + } + return _bound; +} + +void MeshPartPayload::render(RenderArgs* args) const { + return model->renderPart(args, meshIndex, partIndex, _shapeID); +} + diff --git a/libraries/render-utils/src/ModelRenderPayload.h b/libraries/render-utils/src/ModelRenderPayload.h new file mode 100644 index 0000000000..fe38415edc --- /dev/null +++ b/libraries/render-utils/src/ModelRenderPayload.h @@ -0,0 +1,68 @@ +// +// ModelRenderPayload.h +// interface/src/renderer +// +// Created by Sam Gateau on 10/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ModelRenderPayload_h +#define hifi_ModelRenderPayload_h + +#include +#include + +class Model; + +class MeshPartPayload { +public: + MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex); + + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + Model* model; + QUrl url; + int meshIndex; + int partIndex; + int _shapeID; + + // Render Item interface + render::ItemKey getKey() const; + render::Item::Bound getBound() const; + void render(RenderArgs* args) const; + + + mutable render::Item::Bound _bound; + mutable bool _isBoundInvalid = true; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getKey(); + } + // Return opaque for lack of a better idea + return ItemKey::Builder::opaqueShape(); + } + + template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return render::Item::Bound(); + } + template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { + return payload->render(args); + } + + /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { + return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex); + }*/ +} + + +#endif // hifi_ModelRenderPayload_h \ No newline at end of file From 9e393ced46f3b9a3d9fa530e8457e3c0618d7675 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 5 Oct 2015 09:17:16 -0700 Subject: [PATCH 050/152] MOving rednering code of Model into ModelRenderPayload.h/cpp --- libraries/render-utils/src/Model.cpp | 11 +- libraries/render-utils/src/Model.h | 3 +- .../render-utils/src/ModelRenderPayload.cpp | 343 +++++++++++++++++- .../render-utils/src/ModelRenderPayload.h | 39 +- 4 files changed, 364 insertions(+), 32 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index cb7b2b4b0c..c02cd99b1f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1373,7 +1373,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { return AABox(); } -void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) { +void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload) { // PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("Model::renderPart"); if (!_readyWhenAdded) { @@ -1505,6 +1505,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape auto drawPart = drawMesh->getPartBuffer().get(partIndex); + /* if (mesh.blendshapes.isEmpty()) { batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); @@ -1527,7 +1528,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape if (mesh.colors.isEmpty()) { batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } - +*/ + payload->bindMesh(batch); + // guard against partially loaded meshes if (partIndex >= mesh.parts.size()) { return; @@ -1644,9 +1647,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape { PerformanceTimer perfTimer("batch.drawIndexed()"); - batch.drawIndexed(gpu::TRIANGLES, drawPart._numIndices, drawPart._startIndex); + payload->drawCall(batch); } - + if (args) { const int INDICES_PER_TRIANGLE = 3; args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE; diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 093c22938e..a36b773ed7 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -88,7 +88,7 @@ public: bool isVisible() const { return _isVisible; } AABox getPartBounds(int meshIndex, int partIndex); - void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID); + void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload); bool maybeStartBlender(); @@ -494,6 +494,7 @@ private: bool _needsReload = true; bool _needsUpdateClusterMatrices = true; + friend class MeshPartPayload; protected: RigPointer _rig; }; diff --git a/libraries/render-utils/src/ModelRenderPayload.cpp b/libraries/render-utils/src/ModelRenderPayload.cpp index c8961c0c4f..a6c62ee9e1 100644 --- a/libraries/render-utils/src/ModelRenderPayload.cpp +++ b/libraries/render-utils/src/ModelRenderPayload.cpp @@ -13,13 +13,44 @@ #include "Model.h" +namespace render { + template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getKey(); + } + // Return opaque for lack of a better idea + return ItemKey::Builder::opaqueShape(); + } + + template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return render::Item::Bound(); + } + template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { + return payload->render(args); + } + + /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { + return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex); + }*/ +} + using namespace render; MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) { + const std::vector>& networkMeshes = model->_geometry->getMeshes(); + const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); + _drawMesh = networkMesh._mesh; + + _drawPart = _drawMesh->getPartBuffer().get(partIndex); + } + render::ItemKey MeshPartPayload::getKey() const { if (!model->isVisible()) { return ItemKey::Builder().withInvisible().build(); @@ -50,6 +81,316 @@ render::Item::Bound MeshPartPayload::getBound() const { } void MeshPartPayload::render(RenderArgs* args) const { - return model->renderPart(args, meshIndex, partIndex, _shapeID); + return model->renderPart(args, meshIndex, partIndex, _shapeID, this); } +void MeshPartPayload::bindMesh(gpu::Batch& batch) const { + const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); + const std::vector>& networkMeshes = model->_geometry->getMeshes(); + const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + // auto drawMesh = networkMesh._mesh; + + if (mesh.blendshapes.isEmpty()) { + batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); + + batch.setInputFormat((_drawMesh->getVertexFormat())); + auto inputStream = _drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + } else { + batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); + batch.setInputFormat((_drawMesh->getVertexFormat())); + + batch.setInputBuffer(0, model->_blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); + batch.setInputBuffer(1, model->_blendedVertexBuffers[meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); + + auto inputStream = _drawMesh->makeBufferStream().makeRangedStream(2); + + batch.setInputStream(2, inputStream); + } + + if (mesh.colors.isEmpty()) { + batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + } +} + +void MeshPartPayload::drawCall(gpu::Batch& batch) const { + batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); +} +/* +void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) { + // PROFILE_RANGE(__FUNCTION__); + PerformanceTimer perfTimer("Model::renderPart"); + if (!_readyWhenAdded) { + return; // bail asap + } + + auto textureCache = DependencyManager::get(); + + gpu::Batch& batch = *(args->_batch); + auto mode = args->_renderMode; + + + // Capture the view matrix once for the rendering of this model + if (_transforms.empty()) { + _transforms.push_back(Transform()); + } + + auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + const std::vector>& networkMeshes = _geometry->getMeshes(); + + auto networkMaterial = _geometry->getShapeMaterial(shapeID); + if (!networkMaterial) { + return; + }; + auto material = networkMaterial->_material; + if (!material) { + return; + } + + // TODO: Not yet + // auto drawMesh = _geometry->getShapeMesh(shapeID); + // auto drawPart = _geometry->getShapePart(shapeID); + + // guard against partially loaded meshes + if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size() ) { + return; + } + + updateClusterMatrices(); + + const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + const MeshState& state = _meshStates.at(meshIndex); + + auto drawMesh = networkMesh._mesh; + + + auto drawMaterialKey = material->getKey(); + bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); + + bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); + bool hasSpecular = drawMaterialKey.isGlossMap(); // !drawMaterial->specularTextureName.isEmpty(); //mesh.hasSpecularTexture(); + bool hasLightmap = drawMaterialKey.isLightmapMap(); // !drawMaterial->emissiveTextureName.isEmpty(); //mesh.hasEmissiveTexture(); + bool isSkinned = state.clusterMatrices.size() > 1; + bool wireframe = isWireframe(); + + // render the part bounding box +#ifdef DEBUG_BOUNDING_PARTS + { + AABox partBounds = getPartBounds(meshIndex, partIndex); + bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; + + glm::vec4 cubeColor; + if (isSkinned) { + cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); + } else if (inView) { + cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); + } else { + cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); + } + + Transform transform; + transform.setTranslation(partBounds.calcCenter()); + transform.setScale(partBounds.getDimensions()); + batch.setModelTransform(transform); + DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + } +#endif //def DEBUG_BOUNDING_PARTS + + if (wireframe) { + translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; + } + + Locations* locations = nullptr; + pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, + args, locations); + + // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown + // to false to rebuild out mesh groups. + if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { + _meshGroupsKnown = false; // regenerate these lists next time around. + _readyWhenAdded = false; // in case any of our users are using scenes + invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid + return; // FIXME! + } + + int vertexCount = mesh.vertices.size(); + if (vertexCount == 0) { + // sanity check + return; // FIXME! + } + + // Transform stage + if (_transforms.empty()) { + _transforms.push_back(Transform()); + } + + if (isSkinned) { + const float* bones; + if (_cauterizeBones) { + bones = (const float*)state.cauterizedClusterMatrices.constData(); + } else { + bones = (const float*)state.clusterMatrices.constData(); + } + batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones); + _transforms[0] = Transform(); + _transforms[0].preTranslate(_translation); + } else { + if (_cauterizeBones) { + _transforms[0] = Transform(state.cauterizedClusterMatrices[0]); + } else { + _transforms[0] = Transform(state.clusterMatrices[0]); + } + _transforms[0].preTranslate(_translation); + } + batch.setModelTransform(_transforms[0]); + + auto drawPart = drawMesh->getPartBuffer().get(partIndex); + + if (mesh.blendshapes.isEmpty()) { + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + + batch.setInputFormat((drawMesh->getVertexFormat())); + auto inputStream = drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + } else { + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + batch.setInputFormat((drawMesh->getVertexFormat())); + + batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); + batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); + + auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2); + + batch.setInputStream(2, inputStream); + } + + if (mesh.colors.isEmpty()) { + batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + } + + // guard against partially loaded meshes + if (partIndex >= mesh.parts.size()) { + return; + } + + +#ifdef WANT_DEBUG + if (material == nullptr) { + qCDebug(renderutils) << "WARNING: material == nullptr!!!"; + } +#endif + + { + + // apply material properties + if (mode != RenderArgs::SHADOW_RENDER_MODE) { +#ifdef WANT_DEBUG + qCDebug(renderutils) << "Material Changed ---------------------------------------------"; + qCDebug(renderutils) << "part INDEX:" << partIndex; + qCDebug(renderutils) << "NEW part.materialID:" << part.materialID; +#endif //def WANT_DEBUG + + if (locations->materialBufferUnit >= 0) { + batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); + } + + auto materialKey = material->getKey(); + auto textureMaps = material->getTextureMaps(); + glm::mat4 texcoordTransform[2]; + + // Diffuse + if (materialKey.isDiffuseMap()) { + auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; + if (diffuseMap && diffuseMap->isDefined()) { + batch.setResourceTexture(DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); + + if (!diffuseMap->getTextureTransform().isIdentity()) { + diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); + } + } else { + batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); + } + } else { + batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); + } + + // Normal map + if ((locations->normalTextureUnit >= 0) && hasTangents) { + auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; + if (normalMap && normalMap->isDefined()) { + batch.setResourceTexture(NORMAL_MAP_SLOT, normalMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(NORMAL_MAP_SLOT, textureCache->getBlueTexture()); + } + } else { + batch.setResourceTexture(NORMAL_MAP_SLOT, nullptr); + } + + // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that + if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) { + auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; + if (specularMap && specularMap->isDefined()) { + batch.setResourceTexture(SPECULAR_MAP_SLOT, specularMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); + } + } else { + batch.setResourceTexture(SPECULAR_MAP_SLOT, nullptr); + } + + // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too + if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) { + auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; + + if (lightmapMap && lightmapMap->isDefined()) { + batch.setResourceTexture(LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); + + auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); + batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); + + if (!lightmapMap->getTextureTransform().isIdentity()) { + lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); + } + } + else { + batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); + } + } else { + batch.setResourceTexture(LIGHTMAP_MAP_SLOT, nullptr); + } + + // Texcoord transforms ? + if (locations->texcoordMatrices >= 0) { + batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); + } + + // TODO: We should be able to do that just in the renderTransparentJob + if (translucentMesh && locations->lightBufferUnit >= 0) { + PerformanceTimer perfTimer("DLE->setupTransparent()"); + + DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); + } + + + if (args) { + args->_details._materialSwitches++; + } + } + } + + if (args) { + const int INDICES_PER_TRIANGLE = 3; + args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE; + } +} +*/ \ No newline at end of file diff --git a/libraries/render-utils/src/ModelRenderPayload.h b/libraries/render-utils/src/ModelRenderPayload.h index fe38415edc..bee7c186b9 100644 --- a/libraries/render-utils/src/ModelRenderPayload.h +++ b/libraries/render-utils/src/ModelRenderPayload.h @@ -12,9 +12,14 @@ #ifndef hifi_ModelRenderPayload_h #define hifi_ModelRenderPayload_h -#include +#include + #include +#include + +#include + class Model; class MeshPartPayload { @@ -35,34 +40,16 @@ public: render::Item::Bound getBound() const; void render(RenderArgs* args) const; + // MeshPartPayload functions to perform render + void bindMesh(gpu::Batch& batch) const; + void drawCall(gpu::Batch& batch) const; + + model::MeshPointer _drawMesh; + model::Mesh::Part _drawPart; + model::MaterialPointer _drawMaterial; mutable render::Item::Bound _bound; mutable bool _isBoundInvalid = true; }; -namespace render { - template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { - if (payload) { - return payload->getKey(); - } - // Return opaque for lack of a better idea - return ItemKey::Builder::opaqueShape(); - } - - template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { - if (payload) { - return payload->getBound(); - } - return render::Item::Bound(); - } - template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { - return payload->render(args); - } - - /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { - return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex); - }*/ -} - - #endif // hifi_ModelRenderPayload_h \ No newline at end of file From 43f69a0be995ace51dfa0440f775b4bfb9dabef5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 13:23:19 -0700 Subject: [PATCH 051/152] initial knockover blocks --- examples/toys/createKnockoverBlocks.js | 152 +++++++++++++++++++++---- 1 file changed, 130 insertions(+), 22 deletions(-) diff --git a/examples/toys/createKnockoverBlocks.js b/examples/toys/createKnockoverBlocks.js index b5fe22ca73..417dc6cadd 100644 --- a/examples/toys/createKnockoverBlocks.js +++ b/examples/toys/createKnockoverBlocks.js @@ -1,47 +1,155 @@ // // createKnockoverBlocks.js // +// Script Type: Entity Spawner // Created by James B. Pollack on 9/29/2015 // Copyright 2015 High Fidelity, Inc. // // +// This script creates a 'stonehenge' formation of physical blocks for testing knock over properties. // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -var blockDimensions={ - x:0.12, - y:0.25, - z:0.50 + +var BLOCK_GRAVITY = { + x: 0, + y: -9.8, + z: 0 +}; + +var LINEAR_DAMPING = 0.2; + +var RED = { + red: 255, + green: 0, + blue: 0 +}; + +var GREEN = { + red: 0, + green: 255, + blue: 0 +}; + +var BLUE = { + red: 0, + green: 0, + blue: 255 +}; + +var blockDimensions = { + x: 0.12, + y: 0.25, + z: 0.50 }; var centerPosition = { - x: - y: - z: + x: 0, + y: 0, + z: 0 }; +var DISTANCE_IN_FRONT_OF_ME = 2.0; +var position = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME + })); + +// var position={ +// x:0, +// y:0, +// z:0 +// }; var sideBlock1_position = { - x: - y: - z: + x: position.x, + y: position.y, + z: position.z - 0.25 }; - - var sideBlock2_position = { - x: - y: - z: + x: position.x, + y: position.y, + z: position.z + 0.25 }; +var topBlock_position = { + x: position.x, + y: position.y + 0.31, + z: position.z +}; -var sideBlock1_rotation = Quat.fromPitchYawRollDegrees(); -var sideBlock2_rotation = Quat.fromPitchYawRollDegrees(); -var topBlock_rotation = Quat.fromPitchYawRollDegrees(); +var sideBlock1_rotation = Quat.fromPitchYawRollDegrees(90, 90, 0); +var sideBlock2_rotation = Quat.fromPitchYawRollDegrees(90, 90, 0); +var topBlock_rotation = Quat.fromPitchYawRollDegrees(0, 0, 90); -var sideBlock1 = Entities.addEntity(); -var sideBlock2 = Entities.addEntity(); -var topBlock = Entities.addEntity(); -var ground = Entities.addEntity(); \ No newline at end of file +var topBlock = Entities.addEntity({ + name: 'Top Block', + color: BLUE, + type: 'Box', + shapeType: 'box', + dimensions: blockDimensions, + position: topBlock_position, + rotation: topBlock_rotation, + linearDamping: LINEAR_DAMPING, + gravity: BLOCK_GRAVITY, + collisionsWillMove: true, + velocity: { + x: 0, + y: -0.01, + z: 0 + } +}); + +var sideBlock1 = Entities.addEntity({ + name: 'Top Block', + color: GREEN, + type: 'Box', + shapeType: 'box', + dimensions: blockDimensions, + position: sideBlock1_position, + rotation: sideBlock1_rotation, + linearDamping: LINEAR_DAMPING, + gravity: BLOCK_GRAVITY, + collisionsWillMove: true +}); + +var sideBlock2 = Entities.addEntity({ + name: 'Side Block', + color: GREEN, + type: 'Box', + shapeType: 'box', + dimensions: blockDimensions, + position: sideBlock2_position, + rotation: sideBlock2_rotation, + collsionsWillMove: true, + linearDamping: LINEAR_DAMPING, + gravity: BLOCK_GRAVITY, + collisionsWillMove: true +}); + +var ground = Entities.addEntity({ + type: 'Box', + dimensions: { + x: 2, + y: 0.02, + z: 1 + }, + color: RED, + position: { + x: position.x, + y: position.y - 0.25, + z: position.z + } +}); + +function cleanUp() { + Entities.deleteEntity(ground); + Entities.deleteEntity(topBlock); + Entities.deleteEntity(sideBlock1); + Entities.deleteEntity(sideBlock2); +}; +Script.scriptEnding.connect(cleanUp); \ No newline at end of file From e528125af2d5d96cf60d6b40373a71878842d345 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 13:38:48 -0700 Subject: [PATCH 052/152] add test blocks for blockers game --- .../createTestBlocks.js} | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename examples/toys/{createKnockoverBlocks.js => blockers/createTestBlocks.js} (97%) diff --git a/examples/toys/createKnockoverBlocks.js b/examples/toys/blockers/createTestBlocks.js similarity index 97% rename from examples/toys/createKnockoverBlocks.js rename to examples/toys/blockers/createTestBlocks.js index 417dc6cadd..d119f6d483 100644 --- a/examples/toys/createKnockoverBlocks.js +++ b/examples/toys/blockers/createTestBlocks.js @@ -1,5 +1,5 @@ // -// createKnockoverBlocks.js +// createTestBlocks.js // // Script Type: Entity Spawner // Created by James B. Pollack on 9/29/2015 @@ -7,11 +7,11 @@ // // // This script creates a 'stonehenge' formation of physical blocks for testing knock over properties. -// Distributed under the Apache License, Version 2.0. +// +// Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ - var BLOCK_GRAVITY = { x: 0, y: -9.8, @@ -151,5 +151,6 @@ function cleanUp() { Entities.deleteEntity(topBlock); Entities.deleteEntity(sideBlock1); Entities.deleteEntity(sideBlock2); -}; +} + Script.scriptEnding.connect(cleanUp); \ No newline at end of file From 839301bf05a72600e66dd9a3100e0f320433702a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 13:41:20 -0700 Subject: [PATCH 053/152] remove cleanup to make blocks persistent --- examples/toys/blockers/createTestBlocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/blockers/createTestBlocks.js b/examples/toys/blockers/createTestBlocks.js index d119f6d483..44a3d7af61 100644 --- a/examples/toys/blockers/createTestBlocks.js +++ b/examples/toys/blockers/createTestBlocks.js @@ -153,4 +153,4 @@ function cleanUp() { Entities.deleteEntity(sideBlock2); } -Script.scriptEnding.connect(cleanUp); \ No newline at end of file +// Script.scriptEnding.connect(cleanUp); \ No newline at end of file From daf97b0b9db549fbbf220e5a3268edd6edc5e56b Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 14:12:18 -0700 Subject: [PATCH 054/152] header fixes --- examples/toys/blockers/createTestBlocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/blockers/createTestBlocks.js b/examples/toys/blockers/createTestBlocks.js index 44a3d7af61..8d2c20c750 100644 --- a/examples/toys/blockers/createTestBlocks.js +++ b/examples/toys/blockers/createTestBlocks.js @@ -2,7 +2,7 @@ // createTestBlocks.js // // Script Type: Entity Spawner -// Created by James B. Pollack on 9/29/2015 +// Created by James B. Pollack on 10/5/2015 // Copyright 2015 High Fidelity, Inc. // // From 8c8e83dc8e0617d590552174ff3a12e544ae2fa9 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 5 Oct 2015 14:17:12 -0700 Subject: [PATCH 055/152] more debugging on animation.running --- examples/html/entityProperties.html | 12 ++++++- .../entities/src/AnimationPropertyGroup.cpp | 33 ++++++++++++------- .../entities/src/EntityItemProperties.cpp | 1 - libraries/entities/src/EntityTree.cpp | 2 ++ libraries/entities/src/ModelEntityItem.cpp | 7 ++++ 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 5743d65ed0..9ea1933dfb 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -10,6 +10,15 @@ var DEGREES_TO_RADIANS = PI / 180.0; var RADIANS_TO_DEGREES = 180.0 / PI; + debugPrint = function(message) { + EventBridge.emitWebEvent( + JSON.stringify({ + type:"print", + message: message + }) + ); + }; + function enableChildren(el, selector) { els = el.querySelectorAll(selector); for (var i = 0; i < els.length; i++) { @@ -37,10 +46,11 @@ }; } function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) { - return function() { + return function () { var properties = {}; properties[group] = {}; properties[group][propertyName] = this.checked; + //debugPrint(" about to emitWebEvent() properties:" + JSON.stringify(properties)); EventBridge.emitWebEvent( JSON.stringify({ type: "update", diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 29b134235a..5e981cf14a 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -93,11 +93,14 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setFrameIndex, getFrameIndex); } + /* if (_animationLoop) { qDebug() << "copyFromScriptValue() running:" << _animationLoop->getRunning(); } else { qDebug() << "copyFromScriptValue() running:" << getRunning(); } + */ + } @@ -193,7 +196,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, _animationLoop->getLastFrame()); @@ -202,7 +205,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getRunning()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame()); @@ -210,13 +213,6 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } - if (_animationLoop) { - qDebug() << "appendToEditPacket() running:" << _animationLoop->getRunning(); - } else { - qDebug() << "appendToEditPacket() running:" << getRunning(); - } - - return true; } @@ -260,11 +256,18 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF processedBytes += bytesRead; - if (_animationLoop) { - qDebug() << "decodeFromEditPacket() running:" << _animationLoop->getRunning(); + /* + if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { + qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() DID contain PROP_ANIMATION_PLAYING -----------"; + if (_animationLoop) { + qDebug() << " decodeFromEditPacket() _animationLoop->getRunning:" << _animationLoop->getRunning(); + } else { + qDebug() << " decodeFromEditPacket() getRunning:" << getRunning(); + } } else { - qDebug() << "decodeFromEditPacket() running:" << getRunning(); + qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() packet did not contain PROP_ANIMATION_PLAYING"; } + */ return true; } @@ -339,11 +342,13 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } + /* if (_animationLoop) { qDebug() << "setProperties() running:" << _animationLoop->getRunning(); } else { qDebug() << "setProperties() running:" << getRunning(); } + */ return somethingChanged; } @@ -395,11 +400,13 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } + /* if (_animationLoop) { qDebug() << "appendSubclassData() running:" << _animationLoop->getRunning(); } else { qDebug() << "appendSubclassData() running:" << getRunning(); } + */ } @@ -433,11 +440,13 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } + /* if (_animationLoop) { qDebug() << "readEntitySubclassDataFromBuffer() running:" << _animationLoop->getRunning(); } else { qDebug() << "readEntitySubclassDataFromBuffer() running:" << getRunning(); } + */ return bytesRead; } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index cdd6c5b2ca..387032f58c 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1150,7 +1150,6 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem // If any part of the model items didn't fit, then the element is considered partial if (appendState != OctreeElement::COMPLETED) { - // TODO: handle mechanism for handling partial fitting data! // add this item into our list for the next appendElementData() pass //modelTreeElementExtraEncodeData->includedItems.insert(getEntityItemID(), propertiesDidntFit); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index c4c02d364f..44183d76de 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -583,6 +583,8 @@ int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* edi case PacketType::EntityAdd: case PacketType::EntityEdit: { + qCDebug(entities) << "EntityTree::processEditPacketData()... EntityAdd/EntityEdit"; + quint64 startDecode = 0, endDecode = 0; quint64 startLookup = 0, endLookup = 0; quint64 startUpdate = 0, endUpdate = 0; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index e140e88d55..964bc8f46b 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -77,6 +77,8 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { setLastEdited(properties._lastEdited); } + //qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + return somethingChanged; } @@ -121,6 +123,8 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); + //qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + return bytesRead; } @@ -156,6 +160,9 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); + + //qDebug() << "ModelEntityItem::appendSubclassData() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + } From f30a94064f01bd3dc6bd2b7c4a3e10a263954e18 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Mon, 5 Oct 2015 15:50:55 -0700 Subject: [PATCH 056/152] make animation start/stop work --- .../src/RenderableModelEntityItem.cpp | 2 + .../entities/src/AnimationPropertyGroup.cpp | 37 ++++++++++++++++--- libraries/entities/src/ModelEntityItem.cpp | 24 +++++++++++- libraries/entities/src/PropertyGroup.h | 6 +++ 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ed088bc9b5..54f5c384e0 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -269,6 +269,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (_model) { // handle animations.. if (hasAnimation()) { + //qDebug() << "RenderableModelEntityItem::render() -- hasAnimation()"; if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); mapJoints(modelJointNames); @@ -279,6 +280,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { QVector frameDataRotations; QVector frameDataTranslations; getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); + qDebug() << "RenderableModelEntityItem::render() -- getAnimationFrame() newFrame:" << newFrame; assert(frameDataRotations.size() == frameDataTranslations.size()); if (newFrame) { for (int i = 0; i < frameDataRotations.size(); i++) { diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 5e981cf14a..a7e77a75e0 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -342,13 +342,13 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } - /* if (_animationLoop) { - qDebug() << "setProperties() running:" << _animationLoop->getRunning(); + qDebug() << "setProperties() _animationLoop->running:" << _animationLoop->getRunning(); } else { qDebug() << "setProperties() running:" << getRunning(); } - */ + + _somethingChanged = somethingChanged; return somethingChanged; } @@ -414,6 +414,14 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); + bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); + float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); + float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); + bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); + bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); + bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); + int bytesRead = 0; const unsigned char* dataAt = data; @@ -440,13 +448,30 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } - /* + float newFPS = _animationLoop ? _animationLoop->getFPS() : getFPS(); + bool newRunning = _animationLoop ? _animationLoop->getRunning() : getRunning(); + float newFirstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); + float newLastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); + bool newLoop = _animationLoop ? _animationLoop->getLoop() : getLoop(); + bool newHold = _animationLoop ? _animationLoop->getHold() : getHold(); + bool newStartAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); + + // NOTE: we don't check frameIndex because that is assumed to always be changing. + _somethingChanged = newFPS != fps || + newRunning != running || + newFirstFrame != firstFrame || + newLastFrame != lastFrame || + newLoop != loop || + newHold != hold || + newStartAutomatically != startAutomatically; + + + if (_animationLoop) { - qDebug() << "readEntitySubclassDataFromBuffer() running:" << _animationLoop->getRunning(); + qDebug() << "readEntitySubclassDataFromBuffer() _animationLoop->running:" << _animationLoop->getRunning(); } else { qDebug() << "readEntitySubclassDataFromBuffer() running:" << getRunning(); } - */ return bytesRead; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 964bc8f46b..b1f306b758 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -64,6 +64,10 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, updateShapeType); bool somethingChangedInAnimations = _animationProperties.setProperties(properties); + + if (somethingChangedInAnimations) { + _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; + } somethingChanged = somethingChanged || somethingChangedInAnimations; if (somethingChanged) { @@ -77,7 +81,9 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { setLastEdited(properties._lastEdited); } - //qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() + << " properties.animation.running:" << properties.getAnimation().getRunning() + << " running:" << getAnimationIsPlaying(); return somethingChanged; } @@ -109,11 +115,16 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); + qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " args.bitstreamVersion:" << args.bitstreamVersion << " VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP:" << VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP; + if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); } else { // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() // will automatically read into the animation loop + + qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " calling _animationProperties.readEntitySubclassDataFromBuffer()"; + int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); @@ -123,7 +134,11 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); - //qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); + + if (_animationProperties.somethingChanged()) { + _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; + } return bytesRead; } @@ -223,6 +238,7 @@ void ModelEntityItem::getAnimationFrame(bool& newFrame, int frameCount = frames.size(); if (frameCount > 0) { + qDebug() << "getAnimationFrameIndex:" << getAnimationFrameIndex(); int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; if (animationFrameIndex < 0 || animationFrameIndex > frameCount) { animationFrameIndex = 0; @@ -265,6 +281,10 @@ bool ModelEntityItem::needsToCallUpdate() const { } void ModelEntityItem::update(const quint64& now) { + if (hasAnimation()) { + qDebug() << "ModelEntityItem::update() getAnimationIsPlaying():" << getAnimationIsPlaying(); + } + // only advance the frame index if we're playing if (getAnimationIsPlaying()) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; diff --git a/libraries/entities/src/PropertyGroup.h b/libraries/entities/src/PropertyGroup.h index 4069e7be02..d030400993 100644 --- a/libraries/entities/src/PropertyGroup.h +++ b/libraries/entities/src/PropertyGroup.h @@ -81,6 +81,9 @@ public: /// has changed. This will be called with properties change or when new data is loaded from a stream virtual void somethingChangedNotification() { } + /// set to true or false after setProperties() and readEntitySubclassDataFromBuffer() if something in the state has changed. + bool somethingChanged() const { return _somethingChanged; } + virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const = 0; @@ -95,6 +98,9 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData) = 0; + +protected: + bool _somethingChanged = false; }; #endif // hifi_PropertyGroup_h From 41b2f82be57318e8de832f44904b6ed158f0c0f9 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 17:43:44 -0700 Subject: [PATCH 057/152] midway --- examples/toys/basketball.js | 62 +++++---- examples/toys/basketball_hoop/createHoop.js | 1 - examples/toys/basketball_hoop/createRack.js | 136 ++++++++++++++++++++ 3 files changed, 172 insertions(+), 27 deletions(-) create mode 100644 examples/toys/basketball_hoop/createRack.js diff --git a/examples/toys/basketball.js b/examples/toys/basketball.js index d30dce6e72..96b6218b3d 100644 --- a/examples/toys/basketball.js +++ b/examples/toys/basketball.js @@ -17,34 +17,39 @@ var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var basketball = null; var originalPosition = null; -var hasMoved = false; +var hasMoved = false; var GRAVITY = -9.8; var DISTANCE_IN_FRONT_OF_ME = 1.0; var START_MOVE = 0.01; -var DIAMETER = 0.30; +var DIAMETER = 0.30; -function makeBasketball() { +function makeBasketball() { var position = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, - { x: 0, y: 0.0, z: -DISTANCE_IN_FRONT_OF_ME })); + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME + })); var rotation = Quat.multiply(MyAvatar.orientation, - Quat.fromPitchYawRollDegrees(0, -90, 0)); + Quat.fromPitchYawRollDegrees(0, -90, 0)); basketball = Entities.addEntity({ - type: "Model", - position: position, - rotation: rotation, - dimensions: { x: DIAMETER, - y: DIAMETER, - z: DIAMETER }, - collisionsWillMove: true, - collisionSoundURL: collisionSoundURL, - modelURL: basketballURL, - restitution: 1.0, - linearDamping: 0.00001, - shapeType: "sphere" - }); - originalPosition = position; + type: "Model", + position: position, + rotation: rotation, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + collisionsWillMove: true, + collisionSoundURL: collisionSoundURL, + modelURL: basketballURL, + restitution: 1.0, + linearDamping: 0.00001, + shapeType: "sphere" + }); + originalPosition = position; } function update() { @@ -55,28 +60,33 @@ function update() { var moved = Vec3.length(Vec3.subtract(originalPosition, newProperties.position)); if (!hasMoved && (moved > START_MOVE)) { hasMoved = true; - Entities.editEntity(basketball, { gravity: {x: 0, y: GRAVITY, z: 0 }}); + Entities.editEntity(basketball, { + gravity: { + x: 0, + y: GRAVITY, + z: 0 + } + }); } var MAX_DISTANCE = 10.0; var distance = Vec3.length(Vec3.subtract(MyAvatar.position, newProperties.position)); if (distance > MAX_DISTANCE) { deleteStuff(); } - } + } } function scriptEnding() { deleteStuff(); } -function deleteStuff() { +function deleteStuff() { if (basketball != null) { Entities.deleteEntity(basketball); basketball = null; - hasMoved = false; + hasMoved = false; } } Script.update.connect(update); -Script.scriptEnding.connect(scriptEnding); - +Script.scriptEnding.connect(scriptEnding); \ No newline at end of file diff --git a/examples/toys/basketball_hoop/createHoop.js b/examples/toys/basketball_hoop/createHoop.js index 3887e0b421..b0c76b4a53 100644 --- a/examples/toys/basketball_hoop/createHoop.js +++ b/examples/toys/basketball_hoop/createHoop.js @@ -1,6 +1,5 @@ // // createHoop.js -// examples/entityScripts // // Created by James B. Pollack on 9/29/2015 // Copyright 2015 High Fidelity, Inc. diff --git a/examples/toys/basketball_hoop/createRack.js b/examples/toys/basketball_hoop/createRack.js new file mode 100644 index 0000000000..8019aca283 --- /dev/null +++ b/examples/toys/basketball_hoop/createRack.js @@ -0,0 +1,136 @@ +// +// createRack.js +// +// Created by James B. Pollack on10/5/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This is a script that creates a persistent basketball rack. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + +var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; +var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; +var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; +var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_hoop_collision_hull.obj"; +var DIAMETER = 0.30; + +var rackStartPosition = + Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -2 + })); + +var rack = Entities.addEntity({ + type: "Model", + modelURL: rackURL, + position: rackStartPosition, + shapeType: 'compound', + // gravity: { + // x: 0, + // y: -9.8, + // z: 0 + // }, + dimensions: { + x: 0.4, + y: 1.37, + z: 1.73 + }, + collisionsWillMove: false, + ignoreForCollisions: true, + compoundShapeURL: rackCollisionHullURL +}); + +var nonCollidingBalls = []; +var collidingBalls = []; + +function createNonCollidingBalls() { + var i; + var j; + var position = rackStartPosition; + for (i = 0; i < 4; i++) { + var nonCollidingBall = Entities.addEntity({ + type: "Model", + name: 'Static Basketball', + position: { + x: position.x, + y: position.y, + z: position.z + (DIAMETER) - (DIAMETER * i) + }, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + collisionsWillMove: true, + ignoreForCollisions: false, + modelURL: basketballURL + }); + nonCollidingBalls.push(nonCollidingBall); + } + for (i = 0; i < 4; i++) { + var nonCollidingBall = Entities.addEntity({ + type: "Model", + name: 'Static Basketball', + position: { + x: position.x, + y: position.y + DIAMETER, + z: position.z + (DIAMETER) - (DIAMETER * i) + }, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + collisionsWillMove: true, + ignoreForCollisions: false, + modelURL: basketballURL + }); + nonCollidingBalls.push(nonCollidingBall); + } +} + +function createCollidingBalls() { + var position = rackStartPosition; + for (i = 0; i < 4; i++) { + var collidingBall = Entities.addEntity({ + type: "Model", + name: 'Colliding Basketball', + position: { + x: position.x, + y: position.y + DIAMETER * 2, + z: position.z + (DIAMETER) - (DIAMETER * i) + }, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + // restitution: 1.0, + // linearDamping: 0.00001, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + modelURL: basketballURL + }); + collidingBalls.push(collidingBall); + } +} + +function adjustBallPositions() { + var i; + for (i = 0; i < nonCollidingBalls.length; i++) { + Entities.editEntity(nonCollidingBalls[i]) + } +} + +createNonCollidingBalls(); +createCollidingBalls(); \ No newline at end of file From 1b241ea05e1708ba141ee89db6ac6037cb4b8fbb Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 18:13:51 -0700 Subject: [PATCH 058/152] Update createTestBlocks.js --- examples/toys/blockers/createTestBlocks.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/examples/toys/blockers/createTestBlocks.js b/examples/toys/blockers/createTestBlocks.js index 8d2c20c750..d92d8d2b32 100644 --- a/examples/toys/blockers/createTestBlocks.js +++ b/examples/toys/blockers/createTestBlocks.js @@ -58,12 +58,6 @@ var position = Vec3.sum(MyAvatar.position, z: -DISTANCE_IN_FRONT_OF_ME })); -// var position={ -// x:0, -// y:0, -// z:0 -// }; - var sideBlock1_position = { x: position.x, y: position.y, @@ -145,12 +139,3 @@ var ground = Entities.addEntity({ z: position.z } }); - -function cleanUp() { - Entities.deleteEntity(ground); - Entities.deleteEntity(topBlock); - Entities.deleteEntity(sideBlock1); - Entities.deleteEntity(sideBlock2); -} - -// Script.scriptEnding.connect(cleanUp); \ No newline at end of file From 6cc3077d6727bf431348aa80e837ff1e6e84f197 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 5 Oct 2015 18:29:35 -0700 Subject: [PATCH 059/152] end of day --- examples/toys/basketball_hoop/createRack.js | 36 +++++++++------------ 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/examples/toys/basketball_hoop/createRack.js b/examples/toys/basketball_hoop/createRack.js index 8019aca283..726f25eb33 100644 --- a/examples/toys/basketball_hoop/createRack.js +++ b/examples/toys/basketball_hoop/createRack.js @@ -1,7 +1,7 @@ // // createRack.js // -// Created by James B. Pollack on10/5/2015 +// Created by James B. Pollack @imgntn on 10/5/2015 // Copyright 2015 High Fidelity, Inc. // // This is a script that creates a persistent basketball rack. @@ -15,6 +15,8 @@ var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_hoop_collision_hull.obj"; +var basketballSwitcherURL= Script.resolvePath('basketballSwitcher.js'); + var DIAMETER = 0.30; var rackStartPosition = @@ -41,7 +43,7 @@ var rack = Entities.addEntity({ z: 1.73 }, collisionsWillMove: false, - ignoreForCollisions: true, + ignoreForCollisions: false, compoundShapeURL: rackCollisionHullURL }); @@ -50,8 +52,8 @@ var collidingBalls = []; function createNonCollidingBalls() { var i; - var j; var position = rackStartPosition; + for (i = 0; i < 4; i++) { var nonCollidingBall = Entities.addEntity({ type: "Model", @@ -66,12 +68,13 @@ function createNonCollidingBalls() { y: DIAMETER, z: DIAMETER }, - collisionsWillMove: true, - ignoreForCollisions: false, + collisionsWillMove: false, + ignoreForCollisions: true, modelURL: basketballURL }); nonCollidingBalls.push(nonCollidingBall); } + for (i = 0; i < 4; i++) { var nonCollidingBall = Entities.addEntity({ type: "Model", @@ -86,7 +89,7 @@ function createNonCollidingBalls() { y: DIAMETER, z: DIAMETER }, - collisionsWillMove: true, + collisionsWillMove: false, ignoreForCollisions: false, modelURL: basketballURL }); @@ -96,10 +99,12 @@ function createNonCollidingBalls() { function createCollidingBalls() { var position = rackStartPosition; + var i; for (i = 0; i < 4; i++) { var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', + shapeType:'Sphere', position: { x: position.x, y: position.y + DIAMETER * 2, @@ -110,27 +115,16 @@ function createCollidingBalls() { y: DIAMETER, z: DIAMETER }, - // restitution: 1.0, - // linearDamping: 0.00001, - gravity: { - x: 0, - y: -9.8, - z: 0 - }, + restitution: 1.0, + linearDamping: 1, collisionsWillMove: true, ignoreForCollisions: false, - modelURL: basketballURL + modelURL: basketballURL, + script:basketballSwitcherURL }); collidingBalls.push(collidingBall); } } -function adjustBallPositions() { - var i; - for (i = 0; i < nonCollidingBalls.length; i++) { - Entities.editEntity(nonCollidingBalls[i]) - } -} - createNonCollidingBalls(); createCollidingBalls(); \ No newline at end of file From 12fedb6ff0bb146300043eb997ce81f8c2d95a67 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 5 Oct 2015 18:31:05 -0700 Subject: [PATCH 060/152] Move skinning shader features in its own slh and get ready for moving cluster matrices to uniform buffer --- libraries/gpu/src/gpu/Stream.h | 1 + libraries/model/src/model/Geometry.cpp | 35 +- libraries/model/src/model/Geometry.h | 9 +- .../src/DeferredLightingEffect.cpp | 2 +- libraries/render-utils/src/Model.cpp | 499 +----------- libraries/render-utils/src/Model.h | 132 +--- .../render-utils/src/ModelRenderPayload.cpp | 717 +++++++++++------- .../render-utils/src/ModelRenderPayload.h | 163 +++- libraries/render-utils/src/Skinning.slh | 68 ++ libraries/render-utils/src/skin_model.slv | 15 +- .../src/skin_model_normal_map.slv | 14 +- .../render-utils/src/skin_model_shadow.slv | 11 +- 12 files changed, 731 insertions(+), 935 deletions(-) create mode 100644 libraries/render-utils/src/Skinning.slh diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 53509c1033..492af5f62a 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -134,6 +134,7 @@ public: BufferStream(); ~BufferStream(); + void clear() { _buffers.clear(); _offsets.clear(); _strides.clear(); } void addBuffer(const BufferPointer& buffer, Offset offset, Offset stride); const Buffers& getBuffers() const { return _buffers; } diff --git a/libraries/model/src/model/Geometry.cpp b/libraries/model/src/model/Geometry.cpp index 6723293dc1..63adeec0f1 100755 --- a/libraries/model/src/model/Geometry.cpp +++ b/libraries/model/src/model/Geometry.cpp @@ -64,6 +64,24 @@ void Mesh::evalVertexFormat() { } _vertexFormat.reset(vf); + + evalVertexStream(); +} + + +void Mesh::evalVertexStream() { + _vertexStream.clear(); + + int channelNum = 0; + if (hasVertexData()) { + _vertexStream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat->getChannelStride(channelNum)); + channelNum++; + } + for (auto attrib : _attributeBuffers) { + BufferView& view = attrib.second; + _vertexStream.addBuffer(view._buffer, view._offset, _vertexFormat->getChannelStride(channelNum)); + channelNum++; + } } void Mesh::setIndexBuffer(const BufferView& buffer) { @@ -116,23 +134,6 @@ const Box Mesh::evalPartBounds(int partStart, int partEnd, Boxes& bounds) const return totalBound; } -const gpu::BufferStream Mesh::makeBufferStream() const { - gpu::BufferStream stream; - - int channelNum = 0; - if (hasVertexData()) { - stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat->getChannelStride(channelNum)); - channelNum++; - } - for (auto attrib : _attributeBuffers) { - BufferView& view = attrib.second; - stream.addBuffer(view._buffer, view._offset, _vertexFormat->getChannelStride(channelNum)); - channelNum++; - } - - return stream; -} - Geometry::Geometry() { } diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 5ef414a2d1..8b5f448a64 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -57,6 +57,9 @@ public: // Stream format const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; } + // BufferStream on the mesh vertices and attributes matching the vertex format + const gpu::BufferStream getVertexStream() const { return _vertexStream; } + // Index Buffer void setIndexBuffer(const BufferView& buffer); const BufferView& getIndexBuffer() const { return _indexBuffer; } @@ -109,15 +112,12 @@ public: // the returned box is the bounding box of ALL the evaluated part bounds. const Box evalPartBounds(int partStart, int partEnd, Boxes& bounds) const; - - // Generate a BufferStream on the mesh vertices and attributes - const gpu::BufferStream makeBufferStream() const; - static gpu::Primitive topologyToPrimitive(Topology topo) { return static_cast(topo); } protected: gpu::Stream::FormatPointer _vertexFormat; + gpu::BufferStream _vertexStream; BufferView _vertexBuffer; BufferViewMap _attributeBuffers; @@ -127,6 +127,7 @@ protected: BufferView _partBuffer; void evalVertexFormat(); + void evalVertexStream(); }; typedef std::shared_ptr< Mesh > MeshPointer; diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index dbcbe3c05e..e9d2cf4061 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -887,7 +887,7 @@ model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { _spotLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(sizeof(part), (gpu::Byte*) &part), gpu::Element::PART_DRAWCALL)); - _spotLightMesh->makeBufferStream(); + _spotLightMesh->getVertexStream(); } return _spotLightMesh; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index c02cd99b1f..a86cd305dc 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -27,26 +27,6 @@ #include "Model.h" #include "ModelRenderPayload.h" -#include "model_vert.h" -#include "model_shadow_vert.h" -#include "model_normal_map_vert.h" -#include "model_lightmap_vert.h" -#include "model_lightmap_normal_map_vert.h" -#include "skin_model_vert.h" -#include "skin_model_shadow_vert.h" -#include "skin_model_normal_map_vert.h" - -#include "model_frag.h" -#include "model_shadow_frag.h" -#include "model_normal_map_frag.h" -#include "model_normal_specular_map_frag.h" -#include "model_specular_map_frag.h" -#include "model_lightmap_frag.h" -#include "model_lightmap_normal_map_frag.h" -#include "model_lightmap_normal_specular_map_frag.h" -#include "model_lightmap_specular_map_frag.h" -#include "model_translucent_frag.h" - #include "RenderUtilsLogging.h" using namespace std; @@ -92,112 +72,6 @@ Model::~Model() { deleteGeometry(); } -Model::RenderPipelineLib Model::_renderPipelineLib; -const int MATERIAL_GPU_SLOT = 3; -const int DIFFUSE_MAP_SLOT = 0; -const int NORMAL_MAP_SLOT = 1; -const int SPECULAR_MAP_SLOT = 2; -const int LIGHTMAP_MAP_SLOT = 3; -const int LIGHT_BUFFER_SLOT = 4; - -void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key, - gpu::ShaderPointer& vertexShader, - gpu::ShaderPointer& pixelShader ) { - - gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DIFFUSE_MAP_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), NORMAL_MAP_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), SPECULAR_MAP_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), LIGHTMAP_MAP_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_BUFFER_SLOT)); - slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT)); - - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); - gpu::Shader::makeProgram(*program, slotBindings); - - - auto locations = std::make_shared(); - initLocations(program, *locations); - - - auto state = std::make_shared(); - - // Backface on shadow - if (key.isShadow()) { - state->setCullMode(gpu::State::CULL_FRONT); - state->setDepthBias(1.0f); - state->setDepthBiasSlopeScale(4.0f); - } else { - state->setCullMode(gpu::State::CULL_BACK); - } - - // Z test depends if transparent or not - state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); - - // Blend on transparent - state->setBlendFunction(key.isTranslucent(), - gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, // For transparent only, this keep the highlight intensity - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - - // Good to go add the brand new pipeline - auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); - insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations))); - - - if (!key.isWireFrame()) { - - RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME); - auto wireframeState = std::make_shared(state->getValues()); - - wireframeState->setFillMode(gpu::State::FILL_LINE); - - // create a new RenderPipeline with the same shader side and the mirrorState - auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); - insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); - } - - // If not a shadow pass, create the mirror version from the same state, just change the FrontFace - if (!key.isShadow()) { - - RenderKey mirrorKey(key.getRaw() | RenderKey::IS_MIRROR); - auto mirrorState = std::make_shared(state->getValues()); - - // create a new RenderPipeline with the same shader side and the mirrorState - auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState)); - insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations))); - - if (!key.isWireFrame()) { - RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME); - auto wireframeState = std::make_shared(state->getValues()); - - wireframeState->setFillMode(gpu::State::FILL_LINE); - - // create a new RenderPipeline with the same shader side and the mirrorState - auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); - insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); - } - } -} - - -void Model::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, Model::Locations& locations) { - locations.alphaThreshold = program->getUniforms().findLocation("alphaThreshold"); - locations.texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices"); - locations.emissiveParams = program->getUniforms().findLocation("emissiveParams"); - locations.glowIntensity = program->getUniforms().findLocation("glowIntensity"); - locations.normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap"); - locations.diffuseTextureUnit = program->getTextures().findLocation("diffuseMap"); - locations.normalTextureUnit = program->getTextures().findLocation("normalMap"); - locations.specularTextureUnit = program->getTextures().findLocation("specularMap"); - locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); - locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); - locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); - locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); - locations.clusterIndices = program->getInputs().findLocation("inSkinClusterIndex"); - locations.clusterWeights = program->getInputs().findLocation("inSkinClusterWeight"); -} - AbstractViewStateInterface* Model::_viewState = NULL; void Model::setTranslation(const glm::vec3& translation) { @@ -255,128 +129,6 @@ void Model::initJointTransforms() { } void Model::init() { - if (_renderPipelineLib.empty()) { - // 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))); - auto modelLightmapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_lightmap_vert))); - auto modelLightmapNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert))); - auto modelShadowVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_shadow_vert))); - auto skinModelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_vert))); - auto skinModelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_normal_map_vert))); - auto skinModelShadowVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_shadow_vert))); - - // Pixel shaders - auto modelPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_frag))); - auto modelNormalMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_normal_map_frag))); - auto modelSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_specular_map_frag))); - auto modelNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_normal_specular_map_frag))); - auto modelTranslucentPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_translucent_frag))); - auto modelShadowPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_shadow_frag))); - auto modelLightmapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_frag))); - auto modelLightmapNormalMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag))); - auto modelLightmapSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag))); - auto modelLightmapNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag))); - - // Fill the renderPipelineLib - - _renderPipelineLib.addRenderPipeline( - RenderKey(0), - modelVertex, modelPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_TANGENTS), - modelNormalMapVertex, modelNormalMapPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_SPECULAR), - modelVertex, modelSpecularMapPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), - modelNormalMapVertex, modelNormalSpecularMapPixel); - - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::IS_TRANSLUCENT), - modelVertex, modelTranslucentPixel); - // FIXME Ignore lightmap for translucents meshpart - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::IS_TRANSLUCENT | RenderKey::HAS_LIGHTMAP), - 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); - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS), - modelLightmapNormalMapVertex, modelLightmapNormalMapPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_SPECULAR), - modelLightmapVertex, modelLightmapSpecularMapPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), - modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel); - - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::IS_SKINNED), - skinModelVertex, modelPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS), - skinModelNormalMapVertex, modelNormalMapPixel); - - _renderPipelineLib.addRenderPipeline( - RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR), - skinModelVertex, modelSpecularMapPixel); - - _renderPipelineLib.addRenderPipeline( - 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); - } } void Model::reset() { @@ -416,6 +168,9 @@ bool Model::updateGeometry() { MeshState state; state.clusterMatrices.resize(mesh.clusters.size()); state.cauterizedClusterMatrices.resize(mesh.clusters.size()); + if (mesh.clusters.size() > 1) { + state.clusterBuffer = std::make_shared(mesh.clusters.size() * sizeof(glm::mat4), nullptr); + } _meshStates.append(state); auto buffer = std::make_shared(); @@ -1237,6 +992,7 @@ void Model::updateClusterMatrices() { for (int i = 0; i < _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); + for (int j = 0; j < mesh.clusters.size(); j++) { const FBXCluster& cluster = mesh.clusters.at(j); auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); @@ -1250,6 +1006,17 @@ void Model::updateClusterMatrices() { state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; } } + + // Once computed the cluster matrices, update the buffer + if (state.clusterBuffer) { + const float* bones; + if (_cauterizeBones) { + bones = (const float*)state.cauterizedClusterMatrices.constData(); + } else { + bones = (const float*)state.clusterMatrices.constData(); + } + state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) bones); + } } // post the blender if we're not currently waiting for one to finish @@ -1385,12 +1152,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape gpu::Batch& batch = *(args->_batch); auto mode = args->_renderMode; - - // Capture the view matrix once for the rendering of this model - if (_transforms.empty()) { - _transforms.push_back(Transform()); - } - auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME const FBXGeometry& geometry = _geometry->getFBXGeometry(); @@ -1420,9 +1181,22 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape const FBXMesh& mesh = geometry.meshes.at(meshIndex); const MeshState& state = _meshStates.at(meshIndex); - auto drawMesh = networkMesh._mesh; + // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown + // to false to rebuild out mesh groups. + if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { + _meshGroupsKnown = false; // regenerate these lists next time around. + _readyWhenAdded = false; // in case any of our users are using scenes + invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid + return; // FIXME! + } + int vertexCount = mesh.vertices.size(); + if (vertexCount == 0) { + // sanity check + return; // FIXME! + } + auto drawMaterialKey = material->getKey(); bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); @@ -1459,76 +1233,13 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; } - Locations* locations = nullptr; - pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, + ModelRender::Locations* locations = nullptr; + ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, args, locations); - // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown - // to false to rebuild out mesh groups. - if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { - _meshGroupsKnown = false; // regenerate these lists next time around. - _readyWhenAdded = false; // in case any of our users are using scenes - invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid - return; // FIXME! - } - int vertexCount = mesh.vertices.size(); - if (vertexCount == 0) { - // sanity check - return; // FIXME! - } + payload->bindTransform(batch, locations); - // Transform stage - if (_transforms.empty()) { - _transforms.push_back(Transform()); - } - - if (isSkinned) { - const float* bones; - if (_cauterizeBones) { - bones = (const float*)state.cauterizedClusterMatrices.constData(); - } else { - bones = (const float*)state.clusterMatrices.constData(); - } - batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones); - _transforms[0] = Transform(); - _transforms[0].preTranslate(_translation); - } else { - if (_cauterizeBones) { - _transforms[0] = Transform(state.cauterizedClusterMatrices[0]); - } else { - _transforms[0] = Transform(state.clusterMatrices[0]); - } - _transforms[0].preTranslate(_translation); - } - batch.setModelTransform(_transforms[0]); - - auto drawPart = drawMesh->getPartBuffer().get(partIndex); - - /* - if (mesh.blendshapes.isEmpty()) { - batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - - batch.setInputFormat((drawMesh->getVertexFormat())); - auto inputStream = drawMesh->makeBufferStream(); - - batch.setInputStream(0, inputStream); - } else { - batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - batch.setInputFormat((drawMesh->getVertexFormat())); - - batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); - batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); - - auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2); - - batch.setInputStream(2, inputStream); - } - - if (mesh.colors.isEmpty()) { - batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } -*/ payload->bindMesh(batch); // guard against partially loaded meshes @@ -1544,104 +1255,18 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape #endif { - // apply material properties - if (mode != RenderArgs::SHADOW_RENDER_MODE) { - #ifdef WANT_DEBUG - qCDebug(renderutils) << "Material Changed ---------------------------------------------"; - qCDebug(renderutils) << "part INDEX:" << partIndex; - qCDebug(renderutils) << "NEW part.materialID:" << part.materialID; - #endif //def WANT_DEBUG - - if (locations->materialBufferUnit >= 0) { - batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); - } - - auto materialKey = material->getKey(); - auto textureMaps = material->getTextureMaps(); - glm::mat4 texcoordTransform[2]; - - // Diffuse - if (materialKey.isDiffuseMap()) { - auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; - if (diffuseMap && diffuseMap->isDefined()) { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); - - if (!diffuseMap->getTextureTransform().isIdentity()) { - diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); - } - } else { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - - // Normal map - if ((locations->normalTextureUnit >= 0) && hasTangents) { - auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; - if (normalMap && normalMap->isDefined()) { - batch.setResourceTexture(NORMAL_MAP_SLOT, normalMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(NORMAL_MAP_SLOT, textureCache->getBlueTexture()); - } - } else { - batch.setResourceTexture(NORMAL_MAP_SLOT, nullptr); - } - - // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that - if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) { - auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; - if (specularMap && specularMap->isDefined()) { - batch.setResourceTexture(SPECULAR_MAP_SLOT, specularMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); - } - } else { - batch.setResourceTexture(SPECULAR_MAP_SLOT, nullptr); - } - - // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too - if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) { - auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; - - if (lightmapMap && lightmapMap->isDefined()) { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); - - auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); - batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); - - if (!lightmapMap->getTextureTransform().isIdentity()) { - lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); - } - } - else { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, nullptr); - } - - // Texcoord transforms ? - if (locations->texcoordMatrices >= 0) { - batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); - } - - // TODO: We should be able to do that just in the renderTransparentJob - if (translucentMesh && locations->lightBufferUnit >= 0) { - PerformanceTimer perfTimer("DLE->setupTransparent()"); - - DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); - } + payload->bindMaterial(batch, locations); - if (args) { - args->_details._materialSwitches++; - } + // TODO: We should be able to do that just in the renderTransparentJob + if (translucentMesh && locations->lightBufferUnit >= 0) { + PerformanceTimer perfTimer("DLE->setupTransparent()"); + + DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); + } + if (args) { + args->_details._materialSwitches++; } } @@ -1652,7 +1277,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape if (args) { const int INDICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE; + args->_details._trianglesRendered += payload->_drawPart._numIndices / INDICES_PER_TRIANGLE; } } @@ -1684,46 +1309,6 @@ void Model::segregateMeshGroups() { _meshGroupsKnown = true; } -void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, - bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, - Locations*& locations) { - - PerformanceTimer perfTimer("Model::pickPrograms"); - - - RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); - if (mode == RenderArgs::MIRROR_RENDER_MODE) { - key = RenderKey(key.getRaw() | RenderKey::IS_MIRROR); - } - 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; - } - - gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram(); - locations = (*pipeline).second._locations.get(); - - - // Setup the One pipeline - batch.setPipeline((*pipeline).second._pipeline); - - if ((locations->alphaThreshold > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { - batch._glUniform1f(locations->alphaThreshold, alphaThreshold); - } - - if ((locations->glowIntensity > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { - const float DEFAULT_GLOW_INTENSITY = 1.0f; // FIXME - glow is removed - batch._glUniform1f(locations->glowIntensity, DEFAULT_GLOW_INTENSITY); - } - - if ((locations->normalFittingMapUnit > -1)) { - batch.setResourceTexture(locations->normalFittingMapUnit, - DependencyManager::get()->getNormalFittingTexture()); - } -} - bool Model::initWhenReady(render::ScenePointer scene) { if (isActive() && isRenderable() && !_meshGroupsKnown && isLoaded()) { segregateMeshGroups(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index a36b773ed7..108480e4ef 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -47,6 +47,7 @@ namespace render { typedef unsigned int ItemID; } class MeshPartPayload; +class ModelRenderLocations; inline uint qHash(const std::shared_ptr& a, uint seed) { return qHash(a.get(), seed); @@ -257,6 +258,7 @@ protected: public: QVector clusterMatrices; QVector cauterizedClusterMatrices; + gpu::BufferPointer clusterBuffer; }; QVector _meshStates; @@ -323,8 +325,6 @@ private: bool _isVisible; gpu::Buffers _blendedVertexBuffers; - std::vector _transforms; - gpu::Batch _renderBatch; QVector > > _dilatedTextures; @@ -332,25 +332,6 @@ private: int _blendNumber; int _appliedBlendNumber; - class Locations { - public: - int tangent; - int alphaThreshold; - int texcoordMatrices; - int diffuseTextureUnit; - int normalTextureUnit; - int specularTextureUnit; - int emissiveTextureUnit; - int emissiveParams; - int glowIntensity; - int normalFittingMapUnit; - int materialBufferUnit; - int clusterMatrices; - int clusterIndices; - int clusterWeights; - int lightBufferUnit; - }; - QHash, AABox> _calculatedMeshPartBoxes; // world coordinate AABoxes for all sub mesh part boxes bool _calculatedMeshPartBoxesValid; @@ -373,118 +354,9 @@ private: void renderDebugMeshBoxes(gpu::Batch& batch); int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID; - // helper functions used by render() or renderInScene() - - static void pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, - bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, - Locations*& locations); static AbstractViewStateInterface* _viewState; - class RenderKey { - public: - enum FlagBit { - IS_TRANSLUCENT_FLAG = 0, - HAS_LIGHTMAP_FLAG, - HAS_TANGENTS_FLAG, - HAS_SPECULAR_FLAG, - HAS_EMISSIVE_FLAG, - IS_SKINNED_FLAG, - IS_STEREO_FLAG, - IS_DEPTH_ONLY_FLAG, - IS_SHADOW_FLAG, - IS_MIRROR_FLAG, //THis means that the mesh is rendered mirrored, not the same as "Rear view mirror" - IS_WIREFRAME_FLAG, - - NUM_FLAGS, - }; - - enum Flag { - IS_TRANSLUCENT = (1 << IS_TRANSLUCENT_FLAG), - HAS_LIGHTMAP = (1 << HAS_LIGHTMAP_FLAG), - HAS_TANGENTS = (1 << HAS_TANGENTS_FLAG), - HAS_SPECULAR = (1 << HAS_SPECULAR_FLAG), - HAS_EMISSIVE = (1 << HAS_EMISSIVE_FLAG), - IS_SKINNED = (1 << IS_SKINNED_FLAG), - IS_STEREO = (1 << IS_STEREO_FLAG), - IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG), - IS_SHADOW = (1 << IS_SHADOW_FLAG), - IS_MIRROR = (1 << IS_MIRROR_FLAG), - IS_WIREFRAME = (1 << IS_WIREFRAME_FLAG), - }; - typedef unsigned short Flags; - - - - bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); } - - bool isTranslucent() const { return isFlag(IS_TRANSLUCENT); } - bool hasLightmap() const { return isFlag(HAS_LIGHTMAP); } - bool hasTangents() const { return isFlag(HAS_TANGENTS); } - bool hasSpecular() const { return isFlag(HAS_SPECULAR); } - bool hasEmissive() const { return isFlag(HAS_EMISSIVE); } - bool isSkinned() const { return isFlag(IS_SKINNED); } - bool isStereo() const { return isFlag(IS_STEREO); } - bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); } - bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing - bool isMirror() const { return isFlag(IS_MIRROR); } - bool isWireFrame() const { return isFlag(IS_WIREFRAME); } - - Flags _flags = 0; - short _spare = 0; - - int getRaw() { return *reinterpret_cast(this); } - - - RenderKey( - bool translucent, bool hasLightmap, - bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) : - RenderKey( (translucent ? IS_TRANSLUCENT : 0) - | (hasLightmap ? HAS_LIGHTMAP : 0) - | (hasTangents ? HAS_TANGENTS : 0) - | (hasSpecular ? HAS_SPECULAR : 0) - | (isSkinned ? IS_SKINNED : 0) - | (isWireframe ? IS_WIREFRAME : 0) - ) {} - - RenderKey(RenderArgs::RenderMode mode, - bool translucent, float alphaThreshold, bool hasLightmap, - bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) : - RenderKey( ((translucent && (alphaThreshold == 0.0f) && (mode != RenderArgs::SHADOW_RENDER_MODE)) ? IS_TRANSLUCENT : 0) - | (hasLightmap && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_LIGHTMAP : 0) // Lightmap, tangents and specular don't matter for depthOnly - | (hasTangents && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_TANGENTS : 0) - | (hasSpecular && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_SPECULAR : 0) - | (isSkinned ? IS_SKINNED : 0) - | (isWireframe ? IS_WIREFRAME : 0) - | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0) - | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_SHADOW : 0) - | ((mode == RenderArgs::MIRROR_RENDER_MODE) ? IS_MIRROR :0) - ) {} - - RenderKey(int bitmask) : _flags(bitmask) {} - }; - - - class RenderPipeline { - public: - gpu::PipelinePointer _pipeline; - std::shared_ptr _locations; - RenderPipeline(gpu::PipelinePointer pipeline, std::shared_ptr locations) : - _pipeline(pipeline), _locations(locations) {} - }; - - typedef std::unordered_map BaseRenderPipelineMap; - class RenderPipelineLib : public BaseRenderPipelineMap { - public: - typedef RenderKey Key; - - - void addRenderPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader); - - void initLocations(gpu::ShaderPointer& program, Locations& locations); - }; - static RenderPipelineLib _renderPipelineLib; - bool _renderCollisionHull; diff --git a/libraries/render-utils/src/ModelRenderPayload.cpp b/libraries/render-utils/src/ModelRenderPayload.cpp index a6c62ee9e1..e4998e445a 100644 --- a/libraries/render-utils/src/ModelRenderPayload.cpp +++ b/libraries/render-utils/src/ModelRenderPayload.cpp @@ -11,8 +11,299 @@ #include "ModelRenderPayload.h" +#include "DeferredLightingEffect.h" + #include "Model.h" +#include "model_vert.h" +#include "model_shadow_vert.h" +#include "model_normal_map_vert.h" +#include "model_lightmap_vert.h" +#include "model_lightmap_normal_map_vert.h" +#include "skin_model_vert.h" +#include "skin_model_shadow_vert.h" +#include "skin_model_normal_map_vert.h" + +#include "model_frag.h" +#include "model_shadow_frag.h" +#include "model_normal_map_frag.h" +#include "model_normal_specular_map_frag.h" +#include "model_specular_map_frag.h" +#include "model_lightmap_frag.h" +#include "model_lightmap_normal_map_frag.h" +#include "model_lightmap_normal_specular_map_frag.h" +#include "model_lightmap_specular_map_frag.h" +#include "model_translucent_frag.h" + +ModelRender::RenderPipelineLib ModelRender::_renderPipelineLib; + +const ModelRender::RenderPipelineLib& ModelRender::getRenderPipelineLib() { + if (_renderPipelineLib.empty()) { + // 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))); + auto modelLightmapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_lightmap_vert))); + auto modelLightmapNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert))); + auto modelShadowVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_shadow_vert))); + auto skinModelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_vert))); + auto skinModelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_normal_map_vert))); + auto skinModelShadowVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(skin_model_shadow_vert))); + + // Pixel shaders + auto modelPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_frag))); + auto modelNormalMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_normal_map_frag))); + auto modelSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_specular_map_frag))); + auto modelNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_normal_specular_map_frag))); + auto modelTranslucentPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_translucent_frag))); + auto modelShadowPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_shadow_frag))); + auto modelLightmapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_frag))); + auto modelLightmapNormalMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_map_frag))); + auto modelLightmapSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_specular_map_frag))); + auto modelLightmapNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag))); + + // Fill the renderPipelineLib + + _renderPipelineLib.addRenderPipeline( + RenderKey(0), + modelVertex, modelPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_TANGENTS), + modelNormalMapVertex, modelNormalMapPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_SPECULAR), + modelVertex, modelSpecularMapPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), + modelNormalMapVertex, modelNormalSpecularMapPixel); + + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_TRANSLUCENT), + modelVertex, modelTranslucentPixel); + // FIXME Ignore lightmap for translucents meshpart + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_TRANSLUCENT | RenderKey::HAS_LIGHTMAP), + 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); + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS), + modelLightmapNormalMapVertex, modelLightmapNormalMapPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_SPECULAR), + modelLightmapVertex, modelLightmapSpecularMapPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), + modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel); + + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED), + skinModelVertex, modelPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS), + skinModelNormalMapVertex, modelNormalMapPixel); + + _renderPipelineLib.addRenderPipeline( + RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR), + skinModelVertex, modelSpecularMapPixel); + + _renderPipelineLib.addRenderPipeline( + 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); + } + + return _renderPipelineLib; +} + + +void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey key, + gpu::ShaderPointer& vertexShader, + gpu::ShaderPointer& pixelShader) { + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), ModelRender::MATERIAL_GPU_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), ModelRender::DIFFUSE_MAP_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), ModelRender::NORMAL_MAP_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), ModelRender::SPECULAR_MAP_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), ModelRender::LIGHTMAP_MAP_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ModelRender::LIGHT_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT)); + + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); + gpu::Shader::makeProgram(*program, slotBindings); + + + auto locations = std::make_shared(); + initLocations(program, *locations); + + + auto state = std::make_shared(); + + // Backface on shadow + if (key.isShadow()) { + state->setCullMode(gpu::State::CULL_FRONT); + state->setDepthBias(1.0f); + state->setDepthBiasSlopeScale(4.0f); + } else { + state->setCullMode(gpu::State::CULL_BACK); + } + + // Z test depends if transparent or not + state->setDepthTest(true, !key.isTranslucent(), gpu::LESS_EQUAL); + + // Blend on transparent + state->setBlendFunction(key.isTranslucent(), + gpu::State::ONE, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, // For transparent only, this keep the highlight intensity + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + // Good to go add the brand new pipeline + auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations))); + + + if (!key.isWireFrame()) { + + RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME); + auto wireframeState = std::make_shared(state->getValues()); + + wireframeState->setFillMode(gpu::State::FILL_LINE); + + // create a new RenderPipeline with the same shader side and the mirrorState + auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); + insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); + } + + // If not a shadow pass, create the mirror version from the same state, just change the FrontFace + if (!key.isShadow()) { + + RenderKey mirrorKey(key.getRaw() | RenderKey::IS_MIRROR); + auto mirrorState = std::make_shared(state->getValues()); + + // create a new RenderPipeline with the same shader side and the mirrorState + auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState)); + insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations))); + + if (!key.isWireFrame()) { + RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME); + auto wireframeState = std::make_shared(state->getValues()); + + wireframeState->setFillMode(gpu::State::FILL_LINE); + + // create a new RenderPipeline with the same shader side and the mirrorState + auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); + insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); + } + } +} + + +void ModelRender::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, ModelRender::Locations& locations) { + locations.alphaThreshold = program->getUniforms().findLocation("alphaThreshold"); + locations.texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices"); + locations.emissiveParams = program->getUniforms().findLocation("emissiveParams"); + locations.glowIntensity = program->getUniforms().findLocation("glowIntensity"); + locations.normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap"); + locations.diffuseTextureUnit = program->getTextures().findLocation("diffuseMap"); + locations.normalTextureUnit = program->getTextures().findLocation("normalMap"); + locations.specularTextureUnit = program->getTextures().findLocation("specularMap"); + locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); + locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); + locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); + locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); + locations.clusterIndices = program->getInputs().findLocation("inSkinClusterIndex"); + locations.clusterWeights = program->getInputs().findLocation("inSkinClusterWeight"); +} + + +void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, + bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, + Locations*& locations) { + + // PerformanceTimer perfTimer("Model::pickPrograms"); + getRenderPipelineLib(); + + RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); + if (mode == RenderArgs::MIRROR_RENDER_MODE) { + key = RenderKey(key.getRaw() | RenderKey::IS_MIRROR); + } + 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; + } + + gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram(); + locations = (*pipeline).second._locations.get(); + + + // Setup the One pipeline + batch.setPipeline((*pipeline).second._pipeline); + + if ((locations->alphaThreshold > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { + batch._glUniform1f(locations->alphaThreshold, alphaThreshold); + } + + if ((locations->glowIntensity > -1) && (mode != RenderArgs::SHADOW_RENDER_MODE)) { + const float DEFAULT_GLOW_INTENSITY = 1.0f; // FIXME - glow is removed + batch._glUniform1f(locations->glowIntensity, DEFAULT_GLOW_INTENSITY); + } + + if ((locations->normalFittingMapUnit > -1)) { + batch.setResourceTexture(locations->normalFittingMapUnit, + DependencyManager::get()->getNormalFittingTexture()); + } +} + namespace render { template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { if (payload) { @@ -42,34 +333,50 @@ using namespace render; MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) { + initCache(); +} + +void MeshPartPayload::initCache() { const std::vector>& networkMeshes = model->_geometry->getMeshes(); const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); _drawMesh = networkMesh._mesh; - + + const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + _hasColorAttrib = !mesh.colors.isEmpty(); + _isBlendShaped = !mesh.blendshapes.isEmpty(); + _isSkinned = !mesh.clusterIndices.isEmpty(); + + _drawPart = _drawMesh->getPartBuffer().get(partIndex); + auto networkMaterial = model->_geometry->getShapeMaterial(_shapeID); + if (networkMaterial) { + _drawMaterial = networkMaterial->_material; + }; + } - render::ItemKey MeshPartPayload::getKey() const { + ItemKey::Builder builder; + builder.withTypeShape(); + if (!model->isVisible()) { - return ItemKey::Builder().withInvisible().build(); + builder.withInvisible(); } - auto geometry = model->getGeometry(); - if (!geometry.isNull()) { - auto drawMaterial = geometry->getShapeMaterial(_shapeID); - if (drawMaterial) { - auto matKey = drawMaterial->_material->getKey(); - if (matKey.isTransparent() || matKey.isTransparentMap()) { - return ItemKey::Builder::transparentShape(); - } else { - return ItemKey::Builder::opaqueShape(); - } + + if (_isBlendShaped || _isSkinned) { + builder.withDeformed(); + } + + if (_drawMaterial) { + auto matKey = _drawMaterial->getKey(); + if (matKey.isTransparent() || matKey.isTransparentMap()) { + builder.withTransparent(); } } - - // Return opaque for lack of a better idea - return ItemKey::Builder::opaqueShape(); + + return builder.build(); } render::Item::Bound MeshPartPayload::getBound() const { @@ -84,313 +391,139 @@ void MeshPartPayload::render(RenderArgs* args) const { return model->renderPart(args, meshIndex, partIndex, _shapeID, this); } +void MeshPartPayload::drawCall(gpu::Batch& batch) const { + batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); +} + void MeshPartPayload::bindMesh(gpu::Batch& batch) const { - const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); - const std::vector>& networkMeshes = model->_geometry->getMeshes(); - const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); - const FBXMesh& mesh = geometry.meshes.at(meshIndex); - // auto drawMesh = networkMesh._mesh; - - if (mesh.blendshapes.isEmpty()) { + if (!_isBlendShaped) { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); batch.setInputFormat((_drawMesh->getVertexFormat())); - auto inputStream = _drawMesh->makeBufferStream(); - batch.setInputStream(0, inputStream); + batch.setInputStream(0, _drawMesh->getVertexStream()); } else { batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); + batch.setInputFormat((_drawMesh->getVertexFormat())); - + batch.setInputBuffer(0, model->_blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, model->_blendedVertexBuffers[meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); - - auto inputStream = _drawMesh->makeBufferStream().makeRangedStream(2); - - batch.setInputStream(2, inputStream); + batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); } - if (mesh.colors.isEmpty()) { + // TODO: Get rid of that extra call + if (!_hasColorAttrib) { batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } } -void MeshPartPayload::drawCall(gpu::Batch& batch) const { - batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); -} -/* -void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) { - // PROFILE_RANGE(__FUNCTION__); - PerformanceTimer perfTimer("Model::renderPart"); - if (!_readyWhenAdded) { - return; // bail asap +void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const { + if (!_drawMaterial) { + return; } - + auto textureCache = DependencyManager::get(); - - gpu::Batch& batch = *(args->_batch); - auto mode = args->_renderMode; - - - // Capture the view matrix once for the rendering of this model - if (_transforms.empty()) { - _transforms.push_back(Transform()); - } - - auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME - - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const std::vector>& networkMeshes = _geometry->getMeshes(); - - auto networkMaterial = _geometry->getShapeMaterial(shapeID); - if (!networkMaterial) { - return; - }; - auto material = networkMaterial->_material; - if (!material) { - return; - } - - // TODO: Not yet - // auto drawMesh = _geometry->getShapeMesh(shapeID); - // auto drawPart = _geometry->getShapePart(shapeID); - - // guard against partially loaded meshes - if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size() ) { - return; - } - - updateClusterMatrices(); - - const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); - const FBXMesh& mesh = geometry.meshes.at(meshIndex); - const MeshState& state = _meshStates.at(meshIndex); - - auto drawMesh = networkMesh._mesh; - - - auto drawMaterialKey = material->getKey(); - bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); - - bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); - bool hasSpecular = drawMaterialKey.isGlossMap(); // !drawMaterial->specularTextureName.isEmpty(); //mesh.hasSpecularTexture(); - bool hasLightmap = drawMaterialKey.isLightmapMap(); // !drawMaterial->emissiveTextureName.isEmpty(); //mesh.hasEmissiveTexture(); - bool isSkinned = state.clusterMatrices.size() > 1; - bool wireframe = isWireframe(); - - // render the part bounding box -#ifdef DEBUG_BOUNDING_PARTS - { - AABox partBounds = getPartBounds(meshIndex, partIndex); - bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; - - glm::vec4 cubeColor; - if (isSkinned) { - cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); - } else if (inView) { - cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); + + batch.setUniformBuffer(ModelRender::MATERIAL_GPU_SLOT, _drawMaterial->getSchemaBuffer()); + + auto materialKey = _drawMaterial->getKey(); + auto textureMaps = _drawMaterial->getTextureMaps(); + glm::mat4 texcoordTransform[2]; + + // Diffuse + if (materialKey.isDiffuseMap()) { + auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; + if (diffuseMap && diffuseMap->isDefined()) { + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); + + if (!diffuseMap->getTextureTransform().isIdentity()) { + diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); + } } else { - cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); } - - Transform transform; - transform.setTranslation(partBounds.calcCenter()); - transform.setScale(partBounds.getDimensions()); - batch.setModelTransform(transform); - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + } else { + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); } -#endif //def DEBUG_BOUNDING_PARTS - - if (wireframe) { - translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; + + // Normal map + if (materialKey.isNormalMap()) { + auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; + if (normalMap && normalMap->isDefined()) { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, normalMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, textureCache->getBlueTexture()); + } + } else { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, nullptr); } - - Locations* locations = nullptr; - pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, - args, locations); - - // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown - // to false to rebuild out mesh groups. - if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { - _meshGroupsKnown = false; // regenerate these lists next time around. - _readyWhenAdded = false; // in case any of our users are using scenes - invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid - return; // FIXME! + + // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that + if (materialKey.isGlossMap()) { + auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; + if (specularMap && specularMap->isDefined()) { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, specularMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); + } + } else { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, nullptr); } - - int vertexCount = mesh.vertices.size(); - if (vertexCount == 0) { - // sanity check - return; // FIXME! + + // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too + if (materialKey.isLightmapMap()) { + auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; + + if (lightmapMap && lightmapMap->isDefined()) { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); + + auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); + batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); + + if (!lightmapMap->getTextureTransform().isIdentity()) { + lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); + } + } else { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); + } + } else { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, nullptr); } - - // Transform stage - if (_transforms.empty()) { - _transforms.push_back(Transform()); + + // Texcoord transforms ? + if (locations->texcoordMatrices >= 0) { + batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); } - - if (isSkinned) { +} + +void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const { + Transform transform; + // Still relying on the raw data from the + const Model::MeshState& state = model->_meshStates.at(meshIndex); + + if (_isSkinned) { const float* bones; - if (_cauterizeBones) { + if (model->_cauterizeBones) { bones = (const float*)state.cauterizedClusterMatrices.constData(); } else { bones = (const float*)state.clusterMatrices.constData(); } batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones); - _transforms[0] = Transform(); - _transforms[0].preTranslate(_translation); - } else { - if (_cauterizeBones) { - _transforms[0] = Transform(state.cauterizedClusterMatrices[0]); - } else { - _transforms[0] = Transform(state.clusterMatrices[0]); - } - _transforms[0].preTranslate(_translation); - } - batch.setModelTransform(_transforms[0]); - - auto drawPart = drawMesh->getPartBuffer().get(partIndex); - - if (mesh.blendshapes.isEmpty()) { - batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - - batch.setInputFormat((drawMesh->getVertexFormat())); - auto inputStream = drawMesh->makeBufferStream(); - - batch.setInputStream(0, inputStream); - } else { - batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); - batch.setInputFormat((drawMesh->getVertexFormat())); - - batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); - batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); - - auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2); - - batch.setInputStream(2, inputStream); - } - - if (mesh.colors.isEmpty()) { - batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } - - // guard against partially loaded meshes - if (partIndex >= mesh.parts.size()) { - return; - } - - -#ifdef WANT_DEBUG - if (material == nullptr) { - qCDebug(renderutils) << "WARNING: material == nullptr!!!"; - } -#endif - - { - - // apply material properties - if (mode != RenderArgs::SHADOW_RENDER_MODE) { -#ifdef WANT_DEBUG - qCDebug(renderutils) << "Material Changed ---------------------------------------------"; - qCDebug(renderutils) << "part INDEX:" << partIndex; - qCDebug(renderutils) << "NEW part.materialID:" << part.materialID; -#endif //def WANT_DEBUG - - if (locations->materialBufferUnit >= 0) { - batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); - } - - auto materialKey = material->getKey(); - auto textureMaps = material->getTextureMaps(); - glm::mat4 texcoordTransform[2]; - - // Diffuse - if (materialKey.isDiffuseMap()) { - auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; - if (diffuseMap && diffuseMap->isDefined()) { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); - - if (!diffuseMap->getTextureTransform().isIdentity()) { - diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); - } - } else { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - - // Normal map - if ((locations->normalTextureUnit >= 0) && hasTangents) { - auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; - if (normalMap && normalMap->isDefined()) { - batch.setResourceTexture(NORMAL_MAP_SLOT, normalMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(NORMAL_MAP_SLOT, textureCache->getBlueTexture()); - } - } else { - batch.setResourceTexture(NORMAL_MAP_SLOT, nullptr); - } - - // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that - if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) { - auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; - if (specularMap && specularMap->isDefined()) { - batch.setResourceTexture(SPECULAR_MAP_SLOT, specularMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); - } - } else { - batch.setResourceTexture(SPECULAR_MAP_SLOT, nullptr); - } - - // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too - if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) { - auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; - - if (lightmapMap && lightmapMap->isDefined()) { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); - - auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); - batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); - - if (!lightmapMap->getTextureTransform().isIdentity()) { - lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); - } - } - else { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(LIGHTMAP_MAP_SLOT, nullptr); - } - - // Texcoord transforms ? - if (locations->texcoordMatrices >= 0) { - batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); - } - - // TODO: We should be able to do that just in the renderTransparentJob - if (translucentMesh && locations->lightBufferUnit >= 0) { - PerformanceTimer perfTimer("DLE->setupTransparent()"); - - DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); - } - - - if (args) { - args->_details._materialSwitches++; - } - } - } - if (args) { - const int INDICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE; + transform.preTranslate(model->_translation); + } else { + if (model->_cauterizeBones) { + transform = Transform(state.cauterizedClusterMatrices[0]); + } else { + transform = Transform(state.clusterMatrices[0]); + } + transform.preTranslate(model->_translation); } + batch.setModelTransform(transform); } -*/ \ No newline at end of file + diff --git a/libraries/render-utils/src/ModelRenderPayload.h b/libraries/render-utils/src/ModelRenderPayload.h index bee7c186b9..53285f5780 100644 --- a/libraries/render-utils/src/ModelRenderPayload.h +++ b/libraries/render-utils/src/ModelRenderPayload.h @@ -22,6 +22,148 @@ class Model; +class ModelRender { +public: + + static const int MATERIAL_GPU_SLOT = 3; + static const int DIFFUSE_MAP_SLOT = 0; + static const int NORMAL_MAP_SLOT = 1; + static const int SPECULAR_MAP_SLOT = 2; + static const int LIGHTMAP_MAP_SLOT = 3; + static const int LIGHT_BUFFER_SLOT = 4; + + class Locations { + public: + int tangent; + int alphaThreshold; + int texcoordMatrices; + int diffuseTextureUnit; + int normalTextureUnit; + int specularTextureUnit; + int emissiveTextureUnit; + int emissiveParams; + int glowIntensity; + int normalFittingMapUnit; + int materialBufferUnit; + int clusterMatrices; + int clusterIndices; + int clusterWeights; + int lightBufferUnit; + }; + + static void pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold, + bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, + Locations*& locations); + + class RenderKey { + public: + enum FlagBit { + IS_TRANSLUCENT_FLAG = 0, + HAS_LIGHTMAP_FLAG, + HAS_TANGENTS_FLAG, + HAS_SPECULAR_FLAG, + HAS_EMISSIVE_FLAG, + IS_SKINNED_FLAG, + IS_STEREO_FLAG, + IS_DEPTH_ONLY_FLAG, + IS_SHADOW_FLAG, + IS_MIRROR_FLAG, //THis means that the mesh is rendered mirrored, not the same as "Rear view mirror" + IS_WIREFRAME_FLAG, + + NUM_FLAGS, + }; + + enum Flag { + IS_TRANSLUCENT = (1 << IS_TRANSLUCENT_FLAG), + HAS_LIGHTMAP = (1 << HAS_LIGHTMAP_FLAG), + HAS_TANGENTS = (1 << HAS_TANGENTS_FLAG), + HAS_SPECULAR = (1 << HAS_SPECULAR_FLAG), + HAS_EMISSIVE = (1 << HAS_EMISSIVE_FLAG), + IS_SKINNED = (1 << IS_SKINNED_FLAG), + IS_STEREO = (1 << IS_STEREO_FLAG), + IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG), + IS_SHADOW = (1 << IS_SHADOW_FLAG), + IS_MIRROR = (1 << IS_MIRROR_FLAG), + IS_WIREFRAME = (1 << IS_WIREFRAME_FLAG), + }; + typedef unsigned short Flags; + + + + bool isFlag(short flagNum) const { return bool((_flags & flagNum) != 0); } + + bool isTranslucent() const { return isFlag(IS_TRANSLUCENT); } + bool hasLightmap() const { return isFlag(HAS_LIGHTMAP); } + bool hasTangents() const { return isFlag(HAS_TANGENTS); } + bool hasSpecular() const { return isFlag(HAS_SPECULAR); } + bool hasEmissive() const { return isFlag(HAS_EMISSIVE); } + bool isSkinned() const { return isFlag(IS_SKINNED); } + bool isStereo() const { return isFlag(IS_STEREO); } + bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); } + bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing + bool isMirror() const { return isFlag(IS_MIRROR); } + bool isWireFrame() const { return isFlag(IS_WIREFRAME); } + + Flags _flags = 0; + short _spare = 0; + + int getRaw() { return *reinterpret_cast(this); } + + + RenderKey( + bool translucent, bool hasLightmap, + bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) : + RenderKey((translucent ? IS_TRANSLUCENT : 0) + | (hasLightmap ? HAS_LIGHTMAP : 0) + | (hasTangents ? HAS_TANGENTS : 0) + | (hasSpecular ? HAS_SPECULAR : 0) + | (isSkinned ? IS_SKINNED : 0) + | (isWireframe ? IS_WIREFRAME : 0) + ) {} + + RenderKey(RenderArgs::RenderMode mode, + bool translucent, float alphaThreshold, bool hasLightmap, + bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) : + RenderKey(((translucent && (alphaThreshold == 0.0f) && (mode != RenderArgs::SHADOW_RENDER_MODE)) ? IS_TRANSLUCENT : 0) + | (hasLightmap && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_LIGHTMAP : 0) // Lightmap, tangents and specular don't matter for depthOnly + | (hasTangents && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_TANGENTS : 0) + | (hasSpecular && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_SPECULAR : 0) + | (isSkinned ? IS_SKINNED : 0) + | (isWireframe ? IS_WIREFRAME : 0) + | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0) + | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_SHADOW : 0) + | ((mode == RenderArgs::MIRROR_RENDER_MODE) ? IS_MIRROR : 0) + ) {} + + RenderKey(int bitmask) : _flags(bitmask) {} + }; + + + class RenderPipeline { + public: + gpu::PipelinePointer _pipeline; + std::shared_ptr _locations; + RenderPipeline(gpu::PipelinePointer pipeline, std::shared_ptr locations) : + _pipeline(pipeline), _locations(locations) {} + }; + + typedef std::unordered_map BaseRenderPipelineMap; + class RenderPipelineLib : public BaseRenderPipelineMap { + public: + typedef RenderKey Key; + + + void addRenderPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader); + + void initLocations(gpu::ShaderPointer& program, Locations& locations); + }; + static RenderPipelineLib _renderPipelineLib; + + static const ModelRender::RenderPipelineLib& ModelRender::getRenderPipelineLib(); + +}; + + class MeshPartPayload { public: MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex); @@ -41,15 +183,30 @@ public: void render(RenderArgs* args) const; // MeshPartPayload functions to perform render - void bindMesh(gpu::Batch& batch) const; void drawCall(gpu::Batch& batch) const; - + void bindMesh(gpu::Batch& batch) const; + void bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const; + void bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const; + + + void initCache(); + + // Payload resource cached values model::MeshPointer _drawMesh; model::Mesh::Part _drawPart; model::MaterialPointer _drawMaterial; - + bool _hasColorAttrib = false; + bool _isSkinned = false; + bool _isBlendShaped = false; + mutable render::Item::Bound _bound; mutable bool _isBoundInvalid = true; }; +namespace render { + template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload); + template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args); +} + #endif // hifi_ModelRenderPayload_h \ No newline at end of file diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh new file mode 100644 index 0000000000..c1f45f951b --- /dev/null +++ b/libraries/render-utils/src/Skinning.slh @@ -0,0 +1,68 @@ + +<@if not SKINNING_SLH@> +<@def SKINNING_SLH@> + +const int MAX_TEXCOORDS = 2; +const int MAX_CLUSTERS = 128; +const int INDICES_PER_VERTEX = 4; + +uniform mat4 clusterMatrices[MAX_CLUSTERS]; + +void skinPosition(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) { + vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < INDICES_PER_VERTEX; i++) { + mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + float clusterWeight = skinClusterWeight[i]; + newPosition += clusterMatrix * inPosition * clusterWeight; + } + + skinnedPosition = newPosition; +} + +void skinPositionNormal(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, + out vec4 skinnedPosition, out vec3 skinnedNormal) { + vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); + vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < INDICES_PER_VERTEX; i++) { + mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + float clusterWeight = skinClusterWeight[i]; + newPosition += clusterMatrix * inPosition * clusterWeight; + newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; + } + + skinnedPosition = newPosition; + skinnedNormal = newNormal.xyz; +} + +void skinPositionNormalTangent(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent, + out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) { + vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); + vec4 newNormal = vec4(0.0, 0.0, 0.0, 0.0); + vec4 newTangent = vec4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < INDICES_PER_VERTEX; i++) { + mat4 clusterMatrix = clusterMatrices[int(skinClusterIndex[i])]; + float clusterWeight = skinClusterWeight[i]; + newPosition += clusterMatrix * inPosition * clusterWeight; + newNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; + newTangent += clusterMatrix * vec4(inTangent.xyz, 0.0) * clusterWeight; + } + + skinnedPosition = newPosition; + skinnedNormal = newNormal.xyz; + skinnedTangent = newTangent.xyz; +} + + +<@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index 53e68727fb..bb2058b5f8 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -18,11 +18,8 @@ <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; -const int MAX_CLUSTERS = 128; -const int INDICES_PER_VERTEX = 4; +<@include Skinning.slh@> -uniform mat4 clusterMatrices[MAX_CLUSTERS]; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; out vec4 _position; @@ -32,13 +29,9 @@ out vec3 _color; void main(void) { vec4 position = vec4(0.0, 0.0, 0.0, 0.0); - vec4 interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(inSkinClusterIndex[i])]; - float clusterWeight = inSkinClusterWeight[i]; - position += clusterMatrix * inPosition * clusterWeight; - interpolatedNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; - } + vec3 interpolatedNormal = vec3(0.0, 0.0, 0.0); + + skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal); // pass along the diffuse color _color = inColor.rgb; diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index 4c558939d8..f198cb5f77 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -18,11 +18,8 @@ <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; -const int MAX_CLUSTERS = 128; -const int INDICES_PER_VERTEX = 4; +<@include Skinning.slh@> -uniform mat4 clusterMatrices[MAX_CLUSTERS]; uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; out vec4 _position; @@ -35,13 +32,8 @@ void main(void) { vec4 position = vec4(0.0, 0.0, 0.0, 0.0); vec4 interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); vec4 interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(inSkinClusterIndex[i])]; - float clusterWeight = inSkinClusterWeight[i]; - position += clusterMatrix * inPosition * clusterWeight; - interpolatedNormal += clusterMatrix * vec4(inNormal.xyz, 0.0) * clusterWeight; - interpolatedTangent += clusterMatrix * vec4(inTangent.xyz, 0.0) * clusterWeight; - } + + skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz); // pass along the diffuse color _color = inColor.rgb; diff --git a/libraries/render-utils/src/skin_model_shadow.slv b/libraries/render-utils/src/skin_model_shadow.slv index 6cb4da25f4..9c00f9065b 100755 --- a/libraries/render-utils/src/skin_model_shadow.slv +++ b/libraries/render-utils/src/skin_model_shadow.slv @@ -16,18 +16,11 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -const int MAX_CLUSTERS = 128; -const int INDICES_PER_VERTEX = 4; - -uniform mat4 clusterMatrices[MAX_CLUSTERS]; +<@include Skinning.slh@> void main(void) { vec4 position = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < INDICES_PER_VERTEX; i++) { - mat4 clusterMatrix = clusterMatrices[int(inSkinClusterIndex[i])]; - float clusterWeight = inSkinClusterWeight[i]; - position += clusterMatrix * inPosition * clusterWeight; - } + skinPosition(inSkinClusterIndex, inSkinClusterWeight, inPosition, position); // standard transform TransformCamera cam = getTransformCamera(); From 4270b83c0f09f5d178c538b4a9cd4998113e6537 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 5 Oct 2015 23:33:58 -0700 Subject: [PATCH 061/152] Uniform buffer for skeleton joint bind pose --- .../render-utils/src/ModelRenderPayload.cpp | 28 ++++---------- .../render-utils/src/ModelRenderPayload.h | 10 ++--- libraries/render-utils/src/Skinning.slh | 38 ++++++++++--------- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/libraries/render-utils/src/ModelRenderPayload.cpp b/libraries/render-utils/src/ModelRenderPayload.cpp index e4998e445a..31321f402f 100644 --- a/libraries/render-utils/src/ModelRenderPayload.cpp +++ b/libraries/render-utils/src/ModelRenderPayload.cpp @@ -170,6 +170,8 @@ void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey ke gpu::ShaderPointer& pixelShader) { gpu::Shader::BindingSet slotBindings; + + slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), ModelRender::SKINNING_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), ModelRender::MATERIAL_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), ModelRender::DIFFUSE_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), ModelRender::NORMAL_MAP_SLOT)); @@ -258,9 +260,7 @@ void ModelRender::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); - locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); - locations.clusterIndices = program->getInputs().findLocation("inSkinClusterIndex"); - locations.clusterWeights = program->getInputs().findLocation("inSkinClusterWeight"); + locations.skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer"); } @@ -322,10 +322,6 @@ namespace render { template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { return payload->render(args); } - - /* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) { - return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex); - }*/ } using namespace render; @@ -502,28 +498,20 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locatio } void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const { - Transform transform; - // Still relying on the raw data from the + // Still relying on the raw data from the model const Model::MeshState& state = model->_meshStates.at(meshIndex); - if (_isSkinned) { - const float* bones; - if (model->_cauterizeBones) { - bones = (const float*)state.cauterizedClusterMatrices.constData(); - } else { - bones = (const float*)state.clusterMatrices.constData(); - } - batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones); - - transform.preTranslate(model->_translation); + Transform transform; + if (state.clusterBuffer) { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); } else { if (model->_cauterizeBones) { transform = Transform(state.cauterizedClusterMatrices[0]); } else { transform = Transform(state.clusterMatrices[0]); } - transform.preTranslate(model->_translation); } + transform.preTranslate(model->_translation); batch.setModelTransform(transform); } diff --git a/libraries/render-utils/src/ModelRenderPayload.h b/libraries/render-utils/src/ModelRenderPayload.h index 53285f5780..c193a77540 100644 --- a/libraries/render-utils/src/ModelRenderPayload.h +++ b/libraries/render-utils/src/ModelRenderPayload.h @@ -24,7 +24,8 @@ class Model; class ModelRender { public: - + + static const int SKINNING_GPU_SLOT = 2; static const int MATERIAL_GPU_SLOT = 3; static const int DIFFUSE_MAP_SLOT = 0; static const int NORMAL_MAP_SLOT = 1; @@ -34,7 +35,6 @@ public: class Locations { public: - int tangent; int alphaThreshold; int texcoordMatrices; int diffuseTextureUnit; @@ -45,9 +45,7 @@ public: int glowIntensity; int normalFittingMapUnit; int materialBufferUnit; - int clusterMatrices; - int clusterIndices; - int clusterWeights; + int skinClusterBufferUnit; int lightBufferUnit; }; @@ -159,7 +157,7 @@ public: }; static RenderPipelineLib _renderPipelineLib; - static const ModelRender::RenderPipelineLib& ModelRender::getRenderPipelineLib(); + static const RenderPipelineLib& getRenderPipelineLib(); }; diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index c1f45f951b..747f18ab34 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -1,21 +1,25 @@ - -<@if not SKINNING_SLH@> + +<@if not SKINNING_SLH@> <@def SKINNING_SLH@> const int MAX_TEXCOORDS = 2; const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; -uniform mat4 clusterMatrices[MAX_CLUSTERS]; +//uniform mat4 clusterMatrices[MAX_CLUSTERS]; + +layout(std140) uniform skinClusterBuffer { + mat4 clusterMatrices[MAX_CLUSTERS]; +}; void skinPosition(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, out vec4 skinnedPosition) { vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); @@ -43,8 +47,8 @@ void skinPositionNormal(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPo skinnedPosition = newPosition; skinnedNormal = newNormal.xyz; -} - +} + void skinPositionNormalTangent(vec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPosition, vec3 inNormal, vec3 inTangent, out vec4 skinnedPosition, out vec3 skinnedNormal, out vec3 skinnedTangent) { vec4 newPosition = vec4(0.0, 0.0, 0.0, 0.0); @@ -62,7 +66,7 @@ void skinPositionNormalTangent(vec4 skinClusterIndex, vec4 skinClusterWeight, ve skinnedPosition = newPosition; skinnedNormal = newNormal.xyz; skinnedTangent = newTangent.xyz; -} - - +} + + <@endif@> \ No newline at end of file From fc7f0c77a5e06f82d773e728c2e4681d87a445bd Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 00:20:51 -0700 Subject: [PATCH 062/152] Rename ModelRenderPayload files to ModelRenderItem --- libraries/render-utils/src/Model.cpp | 2 +- .../src/{ModelRenderPayload.cpp => ModelRenderItem.cpp} | 4 ++-- .../src/{ModelRenderPayload.h => ModelRenderItem.h} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename libraries/render-utils/src/{ModelRenderPayload.cpp => ModelRenderItem.cpp} (99%) rename libraries/render-utils/src/{ModelRenderPayload.h => ModelRenderItem.h} (99%) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index a86cd305dc..0d9a403923 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -25,7 +25,7 @@ #include "AnimationHandle.h" #include "DeferredLightingEffect.h" #include "Model.h" -#include "ModelRenderPayload.h" +#include "ModelRenderItem.h" #include "RenderUtilsLogging.h" diff --git a/libraries/render-utils/src/ModelRenderPayload.cpp b/libraries/render-utils/src/ModelRenderItem.cpp similarity index 99% rename from libraries/render-utils/src/ModelRenderPayload.cpp rename to libraries/render-utils/src/ModelRenderItem.cpp index 31321f402f..e2118a8f0b 100644 --- a/libraries/render-utils/src/ModelRenderPayload.cpp +++ b/libraries/render-utils/src/ModelRenderItem.cpp @@ -1,5 +1,5 @@ // -// ModelRenderPayload.cpp +// ModelRenderItem.cpp // interface/src/renderer // // Created by Sam Gateau on 10/3/15. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ModelRenderPayload.h" +#include "ModelRenderItem.h" #include "DeferredLightingEffect.h" diff --git a/libraries/render-utils/src/ModelRenderPayload.h b/libraries/render-utils/src/ModelRenderItem.h similarity index 99% rename from libraries/render-utils/src/ModelRenderPayload.h rename to libraries/render-utils/src/ModelRenderItem.h index c193a77540..658d2d2cae 100644 --- a/libraries/render-utils/src/ModelRenderPayload.h +++ b/libraries/render-utils/src/ModelRenderItem.h @@ -1,5 +1,5 @@ // -// ModelRenderPayload.h +// ModelRenderItem.h // interface/src/renderer // // Created by Sam Gateau on 10/3/15. From 59afbf1a04ba3c19bb78c518b9748ece6b2d4e5c Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 01:15:53 -0700 Subject: [PATCH 063/152] Remove the renderPart call from model.cpp and put the code path in the MeshPartPayload::render() --- libraries/render-utils/src/Model.cpp | 141 ------------------ libraries/render-utils/src/Model.h | 1 - .../render-utils/src/ModelRenderItem.cpp | 131 +++++++++++++++- 3 files changed, 126 insertions(+), 147 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 0d9a403923..9a2d9e3dc5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1140,147 +1140,6 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { return AABox(); } -void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload) { -// PROFILE_RANGE(__FUNCTION__); - PerformanceTimer perfTimer("Model::renderPart"); - if (!_readyWhenAdded) { - return; // bail asap - } - - auto textureCache = DependencyManager::get(); - - gpu::Batch& batch = *(args->_batch); - auto mode = args->_renderMode; - - auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME - - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const std::vector>& networkMeshes = _geometry->getMeshes(); - - auto networkMaterial = _geometry->getShapeMaterial(shapeID); - if (!networkMaterial) { - return; - }; - auto material = networkMaterial->_material; - if (!material) { - return; - } - - // TODO: Not yet - // auto drawMesh = _geometry->getShapeMesh(shapeID); - // auto drawPart = _geometry->getShapePart(shapeID); - - // guard against partially loaded meshes - if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size() ) { - return; - } - - updateClusterMatrices(); - - const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); - const FBXMesh& mesh = geometry.meshes.at(meshIndex); - const MeshState& state = _meshStates.at(meshIndex); - - // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown - // to false to rebuild out mesh groups. - if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { - _meshGroupsKnown = false; // regenerate these lists next time around. - _readyWhenAdded = false; // in case any of our users are using scenes - invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid - return; // FIXME! - } - - - int vertexCount = mesh.vertices.size(); - if (vertexCount == 0) { - // sanity check - return; // FIXME! - } - - auto drawMaterialKey = material->getKey(); - bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); - - bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); - bool hasSpecular = drawMaterialKey.isGlossMap(); // !drawMaterial->specularTextureName.isEmpty(); //mesh.hasSpecularTexture(); - bool hasLightmap = drawMaterialKey.isLightmapMap(); // !drawMaterial->emissiveTextureName.isEmpty(); //mesh.hasEmissiveTexture(); - bool isSkinned = state.clusterMatrices.size() > 1; - bool wireframe = isWireframe(); - - // render the part bounding box - #ifdef DEBUG_BOUNDING_PARTS - { - AABox partBounds = getPartBounds(meshIndex, partIndex); - bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; - - glm::vec4 cubeColor; - if (isSkinned) { - cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); - } else if (inView) { - cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); - } else { - cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); - } - - Transform transform; - transform.setTranslation(partBounds.calcCenter()); - transform.setScale(partBounds.getDimensions()); - batch.setModelTransform(transform); - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); - } - #endif //def DEBUG_BOUNDING_PARTS - - if (wireframe) { - translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; - } - - ModelRender::Locations* locations = nullptr; - ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, - args, locations); - - - payload->bindTransform(batch, locations); - - payload->bindMesh(batch); - - // guard against partially loaded meshes - if (partIndex >= mesh.parts.size()) { - return; - } - - - #ifdef WANT_DEBUG - if (material == nullptr) { - qCDebug(renderutils) << "WARNING: material == nullptr!!!"; - } - #endif - - { - // apply material properties - payload->bindMaterial(batch, locations); - - - // TODO: We should be able to do that just in the renderTransparentJob - if (translucentMesh && locations->lightBufferUnit >= 0) { - PerformanceTimer perfTimer("DLE->setupTransparent()"); - - DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); - } - if (args) { - args->_details._materialSwitches++; - } - } - - { - PerformanceTimer perfTimer("batch.drawIndexed()"); - payload->drawCall(batch); - } - - if (args) { - const int INDICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += payload->_drawPart._numIndices / INDICES_PER_TRIANGLE; - } -} - void Model::segregateMeshGroups() { const FBXGeometry& geometry = _geometry->getFBXGeometry(); const std::vector>& networkMeshes = _geometry->getMeshes(); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 108480e4ef..8937ecb94c 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -89,7 +89,6 @@ public: bool isVisible() const { return _isVisible; } AABox getPartBounds(int meshIndex, int partIndex); - void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload); bool maybeStartBlender(); diff --git a/libraries/render-utils/src/ModelRenderItem.cpp b/libraries/render-utils/src/ModelRenderItem.cpp index e2118a8f0b..4ddb7fac66 100644 --- a/libraries/render-utils/src/ModelRenderItem.cpp +++ b/libraries/render-utils/src/ModelRenderItem.cpp @@ -11,6 +11,8 @@ #include "ModelRenderItem.h" +#include + #include "DeferredLightingEffect.h" #include "Model.h" @@ -268,7 +270,7 @@ void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, b bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, Locations*& locations) { - // PerformanceTimer perfTimer("Model::pickPrograms"); + PerformanceTimer perfTimer("ModelRender::pickPrograms"); getRenderPipelineLib(); RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); @@ -383,10 +385,6 @@ render::Item::Bound MeshPartPayload::getBound() const { return _bound; } -void MeshPartPayload::render(RenderArgs* args) const { - return model->renderPart(args, meshIndex, partIndex, _shapeID, this); -} - void MeshPartPayload::drawCall(gpu::Batch& batch) const { batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); } @@ -515,3 +513,126 @@ void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locati batch.setModelTransform(transform); } + +void MeshPartPayload::render(RenderArgs* args) const { + PerformanceTimer perfTimer("MeshPartPayload::render"); + if (!model->_readyWhenAdded) { + return; // bail asap + } + + gpu::Batch& batch = *(args->_batch); + auto mode = args->_renderMode; + + auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + + const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); + const std::vector>& networkMeshes = model->_geometry->getMeshes(); + + // guard against partially loaded meshes + if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)model->_meshStates.size() ) { + return; + } + + // Back to model to update the cluster matrices right now + model->updateClusterMatrices(); + + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + + // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown + // to false to rebuild out mesh groups. + if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { + model->_meshGroupsKnown = false; // regenerate these lists next time around. + model->_readyWhenAdded = false; // in case any of our users are using scenes + model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid + return; // FIXME! + } + + + int vertexCount = mesh.vertices.size(); + if (vertexCount == 0) { + // sanity check + return; // FIXME! + } + + + // guard against partially loaded meshes + if (partIndex >= mesh.parts.size()) { + return; + } + + model::MaterialKey drawMaterialKey; + if (_drawMaterial) { + drawMaterialKey = _drawMaterial->getKey(); + } + bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); + + bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); + bool hasSpecular = drawMaterialKey.isGlossMap(); + bool hasLightmap = drawMaterialKey.isLightmapMap(); + bool isSkinned = _isSkinned; + bool wireframe = model->isWireframe(); + + // render the part bounding box +#ifdef DEBUG_BOUNDING_PARTS + { + AABox partBounds = getPartBounds(meshIndex, partIndex); + bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; + + glm::vec4 cubeColor; + if (isSkinned) { + cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); + } else if (inView) { + cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); + } else { + cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); + } + + Transform transform; + transform.setTranslation(partBounds.calcCenter()); + transform.setScale(partBounds.getDimensions()); + batch.setModelTransform(transform); + DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + } +#endif //def DEBUG_BOUNDING_PARTS + + if (wireframe) { + translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; + } + + ModelRender::Locations* locations = nullptr; + ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, + args, locations); + + + // Bind the model transform and the skinCLusterMatrices if needed + bindTransform(batch, locations); + + //Bind the index buffer and vertex buffer and Blend shapes if needed + bindMesh(batch); + + // apply material properties + bindMaterial(batch, locations); + + + // TODO: We should be able to do that just in the renderTransparentJob + if (translucentMesh && locations->lightBufferUnit >= 0) { + PerformanceTimer perfTimer("DLE->setupTransparent()"); + + DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); + } + if (args) { + args->_details._materialSwitches++; + } + + // Draw! + { + PerformanceTimer perfTimer("batch.drawIndexed()"); + drawCall(batch); + } + + if (args) { + const int INDICES_PER_TRIANGLE = 3; + args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE; + } +} + From 152fdb811212e7d501c70814204da1f669f0a4ae Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 09:44:00 -0700 Subject: [PATCH 064/152] physical rack --- examples/toys/basketball_hoop/createRack.js | 41 ++++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/examples/toys/basketball_hoop/createRack.js b/examples/toys/basketball_hoop/createRack.js index 726f25eb33..a223a1064a 100644 --- a/examples/toys/basketball_hoop/createRack.js +++ b/examples/toys/basketball_hoop/createRack.js @@ -9,16 +9,21 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("../../libraries/utils.js"); + var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; -var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_hoop_collision_hull.obj"; -var basketballSwitcherURL= Script.resolvePath('basketballSwitcher.js'); +var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; +var basketballSwitcherURL = Script.resolvePath('basketballSwitcher.js'); +var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; +var GRABBABLE_DATA_KEY = "grabbableKey"; + var rackStartPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { @@ -28,25 +33,31 @@ var rackStartPosition = })); var rack = Entities.addEntity({ + name:'Basketball Rack', type: "Model", modelURL: rackURL, position: rackStartPosition, shapeType: 'compound', - // gravity: { - // x: 0, - // y: -9.8, - // z: 0 - // }, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + linearDamping:1, dimensions: { x: 0.4, y: 1.37, z: 1.73 }, - collisionsWillMove: false, + collisionsWillMove: true, ignoreForCollisions: false, compoundShapeURL: rackCollisionHullURL }); +setEntityCustomData(GRABBABLE_DATA_KEY, rack, { + grabbable: false +}); + var nonCollidingBalls = []; var collidingBalls = []; @@ -100,11 +111,11 @@ function createNonCollidingBalls() { function createCollidingBalls() { var position = rackStartPosition; var i; - for (i = 0; i < 4; i++) { + for (i = 0; i < NUMBER_OF_BALLS; i++) { var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', - shapeType:'Sphere', + shapeType: 'Sphere', position: { x: position.x, y: position.y + DIAMETER * 2, @@ -116,15 +127,19 @@ function createCollidingBalls() { z: DIAMETER }, restitution: 1.0, - linearDamping: 1, + linearDamping: 0.00001, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, collisionsWillMove: true, ignoreForCollisions: false, modelURL: basketballURL, - script:basketballSwitcherURL }); collidingBalls.push(collidingBall); } } -createNonCollidingBalls(); +// createNonCollidingBalls(); createCollidingBalls(); \ No newline at end of file From c92a6d58ab0d3d97f373683906d702e0d4cbd807 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 09:46:32 -0700 Subject: [PATCH 065/152] Dispatch classes in their properly named files to appease the coding standard gods --- .../render-utils/src/MeshPartPayload.cpp | 349 ++++++++++++++++++ libraries/render-utils/src/MeshPartPayload.h | 69 ++++ libraries/render-utils/src/Model.cpp | 3 +- libraries/render-utils/src/Model.h | 2 - .../{ModelRenderItem.cpp => ModelRender.cpp} | 347 +---------------- .../src/{ModelRenderItem.h => ModelRender.h} | 69 +--- 6 files changed, 436 insertions(+), 403 deletions(-) create mode 100644 libraries/render-utils/src/MeshPartPayload.cpp create mode 100644 libraries/render-utils/src/MeshPartPayload.h rename libraries/render-utils/src/{ModelRenderItem.cpp => ModelRender.cpp} (53%) rename libraries/render-utils/src/{ModelRenderItem.h => ModelRender.h} (76%) diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp new file mode 100644 index 0000000000..d1db4e6c7f --- /dev/null +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -0,0 +1,349 @@ +// +// MeshPartPayload.cpp +// interface/src/renderer +// +// Created by Sam Gateau on 10/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "MeshPartPayload.h" + +#include + +#include "DeferredLightingEffect.h" + +#include "Model.h" + +namespace render { + template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getKey(); + } + // Return opaque for lack of a better idea + return ItemKey::Builder::opaqueShape(); + } + + template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return render::Item::Bound(); + } + template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { + return payload->render(args); + } +} + +using namespace render; + +MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : + model(model), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) +{ + initCache(); +} + +void MeshPartPayload::initCache() { + const std::vector>& networkMeshes = model->_geometry->getMeshes(); + const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); + _drawMesh = networkMesh._mesh; + + const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + _hasColorAttrib = !mesh.colors.isEmpty(); + _isBlendShaped = !mesh.blendshapes.isEmpty(); + _isSkinned = !mesh.clusterIndices.isEmpty(); + + + _drawPart = _drawMesh->getPartBuffer().get(partIndex); + + auto networkMaterial = model->_geometry->getShapeMaterial(_shapeID); + if (networkMaterial) { + _drawMaterial = networkMaterial->_material; + }; + +} + +render::ItemKey MeshPartPayload::getKey() const { + ItemKey::Builder builder; + builder.withTypeShape(); + + if (!model->isVisible()) { + builder.withInvisible(); + } + + if (_isBlendShaped || _isSkinned) { + builder.withDeformed(); + } + + if (_drawMaterial) { + auto matKey = _drawMaterial->getKey(); + if (matKey.isTransparent() || matKey.isTransparentMap()) { + builder.withTransparent(); + } + } + + return builder.build(); +} + +render::Item::Bound MeshPartPayload::getBound() const { + if (_isBoundInvalid) { + model->getPartBounds(meshIndex, partIndex); + _isBoundInvalid = false; + } + return _bound; +} + +void MeshPartPayload::drawCall(gpu::Batch& batch) const { + batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); +} + +void MeshPartPayload::bindMesh(gpu::Batch& batch) const { + if (!_isBlendShaped) { + batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); + + batch.setInputFormat((_drawMesh->getVertexFormat())); + + batch.setInputStream(0, _drawMesh->getVertexStream()); + } else { + batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); + + batch.setInputFormat((_drawMesh->getVertexFormat())); + + batch.setInputBuffer(0, model->_blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); + batch.setInputBuffer(1, model->_blendedVertexBuffers[meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); + batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); + } + + // TODO: Get rid of that extra call + if (!_hasColorAttrib) { + batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + } +} + +void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const { + if (!_drawMaterial) { + return; + } + + auto textureCache = DependencyManager::get(); + + batch.setUniformBuffer(ModelRender::MATERIAL_GPU_SLOT, _drawMaterial->getSchemaBuffer()); + + auto materialKey = _drawMaterial->getKey(); + auto textureMaps = _drawMaterial->getTextureMaps(); + glm::mat4 texcoordTransform[2]; + + // Diffuse + if (materialKey.isDiffuseMap()) { + auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; + if (diffuseMap && diffuseMap->isDefined()) { + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); + + if (!diffuseMap->getTextureTransform().isIdentity()) { + diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); + } + } else { + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); + } + } else { + batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); + } + + // Normal map + if (materialKey.isNormalMap()) { + auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; + if (normalMap && normalMap->isDefined()) { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, normalMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, textureCache->getBlueTexture()); + } + } else { + batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, nullptr); + } + + // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that + if (materialKey.isGlossMap()) { + auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; + if (specularMap && specularMap->isDefined()) { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, specularMap->getTextureView()); + + // texcoord are assumed to be the same has diffuse + } else { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); + } + } else { + batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, nullptr); + } + + // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too + if (materialKey.isLightmapMap()) { + auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; + + if (lightmapMap && lightmapMap->isDefined()) { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); + + auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); + batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); + + if (!lightmapMap->getTextureTransform().isIdentity()) { + lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); + } + } else { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); + } + } else { + batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, nullptr); + } + + // Texcoord transforms ? + if (locations->texcoordMatrices >= 0) { + batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); + } +} + +void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const { + // Still relying on the raw data from the model + const Model::MeshState& state = model->_meshStates.at(meshIndex); + + Transform transform; + if (state.clusterBuffer) { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); + } else { + if (model->_cauterizeBones) { + transform = Transform(state.cauterizedClusterMatrices[0]); + } else { + transform = Transform(state.clusterMatrices[0]); + } + } + transform.preTranslate(model->_translation); + batch.setModelTransform(transform); +} + + +void MeshPartPayload::render(RenderArgs* args) const { + PerformanceTimer perfTimer("MeshPartPayload::render"); + if (!model->_readyWhenAdded) { + return; // bail asap + } + + gpu::Batch& batch = *(args->_batch); + auto mode = args->_renderMode; + + auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + + const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); + const std::vector>& networkMeshes = model->_geometry->getMeshes(); + + // guard against partially loaded meshes + if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)model->_meshStates.size() ) { + return; + } + + // Back to model to update the cluster matrices right now + model->updateClusterMatrices(); + + const FBXMesh& mesh = geometry.meshes.at(meshIndex); + + // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown + // to false to rebuild out mesh groups. + if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { + model->_meshGroupsKnown = false; // regenerate these lists next time around. + model->_readyWhenAdded = false; // in case any of our users are using scenes + model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid + return; // FIXME! + } + + + int vertexCount = mesh.vertices.size(); + if (vertexCount == 0) { + // sanity check + return; // FIXME! + } + + + // guard against partially loaded meshes + if (partIndex >= mesh.parts.size()) { + return; + } + + model::MaterialKey drawMaterialKey; + if (_drawMaterial) { + drawMaterialKey = _drawMaterial->getKey(); + } + bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); + + bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); + bool hasSpecular = drawMaterialKey.isGlossMap(); + bool hasLightmap = drawMaterialKey.isLightmapMap(); + bool isSkinned = _isSkinned; + bool wireframe = model->isWireframe(); + + // render the part bounding box +#ifdef DEBUG_BOUNDING_PARTS + { + AABox partBounds = getPartBounds(meshIndex, partIndex); + bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; + + glm::vec4 cubeColor; + if (isSkinned) { + cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); + } else if (inView) { + cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); + } else { + cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); + } + + Transform transform; + transform.setTranslation(partBounds.calcCenter()); + transform.setScale(partBounds.getDimensions()); + batch.setModelTransform(transform); + DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); + } +#endif //def DEBUG_BOUNDING_PARTS + + if (wireframe) { + translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; + } + + ModelRender::Locations* locations = nullptr; + ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, + args, locations); + + + // Bind the model transform and the skinCLusterMatrices if needed + bindTransform(batch, locations); + + //Bind the index buffer and vertex buffer and Blend shapes if needed + bindMesh(batch); + + // apply material properties + bindMaterial(batch, locations); + + + // TODO: We should be able to do that just in the renderTransparentJob + if (translucentMesh && locations->lightBufferUnit >= 0) { + PerformanceTimer perfTimer("DLE->setupTransparent()"); + + DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); + } + if (args) { + args->_details._materialSwitches++; + } + + // Draw! + { + PerformanceTimer perfTimer("batch.drawIndexed()"); + drawCall(batch); + } + + if (args) { + const int INDICES_PER_TRIANGLE = 3; + args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE; + } +} + diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h new file mode 100644 index 0000000000..7e476445e6 --- /dev/null +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -0,0 +1,69 @@ +// +// MeshPartPayload.h +// interface/src/renderer +// +// Created by Sam Gateau on 10/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_MeshPartPayload_h +#define hifi_MeshPartPayload_h + +#include + +#include + +#include + +#include "ModelRender.h" + +class Model; + +class MeshPartPayload { +public: + MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex); + + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + Model* model; + int meshIndex; + int partIndex; + int _shapeID; + + // Render Item interface + render::ItemKey getKey() const; + render::Item::Bound getBound() const; + void render(RenderArgs* args) const; + + // MeshPartPayload functions to perform render + void drawCall(gpu::Batch& batch) const; + void bindMesh(gpu::Batch& batch) const; + void bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const; + void bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const; + + + void initCache(); + + // Payload resource cached values + model::MeshPointer _drawMesh; + model::Mesh::Part _drawPart; + model::MaterialPointer _drawMaterial; + bool _hasColorAttrib = false; + bool _isSkinned = false; + bool _isBlendShaped = false; + + mutable render::Item::Bound _bound; + mutable bool _isBoundInvalid = true; +}; + +namespace render { + template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload); + template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args); +} + +#endif // hifi_MeshPartPayload_h \ No newline at end of file diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9a2d9e3dc5..2fe95ef64f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -23,9 +23,8 @@ #include "AbstractViewStateInterface.h" #include "AnimationHandle.h" -#include "DeferredLightingEffect.h" #include "Model.h" -#include "ModelRenderItem.h" +#include "MeshPartPayload.h" #include "RenderUtilsLogging.h" diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 8937ecb94c..98341e1a3d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #include diff --git a/libraries/render-utils/src/ModelRenderItem.cpp b/libraries/render-utils/src/ModelRender.cpp similarity index 53% rename from libraries/render-utils/src/ModelRenderItem.cpp rename to libraries/render-utils/src/ModelRender.cpp index 4ddb7fac66..f6b93ce356 100644 --- a/libraries/render-utils/src/ModelRenderItem.cpp +++ b/libraries/render-utils/src/ModelRender.cpp @@ -1,5 +1,5 @@ // -// ModelRenderItem.cpp +// ModelRender.cpp // interface/src/renderer // // Created by Sam Gateau on 10/3/15. @@ -9,14 +9,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "ModelRenderItem.h" +#include "ModelRender.h" -#include +#include #include "DeferredLightingEffect.h" -#include "Model.h" - #include "model_vert.h" #include "model_shadow_vert.h" #include "model_normal_map_vert.h" @@ -172,8 +170,6 @@ void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey ke gpu::ShaderPointer& pixelShader) { gpu::Shader::BindingSet slotBindings; - - slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), ModelRender::SKINNING_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), ModelRender::MATERIAL_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), ModelRender::DIFFUSE_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), ModelRender::NORMAL_MAP_SLOT)); @@ -262,7 +258,9 @@ void ModelRender::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); - locations.skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer"); + locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); + locations.clusterIndices = program->getInputs().findLocation("inSkinClusterIndex"); + locations.clusterWeights = program->getInputs().findLocation("inSkinClusterWeight"); } @@ -270,7 +268,7 @@ void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, b bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, Locations*& locations) { - PerformanceTimer perfTimer("ModelRender::pickPrograms"); + // PerformanceTimer perfTimer("Model::pickPrograms"); getRenderPipelineLib(); RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); @@ -305,334 +303,3 @@ void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, b DependencyManager::get()->getNormalFittingTexture()); } } - -namespace render { - template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { - if (payload) { - return payload->getKey(); - } - // Return opaque for lack of a better idea - return ItemKey::Builder::opaqueShape(); - } - - template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { - if (payload) { - return payload->getBound(); - } - return render::Item::Bound(); - } - template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) { - return payload->render(args); - } -} - -using namespace render; - -MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) : - model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex) -{ - initCache(); -} - -void MeshPartPayload::initCache() { - const std::vector>& networkMeshes = model->_geometry->getMeshes(); - const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get()); - _drawMesh = networkMesh._mesh; - - const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); - const FBXMesh& mesh = geometry.meshes.at(meshIndex); - _hasColorAttrib = !mesh.colors.isEmpty(); - _isBlendShaped = !mesh.blendshapes.isEmpty(); - _isSkinned = !mesh.clusterIndices.isEmpty(); - - - _drawPart = _drawMesh->getPartBuffer().get(partIndex); - - auto networkMaterial = model->_geometry->getShapeMaterial(_shapeID); - if (networkMaterial) { - _drawMaterial = networkMaterial->_material; - }; - -} - -render::ItemKey MeshPartPayload::getKey() const { - ItemKey::Builder builder; - builder.withTypeShape(); - - if (!model->isVisible()) { - builder.withInvisible(); - } - - if (_isBlendShaped || _isSkinned) { - builder.withDeformed(); - } - - if (_drawMaterial) { - auto matKey = _drawMaterial->getKey(); - if (matKey.isTransparent() || matKey.isTransparentMap()) { - builder.withTransparent(); - } - } - - return builder.build(); -} - -render::Item::Bound MeshPartPayload::getBound() const { - if (_isBoundInvalid) { - model->getPartBounds(meshIndex, partIndex); - _isBoundInvalid = false; - } - return _bound; -} - -void MeshPartPayload::drawCall(gpu::Batch& batch) const { - batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex); -} - -void MeshPartPayload::bindMesh(gpu::Batch& batch) const { - if (!_isBlendShaped) { - batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); - - batch.setInputFormat((_drawMesh->getVertexFormat())); - - batch.setInputStream(0, _drawMesh->getVertexStream()); - } else { - batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0); - - batch.setInputFormat((_drawMesh->getVertexFormat())); - - batch.setInputBuffer(0, model->_blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); - batch.setInputBuffer(1, model->_blendedVertexBuffers[meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3)); - batch.setInputStream(2, _drawMesh->getVertexStream().makeRangedStream(2)); - } - - // TODO: Get rid of that extra call - if (!_hasColorAttrib) { - batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } -} - -void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const { - if (!_drawMaterial) { - return; - } - - auto textureCache = DependencyManager::get(); - - batch.setUniformBuffer(ModelRender::MATERIAL_GPU_SLOT, _drawMaterial->getSchemaBuffer()); - - auto materialKey = _drawMaterial->getKey(); - auto textureMaps = _drawMaterial->getTextureMaps(); - glm::mat4 texcoordTransform[2]; - - // Diffuse - if (materialKey.isDiffuseMap()) { - auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP]; - if (diffuseMap && diffuseMap->isDefined()) { - batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, diffuseMap->getTextureView()); - - if (!diffuseMap->getTextureTransform().isIdentity()) { - diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]); - } - } else { - batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(ModelRender::DIFFUSE_MAP_SLOT, textureCache->getGrayTexture()); - } - - // Normal map - if (materialKey.isNormalMap()) { - auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP]; - if (normalMap && normalMap->isDefined()) { - batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, normalMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, textureCache->getBlueTexture()); - } - } else { - batch.setResourceTexture(ModelRender::NORMAL_MAP_SLOT, nullptr); - } - - // TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that - if (materialKey.isGlossMap()) { - auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP]; - if (specularMap && specularMap->isDefined()) { - batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, specularMap->getTextureView()); - - // texcoord are assumed to be the same has diffuse - } else { - batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, textureCache->getBlackTexture()); - } - } else { - batch.setResourceTexture(ModelRender::SPECULAR_MAP_SLOT, nullptr); - } - - // TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too - if (materialKey.isLightmapMap()) { - auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP]; - - if (lightmapMap && lightmapMap->isDefined()) { - batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView()); - - auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); - batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); - - if (!lightmapMap->getTextureTransform().isIdentity()) { - lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); - } - } else { - batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture()); - } - } else { - batch.setResourceTexture(ModelRender::LIGHTMAP_MAP_SLOT, nullptr); - } - - // Texcoord transforms ? - if (locations->texcoordMatrices >= 0) { - batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); - } -} - -void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const { - // Still relying on the raw data from the model - const Model::MeshState& state = model->_meshStates.at(meshIndex); - - Transform transform; - if (state.clusterBuffer) { - batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); - } else { - if (model->_cauterizeBones) { - transform = Transform(state.cauterizedClusterMatrices[0]); - } else { - transform = Transform(state.clusterMatrices[0]); - } - } - transform.preTranslate(model->_translation); - batch.setModelTransform(transform); -} - - -void MeshPartPayload::render(RenderArgs* args) const { - PerformanceTimer perfTimer("MeshPartPayload::render"); - if (!model->_readyWhenAdded) { - return; // bail asap - } - - gpu::Batch& batch = *(args->_batch); - auto mode = args->_renderMode; - - auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME - - const FBXGeometry& geometry = model->_geometry->getFBXGeometry(); - const std::vector>& networkMeshes = model->_geometry->getMeshes(); - - // guard against partially loaded meshes - if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)model->_meshStates.size() ) { - return; - } - - // Back to model to update the cluster matrices right now - model->updateClusterMatrices(); - - const FBXMesh& mesh = geometry.meshes.at(meshIndex); - - // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown - // to false to rebuild out mesh groups. - if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { - model->_meshGroupsKnown = false; // regenerate these lists next time around. - model->_readyWhenAdded = false; // in case any of our users are using scenes - model->invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid - return; // FIXME! - } - - - int vertexCount = mesh.vertices.size(); - if (vertexCount == 0) { - // sanity check - return; // FIXME! - } - - - // guard against partially loaded meshes - if (partIndex >= mesh.parts.size()) { - return; - } - - model::MaterialKey drawMaterialKey; - if (_drawMaterial) { - drawMaterialKey = _drawMaterial->getKey(); - } - bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); - - bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty(); - bool hasSpecular = drawMaterialKey.isGlossMap(); - bool hasLightmap = drawMaterialKey.isLightmapMap(); - bool isSkinned = _isSkinned; - bool wireframe = model->isWireframe(); - - // render the part bounding box -#ifdef DEBUG_BOUNDING_PARTS - { - AABox partBounds = getPartBounds(meshIndex, partIndex); - bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE; - - glm::vec4 cubeColor; - if (isSkinned) { - cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f); - } else if (inView) { - cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f); - } else { - cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); - } - - Transform transform; - transform.setTranslation(partBounds.calcCenter()); - transform.setScale(partBounds.getDimensions()); - batch.setModelTransform(transform); - DependencyManager::get()->renderWireCube(batch, 1.0f, cubeColor); - } -#endif //def DEBUG_BOUNDING_PARTS - - if (wireframe) { - translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; - } - - ModelRender::Locations* locations = nullptr; - ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, - args, locations); - - - // Bind the model transform and the skinCLusterMatrices if needed - bindTransform(batch, locations); - - //Bind the index buffer and vertex buffer and Blend shapes if needed - bindMesh(batch); - - // apply material properties - bindMaterial(batch, locations); - - - // TODO: We should be able to do that just in the renderTransparentJob - if (translucentMesh && locations->lightBufferUnit >= 0) { - PerformanceTimer perfTimer("DLE->setupTransparent()"); - - DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); - } - if (args) { - args->_details._materialSwitches++; - } - - // Draw! - { - PerformanceTimer perfTimer("batch.drawIndexed()"); - drawCall(batch); - } - - if (args) { - const int INDICES_PER_TRIANGLE = 3; - args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE; - } -} - diff --git a/libraries/render-utils/src/ModelRenderItem.h b/libraries/render-utils/src/ModelRender.h similarity index 76% rename from libraries/render-utils/src/ModelRenderItem.h rename to libraries/render-utils/src/ModelRender.h index 658d2d2cae..934c9a61e8 100644 --- a/libraries/render-utils/src/ModelRenderItem.h +++ b/libraries/render-utils/src/ModelRender.h @@ -1,5 +1,5 @@ // -// ModelRenderItem.h +// ModelRender.h // interface/src/renderer // // Created by Sam Gateau on 10/3/15. @@ -9,22 +9,16 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_ModelRenderPayload_h -#define hifi_ModelRenderPayload_h - -#include +#ifndef hifi_ModelRender_h +#define hifi_ModelRender_h #include #include -#include - -class Model; - class ModelRender { public: - + static const int SKINNING_GPU_SLOT = 2; static const int MATERIAL_GPU_SLOT = 3; static const int DIFFUSE_MAP_SLOT = 0; @@ -35,6 +29,7 @@ public: class Locations { public: + int tangent; int alphaThreshold; int texcoordMatrices; int diffuseTextureUnit; @@ -45,7 +40,9 @@ public: int glowIntensity; int normalFittingMapUnit; int materialBufferUnit; - int skinClusterBufferUnit; + int clusterMatrices; + int clusterIndices; + int clusterWeights; int lightBufferUnit; }; @@ -157,54 +154,8 @@ public: }; static RenderPipelineLib _renderPipelineLib; - static const RenderPipelineLib& getRenderPipelineLib(); + static const ModelRender::RenderPipelineLib& ModelRender::getRenderPipelineLib(); }; - -class MeshPartPayload { -public: - MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex); - - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - Model* model; - QUrl url; - int meshIndex; - int partIndex; - int _shapeID; - - // Render Item interface - render::ItemKey getKey() const; - render::Item::Bound getBound() const; - void render(RenderArgs* args) const; - - // MeshPartPayload functions to perform render - void drawCall(gpu::Batch& batch) const; - void bindMesh(gpu::Batch& batch) const; - void bindMaterial(gpu::Batch& batch, const ModelRender::Locations* locations) const; - void bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const; - - - void initCache(); - - // Payload resource cached values - model::MeshPointer _drawMesh; - model::Mesh::Part _drawPart; - model::MaterialPointer _drawMaterial; - bool _hasColorAttrib = false; - bool _isSkinned = false; - bool _isBlendShaped = false; - - mutable render::Item::Bound _bound; - mutable bool _isBoundInvalid = true; -}; - -namespace render { - template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload); - template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload); - template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args); -} - -#endif // hifi_ModelRenderPayload_h \ No newline at end of file +#endif // hifi_ModelRender_h \ No newline at end of file From 429d82e6502b85bf99edb7d06931ac8ae6683440 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 09:54:37 -0700 Subject: [PATCH 066/152] Fixing review comments --- libraries/fbx/src/FBXReader.h | 5 +---- libraries/fbx/src/FBXReader_Mesh.cpp | 12 ++++++------ .../src/model-networking/ModelCache.h | 9 +-------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index a9c3326140..c0cbf5fb18 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -12,8 +12,6 @@ #ifndef hifi_FBXReader_h #define hifi_FBXReader_h -#define USE_MODEL_MESH 1 - #include #include #include @@ -188,9 +186,8 @@ public: QVector blendshapes; unsigned int meshIndex; // the order the meshes appeared in the object file -# if USE_MODEL_MESH + model::MeshPointer _mesh; -# endif }; class ExtractedMesh { diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index c88eaf4137..097862ef38 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -495,8 +495,8 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { return; } - auto ib = std::make_shared(); - ib->resize(totalIndices * sizeof(int)); + auto indexBuffer = std::make_shared(); + indexBuffer->resize(totalIndices * sizeof(int)); int indexNum = 0; int offset = 0; @@ -509,7 +509,7 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { model::Mesh::Part modelPart(indexNum, 0, 0, model::Mesh::TRIANGLES); if (part.quadTrianglesIndices.size()) { - ib->setSubData( offset, + indexBuffer->setSubData(offset, part.quadTrianglesIndices.size() * sizeof(int), (gpu::Byte*) part.quadTrianglesIndices.constData()); offset += part.quadTrianglesIndices.size() * sizeof(int); @@ -518,7 +518,7 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } if (part.triangleIndices.size()) { - ib->setSubData( offset, + indexBuffer->setSubData(offset, part.triangleIndices.size() * sizeof(int), (gpu::Byte*) part.triangleIndices.constData()); offset += part.triangleIndices.size() * sizeof(int); @@ -529,8 +529,8 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { parts.push_back(modelPart); } - gpu::BufferView ibv(ib, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ)); - mesh->setIndexBuffer(ibv); + gpu::BufferView indexBufferView(indexBuffer, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ)); + mesh->setIndexBuffer(indexBufferView); if (parts.size()) { auto pb = std::make_shared(); diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index b53ea18874..cd75794e2b 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -192,13 +192,6 @@ public: class NetworkMesh { public: model::MeshPointer _mesh; - -/* gpu::BufferPointer _indexBuffer; - gpu::BufferPointer _vertexBuffer; - - gpu::BufferStreamPointer _vertexStream; - - gpu::Stream::FormatPointer _vertexFormat; -*/}; +}; #endif // hifi_GeometryCache_h From 1788b7b019b0217508e2cdc9488e6427e44a20c1 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 10:53:38 -0700 Subject: [PATCH 067/152] Fix the bug created by the previous fix --- libraries/fbx/src/FBXReader.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 5b953e5b1b..4b3b3b0fea 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1512,10 +1512,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } extracted.mesh.isEye = (maxJointIndex == geometry.leftEyeJointIndex || maxJointIndex == geometry.rightEyeJointIndex); -# if USE_MODEL_MESH buildModelMesh(extracted, url); -# endif - + if (extracted.mesh.isEye) { if (maxJointIndex == geometry.leftEyeJointIndex) { geometry.leftEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale; From cf3828629e7f3c7426f0ab0a9af567f1ddec2418 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 11:00:21 -0700 Subject: [PATCH 068/152] Fix build on mac and linux --- libraries/render-utils/src/ModelRender.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/ModelRender.h b/libraries/render-utils/src/ModelRender.h index 934c9a61e8..517a6d0187 100644 --- a/libraries/render-utils/src/ModelRender.h +++ b/libraries/render-utils/src/ModelRender.h @@ -154,7 +154,7 @@ public: }; static RenderPipelineLib _renderPipelineLib; - static const ModelRender::RenderPipelineLib& ModelRender::getRenderPipelineLib(); + static const RenderPipelineLib& getRenderPipelineLib(); }; From 2b5742b2778170cb809ccb646d9a6773e9bd9217 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 11:13:35 -0700 Subject: [PATCH 069/152] Some code got overwritten when merging to my office mahcine this morning, that i know got back... --- libraries/render-utils/src/ModelRender.cpp | 10 ++++++---- libraries/render-utils/src/ModelRender.h | 5 +---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/ModelRender.cpp b/libraries/render-utils/src/ModelRender.cpp index f6b93ce356..a5419733ff 100644 --- a/libraries/render-utils/src/ModelRender.cpp +++ b/libraries/render-utils/src/ModelRender.cpp @@ -13,6 +13,8 @@ #include +#include + #include "DeferredLightingEffect.h" #include "model_vert.h" @@ -170,6 +172,7 @@ void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey ke gpu::ShaderPointer& pixelShader) { gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), ModelRender::SKINNING_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), ModelRender::MATERIAL_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), ModelRender::DIFFUSE_MAP_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), ModelRender::NORMAL_MAP_SLOT)); @@ -256,11 +259,10 @@ void ModelRender::RenderPipelineLib::initLocations(gpu::ShaderPointer& program, locations.normalTextureUnit = program->getTextures().findLocation("normalMap"); locations.specularTextureUnit = program->getTextures().findLocation("specularMap"); locations.emissiveTextureUnit = program->getTextures().findLocation("emissiveMap"); + locations.skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer"); locations.materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); locations.lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); - locations.clusterMatrices = program->getUniforms().findLocation("clusterMatrices"); - locations.clusterIndices = program->getInputs().findLocation("inSkinClusterIndex"); - locations.clusterWeights = program->getInputs().findLocation("inSkinClusterWeight"); + } @@ -268,7 +270,7 @@ void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, b bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, Locations*& locations) { - // PerformanceTimer perfTimer("Model::pickPrograms"); + PerformanceTimer perfTimer("Model::pickPrograms"); getRenderPipelineLib(); RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); diff --git a/libraries/render-utils/src/ModelRender.h b/libraries/render-utils/src/ModelRender.h index 517a6d0187..9748710ab1 100644 --- a/libraries/render-utils/src/ModelRender.h +++ b/libraries/render-utils/src/ModelRender.h @@ -29,7 +29,6 @@ public: class Locations { public: - int tangent; int alphaThreshold; int texcoordMatrices; int diffuseTextureUnit; @@ -39,10 +38,8 @@ public: int emissiveParams; int glowIntensity; int normalFittingMapUnit; + int skinClusterBufferUnit; int materialBufferUnit; - int clusterMatrices; - int clusterIndices; - int clusterWeights; int lightBufferUnit; }; From 3c6e9378c39ab0dc5cefa3528c96eef9eaac169a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 6 Oct 2015 20:20:37 +0200 Subject: [PATCH 070/152] fixes merge issues --- interface/src/Application.cpp | 4 ++-- libraries/octree/src/OctreeHeadlessViewer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 565debfbaf..b25f3aa6a5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4981,7 +4981,7 @@ mat4 Application::getEyeProjection(int eye) const { mat4 Application::getEyePose(int eye) const { if (isHMDMode()) { return getActiveDisplayPlugin()->getEyePose((Eye)eye); - } + } return mat4(); } @@ -4990,7 +4990,7 @@ mat4 Application::getEyeOffset(int eye) const { if (isHMDMode()) { mat4 identity; return getActiveDisplayPlugin()->getView((Eye)eye, identity); -} + } return mat4(); } diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 009fcb5cb2..605db15cd2 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -53,8 +53,8 @@ public slots: void setMaxPacketsPerSecond(int maxPacketsPerSecond) { _maxPacketsPerSecond = maxPacketsPerSecond; } // getters for camera attributes - const glm::vec3 getPosition() const { return _viewFrustum.getPosition(); } - const glm::quat getOrientation() const { return _viewFrustum.getOrientation(); } + const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); } + const glm::quat& getOrientation() const { return _viewFrustum.getOrientation(); } // getters for LOD and PPS float getVoxelSizeScale() const { return _voxelSizeScale; } From 5f2112b8a5599f4fec0b4cad07b9957a787f482b Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 11:28:36 -0700 Subject: [PATCH 071/152] finish rack and add to master script, reorganize all bball related scripts --- .../createHoop.js | 1 - .../createRack.js | 6 +- .../createSingleBasketball.js} | 2 +- unpublishedScripts/masterReset.js | 102 +++++++++++++++++- 4 files changed, 104 insertions(+), 7 deletions(-) rename examples/toys/{basketball_hoop => basketball}/createHoop.js (96%) rename examples/toys/{basketball_hoop => basketball}/createRack.js (97%) rename examples/toys/{basketball.js => basketball/createSingleBasketball.js} (98%) diff --git a/examples/toys/basketball_hoop/createHoop.js b/examples/toys/basketball/createHoop.js similarity index 96% rename from examples/toys/basketball_hoop/createHoop.js rename to examples/toys/basketball/createHoop.js index b0c76b4a53..2beb7c9fca 100644 --- a/examples/toys/basketball_hoop/createHoop.js +++ b/examples/toys/basketball/createHoop.js @@ -5,7 +5,6 @@ // Copyright 2015 High Fidelity, Inc. // // This is a script that creates a persistent basketball hoop with a working collision hull. Feel free to move it. -// Run basketball.js to make a basketball. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/examples/toys/basketball_hoop/createRack.js b/examples/toys/basketball/createRack.js similarity index 97% rename from examples/toys/basketball_hoop/createRack.js rename to examples/toys/basketball/createRack.js index a223a1064a..ad0ccb716a 100644 --- a/examples/toys/basketball_hoop/createRack.js +++ b/examples/toys/basketball/createRack.js @@ -17,7 +17,6 @@ var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; -var basketballSwitcherURL = Script.resolvePath('basketballSwitcher.js'); var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; @@ -33,7 +32,7 @@ var rackStartPosition = })); var rack = Entities.addEntity({ - name:'Basketball Rack', + name: 'Basketball Rack', type: "Model", modelURL: rackURL, position: rackStartPosition, @@ -43,7 +42,7 @@ var rack = Entities.addEntity({ y: -9.8, z: 0 }, - linearDamping:1, + linearDamping: 1, dimensions: { x: 0.4, y: 1.37, @@ -51,6 +50,7 @@ var rack = Entities.addEntity({ }, collisionsWillMove: true, ignoreForCollisions: false, + collisionSoundURL: collisionSoundURL, compoundShapeURL: rackCollisionHullURL }); diff --git a/examples/toys/basketball.js b/examples/toys/basketball/createSingleBasketball.js similarity index 98% rename from examples/toys/basketball.js rename to examples/toys/basketball/createSingleBasketball.js index 96b6218b3d..162b572bd1 100644 --- a/examples/toys/basketball.js +++ b/examples/toys/basketball/createSingleBasketball.js @@ -1,5 +1,5 @@ // -// basketball.js +// createSingleBasketball.js // examples // // Created by Philip Rosedale on August 20, 2015 diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index d6759e2b48..4f77651209 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -85,6 +85,8 @@ function createAllToys() { createBasketballHoop(); + createBasketallRack(); + createGates(); createFire(); @@ -98,7 +100,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function (entity) { + entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -521,6 +523,102 @@ function createBasketballHoop() { }); } +function createBasketallRack() { + var NUMBER_OF_BALLS = 4; + var DIAMETER = 0.30; + + var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; + var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; + var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; + var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; + + var rackRotation = Quat.fromPitchYawRollDegrees(0, -90, 0); + + var rackStartPosition = { + x: 542.86, + y: 494.84, + z: 475.06 + }; + var rack = Entities.addEntity({ + name: 'Basketball Rack', + type: "Model", + modelURL: rackURL, + position: rackStartPosition, + rotation: rackRotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + linearDamping: 1, + dimensions: { + x: 0.4, + y: 1.37, + z: 1.73 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + compoundShapeURL: rackCollisionHullURL + }); + + setEntityCustomData(resetKey, rack, { + resetMe: true + }); + + setEntityCustomData(GRABBABLE_DATA_KEY, rack, { + grabbable: false + }); + + var collidingBalls = []; + + + function createCollidingBalls() { + var position = rackStartPosition; + var i; + + for (i = 0; i < NUMBER_OF_BALLS; i++) { + var collidingBall = Entities.addEntity({ + type: "Model", + name: 'Colliding Basketball', + shapeType: 'Sphere', + position: { + x: position.x + (DIAMETER*2) - (DIAMETER * i), + y: position.y + DIAMETER * 2, + z: position.z + }, + dimensions: { + x: DIAMETER, + y: DIAMETER, + z: DIAMETER + }, + restitution: 1.0, + linearDamping: 0.00001, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + collisionSoundURL: basketballCollisionSoundURL, + modelURL: basketballURL, + }); + + collidingBalls.push(collidingBall); + + setEntityCustomData(resetKey, collidingBall, { + resetMe: true + }); + + } + } + + createCollidingBalls(); +} + + + function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; @@ -831,4 +929,4 @@ function cleanup() { if (shouldDeleteOnEndScript) { Script.scriptEnding.connect(cleanup); -} +} \ No newline at end of file From cda1b418aefd3f6fd32dfe0c3dc2f32c98ac0490 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 11:29:41 -0700 Subject: [PATCH 072/152] cleanup --- examples/toys/basketball/createRack.js | 49 -------------------------- 1 file changed, 49 deletions(-) diff --git a/examples/toys/basketball/createRack.js b/examples/toys/basketball/createRack.js index ad0ccb716a..f537a9bdd1 100644 --- a/examples/toys/basketball/createRack.js +++ b/examples/toys/basketball/createRack.js @@ -61,53 +61,6 @@ setEntityCustomData(GRABBABLE_DATA_KEY, rack, { var nonCollidingBalls = []; var collidingBalls = []; -function createNonCollidingBalls() { - var i; - var position = rackStartPosition; - - for (i = 0; i < 4; i++) { - var nonCollidingBall = Entities.addEntity({ - type: "Model", - name: 'Static Basketball', - position: { - x: position.x, - y: position.y, - z: position.z + (DIAMETER) - (DIAMETER * i) - }, - dimensions: { - x: DIAMETER, - y: DIAMETER, - z: DIAMETER - }, - collisionsWillMove: false, - ignoreForCollisions: true, - modelURL: basketballURL - }); - nonCollidingBalls.push(nonCollidingBall); - } - - for (i = 0; i < 4; i++) { - var nonCollidingBall = Entities.addEntity({ - type: "Model", - name: 'Static Basketball', - position: { - x: position.x, - y: position.y + DIAMETER, - z: position.z + (DIAMETER) - (DIAMETER * i) - }, - dimensions: { - x: DIAMETER, - y: DIAMETER, - z: DIAMETER - }, - collisionsWillMove: false, - ignoreForCollisions: false, - modelURL: basketballURL - }); - nonCollidingBalls.push(nonCollidingBall); - } -} - function createCollidingBalls() { var position = rackStartPosition; var i; @@ -140,6 +93,4 @@ function createCollidingBalls() { collidingBalls.push(collidingBall); } } - -// createNonCollidingBalls(); createCollidingBalls(); \ No newline at end of file From 4e8fc08458b32c396a2eb49b4ca8f6124f5a1025 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 6 Oct 2015 20:48:51 +0200 Subject: [PATCH 073/152] made the changes as suggested by @hyperlogic --- interface/src/scripting/HMDScriptingInterface.cpp | 9 +++++++-- interface/src/scripting/HMDScriptingInterface.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 4629ff5917..ca25f5f72a 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -58,16 +58,21 @@ float HMDScriptingInterface::getIPD() const { return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); } +glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); +} + glm::vec3 HMDScriptingInterface::getPosition() const { if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { - return glm::vec3(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()[3]); + return extractTranslation(getWorldHMDMatrix()); } return glm::vec3(); } glm::quat HMDScriptingInterface::getOrientation() const { if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { - return glm::quat_cast(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()); + return glm::normalize(glm::quat_cast(getWorldHMDMatrix())); } return glm::quat(); } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 50944ab695..ac2ab0149e 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -46,6 +46,7 @@ private: bool getHUDLookAtPosition3D(glm::vec3& result) const; + glm::mat4 getWorldHMDMatrix() const; }; #endif // hifi_HMDScriptingInterface_h From a37da41253d7b4f364a5d3e3ce675e25deb68200 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 13:15:35 -0700 Subject: [PATCH 074/152] spell basketball rack correctly --- unpublishedScripts/masterReset.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 4f77651209..23441dff3a 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -85,7 +85,7 @@ function createAllToys() { createBasketballHoop(); - createBasketallRack(); + createBasketballRack(); createGates(); @@ -523,7 +523,7 @@ function createBasketballHoop() { }); } -function createBasketallRack() { +function createBasketballRack() { var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; From cf3b33a96b33257e6b4a620f856486d546fd6d45 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 17:03:00 +0200 Subject: [PATCH 075/152] Replace Application::getInstance() with qApp --- assignment-client/src/octree/OctreeServer.cpp | 2 +- interface/src/Application.cpp | 34 ++++++------ interface/src/Application.h | 9 ++-- interface/src/GLCanvas.cpp | 8 +-- interface/src/LODManager.cpp | 4 +- interface/src/avatar/Avatar.cpp | 18 +++---- interface/src/avatar/AvatarManager.cpp | 10 ++-- interface/src/avatar/AvatarUpdate.cpp | 10 ++-- interface/src/avatar/Head.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 52 +++++++++---------- interface/src/devices/RealSense.cpp | 2 +- .../src/octree/OctreePacketProcessor.cpp | 4 +- .../scripting/ClipboardScriptingInterface.cpp | 10 ++-- .../ControllerScriptingInterface.cpp | 2 +- .../scripting/DesktopScriptingInterface.cpp | 4 +- .../GlobalServicesScriptingInterface.cpp | 2 +- .../src/scripting/HMDScriptingInterface.cpp | 23 ++++++-- .../src/scripting/HMDScriptingInterface.h | 18 ++++--- interface/src/scripting/WebWindowClass.cpp | 6 +-- .../scripting/WindowScriptingInterface.cpp | 36 ++++++------- interface/src/ui/AvatarInputs.cpp | 2 +- interface/src/ui/ChatMessageArea.cpp | 2 +- interface/src/ui/DataWebDialog.cpp | 2 +- interface/src/ui/DataWebPage.cpp | 6 +-- interface/src/ui/HMDToolsDialog.cpp | 24 ++++----- interface/src/ui/JSConsole.cpp | 2 +- interface/src/ui/MarketplaceDialog.cpp | 4 +- interface/src/ui/OctreeStatsDialog.cpp | 10 ++-- interface/src/ui/PreferencesDialog.cpp | 6 +-- interface/src/ui/RunningScriptsWidget.cpp | 28 +++++----- interface/src/ui/ScriptEditorWidget.cpp | 10 ++-- interface/src/ui/ScriptEditorWindow.cpp | 6 +-- interface/src/ui/Stats.cpp | 4 +- interface/src/ui/ToolWindow.cpp | 6 +-- interface/src/ui/overlays/Billboardable.cpp | 2 +- interface/src/ui/overlays/ModelOverlay.cpp | 2 +- interface/src/ui/overlays/Overlays.cpp | 6 +-- 37 files changed, 197 insertions(+), 181 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index ee0403d57b..7899591998 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -191,7 +191,7 @@ void OctreeServer::trackPacketSendingTime(float time) { } -void OctreeServer::trackProcessWaitTime(float time) { +void OctreeServer::trackProcessWaitTime(float time) const float MAX_SHORT_TIME = 10.0f; const float MAX_LONG_TIME = 100.0f; if (time == SKIP_TIME) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b25f3aa6a5..5b21f6bc39 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -218,11 +218,11 @@ public: } if (message->message == UWM_SHOW_APPLICATION) { - MainWindow* applicationWindow = Application::getInstance()->getWindow(); + MainWindow* applicationWindow = qApp->getWindow(); if (applicationWindow->isMinimized()) { applicationWindow->showNormal(); // Restores to windowed or maximized state appropriately. } - Application::getInstance()->setActiveWindow(applicationWindow); // Flashes the taskbar icon if not focus. + qApp->setActiveWindow(applicationWindow); // Flashes the taskbar icon if not focus. return true; } @@ -248,7 +248,7 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt OutputDebugStringA(logMessage.toLocal8Bit().constData()); OutputDebugStringA("\n"); #endif - Application::getInstance()->getLogger()->addMessage(qPrintable(logMessage + "\n")); + qApp->getLogger()->addMessage(qPrintable(logMessage + "\n")); } } @@ -1104,7 +1104,7 @@ void Application::paintGL() { PerformanceTimer perfTimer("renderOverlay"); // NOTE: There is no batch associated with this renderArgs // the ApplicationOverlay class assumes it's viewport is setup to be the device size - QSize size = qApp->getDeviceSize(); + QSize size = getDeviceSize(); renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); _applicationOverlay.renderOverlay(&renderArgs); } @@ -1116,7 +1116,7 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); - Application::getInstance()->cameraMenuChanged(); + cameraMenuChanged(); } // The render mode is default or mirror if the camera is in mirror mode, assigned further below @@ -3561,7 +3561,7 @@ namespace render { skybox = skyStage->getSkybox(); if (skybox) { - skybox->render(batch, *(Application::getInstance()->getDisplayViewFrustum())); + skybox->render(batch, *(qApp->getDisplayViewFrustum())); } } } @@ -4526,7 +4526,7 @@ void Application::loadDialog() { } void Application::loadScriptURLDialog() { - QInputDialog scriptURLDialog(Application::getInstance()->getWindow()); + QInputDialog scriptURLDialog(getWindow()); scriptURLDialog.setWindowTitle("Open and Run Script URL"); scriptURLDialog.setLabelText("Script:"); scriptURLDialog.setWindowFlags(Qt::Sheet); @@ -5095,8 +5095,8 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT; - if (qApp->isHMDMode()) { - pos = qApp->getApplicationCompositor().getPalmClickLocation(palm); + if (isHMDMode()) { + pos = getApplicationCompositor().getPalmClickLocation(palm); } else { // Get directon relative to avatar orientation @@ -5105,7 +5105,7 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) // Get the angles, scaled between (-0.5,0.5) float xAngle = (atan2f(direction.z, direction.x) + (float)M_PI_2); float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2)); - auto canvasSize = qApp->getCanvasSize(); + auto canvasSize = getCanvasSize(); // Get the pixel range over which the xAngle and yAngle are scaled float cursorRange = canvasSize.x * InputDevice::getCursorPixelRangeMult(); @@ -5120,14 +5120,14 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) if (_oldHandLeftClick[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0); - qApp->mouseReleaseEvent(&mouseEvent, deviceID); + mouseReleaseEvent(&mouseEvent, deviceID); _oldHandLeftClick[index] = false; } if (_oldHandRightClick[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0); - qApp->mouseReleaseEvent(&mouseEvent, deviceID); + mouseReleaseEvent(&mouseEvent, deviceID); _oldHandRightClick[index] = false; } @@ -5141,7 +5141,7 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) // Only send the mouse event if the opposite left button isnt held down. // Is this check necessary? if (!_oldHandLeftClick[(int)(!index)]) { - qApp->mouseMoveEvent(&mouseEvent, deviceID); + mouseMoveEvent(&mouseEvent, deviceID); } } _oldHandMouseX[index] = pos.x(); @@ -5162,12 +5162,12 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0); - qApp->mousePressEvent(&mouseEvent, deviceID); + mousePressEvent(&mouseEvent, deviceID); } } else if (_oldHandRightClick[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0); - qApp->mouseReleaseEvent(&mouseEvent, deviceID); + mouseReleaseEvent(&mouseEvent, deviceID); _oldHandRightClick[index] = false; } @@ -5179,12 +5179,12 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0); - qApp->mousePressEvent(&mouseEvent, deviceID); + mousePressEvent(&mouseEvent, deviceID); } } else if (_oldHandLeftClick[index]) { QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0); - qApp->mouseReleaseEvent(&mouseEvent, deviceID); + mouseReleaseEvent(&mouseEvent, deviceID); _oldHandLeftClick[index] = false; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 20ae2f23ab..883f2dd30e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -139,11 +139,10 @@ class Application : public QApplication, public AbstractViewStateInterface, publ friend class DatagramProcessor; public: - static Application* getInstance() { return qApp; } // TODO: replace fully by qApp - static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); } - static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); } - static glm::vec3 getPositionForAudio() { return getInstance()->_myAvatar->getPositionForAudio(); } - static glm::quat getOrientationForAudio() { return getInstance()->_myAvatar->getOrientationForAudio(); } + static const glm::vec3& getPositionForPath() { return qApp->_myAvatar->getPosition(); } + static glm::quat getOrientationForPath() { return qApp->_myAvatar->getOrientation(); } + static glm::vec3 getPositionForAudio() { return qApp->_myAvatar->getPositionForAudio(); } + static glm::quat getOrientationForAudio() { return qApp->_myAvatar->getOrientationForAudio(); } static void initPlugins(); static void shutdownPlugins(); diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 66aae5343b..1988cdffbe 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -62,13 +62,13 @@ void GLCanvas::paintGL() { // FIXME - I'm not sure why this still remains, it appears as if this GLCanvas gets a single paintGL call near // the beginning of the application starting up. I'm not sure if we really need to call Application::paintGL() // in this case, since the display plugins eventually handle all the painting - if (!Application::getInstance()->getWindow()->isMinimized() || !Application::getInstance()->isThrottleFPSEnabled()) { - Application::getInstance()->paintGL(); + if (!qApp->getWindow()->isMinimized() || !qApp->isThrottleFPSEnabled()) { + qApp->paintGL(); } } void GLCanvas::resizeGL(int width, int height) { - Application::getInstance()->resizeGL(); + qApp->resizeGL(); } int updateTime = 0; @@ -95,7 +95,7 @@ bool GLCanvas::event(QEvent* event) { break; case QEvent::Paint: // Ignore paint events that occur after we've decided to quit - if (Application::getInstance()->isAboutToQuit()) { + if (qApp->isAboutToQuit()) { return true; } break; diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index c57f1d0aa7..2a2edef831 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -26,14 +26,14 @@ LODManager::LODManager() { } float LODManager::getLODDecreaseFPS() { - if (Application::getInstance()->isHMDMode()) { + if (qApp->isHMDMode()) { return getHMDLODDecreaseFPS(); } return getDesktopLODDecreaseFPS(); } float LODManager::getLODIncreaseFPS() { - if (Application::getInstance()->isHMDMode()) { + if (qApp->isHMDMode()) { return getHMDLODIncreaseFPS(); } return getDesktopLODIncreaseFPS(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index faf4bffeba..a7a4879403 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -72,7 +72,7 @@ namespace render { avatarPtr->setDisplayingLookatTarget(renderLookAtTarget); if (avatarPtr->isInitialized() && args) { - avatarPtr->render(args, Application::getInstance()->getCamera()->getPosition()); + avatarPtr->render(args, qApp->getCamera()->getPosition()); } } } @@ -98,7 +98,7 @@ Avatar::Avatar(RigPointer rig) : _voiceSphereID(GeometryCache::UNKNOWN_ID) { // we may have been created in the network thread, but we live in the main thread - moveToThread(Application::getInstance()->thread()); + moveToThread(qApp->thread()); // give the pointer to our head to inherited _headData variable from AvatarData _headData = static_cast(new Head(this)); @@ -152,7 +152,7 @@ void Avatar::simulate(float deltaTime) { // update the avatar's position according to its referential if (_referential) { if (_referential->hasExtraData()) { - EntityTreePointer tree = Application::getInstance()->getEntities()->getTree(); + EntityTreePointer tree = qApp->getEntities()->getTree(); switch (_referential->type()) { case Referential::MODEL: _referential = new ModelReferential(_referential, @@ -189,7 +189,7 @@ void Avatar::simulate(float deltaTime) { // simple frustum check float boundingRadius = getBillboardSize(); - bool inViewFrustum = Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) != + bool inViewFrustum = qApp->getViewFrustum()->sphereInFrustum(_position, boundingRadius) != ViewFrustum::OUTSIDE; { @@ -388,9 +388,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { float boundingRadius = getBillboardSize(); ViewFrustum* frustum = nullptr; if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) { - frustum = Application::getInstance()->getShadowViewFrustum(); + frustum = qApp->getShadowViewFrustum(); } else { - frustum = Application::getInstance()->getDisplayViewFrustum(); + frustum = qApp->getDisplayViewFrustum(); } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { @@ -539,7 +539,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { const float DISPLAYNAME_DISTANCE = 20.0f; setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE); - auto cameraMode = Application::getInstance()->getCamera()->getMode(); + auto cameraMode = qApp->getCamera()->getMode(); if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { renderDisplayName(batch, *renderArgs->_viewFrustum, renderArgs->_viewport); } @@ -566,7 +566,7 @@ void Avatar::fixupModelsInScene() { // check to see if when we added our models to the scene they were ready, if they were not ready, then // fix them up in the scene - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; if (_skeletonModel.isRenderable() && _skeletonModel.needsFixupInScene()) { _skeletonModel.removeFromScene(scene, pendingChanges); @@ -653,7 +653,7 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { } // rotate about vertical to face the camera glm::quat rotation = getOrientation(); - glm::vec3 cameraVector = glm::inverse(rotation) * (Application::getInstance()->getCamera()->getPosition() - _position); + glm::vec3 cameraVector = glm::inverse(rotation) * (qApp->getCamera()->getPosition() - _position); rotation = rotation * glm::angleAxis(atan2f(-cameraVector.x, -cameraVector.z), glm::vec3(0.0f, 1.0f, 0.0f)); // compute the size from the billboard camera parameters and scale diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 1790682e56..69d76db7de 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -81,7 +81,7 @@ void AvatarManager::init() { connect(DependencyManager::get().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged, this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; if (DependencyManager::get()->shouldRenderAvatars()) { _myAvatar->addToScene(_myAvatar, scene, pendingChanges); @@ -146,7 +146,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { const float SHRINK_RATE = 0.9f; const float MIN_FADE_SCALE = 0.001f; - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; while (fadingIterator != _avatarFades.end()) { auto avatar = std::static_pointer_cast(*fadingIterator); @@ -171,7 +171,7 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() { // virtual AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { auto avatar = std::dynamic_pointer_cast(AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer)); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; if (DependencyManager::get()->shouldRenderAvatars()) { avatar->addToScene(avatar, scene, pendingChanges); @@ -328,7 +328,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { if (DependencyManager::get()->shouldRenderAvatars()) { for (auto avatarData : _avatarHash) { auto avatar = std::dynamic_pointer_cast(avatarData); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; avatar->addToScene(avatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); @@ -336,7 +336,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { } else { for (auto avatarData : _avatarHash) { auto avatar = std::dynamic_pointer_cast(avatarData); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; avatar->removeFromScene(avatar, scene, pendingChanges); scene->enqueuePendingChanges(pendingChanges); diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index a4391172a7..909d3a7bb9 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -29,11 +29,11 @@ AvatarUpdate::AvatarUpdate() : GenericThread(), _lastAvatarUpdate(0) { void AvatarUpdate::synchronousProcess() { // Keep our own updated value, so that our asynchronous code can consult it. - _isHMDMode = Application::getInstance()->isHMDMode(); - _headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose(); + _isHMDMode = qApp->isHMDMode(); + _headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); if (_updateBillboard) { - Application::getInstance()->getMyAvatar()->doUpdateBillboard(); + qApp->getMyAvatar()->doUpdateBillboard(); } if (!isThreaded()) { @@ -47,7 +47,7 @@ bool AvatarUpdate::process() { quint64 deltaMicroseconds = start - _lastAvatarUpdate; _lastAvatarUpdate = start; float deltaSeconds = (float) deltaMicroseconds / (float) USECS_PER_SECOND; - Application::getInstance()->setAvatarSimrateSample(1.0f / deltaSeconds); + qApp->setAvatarSimrateSample(1.0f / deltaSeconds); QSharedPointer manager = DependencyManager::get(); MyAvatar* myAvatar = manager->getMyAvatar(); @@ -57,7 +57,7 @@ bool AvatarUpdate::process() { manager->updateOtherAvatars(deltaSeconds); myAvatar->startUpdate(); - Application::getInstance()->updateMyAvatarLookAtPosition(); + qApp->updateMyAvatarLookAtPosition(); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes manager->updateMyAvatar(deltaSeconds); myAvatar->endUpdate(); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index d9a1b190d6..1a9b8a49e2 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -94,7 +94,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { // Only use face trackers when not playing back a recording. if (!myAvatar->isPlaying()) { - FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker(); + FaceTracker* faceTracker = qApp->getActiveFaceTracker(); _isFaceTrackerConnected = faceTracker != NULL && !faceTracker->isMuted(); if (_isFaceTrackerConnected) { _blendshapeCoefficients = faceTracker->getBlendshapeCoefficients(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9654305d70..ce5768de48 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -126,7 +126,7 @@ MyAvatar::~MyAvatar() { } QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { - CameraMode mode = Application::getInstance()->getCamera()->getMode(); + CameraMode mode = qApp->getCamera()->getMode(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // fake the avatar position that is sent up to the AvatarMixer glm::vec3 oldPosition = _position; @@ -374,7 +374,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { return; } - FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker(); + FaceTracker* tracker = qApp->getActiveFaceTracker(); bool inFacetracker = tracker && !tracker->isMuted(); if (inHmd) { @@ -388,7 +388,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { estimatedPosition = tracker->getHeadTranslation(); _trackedHeadPosition = estimatedPosition; estimatedRotation = glm::degrees(safeEulerAngles(tracker->getHeadRotation())); - if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + if (qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) { // Invert yaw and roll when in mirror mode // NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror // it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to @@ -442,7 +442,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { // NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror // it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to // match your body movements. - if ((inHmd || inFacetracker) && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + if ((inHmd || inFacetracker) && qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) { relativePosition.x = -relativePosition.x; } @@ -538,7 +538,7 @@ void MyAvatar::clearReferential() { } bool MyAvatar::setModelReferential(const QUuid& id) { - EntityTreePointer tree = Application::getInstance()->getEntities()->getTree(); + EntityTreePointer tree = qApp->getEntities()->getTree(); changeReferential(new ModelReferential(id, tree, this)); if (_referential->isValid()) { return true; @@ -549,7 +549,7 @@ bool MyAvatar::setModelReferential(const QUuid& id) { } bool MyAvatar::setJointReferential(const QUuid& id, int jointIndex) { - EntityTreePointer tree = Application::getInstance()->getEntities()->getTree(); + EntityTreePointer tree = qApp->getEntities()->getTree(); changeReferential(new JointReferential(jointIndex, id, tree, this)); if (!_referential->isValid()) { return true; @@ -856,7 +856,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) { } void MyAvatar::setEnableMeshVisible(bool isEnabled) { - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); _skeletonModel.setVisibleInScene(isEnabled, scene); } @@ -1005,7 +1005,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = glm::vec3(0.0f); glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; - glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); + glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); float smallestAngleTo = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES) / 2.0f; const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; @@ -1023,7 +1023,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = avatarPointer->getPosition(); smallestAngleTo = angleTo; } - if (Application::getInstance()->isLookingAtMyAvatar(avatar)) { + if (qApp->isLookingAtMyAvatar(avatar)) { // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. @@ -1035,11 +1035,11 @@ void MyAvatar::updateLookAtTargetAvatar() { // When not in HMD, these might both answer identity (i.e., the bridge of the nose). That's ok. // By my inpsection of the code and live testing, getEyeOffset and getEyePose are the same. (Application hands identity as offset matrix.) // This might be more work than needed for any given use, but as we explore different formulations, we go mad if we don't work in world space. - glm::mat4 leftEye = Application::getInstance()->getEyeOffset(Eye::Left); - glm::mat4 rightEye = Application::getInstance()->getEyeOffset(Eye::Right); + glm::mat4 leftEye = qApp->getEyeOffset(Eye::Left); + glm::mat4 rightEye = qApp->getEyeOffset(Eye::Right); glm::vec3 leftEyeHeadLocal = glm::vec3(leftEye[3]); glm::vec3 rightEyeHeadLocal = glm::vec3(rightEye[3]); - auto humanSystem = Application::getInstance()->getViewFrustum(); + auto humanSystem = qApp->getViewFrustum(); glm::vec3 humanLeftEye = humanSystem->getPosition() + (humanSystem->getOrientation() * leftEyeHeadLocal); glm::vec3 humanRightEye = humanSystem->getPosition() + (humanSystem->getOrientation() * rightEyeHeadLocal); @@ -1065,7 +1065,7 @@ void MyAvatar::updateLookAtTargetAvatar() { */ // And now we can finally add that offset to the camera. - glm::vec3 corrected = Application::getInstance()->getViewFrustum()->getPosition() + gazeOffset; + glm::vec3 corrected = qApp->getViewFrustum()->getPosition() + gazeOffset; avatar->getHead()->setCorrectedLookAtPosition(corrected); @@ -1172,7 +1172,7 @@ void MyAvatar::clearJointAnimationPriorities() { void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) { Avatar::setFaceModelURL(faceModelURL); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); getHead()->getFaceModel().setVisibleInScene(_prevShouldDrawHead, scene); _billboardValid = false; } @@ -1180,7 +1180,7 @@ void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) { void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { Avatar::setSkeletonModelURL(skeletonModelURL); - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); _billboardValid = false; _skeletonModel.setVisibleInScene(true, scene); _headBoneSet.clear(); @@ -1238,7 +1238,7 @@ void MyAvatar::setAttachmentData(const QVector& attachmentData) } glm::vec3 MyAvatar::getSkeletonPosition() const { - CameraMode mode = Application::getInstance()->getCamera()->getMode(); + CameraMode mode = qApp->getCamera()->getMode(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. @@ -1339,13 +1339,13 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl // This is drawing the lookat vectors from our avatar to wherever we're looking. if (qApp->isHMDMode()) { - glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); + glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); - glm::mat4 leftEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyePose(Eye::Left); + glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyePose(Eye::Left); glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]); - glm::mat4 rightEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyePose(Eye::Right); + glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyePose(Eye::Right); glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]); - glm::mat4 headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose(); + glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); glm::vec3 headPosition = glm::vec3(headPose[3]); getHead()->renderLookAts(renderArgs, @@ -1421,7 +1421,7 @@ void MyAvatar::destroyAnimGraph() { void MyAvatar::preRender(RenderArgs* renderArgs) { - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); const bool shouldDrawHead = shouldRenderHead(renderArgs); if (_skeletonModel.initWhenReady(scene)) { @@ -1476,13 +1476,13 @@ const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f; bool MyAvatar::cameraInsideHead() const { const Head* head = getHead(); - const glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); + const glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); return glm::length(cameraPosition - head->getEyePosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * _scale); } bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { return ((renderArgs->_renderMode != RenderArgs::DEFAULT_RENDER_MODE) || - (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) || + (qApp->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON) || !cameraInsideHead()); } @@ -1526,7 +1526,7 @@ void MyAvatar::updateOrientation(float deltaTime) { glm::vec3 euler = glm::eulerAngles(localOrientation) * DEGREES_PER_RADIAN; //Invert yaw and roll when in mirror mode - if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + if (qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) { YAW(euler) *= -1.0f; ROLL(euler) *= -1.0f; } @@ -1951,7 +1951,7 @@ glm::vec3 MyAvatar::getPositionForAudio() { case AudioListenerMode::FROM_HEAD: return getHead()->getPosition(); case AudioListenerMode::FROM_CAMERA: - return Application::getInstance()->getCamera()->getPosition(); + return qApp->getCamera()->getPosition(); case AudioListenerMode::CUSTOM: return _customListenPosition; } @@ -1963,7 +1963,7 @@ glm::quat MyAvatar::getOrientationForAudio() { case AudioListenerMode::FROM_HEAD: return getHead()->getFinalOrientationInWorldFrame(); case AudioListenerMode::FROM_CAMERA: - return Application::getInstance()->getCamera()->getOrientation(); + return qApp->getCamera()->getOrientation(); case AudioListenerMode::CUSTOM: return _customListenOrientation; } diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index d9b1486f09..ce28e40f2b 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -250,7 +250,7 @@ void RealSense::update() { void RealSense::loadRSSDKFile() { QString locationDir(QStandardPaths::displayName(QStandardPaths::DesktopLocation)); - QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getWindow(), tr("Open RSSDK clip"), + QString fileNameString = QFileDialog::getOpenFileName(qApp->getWindow(), tr("Open RSSDK clip"), locationDir, tr("RSSDK Recordings (*.rssdk)")); if (!fileNameString.isEmpty()) { diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 4a92e7e8ac..8dfee8f73b 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -33,11 +33,11 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share const int WAY_BEHIND = 300; - if (packetsToProcessCount() > WAY_BEHIND && Application::getInstance()->getLogger()->extraDebugging()) { + if (packetsToProcessCount() > WAY_BEHIND && qApp->getLogger()->extraDebugging()) { qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } - Application* app = Application::getInstance(); + Application* app = qApp; bool wasStatsPacket = false; PacketType octreePacketType = packet->getType(); diff --git a/interface/src/scripting/ClipboardScriptingInterface.cpp b/interface/src/scripting/ClipboardScriptingInterface.cpp index 4cebb85648..b0ef6c760d 100644 --- a/interface/src/scripting/ClipboardScriptingInterface.cpp +++ b/interface/src/scripting/ClipboardScriptingInterface.cpp @@ -15,12 +15,12 @@ ClipboardScriptingInterface::ClipboardScriptingInterface() { } float ClipboardScriptingInterface::getClipboardContentsLargestDimension() { - return Application::getInstance()->getEntityClipboard()->getContentsLargestDimension(); + return qApp->getEntityClipboard()->getContentsLargestDimension(); } bool ClipboardScriptingInterface::exportEntities(const QString& filename, const QVector& entityIDs) { bool retVal; - QMetaObject::invokeMethod(Application::getInstance(), "exportEntities", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, retVal), Q_ARG(const QString&, filename), Q_ARG(const QVector&, entityIDs)); @@ -29,7 +29,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, const bool ClipboardScriptingInterface::exportEntities(const QString& filename, float x, float y, float z, float s) { bool retVal; - QMetaObject::invokeMethod(Application::getInstance(), "exportEntities", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(qApp, "exportEntities", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, retVal), Q_ARG(const QString&, filename), Q_ARG(float, x), @@ -41,7 +41,7 @@ bool ClipboardScriptingInterface::exportEntities(const QString& filename, float bool ClipboardScriptingInterface::importEntities(const QString& filename) { bool retVal; - QMetaObject::invokeMethod(Application::getInstance(), "importEntities", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(qApp, "importEntities", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, retVal), Q_ARG(const QString&, filename)); return retVal; @@ -49,7 +49,7 @@ bool ClipboardScriptingInterface::importEntities(const QString& filename) { QVector ClipboardScriptingInterface::pasteEntities(glm::vec3 position) { QVector retVal; - QMetaObject::invokeMethod(Application::getInstance(), "pasteEntities", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(qApp, "pasteEntities", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVector, retVal), Q_ARG(float, position.x), Q_ARG(float, position.y), diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index b182d3b339..6f36a6267f 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -378,7 +378,7 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) { } glm::vec2 ControllerScriptingInterface::getViewportDimensions() const { - return Application::getInstance()->getUiSize(); + return qApp->getUiSize(); } AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) { diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp index 746cdaf36f..843a40348e 100644 --- a/interface/src/scripting/DesktopScriptingInterface.cpp +++ b/interface/src/scripting/DesktopScriptingInterface.cpp @@ -18,10 +18,10 @@ #include "MainWindow.h" int DesktopScriptingInterface::getWidth() { - QSize size = Application::getInstance()->getWindow()->windowHandle()->screen()->virtualSize(); + QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize(); return size.width(); } int DesktopScriptingInterface::getHeight() { - QSize size = Application::getInstance()->getWindow()->windowHandle()->screen()->virtualSize(); + QSize size = qApp->getWindow()->windowHandle()->screen()->virtualSize(); return size.height(); } diff --git a/interface/src/scripting/GlobalServicesScriptingInterface.cpp b/interface/src/scripting/GlobalServicesScriptingInterface.cpp index 668bd92664..8ca381a607 100644 --- a/interface/src/scripting/GlobalServicesScriptingInterface.cpp +++ b/interface/src/scripting/GlobalServicesScriptingInterface.cpp @@ -143,5 +143,5 @@ void GlobalServicesScriptingInterface::updateDownloadInfo() { } void GlobalServicesScriptingInterface::editFriends() { - QMetaObject::invokeMethod(Application::getInstance(), "showFriendsWindow"); + QMetaObject::invokeMethod(qApp, "showFriendsWindow"); } diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 68ac511eaf..b3630a4453 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -10,22 +10,27 @@ // #include "HMDScriptingInterface.h" -#include "display-plugins/DisplayPlugin.h" + +#include + #include +#include "Application.h" +#include "display-plugins/DisplayPlugin.h" + HMDScriptingInterface& HMDScriptingInterface::getInstance() { static HMDScriptingInterface sharedInstance; return sharedInstance; } bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { - Camera* camera = Application::getInstance()->getCamera(); + Camera* camera = qApp->getCamera(); glm::vec3 position = camera->getPosition(); glm::quat orientation = camera->getOrientation(); glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); - const auto& compositor = Application::getInstance()->getApplicationCompositor(); + const auto& compositor = qApp->getApplicationCompositor(); return compositor.calculateRayUICollisionPoint(position, direction, result); } @@ -40,7 +45,7 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* conte glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); glm::vec3 eulers = ::safeEulerAngles(rotation); - return qScriptValueFromValue(engine, Application::getInstance()->getApplicationCompositor() + return qScriptValueFromValue(engine, qApp->getApplicationCompositor() .sphericalToOverlay(glm::vec2(eulers.y, -eulers.x))); } return QScriptValue::NullValue; @@ -55,5 +60,13 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* conte } float HMDScriptingInterface::getIPD() const { - return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); + return qApp->getActiveDisplayPlugin()->getIPD(); +} + +void HMDScriptingInterface::toggleMagnifier() { + qApp->getApplicationCompositor().toggleMagnifier(); +} + +bool HMDScriptingInterface::getMagnifier() const { + return qApp->getApplicationCompositor().hasMagnifier(); } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 82b444abaa..b118fab62b 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -12,32 +12,36 @@ #ifndef hifi_HMDScriptingInterface_h #define hifi_HMDScriptingInterface_h +#include + #include -#include "Application.h" +class QScriptContext; +class QScriptEngine; + class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) Q_PROPERTY(float ipd READ getIPD) + public: static HMDScriptingInterface& getInstance(); - + static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine); static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine); public slots: - void toggleMagnifier() { Application::getInstance()->getApplicationCompositor().toggleMagnifier(); }; + void toggleMagnifier(); private: - HMDScriptingInterface() {}; - bool getMagnifier() const { return Application::getInstance()->getApplicationCompositor().hasMagnifier(); }; - bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } + HMDScriptingInterface() = default; + bool getMagnifier() const; + bool isHMDMode() const; float getIPD() const; bool getHUDLookAtPosition3D(glm::vec3& result) const; - }; #endif // hifi_HMDScriptingInterface_h diff --git a/interface/src/scripting/WebWindowClass.cpp b/interface/src/scripting/WebWindowClass.cpp index a549410305..f9dc9e07ae 100644 --- a/interface/src/scripting/WebWindowClass.cpp +++ b/interface/src/scripting/WebWindowClass.cpp @@ -41,7 +41,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid _isToolWindow(isToolWindow) { if (_isToolWindow) { - ToolWindow* toolWindow = Application::getInstance()->getToolWindow(); + ToolWindow* toolWindow = qApp->getToolWindow(); auto dockWidget = new QDockWidget(title, toolWindow); dockWidget->setFeatures(QDockWidget::DockWidgetMovable); @@ -56,7 +56,7 @@ WebWindowClass::WebWindowClass(const QString& title, const QString& url, int wid _windowWidget = dockWidget; } else { - auto dialogWidget = new QDialog(Application::getInstance()->getWindow(), Qt::Window); + auto dialogWidget = new QDialog(qApp->getWindow(), Qt::Window); dialogWidget->setWindowTitle(title); dialogWidget->resize(width, height); dialogWidget->installEventFilter(this); @@ -120,7 +120,7 @@ void WebWindowClass::setVisible(bool visible) { if (visible) { if (_isToolWindow) { QMetaObject::invokeMethod( - Application::getInstance()->getToolWindow(), "setVisible", Qt::AutoConnection, Q_ARG(bool, visible)); + qApp->getToolWindow(), "setVisible", Qt::AutoConnection, Q_ARG(bool, visible)); } else { QMetaObject::invokeMethod(_windowWidget, "showNormal", Qt::AutoConnection); QMetaObject::invokeMethod(_windowWidget, "raise", Qt::AutoConnection); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 6be67a7261..a5c7087adc 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -32,8 +32,8 @@ WindowScriptingInterface::WindowScriptingInterface() : { const DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); connect(&domainHandler, &DomainHandler::connectedToDomain, this, &WindowScriptingInterface::domainChanged); - connect(Application::getInstance(), &Application::svoImportRequested, this, &WindowScriptingInterface::svoImportRequested); - connect(Application::getInstance(), &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused); + connect(qApp, &Application::svoImportRequested, this, &WindowScriptingInterface::svoImportRequested); + connect(qApp, &Application::domainConnectionRefused, this, &WindowScriptingInterface::domainConnectionRefused); } WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title, const QString& url, int width, int height, bool isToolWindow) { @@ -41,13 +41,13 @@ WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title } QScriptValue WindowScriptingInterface::hasFocus() { - return Application::getInstance()->hasFocus(); + return qApp->hasFocus(); } void WindowScriptingInterface::setFocus() { // It's forbidden to call focus() from another thread. - Application::getInstance()->postLambdaEvent([] { - auto window = Application::getInstance()->getWindow(); + qApp->postLambdaEvent([] { + auto window = qApp->getWindow(); window->activateWindow(); window->setFocus(); }); @@ -55,18 +55,18 @@ void WindowScriptingInterface::setFocus() { void WindowScriptingInterface::raiseMainWindow() { // It's forbidden to call raise() from another thread. - Application::getInstance()->postLambdaEvent([] { - Application::getInstance()->getWindow()->raise(); + qApp->postLambdaEvent([] { + qApp->getWindow()->raise(); }); } void WindowScriptingInterface::setCursorVisible(bool visible) { - QMetaObject::invokeMethod(Application::getInstance(), "setCursorVisible", Qt::BlockingQueuedConnection, + QMetaObject::invokeMethod(qApp, "setCursorVisible", Qt::BlockingQueuedConnection, Q_ARG(bool, visible)); } bool WindowScriptingInterface::isCursorVisible() const { - return !Application::getInstance()->isMouseHidden(); + return !qApp->isMouseHidden(); } void WindowScriptingInterface::setCursorPosition(int x, int y) { @@ -167,7 +167,7 @@ QScriptValue WindowScriptingInterface::peekNonBlockingFormResult(QScriptValue fo /// \param const QString& message message to display /// \return QScriptValue::UndefinedValue QScriptValue WindowScriptingInterface::showAlert(const QString& message) { - QMessageBox::warning(Application::getInstance()->getWindow(), "", message); + QMessageBox::warning(qApp->getWindow(), "", message); return QScriptValue::UndefinedValue; } @@ -175,7 +175,7 @@ QScriptValue WindowScriptingInterface::showAlert(const QString& message) { /// \param const QString& message message to display /// \return QScriptValue `true` if 'Yes' was clicked, `false` otherwise QScriptValue WindowScriptingInterface::showConfirm(const QString& message) { - QMessageBox::StandardButton response = QMessageBox::question(Application::getInstance()->getWindow(), "", message); + QMessageBox::StandardButton response = QMessageBox::question(qApp->getWindow(), "", message); return QScriptValue(response == QMessageBox::Yes); } @@ -487,7 +487,7 @@ QScriptValue WindowScriptingInterface::showForm(const QString& title, QScriptVal QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue form) { - QDialog* editDialog = new QDialog(Application::getInstance()->getWindow()); + QDialog* editDialog = new QDialog(qApp->getWindow()); editDialog->setWindowTitle(title); bool cancelButton = false; @@ -597,7 +597,7 @@ QDialog* WindowScriptingInterface::createForm(const QString& title, QScriptValue /// \param const QString& defaultText default text in the text box /// \return QScriptValue string text value in text box if the dialog was accepted, `null` otherwise. QScriptValue WindowScriptingInterface::showPrompt(const QString& message, const QString& defaultText) { - QInputDialog promptDialog(Application::getInstance()->getWindow()); + QInputDialog promptDialog(qApp->getWindow()); promptDialog.setWindowTitle(""); promptDialog.setLabelText(message); promptDialog.setTextValue(defaultText); @@ -627,7 +627,7 @@ QScriptValue WindowScriptingInterface::showBrowse(const QString& title, const QS path = fileInfo.filePath(); } - QFileDialog fileDialog(Application::getInstance()->getWindow(), title, path, nameFilter); + QFileDialog fileDialog(qApp->getWindow(), title, path, nameFilter); fileDialog.setAcceptMode(acceptMode); QUrl fileUrl(directory); if (acceptMode == QFileDialog::AcceptSave) { @@ -657,17 +657,17 @@ QScriptValue WindowScriptingInterface::showS3Browse(const QString& nameFilter) { } int WindowScriptingInterface::getInnerWidth() { - return Application::getInstance()->getWindow()->geometry().width(); + return qApp->getWindow()->geometry().width(); } int WindowScriptingInterface::getInnerHeight() { - return Application::getInstance()->getWindow()->geometry().height(); + return qApp->getWindow()->geometry().height(); } int WindowScriptingInterface::getX() { - return Application::getInstance()->getWindow()->x(); + return qApp->getWindow()->x(); } int WindowScriptingInterface::getY() { - return Application::getInstance()->getWindow()->y(); + return qApp->getWindow()->y(); } diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index 019deb9690..bc9181945f 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -106,7 +106,7 @@ void AvatarInputs::update() { } void AvatarInputs::toggleCameraMute() { - FaceTracker* faceTracker = Application::getInstance()->getSelectedFaceTracker(); + FaceTracker* faceTracker = qApp->getSelectedFaceTracker(); if (faceTracker) { faceTracker->toggleMute(); } diff --git a/interface/src/ui/ChatMessageArea.cpp b/interface/src/ui/ChatMessageArea.cpp index 1dc38e9c94..bef22b9fed 100644 --- a/interface/src/ui/ChatMessageArea.cpp +++ b/interface/src/ui/ChatMessageArea.cpp @@ -20,7 +20,7 @@ ChatMessageArea::ChatMessageArea(bool useFixedHeight) : QTextBrowser(), _useFixe connect(document()->documentLayout(), &QAbstractTextDocumentLayout::documentSizeChanged, this, &ChatMessageArea::updateLayout); - connect(this, &QTextBrowser::anchorClicked, Application::getInstance(), &Application::openUrl); + connect(this, &QTextBrowser::anchorClicked, qApp, &Application::openUrl); } void ChatMessageArea::setHtml(const QString& html) { diff --git a/interface/src/ui/DataWebDialog.cpp b/interface/src/ui/DataWebDialog.cpp index f405ef50c5..a92e0ac214 100644 --- a/interface/src/ui/DataWebDialog.cpp +++ b/interface/src/ui/DataWebDialog.cpp @@ -28,7 +28,7 @@ DataWebDialog::DataWebDialog() { setPage(new DataWebPage(this)); // have the Application handle external links - connect(this, &QWebView::linkClicked, Application::getInstance(), &Application::openUrl); + connect(this, &QWebView::linkClicked, qApp, &Application::openUrl); } DataWebDialog* DataWebDialog::dialogForPath(const QString& path, diff --git a/interface/src/ui/DataWebPage.cpp b/interface/src/ui/DataWebPage.cpp index 69c9954245..01feacc393 100644 --- a/interface/src/ui/DataWebPage.cpp +++ b/interface/src/ui/DataWebPage.cpp @@ -34,15 +34,15 @@ void DataWebPage::javaScriptConsoleMessage(const QString& message, int lineNumbe bool DataWebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type) { // Handle hifi:// links and links to files with particular extensions QString urlString = request.url().toString(); - if (Application::getInstance()->canAcceptURL(urlString)) { - if (Application::getInstance()->acceptURL(urlString)) { + if (qApp->canAcceptURL(urlString)) { + if (qApp->acceptURL(urlString)) { return false; // we handled it, so QWebPage doesn't need to handle it } } // Make hyperlinks with target="_blank" open in user's Web browser if (type == QWebPage::NavigationTypeLinkClicked && frame == nullptr) { - Application::getInstance()->openUrl(request.url()); + qApp->openUrl(request.url()); return false; // We handled it. } diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index e03e05912c..f37a4a9ba6 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -78,11 +78,11 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : // what screens we're allowed on watchWindow(windowHandle()); auto dialogsManager = DependencyManager::get(); - if (Application::getInstance()->getRunningScriptsWidget()) { - watchWindow(Application::getInstance()->getRunningScriptsWidget()->windowHandle()); + if (qApp->getRunningScriptsWidget()) { + watchWindow(qApp->getRunningScriptsWidget()->windowHandle()); } - if (Application::getInstance()->getToolWindow()) { - watchWindow(Application::getInstance()->getToolWindow()->windowHandle()); + if (qApp->getToolWindow()) { + watchWindow(qApp->getToolWindow()->windowHandle()); } if (dialogsManager->getBandwidthDialog()) { watchWindow(dialogsManager->getBandwidthDialog()->windowHandle()); @@ -110,7 +110,7 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : }); // watch for our application window moving screens. If it does we want to update our screen details - QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + QWindow* mainWindow = qApp->getWindow()->windowHandle(); connect(mainWindow, &QWindow::screenChanged, [this]{ updateUi(); }); @@ -142,7 +142,7 @@ QString HMDToolsDialog::getDebugDetails() const { results += "Desktop's Primary Screen: " + desktopPrimaryScreen->name() + "\n"; results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n"; - QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen(); + QScreen* mainWindowScreen = qApp->getWindow()->windowHandle()->screen(); results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n"; results += "Total Screens: " + QString::number(QApplication::desktop()->screenCount()) + "\n"; @@ -159,15 +159,15 @@ void HMDToolsDialog::toggleHMDMode() { void HMDToolsDialog::enterHMDMode() { if (!qApp->isHMDMode()) { - Application::getInstance()->setActiveDisplayPlugin(_hmdPluginName); - Application::getInstance()->getWindow()->activateWindow(); + qApp->setActiveDisplayPlugin(_hmdPluginName); + qApp->getWindow()->activateWindow(); } } void HMDToolsDialog::leaveHMDMode() { if (qApp->isHMDMode()) { - Application::getInstance()->setActiveDisplayPlugin(_defaultPluginName); - Application::getInstance()->getWindow()->activateWindow(); + qApp->setActiveDisplayPlugin(_defaultPluginName); + qApp->getWindow()->activateWindow(); } } @@ -200,7 +200,7 @@ void HMDToolsDialog::showEvent(QShowEvent* event) { void HMDToolsDialog::hideEvent(QHideEvent* event) { // center the cursor on the main application window - centerCursorOnWidget(Application::getInstance()->getWindow()); + centerCursorOnWidget(qApp->getWindow()); } void HMDToolsDialog::screenCountChanged(int newCount) { @@ -275,7 +275,7 @@ void HMDWindowWatcher::windowScreenChanged(QScreen* screen) { QScreen* betterScreen = NULL; QScreen* lastApplicationScreen = _hmdTools->getLastApplicationScreen(); - QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle(); + QWindow* appWindow = qApp->getWindow()->windowHandle(); QScreen* appScreen = appWindow->screen(); if (_previousScreen && _previousScreen != hmdScreen) { diff --git a/interface/src/ui/JSConsole.cpp b/interface/src/ui/JSConsole.cpp index 74585df855..6e5b22399d 100644 --- a/interface/src/ui/JSConsole.cpp +++ b/interface/src/ui/JSConsole.cpp @@ -53,7 +53,7 @@ JSConsole::JSConsole(QWidget* parent, ScriptEngine* scriptEngine) : if (_scriptEngine == NULL) { - _scriptEngine = Application::getInstance()->loadScript(QString(), false); + _scriptEngine = qApp->loadScript(QString(), false); } connect(_scriptEngine, SIGNAL(evaluationFinished(QScriptValue, bool)), diff --git a/interface/src/ui/MarketplaceDialog.cpp b/interface/src/ui/MarketplaceDialog.cpp index b9c640054c..11286e0ee1 100644 --- a/interface/src/ui/MarketplaceDialog.cpp +++ b/interface/src/ui/MarketplaceDialog.cpp @@ -20,8 +20,8 @@ MarketplaceDialog::MarketplaceDialog(QQuickItem* parent) : OffscreenQmlDialog(pa bool MarketplaceDialog::navigationRequested(const QString& url) { qDebug() << url; - if (Application::getInstance()->canAcceptURL(url)) { - if (Application::getInstance()->acceptURL(url)) { + if (qApp->canAcceptURL(url)) { + if (qApp->acceptURL(url)) { return false; // we handled it, so QWebPage doesn't need to handle it } } diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index c2d72de9d6..d3ff017633 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -129,7 +129,7 @@ OctreeStatsDialog::~OctreeStatsDialog() { void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Processed Entities Related stats - auto entities = Application::getInstance()->getEntities(); + auto entities = qApp->getEntities(); auto entitiesTree = entities->getTree(); // Do this ever paint event... even if we don't update @@ -196,7 +196,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { unsigned long totalInternal = 0; unsigned long totalLeaves = 0; - NodeToOctreeSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats(); + NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats(); sceneStats->withReadLock([&] { for (NodeToOctreeSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) { //const QUuid& uuid = i->first; @@ -264,7 +264,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { QString averageReadBitstreamPerPacketString = locale.toString(averageReadBitstreamPerPacket); label = _labels[_processedPackets]; - const OctreePacketProcessor& entitiesPacketProcessor = Application::getInstance()->getOctreePacketProcessor(); + const OctreePacketProcessor& entitiesPacketProcessor = qApp->getOctreePacketProcessor(); auto incomingPPS = entitiesPacketProcessor.getIncomingPPS(); auto processedPPS = entitiesPacketProcessor.getProcessedPPS(); @@ -351,7 +351,7 @@ void OctreeStatsDialog::showAllOctreeServers() { int serverCount = 0; showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity", - Application::getInstance()->getEntityServerJurisdictions()); + qApp->getEntityServerJurisdictions()); if (_octreeServerLabelsCount > serverCount) { for (int i = serverCount; i < _octreeServerLabelsCount; i++) { @@ -427,7 +427,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser // now lookup stats details for this server... if (_extraServerDetails[serverCount-1] != LESS) { - NodeToOctreeSceneStats* sceneStats = Application::getInstance()->getOcteeSceneStats(); + NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats(); sceneStats->withReadLock([&] { if (sceneStats->find(nodeUUID) != sceneStats->end()) { OctreeSceneStats& stats = sceneStats->at(nodeUUID); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 81e4d61b5e..1b55c6fa2b 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -45,14 +45,14 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : connect(ui.buttonBrowseLocation, &QPushButton::clicked, this, &PreferencesDialog::openSnapshotLocationBrowser); connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser); - connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, Application::getInstance(), &Application::loadDefaultScripts); + connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, qApp, &Application::loadDefaultScripts); connect(ui.buttonChangeAppearance, &QPushButton::clicked, this, &PreferencesDialog::openFullAvatarModelBrowser); connect(ui.appearanceDescription, &QLineEdit::textChanged, this, [this](const QString& url) { DependencyManager::get()->getMyAvatar()->useFullAvatarURL(url, ""); this->fullAvatarURLChanged(url, ""); }); - connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged); + connect(qApp, &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged); // move dialog to left side move(parentWidget()->geometry().topLeft()); @@ -298,7 +298,7 @@ void PreferencesDialog::savePreferences() { audio->setOutputStarveDetectionThreshold(ui.outputStarveDetectionThresholdSpinner->value()); audio->setOutputStarveDetectionPeriod(ui.outputStarveDetectionPeriodSpinner->value()); - Application::getInstance()->resizeGL(); + qApp->resizeGL(); // LOD items auto lodManager = DependencyManager::get(); diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 61b03bd610..3752ea2176 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -57,15 +57,15 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter); connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); - connect(ui->reloadAllButton, &QPushButton::clicked, Application::getInstance(), &Application::reloadAllScripts); + connect(ui->reloadAllButton, &QPushButton::clicked, qApp, &Application::reloadAllScripts); connect(ui->stopAllButton, &QPushButton::clicked, this, &RunningScriptsWidget::allScriptsStopped); - connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, Application::getInstance(), &Application::loadDialog); - connect(ui->loadScriptFromURLButton, &QPushButton::clicked, Application::getInstance(), &Application::loadScriptURLDialog); + connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, qApp, &Application::loadDialog); + connect(ui->loadScriptFromURLButton, &QPushButton::clicked, qApp, &Application::loadScriptURLDialog); connect(&_reloadSignalMapper, static_cast(&QSignalMapper::mapped), - Application::getInstance(), &Application::reloadOneScript); + qApp, &Application::reloadOneScript); connect(&_stopSignalMapper, static_cast(&QSignalMapper::mapped), - [](const QString& script) { Application::getInstance()->stopScript(script); }); + [](const QString& script) { qApp->stopScript(script); }); UIUtil::scaleWidgetFontSizes(this); } @@ -83,7 +83,7 @@ void RunningScriptsWidget::updateFileFilter(const QString& filter) { void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) { QVariant scriptFile = _scriptsModelFilter.data(index, ScriptsModel::ScriptPath); - Application::getInstance()->loadScript(scriptFile.toString()); + qApp->loadScript(scriptFile.toString()); } void RunningScriptsWidget::loadSelectedScript() { @@ -172,7 +172,7 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) { ui->filterLineEdit->setFocus(); } - QRect parentGeometry = Application::getInstance()->getDesirableApplicationGeometry(); + QRect parentGeometry = qApp->getDesirableApplicationGeometry(); int titleBarHeight = UIUtil::getWindowTitleBarHeight(this); int topMargin = titleBarHeight; @@ -217,13 +217,13 @@ void RunningScriptsWidget::keyPressEvent(QKeyEvent *keyEvent) { } void RunningScriptsWidget::allScriptsStopped() { - Application::getInstance()->stopAllScripts(); + qApp->stopAllScripts(); } QVariantList RunningScriptsWidget::getRunning() { const int WINDOWS_DRIVE_LETTER_SIZE = 1; QVariantList result; - foreach(const QString& runningScript, Application::getInstance()->getRunningScripts()) { + foreach(const QString& runningScript, qApp->getRunningScripts()) { QUrl runningScriptURL = QUrl(runningScript); if (runningScriptURL.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { runningScriptURL = QUrl::fromLocalFile(runningScriptURL.toDisplayString(QUrl::FormattingOptions(QUrl::FullyEncoded))); @@ -245,7 +245,7 @@ QVariantList RunningScriptsWidget::getPublic() { QVariantList RunningScriptsWidget::getPublicChildNodes(TreeNodeFolder* parent) { QVariantList result; - QList treeNodes = Application::getInstance()->getRunningScriptsWidget()->getScriptsModel() + QList treeNodes = qApp->getRunningScriptsWidget()->getScriptsModel() ->getFolderNodes(parent); for (int i = 0; i < treeNodes.size(); i++) { TreeNodeBase* node = treeNodes.at(i); @@ -273,7 +273,7 @@ QVariantList RunningScriptsWidget::getPublicChildNodes(TreeNodeFolder* parent) { QVariantList RunningScriptsWidget::getLocal() { QVariantList result; - QList treeNodes = Application::getInstance()->getRunningScriptsWidget()->getScriptsModel() + QList treeNodes = qApp->getRunningScriptsWidget()->getScriptsModel() ->getFolderNodes(NULL); for (int i = 0; i < treeNodes.size(); i++) { TreeNodeBase* node = treeNodes.at(i); @@ -293,14 +293,14 @@ QVariantList RunningScriptsWidget::getLocal() { } bool RunningScriptsWidget::stopScriptByName(const QString& name) { - foreach (const QString& runningScript, Application::getInstance()->getRunningScripts()) { + foreach (const QString& runningScript, qApp->getRunningScripts()) { if (QUrl(runningScript).fileName().toLower() == name.trimmed().toLower()) { - return Application::getInstance()->stopScript(runningScript, false); + return qApp->stopScript(runningScript, false); } } return false; } bool RunningScriptsWidget::stopScript(const QString& name, bool restart) { - return Application::getInstance()->stopScript(name, restart); + return qApp->stopScript(name, restart); } diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index fa829d4ace..76327804b6 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -98,7 +98,7 @@ bool ScriptEditorWidget::setRunning(bool run) { if (run) { const QString& scriptURLString = QUrl(_currentScript).toString(); // Reload script so that an out of date copy is not retrieved from the cache - _scriptEngine = Application::getInstance()->loadScript(scriptURLString, true, true, false, true); + _scriptEngine = qApp->loadScript(scriptURLString, true, true, false, true); connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); @@ -106,7 +106,7 @@ bool ScriptEditorWidget::setRunning(bool run) { connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } else { connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); - Application::getInstance()->stopScript(_currentScript); + qApp->stopScript(_currentScript); _scriptEngine = NULL; } return true; @@ -170,7 +170,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { } const QString& scriptURLString = QUrl(_currentScript).toString(); - _scriptEngine = Application::getInstance()->getScriptEngine(scriptURLString); + _scriptEngine = qApp->getScriptEngine(scriptURLString); if (_scriptEngine != NULL) { connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); @@ -186,10 +186,10 @@ bool ScriptEditorWidget::save() { bool ScriptEditorWidget::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save script"), - Application::getInstance()->getPreviousScriptLocation(), + qApp->getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); if (!fileName.isEmpty()) { - Application::getInstance()->setPreviousScriptLocation(fileName); + qApp->setPreviousScriptLocation(fileName); return saveFile(fileName); } else { return false; diff --git a/interface/src/ui/ScriptEditorWindow.cpp b/interface/src/ui/ScriptEditorWindow.cpp index 41d172cf48..b5c8500083 100644 --- a/interface/src/ui/ScriptEditorWindow.cpp +++ b/interface/src/ui/ScriptEditorWindow.cpp @@ -90,10 +90,10 @@ void ScriptEditorWindow::loadScriptMenu(const QString& scriptName) { void ScriptEditorWindow::loadScriptClicked() { QString scriptName = QFileDialog::getOpenFileName(this, tr("Interface"), - Application::getInstance()->getPreviousScriptLocation(), + qApp->getPreviousScriptLocation(), tr("JavaScript Files (*.js)")); if (!scriptName.isEmpty()) { - Application::getInstance()->setPreviousScriptLocation(scriptName); + qApp->setPreviousScriptLocation(scriptName); addScriptEditorWidget("loading...")->loadFile(scriptName); updateButtons(); } @@ -101,7 +101,7 @@ void ScriptEditorWindow::loadScriptClicked() { void ScriptEditorWindow::loadMenuAboutToShow() { _loadMenu->clear(); - QStringList runningScripts = Application::getInstance()->getRunningScripts(); + QStringList runningScripts = qApp->getRunningScripts(); if (runningScripts.count() > 0) { QSignalMapper* signalMapper = new QSignalMapper(this); foreach (const QString& runningScript, runningScripts) { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 831664e3e6..f4ff2feb02 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -115,7 +115,7 @@ void Stats::updateStats(bool force) { STAT_UPDATE(avatarCount, avatarManager->size() - 1); STAT_UPDATE(serverCount, nodeList->size()); STAT_UPDATE(framerate, (int)qApp->getFps()); - STAT_UPDATE(simrate, (int)Application::getInstance()->getAverageSimsPerSecond()); + STAT_UPDATE(simrate, (int)qApp->getAverageSimsPerSecond()); STAT_UPDATE(avatarSimrate, (int)qApp->getAvatarSimrate()); auto bandwidthRecorder = DependencyManager::get(); @@ -207,7 +207,7 @@ void Stats::updateStats(bool force) { unsigned long totalLeaves = 0; std::stringstream sendingModeStream(""); sendingModeStream << "["; - NodeToOctreeSceneStats* octreeServerSceneStats = Application::getInstance()->getOcteeSceneStats(); + NodeToOctreeSceneStats* octreeServerSceneStats = qApp->getOcteeSceneStats(); for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) { //const QUuid& uuid = i->first; OctreeSceneStats& stats = i->second; diff --git a/interface/src/ui/ToolWindow.cpp b/interface/src/ui/ToolWindow.cpp index 4edae4f2a4..95dd522415 100644 --- a/interface/src/ui/ToolWindow.cpp +++ b/interface/src/ui/ToolWindow.cpp @@ -25,7 +25,7 @@ ToolWindow::ToolWindow(QWidget* parent) : # ifndef Q_OS_LINUX setDockOptions(QMainWindow::ForceTabbedDocks); # endif - Application::getInstance()->installEventFilter(this); + qApp->installEventFilter(this); } bool ToolWindow::event(QEvent* event) { @@ -34,7 +34,7 @@ bool ToolWindow::event(QEvent* event) { if (!_hasShown) { _hasShown = true; - QMainWindow* mainWindow = Application::getInstance()->getWindow(); + QMainWindow* mainWindow = qApp->getWindow(); QRect mainGeometry = mainWindow->geometry(); int titleBarHeight = UIUtil::getWindowTitleBarHeight(this); @@ -57,7 +57,7 @@ bool ToolWindow::eventFilter(QObject* sender, QEvent* event) { # ifndef Q_OS_LINUX switch (event->type()) { case QEvent::WindowStateChange: - if (Application::getInstance()->getWindow()->isMinimized()) { + if (qApp->getWindow()->isMinimized()) { // If we are already visible, we are self-hiding _selfHidden = isVisible(); setVisible(false); diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index c6edad501f..18e80c2b4f 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -30,7 +30,7 @@ QScriptValue Billboardable::getProperty(QScriptEngine* scriptEngine, const QStri void Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offsetRotation) { if (isFacingAvatar()) { glm::vec3 billboardPos = transform.getTranslation(); - glm::vec3 cameraPos = Application::getInstance()->getCamera()->getPosition(); + glm::vec3 cameraPos = qApp->getCamera()->getPosition(); glm::vec3 look = cameraPos - billboardPos; float elevation = -asinf(look.y / glm::length(look)); float azimuth = atan2f(look.x, look.z); diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index b6422d86e0..b9cbde9f31 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -71,7 +71,7 @@ void ModelOverlay::render(RenderArgs* args) { // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; if (_model.needsFixupInScene()) { _model.removeFromScene(scene, pendingChanges); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index db3360cbbf..29e9d62542 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -76,7 +76,7 @@ void Overlays::update(float deltatime) { void Overlays::cleanupOverlaysToDelete() { if (!_overlaysToDelete.isEmpty()) { - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; { @@ -169,7 +169,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope } else if (type == Grid3DOverlay::TYPE) { thisOverlay = std::make_shared(); } else if (type == LocalModelsOverlay::TYPE) { - thisOverlay = std::make_shared(Application::getInstance()->getEntityClipboardRenderer()); + thisOverlay = std::make_shared(qApp->getEntityClipboardRenderer()); } else if (type == ModelOverlay::TYPE) { thisOverlay = std::make_shared(); } else if (type == Web3DOverlay::TYPE) { @@ -196,7 +196,7 @@ unsigned int Overlays::addOverlay(Overlay::Pointer overlay) { } else { _overlaysWorld[thisID] = overlay; - render::ScenePointer scene = Application::getInstance()->getMain3DScene(); + render::ScenePointer scene = qApp->getMain3DScene(); render::PendingChanges pendingChanges; overlay->addToScene(overlay, scene, pendingChanges); From 0f18db886c45e7f65bd953ee84b7a079c41ef80f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 17:19:50 +0200 Subject: [PATCH 076/152] Remove 4 Application static methods - Replace by lambda - Cleaned up global scope --- interface/src/Application.cpp | 8 ++++---- interface/src/Application.h | 4 ---- libraries/audio-client/src/AudioClient.h | 4 ++-- libraries/networking/src/AddressManager.h | 9 ++++----- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5b21f6bc39..88dae16ee2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -432,8 +432,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : auto audioIO = DependencyManager::get(); - audioIO->setPositionGetter(getPositionForAudio); - audioIO->setOrientationGetter(getOrientationForAudio); + audioIO->setPositionGetter([]{ return qApp->_myAvatar->getPositionForAudio(); }); + audioIO->setOrientationGetter([]{ return qApp->_myAvatar->getOrientationForAudio(); }); audioIO->moveToThread(audioThread); @@ -524,8 +524,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : auto addressManager = DependencyManager::get(); // use our MyAvatar position and quat for address manager path - addressManager->setPositionGetter(getPositionForPath); - addressManager->setOrientationGetter(getOrientationForPath); + addressManager->setPositionGetter([]{ return qApp->_myAvatar->getPosition(); }); + addressManager->setOrientationGetter([]{ return qApp->_myAvatar->getOrientation(); }); connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress); diff --git a/interface/src/Application.h b/interface/src/Application.h index 883f2dd30e..799ec30471 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -139,10 +139,6 @@ class Application : public QApplication, public AbstractViewStateInterface, publ friend class DatagramProcessor; public: - static const glm::vec3& getPositionForPath() { return qApp->_myAvatar->getPosition(); } - static glm::quat getOrientationForPath() { return qApp->_myAvatar->getOrientation(); } - static glm::vec3 getPositionForAudio() { return qApp->_myAvatar->getPositionForAudio(); } - static glm::quat getOrientationForAudio() { return qApp->_myAvatar->getOrientationForAudio(); } static void initPlugins(); static void shutdownPlugins(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 1ef56649fa..e699ee9266 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -76,8 +76,6 @@ class QIODevice; typedef struct ty_gverb ty_gverb; -typedef glm::vec3 (*AudioPositionGetter)(); -typedef glm::quat (*AudioOrientationGetter)(); class NLPacket; @@ -85,6 +83,8 @@ class AudioClient : public AbstractAudioInterface, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY public: + using AudioPositionGetter = std::function; + using AudioOrientationGetter = std::function; class AudioOutputIODevice : public QIODevice { public: diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index fbb895795b..e0b54e4072 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -28,9 +28,6 @@ const QString INDEX_PATH = "/"; const QString GET_PLACE = "/api/v1/places/%1"; -typedef const glm::vec3& (*PositionGetter)(); -typedef glm::quat (*OrientationGetter)(); - class AddressManager : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -40,6 +37,8 @@ class AddressManager : public QObject, public Dependency { Q_PROPERTY(QString hostname READ getHost) Q_PROPERTY(QString pathname READ currentPath) public: + using PositionGetter = std::function; + using OrientationGetter = std::function; enum LookupTrigger { UserInput, @@ -130,8 +129,8 @@ private: QString _host; quint16 _port; QUuid _rootPlaceID; - PositionGetter _positionGetter { nullptr }; - OrientationGetter _orientationGetter { nullptr }; + PositionGetter _positionGetter; + OrientationGetter _orientationGetter; QStack _backStack; QStack _forwardStack; From 92e974929c8bd2c73e7ef70930e26a56b8b15970 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 17:26:55 +0200 Subject: [PATCH 077/152] Move tray icon to MainWindow --- interface/src/Application.cpp | 4 ---- interface/src/Application.h | 4 ---- interface/src/MainWindow.cpp | 1 + interface/src/MainWindow.h | 2 ++ 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 88dae16ee2..40104f8fbf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -357,7 +356,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _octreeProcessor(), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), - _trayIcon(new QSystemTrayIcon(_window)), _lastNackTime(usecTimestampNow()), _lastSendDownstreamAudioStats(usecTimestampNow()), _isThrottleFPSEnabled(true), @@ -664,8 +662,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : cameraMenuChanged(); } - _trayIcon->show(); - // set the local loopback interface for local sounds from audio scripts AudioScriptingInterface::getInstance().setLocalAudioInterface(audioIO.data()); diff --git a/interface/src/Application.h b/interface/src/Application.h index 799ec30471..a3a34f3cea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -77,7 +77,6 @@ class QGLWidget; class QKeyEvent; class QMouseEvent; -class QSystemTrayIcon; class QTouchEvent; class QWheelEvent; class OffscreenGlCanvas; @@ -233,7 +232,6 @@ public: FaceTracker* getActiveFaceTracker(); FaceTracker* getSelectedFaceTracker(); - QSystemTrayIcon* getTrayIcon() { return _trayIcon; } ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; } const ApplicationOverlay& getApplicationOverlay() const { return _applicationOverlay; } ApplicationCompositor& getApplicationCompositor() { return _compositor; } @@ -621,8 +619,6 @@ private: bool _runningScriptsWidgetWasVisible; QString _scriptsLocation; - QSystemTrayIcon* _trayIcon; - quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; diff --git a/interface/src/MainWindow.cpp b/interface/src/MainWindow.cpp index 16aedc4bb7..34e1638e94 100644 --- a/interface/src/MainWindow.cpp +++ b/interface/src/MainWindow.cpp @@ -31,6 +31,7 @@ MainWindow::MainWindow(QWidget* parent) : _windowState("WindowState", 0) { setAcceptDrops(true); + _trayIcon.show(); } void MainWindow::restoreGeometry() { diff --git a/interface/src/MainWindow.h b/interface/src/MainWindow.h index eb262e0f97..6a401cf2b7 100644 --- a/interface/src/MainWindow.h +++ b/interface/src/MainWindow.h @@ -13,6 +13,7 @@ #define __hifi__MainWindow__ #include +#include #include @@ -42,6 +43,7 @@ protected: private: Setting::Handle _windowGeometry; Setting::Handle _windowState; + QSystemTrayIcon _trayIcon; }; #endif /* defined(__hifi__MainWindow__) */ From 0aab013a0e0101f2003782a23c9e0a051fae6cbf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 17:55:34 +0200 Subject: [PATCH 078/152] Remove unused members --- interface/src/Application.cpp | 9 +-------- interface/src/Application.h | 7 ------- interface/src/GLCanvas.cpp | 1 - 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 40104f8fbf..ef179c65f3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -327,7 +327,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _window(new MainWindow(desktop())), _toolWindow(NULL), _friendsWindow(NULL), - _undoStack(), _undoStackScriptingInterface(&_undoStack), _frameCount(0), _fps(60.0f), @@ -336,8 +335,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _entities(true, this, this), _entityClipboardRenderer(false, this, this), _entityClipboard(new EntityTree()), - _viewFrustum(), - _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _firstRun("firstRun", true), @@ -353,7 +350,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _isTouchPressed(false), _mousePressed(false), _enableProcessOctreeThread(true), - _octreeProcessor(), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), _lastNackTime(usecTimestampNow()), @@ -361,10 +357,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _isThrottleFPSEnabled(true), _aboutToQuit(false), _notifiedPacketVersionMismatchThisDomain(false), - _domainConnectionRefusals(QList()), _maxOctreePPS(maxOctreePacketsPerSecond.get()), - _lastFaceTrackerUpdate(0), - _applicationOverlay() + _lastFaceTrackerUpdate(0) { thread()->setObjectName("Main Thread"); @@ -1342,7 +1336,6 @@ void Application::resizeGL() { uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize(); uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale()); if (_renderResolution != renderSize) { - _numFramesSinceLastResize = 0; _renderResolution = renderSize; DependencyManager::get()->setFrameBufferSize(fromGlm(renderSize)); diff --git a/interface/src/Application.h b/interface/src/Application.h index a3a34f3cea..0501b2c34d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -518,8 +518,6 @@ private: QUndoStack _undoStack; UndoStackScriptingInterface _undoStackScriptingInterface; - glm::vec3 _gravity; - // Frame Rate Measurement int _frameCount; @@ -543,8 +541,6 @@ private: ViewFrustum _shadowViewFrustum; quint64 _lastQueriedTime; - float _trailingAudioLoudness; - OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers KeyboardMouseDevice* _keyboardMouseDevice{ nullptr }; // Default input device, the good old keyboard mouse and maybe touchpad @@ -659,10 +655,7 @@ private: int _oldHandMouseY[2]; bool _oldHandLeftClick[2]; bool _oldHandRightClick[2]; - int _numFramesSinceLastResize = 0; - bool _overlayEnabled = true; - QRect _savedGeometry; DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface(); EntityItemID _keyboardFocusedItem; diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 1988cdffbe..306e57cfa0 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -71,7 +71,6 @@ void GLCanvas::resizeGL(int width, int height) { qApp->resizeGL(); } -int updateTime = 0; bool GLCanvas::event(QEvent* event) { switch (event->type()) { case QEvent::MouseMove: From a5f31dba5f377540dabff1e17e7e9bf8acafbbf6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 17:56:11 +0200 Subject: [PATCH 079/152] Fix startup timer --- interface/src/Application.cpp | 14 ++++---------- interface/src/Application.h | 2 -- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ef179c65f3..e0892a90eb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -321,7 +321,7 @@ Cube3DOverlay* _keyboardFocusHighlight{ nullptr }; int _keyboardFocusHighlightID{ -1 }; PluginContainer* _pluginContainer; -Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : +Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : QApplication(argc, argv), _dependencyManagerIsSetup(setupEssentials(argc, argv)), _window(new MainWindow(desktop())), @@ -330,7 +330,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _undoStackScriptingInterface(&_undoStack), _frameCount(0), _fps(60.0f), - _justStarted(true), _physicsEngine(new PhysicsEngine(Vectors::ZERO)), _entities(true, this, this), _entityClipboardRenderer(false, this, this), @@ -385,8 +384,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _myAvatar = DependencyManager::get()->getMyAvatar(); - _applicationStartupTime = startup_time; - qCDebug(interfaceapp) << "[VERSION] Build sequence: " << qPrintable(applicationVersion()); _bookmarks = new Bookmarks(); // Before setting up the menu @@ -765,6 +762,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : }); connect(this, &Application::applicationStateChanged, this, &Application::activeChanged); + + + qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0f); } void Application::aboutToQuit() { @@ -959,12 +959,6 @@ void Application::initializeGL() { idleTimer->start(TARGET_SIM_FRAME_PERIOD_MS); _idleLoopStdev.reset(); - if (_justStarted) { - float startupTime = (float)_applicationStartupTime.elapsed() / 1000.0f; - _justStarted = false; - qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTime); - } - // update before the first render update(1.0f / _fps); diff --git a/interface/src/Application.h b/interface/src/Application.h index 0501b2c34d..c879dbf0ce 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -522,10 +522,8 @@ private: int _frameCount; float _fps; - QElapsedTimer _applicationStartupTime; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; - bool _justStarted; ShapeManager _shapeManager; PhysicalEntitySimulation _entitySimulation; From e74df484cc197b4c74c8d24cd59d13458110bcd9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 18:12:27 +0200 Subject: [PATCH 080/152] Remove unused methods --- interface/src/Application.cpp | 19 ------------------- interface/src/Application.h | 5 ----- 2 files changed, 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e0892a90eb..ef9b91e639 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3766,25 +3766,6 @@ void Application::resetSensors() { QMetaObject::invokeMethod(DependencyManager::get().data(), "reset", Qt::QueuedConnection); } -static void setShortcutsEnabled(QWidget* widget, bool enabled) { - foreach (QAction* action, widget->actions()) { - QKeySequence shortcut = action->shortcut(); - if (!shortcut.isEmpty() && (shortcut[0] & (Qt::CTRL | Qt::ALT | Qt::META)) == 0) { - // it's a shortcut that may coincide with a "regular" key, so switch its context - action->setShortcutContext(enabled ? Qt::WindowShortcut : Qt::WidgetShortcut); - } - } - foreach (QObject* child, widget->children()) { - if (child->isWidgetType()) { - setShortcutsEnabled(static_cast(child), enabled); - } - } -} - -void Application::setMenuShortcutsEnabled(bool enabled) { - setShortcutsEnabled(_window->menuBar(), enabled); -} - void Application::updateWindowTitle(){ QString buildVersion = " (build " + applicationVersion() + ")"; diff --git a/interface/src/Application.h b/interface/src/Application.h index c879dbf0ce..176e2524e0 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -497,11 +497,6 @@ private: void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false); - void setMenuShortcutsEnabled(bool enabled); - - static void attachNewHeadToNode(Node *newNode); - static void* networkReceive(void* args); // network receive thread - int sendNackPackets(); bool _dependencyManagerIsSetup; From 77a78148549f27448cf4dab496fbf72d52d6bf96 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 18:48:26 +0200 Subject: [PATCH 081/152] Move sendPingPackets --- interface/src/Application.cpp | 54 ++++++-------------- interface/src/Application.h | 2 - libraries/networking/src/LimitedNodeList.cpp | 16 ++++++ libraries/networking/src/LimitedNodeList.h | 1 + 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ef9b91e639..f5c87e1b96 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -163,22 +163,6 @@ extern "C" { } #endif -enum CustomEventTypes { - Lambda = QEvent::User + 1 -}; - -class LambdaEvent : public QEvent { - std::function _fun; -public: - LambdaEvent(const std::function & fun) : - QEvent(static_cast(Lambda)), _fun(fun) { - } - LambdaEvent(std::function && fun) : - QEvent(static_cast(Lambda)), _fun(fun) { - } - void call() { _fun(); } -}; - using namespace std; static QTimer* locationUpdateTimer = NULL; @@ -239,6 +223,22 @@ public: }; #endif +enum CustomEventTypes { + Lambda = QEvent::User + 1 +}; + +class LambdaEvent : public QEvent { + std::function _fun; +public: + LambdaEvent(const std::function & fun) : + QEvent(static_cast(Lambda)), _fun(fun) { + } + LambdaEvent(std::function && fun) : + QEvent(static_cast(Lambda)), _fun(fun) { + } + void call() { _fun(); } +}; + void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message); @@ -2090,29 +2090,10 @@ bool Application::acceptSnapshot(const QString& urlString) { return true; } -void Application::sendPingPackets() { - - auto nodeList = DependencyManager::get(); - - nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool { - switch (node->getType()) { - case NodeType::AvatarMixer: - case NodeType::AudioMixer: - case NodeType::EntityServer: - case NodeType::AssetServer: - return true; - default: - return false; - } - }, [nodeList](const SharedNodePointer& node) { - nodeList->sendPacket(nodeList->constructPingPacket(), *node); - }); -} - // Every second, check the frame rates and other stuff void Application::checkFPS() { if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) { - sendPingPackets(); + DependencyManager::get()->sendPingPackets(); } float diffTime = (float)_timerStart.nsecsElapsed() / 1000000000.0f; @@ -3804,7 +3785,6 @@ void Application::clearDomainOctreeDetails() { // reset the model renderer _entities.clear(); - } void Application::domainChanged(const QString& domainHostname) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 176e2524e0..5ae8219b99 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -464,8 +464,6 @@ private slots: private: void resetCameras(Camera& camera, const glm::uvec2& size); - void sendPingPackets(); - void initDisplay(); void init(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c13a82f821..630c4c79bf 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -661,6 +661,22 @@ void LimitedNodeList::sendSTUNRequest() { _nodeSocket.writeDatagram(stunRequestPacket, sizeof(stunRequestPacket), _stunSockAddr); } +void LimitedNodeList::sendPingPackets() { + eachMatchingNode([](const SharedNodePointer& node)->bool { + switch (node->getType()) { + case NodeType::AvatarMixer: + case NodeType::AudioMixer: + case NodeType::EntityServer: + case NodeType::AssetServer: + return true; + default: + return false; + } + }, [&](const SharedNodePointer& node) { + sendPacket(constructPingPacket(), *node); + }); +} + void LimitedNodeList::processSTUNResponse(std::unique_ptr packet) { // check the cookie to make sure this is actually a STUN response // and read the first attribute and make sure it is a XOR_MAPPED_ADDRESS diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index abf292e65e..40c5390c7e 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -230,6 +230,7 @@ public slots: void startSTUNPublicSocketUpdate(); virtual void sendSTUNRequest(); + void sendPingPackets(); void killNodeWithUUID(const QUuid& nodeUUID); From 7da55747f51537b7ae56e23c0fa422cdae3b596f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 19:21:04 +0200 Subject: [PATCH 082/152] Simplify friends window --- interface/src/Application.cpp | 20 +++++++++----------- interface/src/Application.h | 2 -- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5c87e1b96..9dc2a50d10 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -326,7 +326,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _dependencyManagerIsSetup(setupEssentials(argc, argv)), _window(new MainWindow(desktop())), _toolWindow(NULL), - _friendsWindow(NULL), _undoStackScriptingInterface(&_undoStack), _frameCount(0), _fps(60.0f), @@ -4625,21 +4624,20 @@ void Application::activeChanged(Qt::ApplicationState state) { } } void Application::showFriendsWindow() { + const QString FRIENDS_WINDOW_OBJECT_NAME = "FriendsWindow"; const QString FRIENDS_WINDOW_TITLE = "Add/Remove Friends"; const QString FRIENDS_WINDOW_URL = "https://metaverse.highfidelity.com/user/friends"; const int FRIENDS_WINDOW_WIDTH = 290; const int FRIENDS_WINDOW_HEIGHT = 500; - if (!_friendsWindow) { - _friendsWindow = new WebWindowClass(FRIENDS_WINDOW_TITLE, FRIENDS_WINDOW_URL, FRIENDS_WINDOW_WIDTH, - FRIENDS_WINDOW_HEIGHT, false); - connect(_friendsWindow, &WebWindowClass::closed, this, &Application::friendsWindowClosed); + auto webWindowClass = _window->findChildren(FRIENDS_WINDOW_OBJECT_NAME); + if (webWindowClass.empty()) { + auto friendsWindow = new WebWindowClass(FRIENDS_WINDOW_TITLE, FRIENDS_WINDOW_URL, FRIENDS_WINDOW_WIDTH, + FRIENDS_WINDOW_HEIGHT, false); + friendsWindow->setParent(_window); + friendsWindow->setObjectName(FRIENDS_WINDOW_OBJECT_NAME); + connect(friendsWindow, &WebWindowClass::closed, &WebWindowClass::deleteLater); + friendsWindow->setVisible(true); } - _friendsWindow->setVisible(true); -} - -void Application::friendsWindowClosed() { - delete _friendsWindow; - _friendsWindow = NULL; } void Application::postLambdaEvent(std::function f) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 5ae8219b99..9bb19dd6b7 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -393,7 +393,6 @@ public slots: void saveScripts(); void showFriendsWindow(); - void friendsWindowClosed(); void packageModel(); @@ -506,7 +505,6 @@ private: MainWindow* _window; ToolWindow* _toolWindow; - WebWindowClass* _friendsWindow; QUndoStack _undoStack; UndoStackScriptingInterface _undoStackScriptingInterface; From 765608d0fffabb6313897cafabb541d44d8d0d6c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 19:49:02 +0200 Subject: [PATCH 083/152] More unused --- interface/src/Application.cpp | 10 ---------- interface/src/Application.h | 17 +---------------- .../src/AbstractViewStateInterface.h | 3 +-- 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9dc2a50d10..278c1fcddc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2962,12 +2962,6 @@ void Application::update(float deltaTime) { _avatarUpdate->synchronousProcess(); - { - PerformanceTimer perfTimer("emitSimulating"); - // let external parties know we're updating - emit simulating(deltaTime); - } - // Update _viewFrustum with latest camera and view frustum data... // NOTE: we get this from the view frustum, to make it simpler, since the // loadViewFrumstum() method will get the correct details from the camera @@ -3316,10 +3310,6 @@ glm::vec3 Application::getSunDirection() { // FIXME, preprocessor guard this check to occur only in DEBUG builds static QThread * activeRenderingThread = nullptr; -bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { - return DependencyManager::get()->shouldRenderMesh(largestDimension, distanceToCamera); -} - float Application::getSizeScale() const { return DependencyManager::get()->getOctreeSizeScale(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 9bb19dd6b7..d1db393cbc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -252,10 +252,6 @@ public: virtual AbstractControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; } virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine); - void resetProfile(const QString& username); - - virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera); - QImage renderAvatarBillboard(RenderArgs* renderArgs); void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false); @@ -319,10 +315,8 @@ public: int getMaxOctreePacketsPerSecond(); render::ScenePointer getMain3DScene() { return _main3DScene; } - render::EnginePointer getRenderEngine() { return _renderEngine; } - render::ScenePointer getMain3DScene() const { return _main3DScene; } - + render::EnginePointer getRenderEngine() { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } const QRect& getMirrorViewRect() const { return _mirrorViewRect; } @@ -336,13 +330,6 @@ public: float getAverageSimsPerSecond(); signals: - - /// Fired when we're simulating; allows external parties to hook in. - void simulating(float deltaTime); - - /// Fired when the import window is closed - void importDone(); - void scriptLocationChanged(const QString& newPath); void svoImportRequested(const QString& url); @@ -350,8 +337,6 @@ signals: void checkBackgroundDownloads(); void domainConnectionRefused(const QString& reason); - void headURLChanged(const QString& newValue, const QString& modelName); - void bodyURLChanged(const QString& newValue, const QString& modelName); void fullAvatarURLChanged(const QString& newValue, const QString& modelName); void beforeAboutToQuit(); diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index a9cd7db20c..2b6c66b36a 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -44,8 +44,7 @@ public: virtual ViewFrustum* getShadowViewFrustum() = 0; virtual QThread* getMainThread() = 0; - - virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera) = 0; + virtual float getSizeScale() const = 0; virtual int getBoundaryLevelAdjust() const = 0; virtual PickRay computePickRay(float x, float y) const = 0; From 311edabe51603754077ee5ece8bfa51b4837afbe Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 20:05:09 +0200 Subject: [PATCH 084/152] More header cleanup --- interface/src/Application.cpp | 20 ++++++++++++++ interface/src/Application.h | 36 ++------------------------ interface/src/PluginContainerProxy.cpp | 4 +-- interface/src/avatar/Avatar.h | 3 +++ 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 278c1fcddc..de227cd934 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -172,6 +172,26 @@ static QTimer* billboardPacketTimer = NULL; static QTimer* checkFPStimer = NULL; static QTimer* idleTimer = NULL; +static const QString SNAPSHOT_EXTENSION = ".jpg"; +static const QString SVO_EXTENSION = ".svo"; +static const QString SVO_JSON_EXTENSION = ".svo.json"; +static const QString JS_EXTENSION = ".js"; +static const QString FST_EXTENSION = ".fst"; + +static const int MIRROR_VIEW_TOP_PADDING = 5; +static const int MIRROR_VIEW_LEFT_PADDING = 10; +static const int MIRROR_VIEW_WIDTH = 265; +static const int MIRROR_VIEW_HEIGHT = 215; +static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; +static const float MIRROR_REARVIEW_DISTANCE = 0.722f; +static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; +static const float MIRROR_FIELD_OF_VIEW = 30.0f; + +static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; + +static const QString INFO_HELP_PATH = "html/interface-welcome.html"; +static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html"; + static const unsigned int TARGET_SIM_FRAMERATE = 60; static const unsigned int THROTTLED_SIM_FRAMERATE = 15; static const int TARGET_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / TARGET_SIM_FRAMERATE; diff --git a/interface/src/Application.h b/interface/src/Application.h index d1db393cbc..71a678c6a2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -74,48 +74,17 @@ #include "render/Engine.h" -class QGLWidget; -class QKeyEvent; -class QMouseEvent; -class QTouchEvent; -class QWheelEvent; class OffscreenGlCanvas; class GLCanvas; class FaceTracker; class MainWindow; -class Node; -class ScriptEngine; namespace gpu { class Context; typedef std::shared_ptr ContextPointer; } - -static const QString SNAPSHOT_EXTENSION = ".jpg"; -static const QString SVO_EXTENSION = ".svo"; -static const QString SVO_JSON_EXTENSION = ".svo.json"; -static const QString JS_EXTENSION = ".js"; -static const QString FST_EXTENSION = ".fst"; - -static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees -static const float BILLBOARD_DISTANCE = 5.56f; // meters - -static const int MIRROR_VIEW_TOP_PADDING = 5; -static const int MIRROR_VIEW_LEFT_PADDING = 10; -static const int MIRROR_VIEW_WIDTH = 265; -static const int MIRROR_VIEW_HEIGHT = 215; -static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f; -static const float MIRROR_REARVIEW_DISTANCE = 0.722f; -static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; -static const float MIRROR_FIELD_OF_VIEW = 30.0f; - -static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; - -static const QString INFO_HELP_PATH = "html/interface-welcome.html"; -static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html"; - #ifdef Q_OS_WIN static const UINT UWM_IDENTIFY_INSTANCES = RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME")); @@ -129,8 +98,6 @@ class Application; #endif #define qApp (static_cast(QCoreApplication::instance())) -typedef bool (Application::* AcceptURLMethod)(const QString &); - class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface { Q_OBJECT @@ -606,7 +573,8 @@ private: GLCanvas* _glWidget{ nullptr }; void checkSkeleton(); - + + typedef bool (Application::* AcceptURLMethod)(const QString &); QHash _acceptedExtensions; QList _domainConnectionRefusals; diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 469e7f7c77..3310d9e4cd 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -78,7 +78,7 @@ void PluginContainerProxy::setIsOptionChecked(const QString& path, bool checked) // Additionally, setting fullscreen isn't hiding the menu on windows // make it useless for stereoscopic modes. void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) { - auto _window = qApp->_window; + auto _window = qApp->getWindow(); if (!_window->isFullScreen()) { _savedGeometry = _window->geometry(); } @@ -101,7 +101,7 @@ void PluginContainerProxy::setFullscreen(const QScreen* target, bool hideMenu) { } void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) { - auto _window = qApp->_window; + auto _window = qApp->getWindow(); _window->showNormal(); QRect targetGeometry = _savedGeometry; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 5ff3f37ef5..2515f260a1 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -37,6 +37,9 @@ static const float SCALING_RATIO = .05f; static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1 static const float RESCALING_TOLERANCE = .02f; +static const float BILLBOARD_FIELD_OF_VIEW = 30.0f; // degrees +static const float BILLBOARD_DISTANCE = 5.56f; // meters + extern const float CHAT_MESSAGE_SCALE; extern const float CHAT_MESSAGE_HEIGHT; From 38f23ef79eb3d5ed6987032588594ecfa264de3e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 21:01:34 +0200 Subject: [PATCH 085/152] Remove Application friend --- interface/src/Application.h | 12 ++++++------ interface/src/PluginContainerProxy.cpp | 2 +- interface/src/octree/OctreePacketProcessor.cpp | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 71a678c6a2..21a4a4429a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -100,11 +100,13 @@ class Application; class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface { Q_OBJECT - + + // TODO? Get rid of those friend class OctreePacketProcessor; - friend class DatagramProcessor; + friend class PluginContainerProxy; public: + // FIXME? Empty methods, do we still need them? static void initPlugins(); static void shutdownPlugins(); @@ -205,6 +207,8 @@ public: const ApplicationCompositor& getApplicationCompositor() const { return _compositor; } Overlays& getOverlays() { return _overlays; } + bool isForeground() const { return _isForeground; } + float getFps() const { return _fps; } float getFieldOfView() { return _fieldOfView.get(); } @@ -239,8 +243,6 @@ public: DisplayPlugin* getActiveDisplayPlugin(); const DisplayPlugin* getActiveDisplayPlugin() const; -public: - FileLogger* getLogger() { return _logger; } glm::vec2 getViewportDimensions() const; @@ -608,8 +610,6 @@ private: quint64 _lastSimsPerSecondUpdate = 0; bool _isForeground = true; // starts out assumed to be in foreground bool _inPaint = false; - - friend class PluginContainerProxy; }; #endif // hifi_Application_h diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 3310d9e4cd..4126b7b9bd 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -17,7 +17,7 @@ PluginContainerProxy::PluginContainerProxy() { } bool PluginContainerProxy::isForeground() { - return qApp->_isForeground && !qApp->getWindow()->isMinimized(); + return qApp->isForeground() && !qApp->getWindow()->isMinimized(); } void PluginContainerProxy::addMenu(const QString& menuName) { diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 8dfee8f73b..2fa0267dc6 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -37,7 +37,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share qDebug("OctreePacketProcessor::processPacket() packets to process=%d", packetsToProcessCount()); } - Application* app = qApp; bool wasStatsPacket = false; PacketType octreePacketType = packet->getType(); @@ -46,7 +45,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // then process any remaining bytes as if it was another packet if (octreePacketType == PacketType::OctreeStats) { - int statsMessageLength = app->processOctreeStats(*packet, sendingNode); + int statsMessageLength = qApp->processOctreeStats(*packet, sendingNode); wasStatsPacket = true; int piggybackBytes = packet->getPayloadSize() - statsMessageLength; @@ -84,7 +83,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share return; // bail since piggyback version doesn't match } - app->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket); + qApp->trackIncomingOctreePacket(*packet, sendingNode, wasStatsPacket); // seek back to beginning of packet after tracking packet->seek(0); @@ -92,13 +91,13 @@ void OctreePacketProcessor::processPacket(QSharedPointer packet, Share switch(packetType) { case PacketType::EntityErase: { if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processEraseMessage(*packet, sendingNode); + qApp->getEntities()->processEraseMessage(*packet, sendingNode); } } break; case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { - app->_entities.processDatagram(*packet, sendingNode); + qApp->getEntities()->processDatagram(*packet, sendingNode); } } break; From f55f146d1be953558baa5f8ca23b560051870fc2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 21:24:10 +0200 Subject: [PATCH 086/152] More code cleanup --- interface/src/Application.h | 8 ++------ interface/src/ui/DialogsManager.cpp | 14 ++++++++++++++ interface/src/ui/DialogsManager.h | 16 +--------------- interface/src/ui/HMDToolsDialog.cpp | 7 ++++--- interface/src/ui/HMDToolsDialog.h | 1 + interface/src/ui/OverlayConductor.cpp | 7 ++++--- interface/src/ui/Stats.cpp | 1 + 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 21a4a4429a..c2c8606653 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -12,6 +12,8 @@ #ifndef hifi_Application_h #define hifi_Application_h +#include + #include #include #include @@ -19,24 +21,19 @@ #include #include #include -#include #include #include #include #include -#include #include -#include #include -#include #include #include #include #include #include #include -#include #include #include @@ -171,7 +168,6 @@ public: EntityTreeRenderer* getEntities() { return &_entities; } QUndoStack* getUndoStack() { return &_undoStack; } MainWindow* getWindow() { return _window; } - OctreeQuery& getOctreeQuery() { return _octreeQuery; } EntityTreePointer getEntityClipboard() { return _entityClipboard; } EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 308cfc9e8c..00bc95b5fa 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -32,6 +33,19 @@ #include "ScriptEditorWindow.h" #include "UpdateDialog.h" +template +void DialogsManager::maybeCreateDialog(QPointer& member) { + if (!member) { + MainWindow* parent = qApp->getWindow(); + Q_CHECK_PTR(parent); + member = new T(parent); + Q_CHECK_PTR(member); + + if (_hmdToolsDialog && member->windowHandle()) { + _hmdToolsDialog->watchWindow(member->windowHandle()); + } + } +} void DialogsManager::toggleAddressBar() { AddressBarDialog::toggle(); diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index d54e91b9d6..133fe459d0 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -14,13 +14,10 @@ #include -#include #include #include "HMDToolsDialog.h" -class QAction; - class AnimationsDialog; class AttachmentsDialog; class AudioStatsDialog; @@ -78,18 +75,7 @@ private: DialogsManager() {} template - void maybeCreateDialog(QPointer& member) { - if (!member) { - MainWindow* parent = qApp->getWindow(); - Q_CHECK_PTR(parent); - member = new T(parent); - Q_CHECK_PTR(member); - - if (_hmdToolsDialog && member->windowHandle()) { - _hmdToolsDialog->watchWindow(member->windowHandle()); - } - } - } + void maybeCreateDialog(QPointer& member); QPointer _animationsDialog; QPointer _attachmentsDialog; diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index f37a4a9ba6..c1ea541864 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -9,11 +9,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include #include #include -#include - -#include +#include #include #include #include @@ -22,6 +22,7 @@ #include #include +#include "Application.h" #include "MainWindow.h" #include "Menu.h" #include "ui/DialogsManager.h" diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index 11cab91673..7d30fc17f6 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -15,6 +15,7 @@ #include class HMDWindowWatcher; +class QLabel; class HMDToolsDialog : public QDialog { Q_OBJECT diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 6e4d7e8248..f777e5d4dc 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -8,10 +8,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "Application.h" -#include "InterfaceLogging.h" -#include "avatar/AvatarManager.h" +#include +#include "Application.h" +#include "avatar/AvatarManager.h" +#include "InterfaceLogging.h" #include "OverlayConductor.h" OverlayConductor::OverlayConductor() { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index f4ff2feb02..fe5769c65c 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "BandwidthRecorder.h" From 34bba28775f354d171f131375fec492c8dddf0dd Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 21:53:57 +0200 Subject: [PATCH 087/152] More header cleanup --- interface/src/Application.cpp | 7 ++++--- interface/src/Application.h | 24 +++++++----------------- interface/src/avatar/MyAvatar.cpp | 2 ++ interface/src/ui/AvatarInputs.cpp | 5 +++-- interface/src/ui/ScriptEditBox.cpp | 5 ++++- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index de227cd934..8e7f2b6973 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -111,12 +111,16 @@ #include "LODManager.h" #include "Menu.h" #include "ModelPackager.h" +#include "Stars.h" #include "Util.h" #include "InterfaceLogging.h" #include "InterfaceActionFactory.h" +#include "PluginContainerProxy.h" +#include "AnimDebugDraw.h" #include "avatar/AvatarManager.h" #include "audio/AudioScope.h" + #include "devices/DdeFaceTracker.h" #include "devices/EyeTracker.h" #include "devices/Faceshift.h" @@ -152,9 +156,6 @@ #include "ui/UpdateDialog.h" #include "ui/overlays/Cube3DOverlay.h" -#include "PluginContainerProxy.h" -#include "AnimDebugDraw.h" - // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU // FIXME seems to be broken. #if defined(Q_OS_WIN) diff --git a/interface/src/Application.h b/interface/src/Application.h index c2c8606653..e9eacf7e36 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -37,31 +37,27 @@ #include #include -#include "AudioClient.h" + #include "Bookmarks.h" #include "Camera.h" #include "Environment.h" #include "FileLogger.h" #include "Menu.h" #include "Physics.h" -#include "Stars.h" #include "avatar/AvatarUpdate.h" -#include "avatar/Avatar.h" #include "avatar/MyAvatar.h" #include "scripting/ControllerScriptingInterface.h" #include "scripting/DialogsManagerScriptingInterface.h" -#include "scripting/WebWindowClass.h" -#include "ui/AudioStatsDialog.h" -#include "ui/BandwidthDialog.h" -#include "ui/ModelsBrowser.h" -#include "ui/OctreeStatsDialog.h" #include "ui/SnapshotShareDialog.h" -#include "ui/LodToolsDialog.h" -#include "ui/LogDialog.h" -#include "ui/overlays/Overlays.h" #include "ui/ApplicationOverlay.h" #include "ui/ApplicationCompositor.h" +#include "ui/AudioStatsDialog.h" +#include "ui/BandwidthDialog.h" +#include "ui/LodToolsDialog.h" +#include "ui/LogDialog.h" +#include "ui/OctreeStatsDialog.h" #include "ui/OverlayConductor.h" +#include "ui/overlays/Overlays.h" #include "ui/RunningScriptsWidget.h" #include "ui/ToolWindow.h" #include "octree/OctreePacketProcessor.h" @@ -72,16 +68,10 @@ #include "render/Engine.h" class OffscreenGlCanvas; - class GLCanvas; class FaceTracker; class MainWindow; -namespace gpu { - class Context; - typedef std::shared_ptr ContextPointer; -} - #ifdef Q_OS_WIN static const UINT UWM_IDENTIFY_INSTANCES = RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME")); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ce5768de48..6ed2cf9ad0 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "devices/Faceshift.h" + #include "Application.h" #include "AvatarManager.h" #include "Environment.h" diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index bc9181945f..a9827a23c2 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -7,13 +7,14 @@ // -#include "Application.h" #include "AvatarInputs.h" +#include #include -#include "Menu.h" +#include "Application.h" #include "devices/FaceTracker.h" +#include "Menu.h" HIFI_QML_DEF(AvatarInputs) diff --git a/interface/src/ui/ScriptEditBox.cpp b/interface/src/ui/ScriptEditBox.cpp index acabaa3c8f..2aea225b17 100644 --- a/interface/src/ui/ScriptEditBox.cpp +++ b/interface/src/ui/ScriptEditBox.cpp @@ -10,8 +10,11 @@ // #include "ScriptEditBox.h" + +#include +#include + #include "ScriptLineNumberArea.h" -#include "Application.h" ScriptEditBox::ScriptEditBox(QWidget* parent) : QPlainTextEdit(parent) From dde11c5cd1394fd934859de5aebe0bbac350cf6f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 22:38:49 +0200 Subject: [PATCH 088/152] More unused --- interface/src/Application.cpp | 5 ----- interface/src/Application.h | 9 --------- interface/src/scripting/WindowScriptingInterface.cpp | 4 ---- interface/src/scripting/WindowScriptingInterface.h | 2 -- interface/src/ui/ApplicationCompositor.cpp | 2 +- 5 files changed, 1 insertion(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8e7f2b6973..c6a8feb1a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -363,7 +363,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), - _cursorVisible(true), _lastMouseMove(usecTimestampNow()), _lastMouseMoveWasSimulated(false), _isTouchPressed(false), @@ -2809,10 +2808,6 @@ void Application::updateCursor(float deltaTime) { lastMousePos = QCursor::pos(); } -void Application::setCursorVisible(bool visible) { - _cursorVisible = visible; -} - void Application::update(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); diff --git a/interface/src/Application.h b/interface/src/Application.h index e9eacf7e36..98aa4b3013 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -163,7 +163,6 @@ public: EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } bool isMousePressed() const { return _mousePressed; } - bool isMouseHidden() const { return !_cursorVisible; } const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } bool mouseOnScreen() const; @@ -397,12 +396,9 @@ private slots: void audioMuteToggled(); void faceTrackerMuteToggled(); - void setCursorVisible(bool visible); void activeChanged(Qt::ApplicationState state); private: - void resetCameras(Camera& camera, const glm::uvec2& size); - void initDisplay(); void init(); @@ -423,10 +419,6 @@ private: void updateDialogs(float deltaTime); void updateCursor(float deltaTime); - Avatar* findLookatTargetAvatar(glm::vec3& eyePosition, QUuid &nodeUUID); - - void renderLookatIndicator(glm::vec3 pointOfInterest); - void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); @@ -497,7 +489,6 @@ private: Environment _environment; - bool _cursorVisible; ivec2 _mouseDragStarted; quint64 _lastMouseMove; diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index a5c7087adc..46edbe7420 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -65,10 +65,6 @@ void WindowScriptingInterface::setCursorVisible(bool visible) { Q_ARG(bool, visible)); } -bool WindowScriptingInterface::isCursorVisible() const { - return !qApp->isMouseHidden(); -} - void WindowScriptingInterface::setCursorPosition(int x, int y) { QCursor::setPos(x, y); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 9bc8a834bd..678a66102d 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -27,14 +27,12 @@ class WindowScriptingInterface : public QObject, public Dependency { Q_PROPERTY(int innerHeight READ getInnerHeight) Q_PROPERTY(int x READ getX) Q_PROPERTY(int y READ getY) - Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible) public: WindowScriptingInterface(); int getInnerWidth(); int getInnerHeight(); int getX(); int getY(); - bool isCursorVisible() const; public slots: QScriptValue getCursorPositionX(); diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 98c2efc8f3..5e88a90d71 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -425,7 +425,7 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi //Renders optional pointers void ApplicationCompositor::renderPointers(gpu::Batch& batch) { - if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) { + if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated()) { //If we are in oculus, render reticle later auto trueMouse = qApp->getTrueMouse(); trueMouse /= qApp->getCanvasSize(); From 4ccc2bbcd08be024a22efd602ecc658dde648cfb Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 23:15:37 +0200 Subject: [PATCH 089/152] Enclose entire functions in ifdef --- interface/src/Application.cpp | 19 +++++-------------- interface/src/Application.h | 4 +++- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c6a8feb1a4..6cd129af4d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2304,8 +2304,8 @@ void Application::setActiveFaceTracker() { #endif } -void Application::setActiveEyeTracker() { #ifdef HAVE_IVIEWHMD +void Application::setActiveEyeTracker() { auto eyeTracker = DependencyManager::get(); if (!eyeTracker->isInitialized()) { return; @@ -2318,29 +2318,20 @@ void Application::setActiveEyeTracker() { Menu::getInstance()->getActionForOption(MenuOption::OnePointCalibration)->setEnabled(isEyeTracking && !isSimulating); Menu::getInstance()->getActionForOption(MenuOption::ThreePointCalibration)->setEnabled(isEyeTracking && !isSimulating); Menu::getInstance()->getActionForOption(MenuOption::FivePointCalibration)->setEnabled(isEyeTracking && !isSimulating); -#endif } void Application::calibrateEyeTracker1Point() { -#ifdef HAVE_IVIEWHMD - auto eyeTracker = DependencyManager::get(); - eyeTracker->calibrate(1); -#endif + DependencyManager::get()->calibrate(1); } void Application::calibrateEyeTracker3Points() { -#ifdef HAVE_IVIEWHMD - auto eyeTracker = DependencyManager::get(); - eyeTracker->calibrate(3); -#endif + DependencyManager::get()->calibrate(3); } void Application::calibrateEyeTracker5Points() { -#ifdef HAVE_IVIEWHMD - auto eyeTracker = DependencyManager::get(); - eyeTracker->calibrate(5); -#endif + DependencyManager::get()->calibrate(5); } +#endif bool Application::exportEntities(const QString& filename, const QVector& entityIDs) { QVector entities; diff --git a/interface/src/Application.h b/interface/src/Application.h index 98aa4b3013..5172f34269 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -350,11 +350,13 @@ public slots: void resetSensors(); void setActiveFaceTracker(); - + +#ifdef HAVE_IVIEWHMD void setActiveEyeTracker(); void calibrateEyeTracker1Point(); void calibrateEyeTracker3Points(); void calibrateEyeTracker5Points(); +#endif void aboutApp(); void showEditEntitiesHelp(); From 8c653c70fb838563d5559ecd5fb138b290f4a7e1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 23:19:55 +0200 Subject: [PATCH 090/152] Remove fps throttle from Application --- interface/src/Application.cpp | 5 ----- interface/src/Application.h | 5 ----- interface/src/GLCanvas.cpp | 4 +++- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6cd129af4d..04c7eafc4f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -372,7 +372,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _runningScriptsWidgetWasVisible(false), _lastNackTime(usecTimestampNow()), _lastSendDownstreamAudioStats(usecTimestampNow()), - _isThrottleFPSEnabled(true), _aboutToQuit(false), _notifiedPacketVersionMismatchThisDomain(false), _maxOctreePPS(maxOctreePacketsPerSecond.get()), @@ -4526,10 +4525,6 @@ void Application::takeSnapshot() { } -void Application::setThrottleFPSEnabled() { - _isThrottleFPSEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ThrottleFPSIfNotFocus); -} - float Application::getRenderResolutionScale() const { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) { return 1.0f; diff --git a/interface/src/Application.h b/interface/src/Application.h index 5172f34269..a85efd53a7 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -345,9 +345,6 @@ public slots: void domainSettingsReceived(const QJsonObject& domainSettingsObject); - void setThrottleFPSEnabled(); - bool isThrottleFPSEnabled() { return _isThrottleFPSEnabled; } - void resetSensors(); void setActiveFaceTracker(); @@ -539,8 +536,6 @@ private: quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; - - bool _isThrottleFPSEnabled; bool _aboutToQuit; diff --git a/interface/src/GLCanvas.cpp b/interface/src/GLCanvas.cpp index 306e57cfa0..d9cde868a9 100644 --- a/interface/src/GLCanvas.cpp +++ b/interface/src/GLCanvas.cpp @@ -17,6 +17,7 @@ #include #include "MainWindow.h" +#include "Menu.h" static QGLFormat& getDesiredGLFormat() { // Specify an OpenGL 3.3 format using the Core profile. @@ -62,7 +63,8 @@ void GLCanvas::paintGL() { // FIXME - I'm not sure why this still remains, it appears as if this GLCanvas gets a single paintGL call near // the beginning of the application starting up. I'm not sure if we really need to call Application::paintGL() // in this case, since the display plugins eventually handle all the painting - if (!qApp->getWindow()->isMinimized() || !qApp->isThrottleFPSEnabled()) { + bool isThrottleFPSEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ThrottleFPSIfNotFocus); + if (!qApp->getWindow()->isMinimized() || !isThrottleFPSEnabled) { qApp->paintGL(); } } From 9c7a480fdac4dc6e57ebedd46a093e6648fb4754 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 24 Sep 2015 23:27:14 +0200 Subject: [PATCH 091/152] Remove shadowMatrices/Distances --- interface/src/Application.h | 5 ----- libraries/render-utils/src/AbstractViewStateInterface.h | 4 ---- 2 files changed, 9 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index a85efd53a7..75e65a893a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -212,7 +212,6 @@ public: void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false); - virtual const glm::vec3& getShadowDistances() const { return _shadowDistances; } virtual ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); } virtual QThread* getMainThread() { return thread(); } virtual float getSizeScale() const; @@ -482,10 +481,6 @@ private: float _rotateMirror; float _raiseMirror; - static const int CASCADED_SHADOW_MATRIX_COUNT = 4; - glm::mat4 _shadowMatrices[CASCADED_SHADOW_MATRIX_COUNT]; - glm::vec3 _shadowDistances; - Environment _environment; ivec2 _mouseDragStarted; diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 2b6c66b36a..b65289933c 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -29,10 +29,6 @@ class EnvironmentData; /// Interface provided by Application to other objects that need access to the current view state details class AbstractViewStateInterface { public: - - /// Returns the shadow distances for the current view state - virtual const glm::vec3& getShadowDistances() const = 0; - /// gets the current view frustum for rendering the view state virtual ViewFrustum* getCurrentViewFrustum() = 0; From ba5c20b7a6ab0ff9a54a0956b91a15465fe93069 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 25 Sep 2015 17:42:42 +0200 Subject: [PATCH 092/152] Header cleanup --- interface/src/Util.cpp | 12 +++++++----- interface/src/scripting/MenuScriptingInterface.cpp | 4 ++-- interface/src/scripting/MenuScriptingInterface.h | 5 +---- .../src/scripting/SettingsScriptingInterface.cpp | 3 +-- interface/src/scripting/SettingsScriptingInterface.h | 3 --- interface/src/ui/ScriptLineNumberArea.cpp | 2 +- interface/src/ui/ScriptLineNumberArea.h | 3 ++- interface/src/ui/overlays/Billboard3DOverlay.cpp | 1 - interface/src/ui/overlays/Billboardable.cpp | 1 + interface/src/ui/overlays/Billboardable.h | 7 +++++-- interface/src/ui/overlays/Image3DOverlay.cpp | 2 +- interface/src/ui/overlays/OverlayPanel.cpp | 1 - interface/src/ui/overlays/OverlaysPayload.cpp | 2 +- interface/src/ui/overlays/Text3DOverlay.cpp | 4 ++-- 14 files changed, 24 insertions(+), 26 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index d09dd41999..3d97d48f90 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "Util.h" + #include #include #include @@ -19,17 +21,17 @@ #include #include +#include #include #include -#include #include +#include +#include +#include -#include "world.h" -#include "Application.h" #include "InterfaceLogging.h" - -#include "Util.h" +#include "world.h" using namespace std; diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp index 277c611f04..ff7784b9ae 100644 --- a/interface/src/scripting/MenuScriptingInterface.cpp +++ b/interface/src/scripting/MenuScriptingInterface.cpp @@ -9,10 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "Application.h" - #include "MenuScriptingInterface.h" +#include "Menu.h" +#include MenuScriptingInterface* MenuScriptingInterface::getInstance() { static MenuScriptingInterface sharedInstance; diff --git a/interface/src/scripting/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h index fda8207780..5c01318a38 100644 --- a/interface/src/scripting/MenuScriptingInterface.h +++ b/interface/src/scripting/MenuScriptingInterface.h @@ -12,13 +12,10 @@ #ifndef hifi_MenuScriptingInterface_h #define hifi_MenuScriptingInterface_h -#include -#include #include #include -#include "Menu.h" -#include +class MenuItemProperties; class MenuScriptingInterface : public QObject { Q_OBJECT diff --git a/interface/src/scripting/SettingsScriptingInterface.cpp b/interface/src/scripting/SettingsScriptingInterface.cpp index a5994779e2..2f14c33dc7 100644 --- a/interface/src/scripting/SettingsScriptingInterface.cpp +++ b/interface/src/scripting/SettingsScriptingInterface.cpp @@ -9,10 +9,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - #include "SettingsScriptingInterface.h" +#include SettingsScriptingInterface* SettingsScriptingInterface::getInstance() { static SettingsScriptingInterface sharedInstance; diff --git a/interface/src/scripting/SettingsScriptingInterface.h b/interface/src/scripting/SettingsScriptingInterface.h index e3138be4a0..2fe55eaea0 100644 --- a/interface/src/scripting/SettingsScriptingInterface.h +++ b/interface/src/scripting/SettingsScriptingInterface.h @@ -12,12 +12,9 @@ #ifndef hifi_SettingsScriptingInterface_h #define hifi_SettingsScriptingInterface_h -#include #include #include -#include "Application.h" - class SettingsScriptingInterface : public QObject { Q_OBJECT SettingsScriptingInterface() { }; diff --git a/interface/src/ui/ScriptLineNumberArea.cpp b/interface/src/ui/ScriptLineNumberArea.cpp index 5bb08918b9..6d7e9185ea 100644 --- a/interface/src/ui/ScriptLineNumberArea.cpp +++ b/interface/src/ui/ScriptLineNumberArea.cpp @@ -11,7 +11,7 @@ #include "ScriptLineNumberArea.h" -#include "Application.h" +#include "ScriptEditBox.h" ScriptLineNumberArea::ScriptLineNumberArea(ScriptEditBox* scriptEditBox) : QWidget(scriptEditBox) diff --git a/interface/src/ui/ScriptLineNumberArea.h b/interface/src/ui/ScriptLineNumberArea.h index 47c540ca0e..00bd078170 100644 --- a/interface/src/ui/ScriptLineNumberArea.h +++ b/interface/src/ui/ScriptLineNumberArea.h @@ -13,7 +13,8 @@ #define hifi_ScriptLineNumberArea_h #include -#include "ScriptEditBox.h" + +class ScriptEditBox; class ScriptLineNumberArea : public QWidget { diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index 0b27673e18..908676e0eb 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -10,7 +10,6 @@ // #include "Billboard3DOverlay.h" -#include "Application.h" Billboard3DOverlay::Billboard3DOverlay(const Billboard3DOverlay* billboard3DOverlay) : Planar3DOverlay(billboard3DOverlay), diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index 18e80c2b4f..997cf27609 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -12,6 +12,7 @@ #include "Billboardable.h" #include +#include void Billboardable::setProperties(const QScriptValue &properties) { QScriptValue isFacingAvatar = properties.property("isFacingAvatar"); diff --git a/interface/src/ui/overlays/Billboardable.h b/interface/src/ui/overlays/Billboardable.h index 1388f13e60..82387ad703 100644 --- a/interface/src/ui/overlays/Billboardable.h +++ b/interface/src/ui/overlays/Billboardable.h @@ -13,9 +13,12 @@ #define hifi_Billboardable_h #include -#include -#include +#include + +class QScriptEngine; +class QString; +class Transform; class Billboardable { public: diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index 2f8450131f..11fb647f01 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -18,8 +18,8 @@ #include #include #include +#include -#include "Application.h" #include "GeometryUtil.h" diff --git a/interface/src/ui/overlays/OverlayPanel.cpp b/interface/src/ui/overlays/OverlayPanel.cpp index db91b7e0e3..3d7b93822e 100644 --- a/interface/src/ui/overlays/OverlayPanel.cpp +++ b/interface/src/ui/overlays/OverlayPanel.cpp @@ -18,7 +18,6 @@ #include "avatar/AvatarManager.h" #include "avatar/MyAvatar.h" -#include "Application.h" #include "Base3DOverlay.h" PropertyBinding::PropertyBinding(QString avatar, QUuid entity) : diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index 5b91ff5b52..02d432ea81 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -13,8 +13,8 @@ #include #include -#include #include +#include #include #include diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 563f454057..8c448234ad 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -11,11 +11,11 @@ #include "Text3DOverlay.h" #include +#include +#include #include #include -#include "Application.h" - const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 }; const float DEFAULT_BACKGROUND_ALPHA = 0.7f; const float DEFAULT_MARGIN = 0.1f; From 9827c9085156be3eadb996ff1a906bc3b1736b1e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 2 Oct 2015 16:03:38 -0700 Subject: [PATCH 093/152] Rebase fixes --- interface/src/Application.cpp | 3 +-- interface/src/FileLogger.cpp | 2 +- interface/src/ui/Stats.cpp | 1 + interface/src/ui/overlays/Overlays.cpp | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 04c7eafc4f..472b516e6c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -402,7 +402,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _myAvatar = DependencyManager::get()->getMyAvatar(); - qCDebug(interfaceapp) << "[VERSION] Build sequence: " << qPrintable(applicationVersion()); + qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion()); _bookmarks = new Bookmarks(); // Before setting up the menu @@ -781,7 +781,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(this, &Application::applicationStateChanged, this, &Application::activeChanged); - qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0f); } diff --git a/interface/src/FileLogger.cpp b/interface/src/FileLogger.cpp index f09397322f..10dce38fbc 100644 --- a/interface/src/FileLogger.cpp +++ b/interface/src/FileLogger.cpp @@ -59,7 +59,7 @@ protected: _lastRollTime = now; file.open(QIODevice::WriteOnly | QIODevice::Truncate); file.close(); - qDebug() << "Rolled log file: " << newFileName; + qDebug() << "Rolled log file:" << newFileName; } } } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index fe5769c65c..5e73e62832 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 29e9d62542..96553843c8 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -10,10 +10,11 @@ #include "Overlays.h" -#include - #include +#include + +#include #include #include From 2fc80e58b64cbd6e8fc410fdf06e06dce71c8119 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 2 Oct 2015 17:09:49 -0700 Subject: [PATCH 094/152] Fix warning --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 472b516e6c..642d60a785 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -781,7 +781,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(this, &Application::applicationStateChanged, this, &Application::activeChanged); - qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0f); + qCDebug(interfaceapp, "Startup time: %4.2f seconds.", (double)startupTimer.elapsed() / 1000.0); } void Application::aboutToQuit() { diff --git a/interface/src/Application.h b/interface/src/Application.h index 75e65a893a..1afb43a8a3 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -97,7 +97,7 @@ public: static void initPlugins(); static void shutdownPlugins(); - Application(int& argc, char** argv, QElapsedTimer &startup_time); + Application(int& argc, char** argv, QElapsedTimer& startup_time); ~Application(); void postLambdaEvent(std::function f); From 35e2f8cd89045b9580e54017aac3751bcc90800f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 2 Oct 2015 19:37:49 -0700 Subject: [PATCH 095/152] Removed _myAvatar from Application --- interface/src/Application.cpp | 292 ++++++++++++-------------- interface/src/Application.h | 13 +- interface/src/avatar/Avatar.cpp | 8 + interface/src/avatar/Avatar.h | 6 +- interface/src/avatar/AvatarUpdate.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 2 +- 6 files changed, 146 insertions(+), 177 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 642d60a785..b1ca987640 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -400,8 +400,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto nodeList = DependencyManager::get(); - _myAvatar = DependencyManager::get()->getMyAvatar(); - qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion()); _bookmarks = new Bookmarks(); // Before setting up the menu @@ -439,8 +437,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto audioIO = DependencyManager::get(); - audioIO->setPositionGetter([]{ return qApp->_myAvatar->getPositionForAudio(); }); - audioIO->setOrientationGetter([]{ return qApp->_myAvatar->getOrientationForAudio(); }); + audioIO->setPositionGetter([this]{ return getMyAvatar()->getPositionForAudio(); }); + audioIO->setOrientationGetter([this]{ return getMyAvatar()->getOrientationForAudio(); }); audioIO->moveToThread(audioThread); @@ -455,8 +453,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected); connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { auto audioClient = DependencyManager::get(); - float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), - position); + auto myAvatarPosition = DependencyManager::get()->getMyAvatar()->getPosition(); + float distance = glm::distance(myAvatarPosition, position); bool shouldMute = !audioClient->isMuted() && (distance < radius); if (shouldMute) { @@ -500,8 +498,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled); - connect(nodeList.data(), SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); - connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); + connect(nodeList.data(), &NodeList::uuidChanged, getMyAvatar(), &MyAvatar::setSessionUUID); connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch); @@ -531,8 +528,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto addressManager = DependencyManager::get(); // use our MyAvatar position and quat for address manager path - addressManager->setPositionGetter([]{ return qApp->_myAvatar->getPosition(); }); - addressManager->setOrientationGetter([]{ return qApp->_myAvatar->getOrientation(); }); + addressManager->setPositionGetter([this]{ return getMyAvatar()->getPosition(); }); + addressManager->setOrientationGetter([this]{ return getMyAvatar()->getOrientation(); }); connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress); @@ -551,12 +548,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // send the identity packet for our avatar each second to our avatar mixer identityPacketTimer = new QTimer(); - connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket); + connect(identityPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendIdentityPacket); identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // send the billboard packet for our avatar every few seconds billboardPacketTimer = new QTimer(); - connect(billboardPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendBillboardPacket); + connect(billboardPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendBillboardPacket); billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); @@ -623,7 +620,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived, bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData); - connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded, + connect(&getMyAvatar()->getSkeletonModel(), &SkeletonModel::skeletonLoaded, this, &Application::checkSkeleton, Qt::QueuedConnection); // Setup the userInputMapper with the actions @@ -712,7 +709,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : applicationUpdater->checkForUpdate(); // Now that menu is initalized we can sync myAvatar with it's state. - _myAvatar->updateMotionBehaviorFromMenu(); + getMyAvatar()->updateMotionBehaviorFromMenu(); // the 3Dconnexion device wants to be initiliazed after a window is displayed. ConnexionClient::getInstance().init(); @@ -877,7 +874,6 @@ Application::~Application() { Menu::getInstance()->deleteLater(); _physicsEngine->setCharacterController(NULL); - _myAvatar = NULL; ModelEntityItem::cleanupLoadedAnimations(); @@ -1057,7 +1053,7 @@ void Application::paintGL() { _offscreenContext->makeCurrent(); // update the avatar with a fresh HMD pose - _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose()); + getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); auto lodManager = DependencyManager::get(); @@ -1112,8 +1108,10 @@ void Application::paintGL() { { PerformanceTimer perfTimer("CameraUpdates"); - - _myAvatar->startCapture(); + + auto myAvatar = getMyAvatar(); + + myAvatar->startCapture(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); @@ -1128,51 +1126,51 @@ void Application::paintGL() { // or with changes from the face tracker if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { if (isHMDMode()) { - mat4 camMat = _myAvatar->getSensorToWorldMatrix() * _myAvatar->getHMDSensorMatrix(); + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setRotation(glm::quat_cast(camMat)); } else { - _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * hmdRotation); + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() * hmdRotation); // Ignore MenuOption::CenterPlayerInView in HMD view - glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + _myAvatar->getOrientation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f) + hmdOffset)); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f) + hmdOffset)); } else { - _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); + _myCamera.setRotation(myAvatar->getHead()->getOrientation()); if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + _myCamera.getRotation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); } else { - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + _myAvatar->getOrientation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() + * (myAvatar->getScale() * myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); } } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); } else { - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() + _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; @@ -1181,7 +1179,7 @@ void Application::paintGL() { if (!isHMDMode()) { _myCamera.update(1.0f / _fps); } - _myAvatar->endCapture(); + myAvatar->endCapture(); } // Primary rendering pass @@ -1704,7 +1702,7 @@ void Application::keyPressEvent(QKeyEvent* event) { auto& cursorManager = Cursor::Manager::instance(); cursorManager.setScale(cursorManager.getScale() * 1.1f); } else { - _myAvatar->increaseSize(); + getMyAvatar()->increaseSize(); } break; } @@ -1714,13 +1712,13 @@ void Application::keyPressEvent(QKeyEvent* event) { auto& cursorManager = Cursor::Manager::instance(); cursorManager.setScale(cursorManager.getScale() / 1.1f); } else { - _myAvatar->decreaseSize(); + getMyAvatar()->decreaseSize(); } break; } case Qt::Key_Equal: - _myAvatar->resetSize(); + getMyAvatar()->resetSize(); break; case Qt::Key_Space: { if (!event->isAutoRepeat()) { @@ -2408,7 +2406,7 @@ void Application::loadSettings() { //DependencyManager::get()->setAutomaticLODAdjust(false); Menu::getInstance()->loadSettings(); - _myAvatar->loadData(); + getMyAvatar()->loadData(); } void Application::saveSettings() { @@ -2416,7 +2414,7 @@ void Application::saveSettings() { DependencyManager::get()->saveSettings(); Menu::getInstance()->saveSettings(); - _myAvatar->saveData(); + getMyAvatar()->saveData(); } bool Application::importEntities(const QString& urlOrFilename) { @@ -2451,7 +2449,6 @@ void Application::init() { DependencyManager::get()->init(this); - // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager DependencyManager::get()->init(); _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); @@ -2504,7 +2501,7 @@ void Application::init() { // Make sure any new sounds are loaded as soon as know about them. connect(tree.get(), &EntityTree::newCollisionSoundURL, DependencyManager::get().data(), &SoundCache::getSound); - connect(_myAvatar, &MyAvatar::newCollisionSoundURL, DependencyManager::get().data(), &SoundCache::getSound); + connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, DependencyManager::get().data(), &SoundCache::getSound); setAvatarUpdateThreading(); } @@ -2529,47 +2526,19 @@ void Application::setAvatarUpdateThreading(bool isThreaded) { if (_avatarUpdate && (_avatarUpdate->isThreaded() == isThreaded)) { return; } - bool isRigEnabled = getMyAvatar()->getEnableRigAnimations(); - bool isGraphEnabled = getMyAvatar()->getEnableAnimGraph(); + + auto myAvatar = getMyAvatar(); + bool isRigEnabled = myAvatar->getEnableRigAnimations(); + bool isGraphEnabled = myAvatar->getEnableAnimGraph(); if (_avatarUpdate) { _avatarUpdate->terminate(); // Must be before we shutdown anim graph. } - getMyAvatar()->setEnableRigAnimations(false); - getMyAvatar()->setEnableAnimGraph(false); + myAvatar->setEnableRigAnimations(false); + myAvatar->setEnableAnimGraph(false); _avatarUpdate = new AvatarUpdate(); _avatarUpdate->initialize(isThreaded); - getMyAvatar()->setEnableRigAnimations(isRigEnabled); - getMyAvatar()->setEnableAnimGraph(isGraphEnabled); -} - - -void Application::closeMirrorView() { - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - Menu::getInstance()->triggerOption(MenuOption::Mirror); - } -} - -void Application::restoreMirrorView() { - if (!Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror); - } -} - -void Application::shrinkMirrorView() { - if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { - Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror); - } -} - -const float HEAD_SPHERE_RADIUS = 0.1f; - -bool Application::isLookingAtMyAvatar(AvatarSharedPointer avatar) { - glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); - glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); - if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { - return true; - } - return false; + myAvatar->setEnableRigAnimations(isRigEnabled); + myAvatar->setEnableAnimGraph(isGraphEnabled); } void Application::updateLOD() { @@ -2614,7 +2583,8 @@ void Application::updateMyAvatarLookAtPosition() { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); - _myAvatar->updateLookAtTargetAvatar(); + auto myAvatar = getMyAvatar(); + myAvatar->updateLookAtTargetAvatar(); FaceTracker* faceTracker = getActiveFaceTracker(); auto eyeTracker = DependencyManager::get(); @@ -2630,28 +2600,28 @@ void Application::updateMyAvatarLookAtPosition() { if (isHMD) { glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); glm::quat hmdRotation = glm::quat_cast(headPose); - lookAtSpot = _myCamera.getPosition() + _myAvatar->getOrientation() * (hmdRotation * lookAtPosition); + lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); } else { - lookAtSpot = _myAvatar->getHead()->getEyePosition() - + (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * lookAtPosition); + lookAtSpot = myAvatar->getHead()->getEyePosition() + + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * lookAtPosition); } } else { - AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().lock(); - if (lookingAt && _myAvatar != lookingAt.get()) { + AvatarSharedPointer lookingAt = myAvatar->getLookAtTargetAvatar().lock(); + if (lookingAt && myAvatar != lookingAt.get()) { // If I am looking at someone else, look directly at one of their eyes isLookingAtSomeone = true; auto lookingAtHead = static_pointer_cast(lookingAt)->getHead(); const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE; glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; - glm::vec3 fromLookingAtToMe = glm::normalize(_myAvatar->getHead()->getEyePosition() + glm::vec3 fromLookingAtToMe = glm::normalize(myAvatar->getHead()->getEyePosition() - lookingAtHead->getEyePosition()); float faceAngle = glm::angle(lookingAtFaceOrientation, fromLookingAtToMe); if (faceAngle < MAXIMUM_FACE_ANGLE) { // Randomly look back and forth between look targets eyeContactTarget target = Menu::getInstance()->isOptionChecked(MenuOption::FixGaze) ? - LEFT_EYE : _myAvatar->getEyeContactTarget(); + LEFT_EYE : myAvatar->getEyeContactTarget(); switch (target) { case LEFT_EYE: lookAtSpot = lookingAtHead->getLeftEyePosition(); @@ -2673,10 +2643,10 @@ void Application::updateMyAvatarLookAtPosition() { glm::mat4 headPose = _avatarUpdate->getHeadPose() ; glm::quat headRotation = glm::quat_cast(headPose); lookAtSpot = _myCamera.getPosition() + - _myAvatar->getOrientation() * (headRotation * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); + myAvatar->getOrientation() * (headRotation * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } else { - lookAtSpot = _myAvatar->getHead()->getEyePosition() + - (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); + lookAtSpot = myAvatar->getHead()->getEyePosition() + + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } } @@ -2685,7 +2655,7 @@ void Application::updateMyAvatarLookAtPosition() { float eyePitch = faceTracker->getEstimatedEyePitch(); float eyeYaw = faceTracker->getEstimatedEyeYaw(); const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; - glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); + glm::vec3 origin = myAvatar->getHead()->getEyePosition(); float deflection = faceTracker->getEyeDeflection(); if (isLookingAtSomeone) { deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; @@ -2696,7 +2666,7 @@ void Application::updateMyAvatarLookAtPosition() { } } - _myAvatar->getHead()->setLookAtPosition(lookAtSpot); + myAvatar->getHead()->setLookAtPosition(lookAtSpot); } void Application::updateThreads(float deltaTime) { @@ -2719,13 +2689,13 @@ void Application::cameraMenuChanged() { } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myAvatar->setBoomLength(MyAvatar::ZOOM_MIN); + getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); } } else if (Menu::getInstance()->isOptionChecked(MenuOption::ThirdPerson)) { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - if (_myAvatar->getBoomLength() == MyAvatar::ZOOM_MIN) { - _myAvatar->setBoomLength(MyAvatar::ZOOM_DEFAULT); + if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) { + getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT); } } } else if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) { @@ -2753,7 +2723,7 @@ void Application::reloadResourceCaches() { void Application::rotationModeChanged() { if (!Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myAvatar->setHeadPitch(0); + getMyAvatar()->setHeadPitch(0); } } @@ -2839,8 +2809,9 @@ void Application::update(float deltaTime) { } + auto myAvatar = getMyAvatar(); auto userInputMapper = DependencyManager::get(); - userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix()); + userInputMapper->setSensorToWorldMat(myAvatar->getSensorToWorldMatrix()); userInputMapper->update(deltaTime); // This needs to go after userInputMapper->update() because of the keyboard @@ -2861,15 +2832,15 @@ void Application::update(float deltaTime) { _controllerScriptingInterface.updateInputControllers(); // Transfer the user inputs to the driveKeys - _myAvatar->clearDriveKeys(); + myAvatar->clearDriveKeys(); if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) { if (!_controllerScriptingInterface.areActionsCaptured()) { - _myAvatar->setDriveKeys(FWD, userInputMapper->getActionState(UserInputMapper::LONGITUDINAL_FORWARD)); - _myAvatar->setDriveKeys(BACK, userInputMapper->getActionState(UserInputMapper::LONGITUDINAL_BACKWARD)); - _myAvatar->setDriveKeys(UP, userInputMapper->getActionState(UserInputMapper::VERTICAL_UP)); - _myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN)); - _myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT)); - _myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT)); + myAvatar->setDriveKeys(FWD, userInputMapper->getActionState(UserInputMapper::LONGITUDINAL_FORWARD)); + myAvatar->setDriveKeys(BACK, userInputMapper->getActionState(UserInputMapper::LONGITUDINAL_BACKWARD)); + myAvatar->setDriveKeys(UP, userInputMapper->getActionState(UserInputMapper::VERTICAL_UP)); + myAvatar->setDriveKeys(DOWN, userInputMapper->getActionState(UserInputMapper::VERTICAL_DOWN)); + myAvatar->setDriveKeys(LEFT, userInputMapper->getActionState(UserInputMapper::LATERAL_LEFT)); + myAvatar->setDriveKeys(RIGHT, userInputMapper->getActionState(UserInputMapper::LATERAL_RIGHT)); if (deltaTime > FLT_EPSILON) { // For rotations what we really want are meausures of "angles per second" (in order to prevent // fps-dependent spin rates) so we need to scale the units of the controller contribution. @@ -2877,14 +2848,14 @@ void Application::update(float deltaTime) { // controllers to provide a delta_per_second value rather than a raw delta.) const float EXPECTED_FRAME_RATE = 60.0f; float timeFactor = EXPECTED_FRAME_RATE * deltaTime; - _myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP) / timeFactor); - _myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); - _myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT) / timeFactor); - _myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); + myAvatar->setDriveKeys(ROT_UP, userInputMapper->getActionState(UserInputMapper::PITCH_UP) / timeFactor); + myAvatar->setDriveKeys(ROT_DOWN, userInputMapper->getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); + myAvatar->setDriveKeys(ROT_LEFT, userInputMapper->getActionState(UserInputMapper::YAW_LEFT) / timeFactor); + myAvatar->setDriveKeys(ROT_RIGHT, userInputMapper->getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); } } - _myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN)); - _myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT)); + myAvatar->setDriveKeys(BOOM_IN, userInputMapper->getActionState(UserInputMapper::BOOM_IN)); + myAvatar->setDriveKeys(BOOM_OUT, userInputMapper->getActionState(UserInputMapper::BOOM_OUT)); } UserInputMapper::PoseValue leftHand = userInputMapper->getPoseState(UserInputMapper::LEFT_HAND); UserInputMapper::PoseValue rightHand = userInputMapper->getPoseState(UserInputMapper::RIGHT_HAND); @@ -2906,7 +2877,7 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("physics"); - _myAvatar->relayDriveKeysToCharacterController(); + myAvatar->relayDriveKeysToCharacterController(); static VectorOfMotionStates motionStates; _entitySimulation.getObjectsToDelete(motionStates); @@ -3025,7 +2996,7 @@ void Application::update(float deltaTime) { } // update sensorToWorldMatrix for rendering camera. - _myAvatar->updateSensorToWorldMatrix(); + myAvatar->updateSensorToWorldMatrix(); } @@ -3336,6 +3307,14 @@ PickRay Application::computePickRay(float x, float y) const { return result; } +MyAvatar* Application::getMyAvatar() const { + return DependencyManager::get()->getMyAvatar(); +} + +const glm::vec3& Application::getAvatarPosition() const { + return getMyAvatar()->getPosition(); +} + QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { const int BILLBOARD_SIZE = 64; @@ -3530,9 +3509,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. - _myAvatar->startRender(); - _myAvatar->preRender(renderArgs); - _myAvatar->endRender(); + auto myAvatar = getMyAvatar(); + myAvatar->startRender(); + myAvatar->preRender(renderArgs); + myAvatar->endRender(); activeRenderingThread = QThread::currentThread(); @@ -3646,9 +3626,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine - _myAvatar->startRenderRun(); + myAvatar->startRenderRun(); _renderEngine->run(); - _myAvatar->endRenderRun(); + myAvatar->endRenderRun(); auto engineRC = _renderEngine->getRenderContext(); sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); @@ -3671,15 +3651,17 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi float aspect = (float)region.width() / region.height(); float fov = MIRROR_FIELD_OF_VIEW; + auto myAvatar = getMyAvatar(); + // bool eyeRelativeCamera = false; if (billboard) { fov = BILLBOARD_FIELD_OF_VIEW; // degees - _mirrorCamera.setPosition(_myAvatar->getPosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale()); + _mirrorCamera.setPosition(myAvatar->getPosition() + + myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * myAvatar->getScale()); } else if (!AvatarInputs::getInstance()->mirrorZoomed()) { - _mirrorCamera.setPosition(_myAvatar->getChestPosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); + _mirrorCamera.setPosition(myAvatar->getChestPosition() + + myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale()); } else { // HEAD zoom level // FIXME note that the positioing of the camera relative to the avatar can suffer limited @@ -3698,11 +3680,11 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further // investigated in order to adapt the technique while fixing the head rendering issue, // but the complexity of the hack suggests that a better approach - _mirrorCamera.setPosition(_myAvatar->getDefaultEyePosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); + _mirrorCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * myAvatar->getScale()); } _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); - _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _mirrorCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); // set the bounds of rear mirror view @@ -3736,7 +3718,7 @@ void Application::resetSensors() { QPoint windowCenter = mainWindow->geometry().center(); _glWidget->cursor().setPos(currentScreen, windowCenter); - _myAvatar->reset(); + getMyAvatar()->reset(); QMetaObject::invokeMethod(DependencyManager::get().data(), "reset", Qt::QueuedConnection); } @@ -3819,7 +3801,7 @@ void Application::connectedToDomain(const QString& hostname) { void Application::nodeAdded(SharedNodePointer node) { if (node->getType() == NodeType::AvatarMixer) { // new avatar mixer, send off our identity packet right away - _myAvatar->sendIdentityPacket(); + getMyAvatar()->sendIdentityPacket(); } else if (node->getType() == NodeType::AssetServer) { // the addition of an asset-server always re-enables the upload to asset server menu option Menu::getInstance()->getActionForOption(MenuOption::UploadAsset)->setEnabled(true); @@ -4008,7 +3990,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri AvatarManager::registerMetaTypes(scriptEngine); // hook our avatar and avatar hash map object into this script engine - scriptEngine->registerGlobalObject("MyAvatar", _myAvatar); + scriptEngine->registerGlobalObject("MyAvatar", getMyAvatar()); qScriptRegisterMetaType(scriptEngine, audioListenModeToScriptValue, audioListenModeFromScriptValue); scriptEngine->registerGlobalObject("AvatarList", DependencyManager::get().data()); @@ -4181,7 +4163,7 @@ bool Application::askToSetAvatarUrl(const QString& url) { msgBox.exec(); if (msgBox.clickedButton() == bodyAndHeadButton) { - _myAvatar->useFullAvatarURL(url, modelName); + getMyAvatar()->useFullAvatarURL(url, modelName); emit fullAvatarURLChanged(url, modelName); } else { qCDebug(interfaceapp) << "Declined to use the avatar: " << url; @@ -4309,8 +4291,8 @@ void Application::stopAllScripts(bool restart) { // HACK: ATM scripts cannot set/get their animation priorities, so we clear priorities // whenever a script stops in case it happened to have been setting joint rotations. // TODO: expose animation priorities and provide a layered animation control system. - _myAvatar->clearJointAnimationPriorities(); - _myAvatar->clearScriptableSettings(); + getMyAvatar()->clearJointAnimationPriorities(); + getMyAvatar()->clearScriptableSettings(); } bool Application::stopScript(const QString& scriptHash, bool restart) { @@ -4328,10 +4310,10 @@ bool Application::stopScript(const QString& scriptHash, bool restart) { // HACK: ATM scripts cannot set/get their animation priorities, so we clear priorities // whenever a script stops in case it happened to have been setting joint rotations. // TODO: expose animation priorities and provide a layered animation control system. - _myAvatar->clearJointAnimationPriorities(); + getMyAvatar()->clearJointAnimationPriorities(); } if (_scriptEnginesHash.empty()) { - _myAvatar->clearScriptableSettings(); + getMyAvatar()->clearScriptableSettings(); } return stoppedScript; } @@ -4390,22 +4372,6 @@ void Application::openUrl(const QUrl& url) { } } -void Application::updateMyAvatarTransform() { - const float SIMULATION_OFFSET_QUANTIZATION = 16.0f; // meters - glm::vec3 avatarPosition = _myAvatar->getPosition(); - glm::vec3 physicsWorldOffset = _physicsEngine->getOriginOffset(); - if (glm::distance(avatarPosition, physicsWorldOffset) > SIMULATION_OFFSET_QUANTIZATION) { - glm::vec3 newOriginOffset = avatarPosition; - int halfExtent = (int)HALF_SIMULATION_EXTENT; - for (int i = 0; i < 3; ++i) { - newOriginOffset[i] = (float)(glm::max(halfExtent, - ((int)(avatarPosition[i] / SIMULATION_OFFSET_QUANTIZATION)) * (int)SIMULATION_OFFSET_QUANTIZATION)); - } - // TODO: Andrew to replace this with method that actually moves existing object positions in PhysicsEngine - _physicsEngine->setOriginOffset(newOriginOffset); - } -} - void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) { // from the domain-handler, figure out the satoshi cost per voxel and per meter cubed const QString VOXEL_SETTINGS_KEY = "voxels"; @@ -4584,7 +4550,7 @@ void Application::notifyPacketVersionMismatch() { } void Application::checkSkeleton() { - if (_myAvatar->getSkeletonModel().isActive() && !_myAvatar->getSkeletonModel().hasSkeleton()) { + if (getMyAvatar()->getSkeletonModel().isActive() && !getMyAvatar()->getSkeletonModel().hasSkeleton()) { qCDebug(interfaceapp) << "MyAvatar model has no skeleton"; QString message = "Your selected avatar body has no skeleton.\n\nThe default body will be loaded..."; @@ -4594,9 +4560,9 @@ void Application::checkSkeleton() { msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); - _myAvatar->useFullAvatarURL(AvatarData::defaultFullAvatarModelUrl(), DEFAULT_FULL_AVATAR_MODEL_NAME); + getMyAvatar()->useFullAvatarURL(AvatarData::defaultFullAvatarModelUrl(), DEFAULT_FULL_AVATAR_MODEL_NAME); } else { - _physicsEngine->setCharacterController(_myAvatar->getCharacterController()); + _physicsEngine->setCharacterController(getMyAvatar()->getCharacterController()); } } @@ -4956,8 +4922,8 @@ void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float // transform from sensor space, to world space, to avatar model space. glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation()); - glm::mat4 sensorToWorldMat = _myAvatar->getSensorToWorldMatrix(); - glm::mat4 modelMat = createMatFromQuatAndPos(_myAvatar->getOrientation(), _myAvatar->getPosition()); + glm::mat4 sensorToWorldMat = getMyAvatar()->getSensorToWorldMatrix(); + glm::mat4 modelMat = createMatFromQuatAndPos(getMyAvatar()->getOrientation(), getMyAvatar()->getPosition()); glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat; glm::vec3 position = extractTranslation(objectPose); @@ -5033,7 +4999,7 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) } else { // Get directon relative to avatar orientation - glm::vec3 direction = glm::inverse(_myAvatar->getOrientation()) * palm->getFingerDirection(); + glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection(); // Get the angles, scaled between (-0.5,0.5) float xAngle = (atan2f(direction.z, direction.x) + (float)M_PI_2); diff --git a/interface/src/Application.h b/interface/src/Application.h index 1afb43a8a3..4df7e42004 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -217,7 +217,7 @@ public: virtual float getSizeScale() const; virtual int getBoundaryLevelAdjust() const; virtual PickRay computePickRay(float x, float y) const; - virtual const glm::vec3& getAvatarPosition() const { return _myAvatar->getPosition(); } + virtual const glm::vec3& getAvatarPosition() const; virtual void overrideEnvironmentData(const EnvironmentData& newData) { _environment.override(newData); } virtual void endOverrideEnvironmentData() { _environment.endOverride(); } virtual qreal getDevicePixelRatio(); @@ -235,8 +235,6 @@ public: QStringList getRunningScripts() { return _scriptEnginesHash.keys(); } ScriptEngine* getScriptEngine(const QString& scriptHash) { return _scriptEnginesHash.value(scriptHash, NULL); } - - bool isLookingAtMyAvatar(AvatarSharedPointer avatar); float getRenderResolutionScale() const; int getRenderAmbientLight() const; @@ -276,7 +274,6 @@ public: void updateMyAvatarLookAtPosition(); AvatarUpdate* getAvatarUpdater() { return _avatarUpdate; } - MyAvatar* getMyAvatar() { return _myAvatar; } float getAvatarSimrate(); void setAvatarSimrateSample(float sample); @@ -336,7 +333,6 @@ public slots: void openUrl(const QUrl& url); - void updateMyAvatarTransform(); void setAvatarUpdateThreading(); void setAvatarUpdateThreading(bool isThreaded); void setRawAvatarUpdateThreading(); @@ -383,10 +379,6 @@ private slots: void rotationModeChanged(); - void closeMirrorView(); - void restoreMirrorView(); - void shrinkMirrorView(); - void manageRunningScriptsWidgetVisibility(bool shown); void runTests(); @@ -425,6 +417,8 @@ private: void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard = false); int sendNackPackets(); + + MyAvatar* getMyAvatar() const; bool _dependencyManagerIsSetup; @@ -463,7 +457,6 @@ private: OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers KeyboardMouseDevice* _keyboardMouseDevice{ nullptr }; // Default input device, the good old keyboard mouse and maybe touchpad - MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be) AvatarUpdate* _avatarUpdate {nullptr}; SimpleMovingAverage _avatarSimsPerSecond {10}; int _avatarSimsPerSecondReport {0}; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index a7a4879403..ddee5dfc1f 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -245,6 +245,14 @@ void Avatar::simulate(float deltaTime) { measureMotionDerivatives(deltaTime); } +bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) { + const float HEAD_SPHERE_RADIUS = 0.1f; + glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); + glm::vec3 myEyePosition = getHead()->getEyePosition(); + + return glm::distance(theirLookAt, myEyePosition) <= (HEAD_SPHERE_RADIUS * getScale()); +} + void Avatar::slamPosition(const glm::vec3& newPosition) { setPosition(newPosition); _positionDeltaAccumulator = glm::vec3(0.0f); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2515f260a1..1800f4fdd1 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -80,7 +80,7 @@ public: typedef render::Payload Payload; typedef std::shared_ptr PayloadPointer; - + void init(); void simulate(float deltaTime); @@ -201,7 +201,9 @@ protected: glm::vec3 _worldUpDirection; float _stringLength; bool _moving; ///< set when position is changing - + + bool isLookingAtMe(AvatarSharedPointer avatar); + // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; } diff --git a/interface/src/avatar/AvatarUpdate.cpp b/interface/src/avatar/AvatarUpdate.cpp index 909d3a7bb9..acdb251950 100644 --- a/interface/src/avatar/AvatarUpdate.cpp +++ b/interface/src/avatar/AvatarUpdate.cpp @@ -33,7 +33,7 @@ void AvatarUpdate::synchronousProcess() { _headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); if (_updateBillboard) { - qApp->getMyAvatar()->doUpdateBillboard(); + DependencyManager::get()->getMyAvatar()->doUpdateBillboard(); } if (!isThreaded()) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6ed2cf9ad0..60f7857f27 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1025,7 +1025,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = avatarPointer->getPosition(); smallestAngleTo = angleTo; } - if (qApp->isLookingAtMyAvatar(avatar)) { + if (isLookingAtMe(avatar)) { // Alter their gaze to look directly at my camera; this looks more natural than looking at my avatar's face. glm::vec3 lookAtPosition = avatar->getHead()->getLookAtPosition(); // A position, in world space, on my avatar. From 60ebd3a544d2866257c80fc3183fd26d488a8a1c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 2 Oct 2015 19:42:06 -0700 Subject: [PATCH 096/152] Remove unused members (Mostly mouse stuff) --- interface/src/Application.cpp | 109 +------------- interface/src/Application.h | 162 +++++++++------------ interface/src/ui/ApplicationCompositor.cpp | 2 +- 3 files changed, 69 insertions(+), 204 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b1ca987640..cb6ce018c5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -11,8 +11,6 @@ #include "Application.h" -#include - #include #include #include @@ -363,10 +361,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), - _lastMouseMove(usecTimestampNow()), _lastMouseMoveWasSimulated(false), - _isTouchPressed(false), - _mousePressed(false), _enableProcessOctreeThread(true), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), @@ -1724,7 +1719,7 @@ void Application::keyPressEvent(QKeyEvent* event) { if (!event->isAutoRepeat()) { // this starts an HFActionEvent HFActionEvent startActionEvent(HFActionEvent::startType(), - computePickRay(getTrueMouseX(), getTrueMouseY())); + computePickRay(getTrueMouse().x, getTrueMouse().y)); sendEvent(this, &startActionEvent); } @@ -1775,7 +1770,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { if (!event->isAutoRepeat()) { // this ends the HFActionEvent HFActionEvent endActionEvent(HFActionEvent::endType(), - computePickRay(getTrueMouseX(), getTrueMouseY())); + computePickRay(getTrueMouse().x, getTrueMouse().y)); sendEvent(this, &endActionEvent); } break; @@ -1817,9 +1812,6 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { PROFILE_RANGE(__FUNCTION__); // Used by application overlay to determine how to draw cursor(s) _lastMouseMoveWasSimulated = deviceID > 0; - if (!_lastMouseMoveWasSimulated) { - _lastMouseMove = usecTimestampNow(); - } if (_aboutToQuit) { return; @@ -1897,9 +1889,6 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { } if (event->button() == Qt::LeftButton) { - _mouseDragStarted = getTrueMouse(); - _mousePressed = true; - // nobody handled this - make it an action event on the _window object HFActionEvent actionEvent(HFActionEvent::startType(), computePickRay(event->x(), event->y())); @@ -1955,8 +1944,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { } if (event->button() == Qt::LeftButton) { - _mousePressed = false; - // fire an action end event HFActionEvent actionEvent(HFActionEvent::endType(), computePickRay(event->x(), event->y())); @@ -1982,24 +1969,6 @@ void Application::touchUpdateEvent(QTouchEvent* event) { if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchUpdateEvent(event); } - - bool validTouch = false; - if (hasFocus()) { - const QList& tPoints = event->touchPoints(); - _touchAvg = vec2(); - int numTouches = tPoints.count(); - if (numTouches > 1) { - for (int i = 0; i < numTouches; ++i) { - _touchAvg += toGlm(tPoints[i].pos()); - } - _touchAvg /= (float)(numTouches); - validTouch = true; - } - } - if (!_isTouchPressed) { - _touchDragStartedAvg = _touchAvg; - } - _isTouchPressed = validTouch; } void Application::touchBeginEvent(QTouchEvent* event) { @@ -2037,9 +2006,6 @@ void Application::touchEndEvent(QTouchEvent* event) { } // put any application specific touch behavior below here.. - _touchDragStartedAvg = _touchAvg; - _isTouchPressed = false; - } void Application::wheelEvent(QWheelEvent* event) { @@ -2230,19 +2196,6 @@ void Application::setLowVelocityFilter(bool lowVelocityFilter) { InputDevice::setLowVelocityFilter(lowVelocityFilter); } -bool Application::mouseOnScreen() const { - glm::ivec2 mousePosition = getTrueMouse(); - return (glm::all(glm::greaterThanEqual(mousePosition, glm::ivec2(0))) && - glm::all(glm::lessThanEqual(mousePosition, glm::ivec2(getCanvasSize())))); -} - -ivec2 Application::getMouseDragStarted() const { - if (isHMDMode()) { - return _compositor.screenToOverlay(getTrueMouseDragStarted()); - } - return getTrueMouseDragStarted(); -} - ivec2 Application::getMouse() const { if (isHMDMode()) { return _compositor.screenToOverlay(getTrueMouse()); @@ -2250,11 +2203,6 @@ ivec2 Application::getMouse() const { return getTrueMouse(); } - -ivec2 Application::getTrueMouseDragStarted() const { - return _mouseDragStarted; -} - FaceTracker* Application::getActiveFaceTracker() { auto faceshift = DependencyManager::get(); auto dde = DependencyManager::get(); @@ -2551,29 +2499,6 @@ void Application::updateLOD() { } } -void Application::updateMouseRay() { - PerformanceTimer perfTimer("mouseRay"); - - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateMouseRay()"); - - // make sure the frustum is up-to-date - loadViewFrustum(_myCamera, _viewFrustum); - - PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY()); - _mouseRayOrigin = pickRay.origin; - _mouseRayDirection = pickRay.direction; - - // adjust for mirroring - if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - glm::vec3 mouseRayOffset = _mouseRayOrigin - _viewFrustum.getPosition(); - _mouseRayOrigin -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), mouseRayOffset) + - _viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), mouseRayOffset)); - _mouseRayDirection -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), _mouseRayDirection) + - _viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), _mouseRayDirection)); - } -} - // Called during Application::update immediately before AvatarManager::updateMyAvatar, updating my data that is then sent to everyone. // (Maybe this code should be moved there?) // The principal result is to call updateLookAtTargetAvatar() and then setLookAtPosition(). @@ -2727,12 +2652,6 @@ void Application::rotationModeChanged() { } } -void Application::updateCamera(float deltaTime) { - PerformanceTimer perfTimer("updateCamera"); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateCamera()"); -} - void Application::updateDialogs(float deltaTime) { PerformanceTimer perfTimer("updateDialogs"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); @@ -2757,22 +2676,11 @@ void Application::updateDialogs(float deltaTime) { } } -void Application::updateCursor(float deltaTime) { - PerformanceTimer perfTimer("updateCursor"); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateCursor()"); - - static QPoint lastMousePos = QPoint(); - _lastMouseMove = (lastMousePos == QCursor::pos()) ? _lastMouseMove : usecTimestampNow(); - lastMousePos = QCursor::pos(); -} - void Application::update(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); updateLOD(); - updateMouseRay(); // check what's under the mouse and update the mouse voxel { PerformanceTimer perfTimer("devices"); @@ -2870,10 +2778,7 @@ void Application::update(float deltaTime) { } updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... - - updateCamera(deltaTime); // handle various camera tweaks like off axis projection updateDialogs(deltaTime); // update various stats dialogs if present - updateCursor(deltaTime); // Handle cursor updates { PerformanceTimer perfTimer("physics"); @@ -4334,14 +4239,6 @@ void Application::loadDefaultScripts() { } } -void Application::manageRunningScriptsWidgetVisibility(bool shown) { - if (_runningScriptsWidgetWasVisible && shown) { - _runningScriptsWidget->show(); - } else if (_runningScriptsWidgetWasVisible && !shown) { - _runningScriptsWidget->hide(); - } -} - void Application::toggleRunningScriptsWidget() { if (_runningScriptsWidget->isVisible()) { if (_runningScriptsWidget->hasFocus()) { @@ -4624,7 +4521,7 @@ QSize Application::getDeviceSize() const { } PickRay Application::computePickRay() const { - return computePickRay(getTrueMouseX(), getTrueMouseY()); + return computePickRay(getTrueMouse().x, getTrueMouse().y); } bool Application::isThrottleRendering() const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 4df7e42004..68cfc6aeaf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -111,27 +111,6 @@ public: void paintGL(); void resizeGL(); - void resizeEvent(QResizeEvent * size); - - void keyPressEvent(QKeyEvent* event); - void keyReleaseEvent(QKeyEvent* event); - - void focusOutEvent(QFocusEvent* event); - void focusInEvent(QFocusEvent* event); - - void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0); - void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0); - void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0); - void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0); - - void touchBeginEvent(QTouchEvent* event); - void touchEndEvent(QTouchEvent* event); - void touchUpdateEvent(QTouchEvent* event); - - void wheelEvent(QWheelEvent* event); - void dropEvent(QDropEvent* event); - void dragEnterEvent(QDragEnterEvent* event); - bool event(QEvent* event); bool eventFilter(QObject* object, QEvent* event); @@ -162,25 +141,8 @@ public: EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } - bool isMousePressed() const { return _mousePressed; } - const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } - const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } - bool mouseOnScreen() const; - ivec2 getMouse() const; ivec2 getTrueMouse() const; - ivec2 getMouseDragStarted() const; - ivec2 getTrueMouseDragStarted() const; - - // TODO get rid of these and use glm types directly - int getMouseX() const { return getMouse().x; } - int getMouseY() const { return getMouse().y; } - int getTrueMouseX() const { return getTrueMouse().x; } - int getTrueMouseY() const { return getTrueMouse().y; } - int getMouseDragStartedX() const { return getMouseDragStarted().x; } - int getMouseDragStartedY() const { return getMouseDragStarted().y; } - int getTrueMouseDragStartedX() const { return getTrueMouseDragStarted().x; } - int getTrueMouseDragStartedY() const { return getTrueMouseDragStarted().y; } bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; } FaceTracker* getActiveFaceTracker(); @@ -199,8 +161,6 @@ public: float getFieldOfView() { return _fieldOfView.get(); } void setFieldOfView(float fov) { _fieldOfView.set(fov); } - bool importSVOFromURL(const QString& urlString); - NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } ToolWindow* getToolWindow() { return _toolWindow ; } @@ -210,8 +170,6 @@ public: QImage renderAvatarBillboard(RenderArgs* renderArgs); - void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false); - virtual ViewFrustum* getCurrentViewFrustum() { return getDisplayViewFrustum(); } virtual QThread* getMainThread() { return thread(); } virtual float getSizeScale() const; @@ -237,7 +195,6 @@ public: ScriptEngine* getScriptEngine(const QString& scriptHash) { return _scriptEnginesHash.value(scriptHash, NULL); } float getRenderResolutionScale() const; - int getRenderAmbientLight() const; bool isAboutToQuit() const { return _aboutToQuit; } @@ -258,7 +215,6 @@ public: QString getScriptsLocation(); void setScriptsLocation(const QString& scriptsLocation); - void initializeAcceptedFiles(); bool canAcceptURL(const QString& url); bool acceptURL(const QString& url); @@ -293,15 +249,6 @@ signals: void activeDisplayPluginChanged(); public slots: - void setSessionUUID(const QUuid& sessionUUID); - void domainChanged(const QString& domainHostname); - void updateWindowTitle(); - void nodeAdded(SharedNodePointer node); - void nodeKilled(SharedNodePointer node); - void packetSent(quint64 length); - void updateDisplayMode(); - void updateInputModes(); - QVector pasteEntities(float x, float y, float z); bool exportEntities(const QString& filename, const QVector& entityIDs); bool exportEntities(const QString& filename, float x, float y, float z, float scale); @@ -311,21 +258,15 @@ public slots: void loadDialog(); void loadScriptURLDialog(); void toggleLogDialog(); - bool acceptSnapshot(const QString& urlString); - bool askToSetAvatarUrl(const QString& url); - bool askToLoadScript(const QString& scriptFilenameOrURL); ScriptEngine* loadScript(const QString& scriptFilename = QString(), bool isUserLoaded = true, bool loadScriptFromEditor = false, bool activateMainWindow = false, bool reload = false); - void reloadScript(const QString& scriptName, bool isUserLoaded = true); - void scriptFinished(const QString& scriptName); void stopAllScripts(bool restart = false); bool stopScript(const QString& scriptHash, bool restart = false); void reloadAllScripts(); void reloadOneScript(const QString& scriptName); void loadDefaultScripts(); void toggleRunningScriptsWidget(); - void saveScripts(); void showFriendsWindow(); @@ -338,8 +279,6 @@ public slots: void setRawAvatarUpdateThreading(); void setRawAvatarUpdateThreading(bool isThreaded); - void domainSettingsReceived(const QJsonObject& domainSettingsObject); - void resetSensors(); void setActiveFaceTracker(); @@ -353,19 +292,16 @@ public slots: void aboutApp(); void showEditEntitiesHelp(); - void loadSettings(); - void saveSettings(); - - void notifyPacketVersionMismatch(); - - void handleDomainConnectionDeniedPacket(QSharedPointer packet); - void cameraMenuChanged(); void reloadResourceCaches(); void crashApplication(); - + + void rotationModeChanged(); + + void runTests(); + private slots: void clearDomainOctreeDetails(); void checkFPS(); @@ -377,17 +313,36 @@ private slots: void connectedToDomain(const QString& hostname); - void rotationModeChanged(); - - void manageRunningScriptsWidgetVisibility(bool shown); - - void runTests(); - void audioMuteToggled(); void faceTrackerMuteToggled(); void activeChanged(Qt::ApplicationState state); - + + void domainSettingsReceived(const QJsonObject& domainSettingsObject); + void handleDomainConnectionDeniedPacket(QSharedPointer packet); + + void notifyPacketVersionMismatch(); + + void loadSettings(); + void saveSettings(); + + void scriptFinished(const QString& scriptName); + void saveScripts(); + void reloadScript(const QString& scriptName, bool isUserLoaded = true); + + bool acceptSnapshot(const QString& urlString); + bool askToSetAvatarUrl(const QString& url); + bool askToLoadScript(const QString& scriptFilenameOrURL); + + void setSessionUUID(const QUuid& sessionUUID); + void domainChanged(const QString& domainHostname); + void updateWindowTitle(); + void nodeAdded(SharedNodePointer node); + void nodeKilled(SharedNodePointer node); + void packetSent(quint64 length); + void updateDisplayMode(); + void updateInputModes(); + private: void initDisplay(); void init(); @@ -403,11 +358,8 @@ private: // Various helper functions called during update() void updateLOD(); - void updateMouseRay(); void updateThreads(float deltaTime); - void updateCamera(float deltaTime); void updateDialogs(float deltaTime); - void updateCursor(float deltaTime); void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); @@ -418,7 +370,41 @@ private: int sendNackPackets(); + void takeSnapshot(); + MyAvatar* getMyAvatar() const; + + void initializeAcceptedFiles(); + int getRenderAmbientLight() const; + + void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false, bool billboard = false); + + bool importSVOFromURL(const QString& urlString); + + int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode); + void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket); + + void resizeEvent(QResizeEvent* size); + + void keyPressEvent(QKeyEvent* event); + void keyReleaseEvent(QKeyEvent* event); + + void focusOutEvent(QFocusEvent* event); + void focusInEvent(QFocusEvent* event); + + void mouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0); + void mousePressEvent(QMouseEvent* event, unsigned int deviceID = 0); + void mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0); + void mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0); + + void touchBeginEvent(QTouchEvent* event); + void touchEndEvent(QTouchEvent* event); + void touchUpdateEvent(QTouchEvent* event); + + void wheelEvent(QWheelEvent* event); + void dropEvent(QDropEvent* event); + void dragEnterEvent(QDragEnterEvent* event); + bool _dependencyManagerIsSetup; @@ -476,21 +462,8 @@ private: Environment _environment; - ivec2 _mouseDragStarted; - - quint64 _lastMouseMove; bool _lastMouseMoveWasSimulated; - glm::vec3 _mouseRayOrigin; - glm::vec3 _mouseRayDirection; - - vec2 _touchAvg; - vec2 _touchDragStartedAvg; - - bool _isTouchPressed; // true if multitouch has been pressed (clear when finished) - - bool _mousePressed; // true if mouse has been pressed (clear when finished) - QSet _keysPressed; bool _enableProcessOctreeThread; @@ -501,9 +474,6 @@ private: StDev _idleLoopStdev; float _idleLoopMeasuredJitter; - int processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode); - void trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket); - NodeToJurisdictionMap _entityServerJurisdictions; NodeToOctreeSceneStats _octreeServerSceneStats; @@ -513,8 +483,6 @@ private: FileLogger* _logger; - void takeSnapshot(); - TouchEvent _lastTouchEvent; RunningScriptsWidget* _runningScriptsWidget; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 5e88a90d71..cb4ae9990c 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -429,7 +429,7 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) { //If we are in oculus, render reticle later auto trueMouse = qApp->getTrueMouse(); trueMouse /= qApp->getCanvasSize(); - QPoint position = QPoint(qApp->getTrueMouseX(), qApp->getTrueMouseY()); + QPoint position = QPoint(qApp->getTrueMouse().x, qApp->getTrueMouse().y); _reticlePosition[MOUSE] = position; _reticleActive[MOUSE] = true; _magActive[MOUSE] = _magnifier; From 5e9425d9ebb940028bc5c80b402fb81b0c89d98b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 19:48:28 -0700 Subject: [PATCH 097/152] Fix view frustum preference --- interface/src/Application.cpp | 24 +++++++++++++++--------- interface/src/Application.h | 2 +- interface/src/avatar/MyAvatar.cpp | 3 +-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cb6ce018c5..f6fddc06fd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1316,6 +1316,13 @@ void Application::faceTrackerMuteToggled() { Menu::getInstance()->getActionForOption(MenuOption::CalibrateCamera)->setEnabled(!isMuted); } +void Application::setFieldOfView(float fov) { + if (fov != _fieldOfView.get()) { + _fieldOfView.set(fov); + resizeGL(); + } +} + void Application::aboutApp() { InfoView::show(INFO_HELP_PATH); } @@ -1342,16 +1349,15 @@ void Application::resizeGL() { if (_renderResolution != renderSize) { _renderResolution = renderSize; DependencyManager::get()->setFrameBufferSize(fromGlm(renderSize)); - - // Possible change in aspect ratio - loadViewFrustum(_myCamera, _viewFrustum); - float fov = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES); - // FIXME the aspect ratio for stereo displays is incorrect based on this. - float aspectRatio = displayPlugin->getRecommendedAspectRatio(); - _myCamera.setProjection(glm::perspective(fov, aspectRatio, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); } - - + + // FIXME the aspect ratio for stereo displays is incorrect based on this. + float aspectRatio = displayPlugin->getRecommendedAspectRatio(); + _myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio, + DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); + // Possible change in aspect ratio + loadViewFrustum(_myCamera, _viewFrustum); + auto offscreenUi = DependencyManager::get(); auto uiSize = displayPlugin->getRecommendedUiSize(); // Bit of a hack since there's no device pixel ratio change event I can find. diff --git a/interface/src/Application.h b/interface/src/Application.h index 68cfc6aeaf..fa736b5ac6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -159,7 +159,7 @@ public: float getFps() const { return _fps; } float getFieldOfView() { return _fieldOfView.get(); } - void setFieldOfView(float fov) { _fieldOfView.set(fov); } + void setFieldOfView(float fov); NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 60f7857f27..f94362c4e4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -428,8 +428,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { head->setDeltaYaw(estimatedRotation.y); head->setDeltaRoll(estimatedRotation.z); } else { - float magnifyFieldOfView = qApp->getFieldOfView() / - _realWorldFieldOfView.get(); + float magnifyFieldOfView = qApp->getViewFrustum()->getFieldOfView() / _realWorldFieldOfView.get(); head->setDeltaPitch(estimatedRotation.x * magnifyFieldOfView); head->setDeltaYaw(estimatedRotation.y * magnifyFieldOfView); head->setDeltaRoll(estimatedRotation.z); From e9b7125894ebc6350f3f111612284e55979849bf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 21:11:32 -0700 Subject: [PATCH 098/152] Misc cleanup --- interface/src/Application.cpp | 31 ++++++++++------------- interface/src/Application.h | 8 +++--- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/devices/3DConnexionClient.h | 2 -- interface/src/ui/PreferencesDialog.cpp | 4 +-- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f6fddc06fd..2df1d7a687 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -199,6 +199,13 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI const QString CHECK_VERSION_URL = "https://highfidelity.com/latestVersion.xml"; const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion"; +#ifndef __APPLE__ +static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); +#else +// Temporary fix to Qt bug: http://stackoverflow.com/questions/16194475 +static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).append("/script.js"); +#endif + const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); @@ -355,8 +362,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _firstRun("firstRun", true), - _previousScriptLocation("LastScriptLocation"), - _scriptsLocationHandle("scriptsLocation"), + _previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION), + _scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION), _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), _scaleMirror(1.0f), _rotateMirror(0.0f), @@ -1005,7 +1012,7 @@ void Application::initializeUi() { return result; }); offscreenUi->resume(); - connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect & r){ + connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){ static qreal oldDevicePixelRatio = 0; qreal devicePixelRatio = getActiveDisplayPlugin()->devicePixelRatio(); if (devicePixelRatio != oldDevicePixelRatio) { @@ -1331,7 +1338,7 @@ void Application::showEditEntitiesHelp() { InfoView::show(INFO_EDIT_ENTITIES_PATH); } -void Application::resizeEvent(QResizeEvent * event) { +void Application::resizeEvent(QResizeEvent* event) { resizeGL(); } @@ -1340,11 +1347,11 @@ void Application::resizeGL() { if (nullptr == _displayPlugin) { return; } - + auto displayPlugin = getActiveDisplayPlugin(); // Set the desired FBO texture size. If it hasn't changed, this does nothing. // Otherwise, it must rebuild the FBOs - uvec2 framebufferSize = getActiveDisplayPlugin()->getRecommendedRenderSize(); + uvec2 framebufferSize = displayPlugin->getRecommendedRenderSize(); uvec2 renderSize = uvec2(vec2(framebufferSize) * getRenderResolutionScale()); if (_renderResolution != renderSize) { _renderResolution = renderSize; @@ -4303,17 +4310,7 @@ void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject } QString Application::getPreviousScriptLocation() { - QString suggestedName; - if (_previousScriptLocation.get().isEmpty()) { - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); -// Temporary fix to Qt bug: http://stackoverflow.com/questions/16194475 -#ifdef __APPLE__ - suggestedName = desktopLocation.append("/script.js"); -#endif - } else { - suggestedName = _previousScriptLocation.get(); - } - return suggestedName; + return _previousScriptLocation.get(); } void Application::setPreviousScriptLocation(const QString& previousScriptLocation) { diff --git a/interface/src/Application.h b/interface/src/Application.h index fa736b5ac6..8e906c789b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -451,10 +451,10 @@ private: Camera _mirrorCamera; // Cammera for mirror view QRect _mirrorViewRect; - Setting::Handle _firstRun; - Setting::Handle _previousScriptLocation; - Setting::Handle _scriptsLocationHandle; - Setting::Handle _fieldOfView; + Setting::Handle _firstRun; + Setting::Handle _previousScriptLocation; + Setting::Handle _scriptsLocationHandle; + Setting::Handle _fieldOfView; float _scaleMirror; float _rotateMirror; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f94362c4e4..0105d1b648 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -437,7 +437,6 @@ void MyAvatar::updateFromTrackers(float deltaTime) { // Update torso lean distance based on accelerometer data const float TORSO_LENGTH = 0.5f; glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f); - const float MAX_LEAN = 45.0f; // Invert left/right lean when in mirror mode // NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror @@ -447,6 +446,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) { relativePosition.x = -relativePosition.x; } + const float MAX_LEAN = 45.0f; head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), -MAX_LEAN, MAX_LEAN)); head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), diff --git a/interface/src/devices/3DConnexionClient.h b/interface/src/devices/3DConnexionClient.h index dd5dc7cb08..cdf8e1e2a1 100755 --- a/interface/src/devices/3DConnexionClient.h +++ b/interface/src/devices/3DConnexionClient.h @@ -16,8 +16,6 @@ #include #include "InterfaceLogging.h" -#include "Application.h" - #ifndef HAVE_3DCONNEXIONCLIENT class ConnexionClient : public QObject { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 1b55c6fa2b..f90bac234d 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -183,7 +183,7 @@ void PreferencesDialog::loadPreferences() { ui.outputStarveDetectionThresholdSpinner->setValue(audio->getOutputStarveDetectionThreshold()); ui.outputStarveDetectionPeriodSpinner->setValue(audio->getOutputStarveDetectionPeriod()); - ui.realWorldFieldOfViewSpin->setValue(DependencyManager::get()->getMyAvatar()->getRealWorldFieldOfView()); + ui.realWorldFieldOfViewSpin->setValue(myAvatar->getRealWorldFieldOfView()); ui.fieldOfViewSpin->setValue(qApp->getFieldOfView()); @@ -258,7 +258,7 @@ void PreferencesDialog::savePreferences() { } } - DependencyManager::get()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); + myAvatar->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); qApp->setFieldOfView(ui.fieldOfViewSpin->value()); From 39e0d0e1dc6243c100580580860ce1093daaa906 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 21:12:12 -0700 Subject: [PATCH 099/152] Put timers on the stack --- interface/src/Application.cpp | 63 +++++++++++++---------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2df1d7a687..1bef9771eb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -164,12 +164,12 @@ extern "C" { using namespace std; -static QTimer* locationUpdateTimer = NULL; -static QTimer* balanceUpdateTimer = NULL; -static QTimer* identityPacketTimer = NULL; -static QTimer* billboardPacketTimer = NULL; -static QTimer* checkFPStimer = NULL; -static QTimer* idleTimer = NULL; +static QTimer locationUpdateTimer; +static QTimer balanceUpdateTimer; +static QTimer identityPacketTimer; +static QTimer billboardPacketTimer; +static QTimer checkFPStimer; +static QTimer idleTimer; static const QString SNAPSHOT_EXTENSION = ".jpg"; static const QString SVO_EXTENSION = ".svo"; @@ -489,10 +489,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000; - locationUpdateTimer = new QTimer(this); auto discoverabilityManager = DependencyManager::get(); - connect(locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); - locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); + connect(&locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); + locationUpdateTimer.start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); // if we get a domain change, immediately attempt update location in metaverse server connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain, @@ -510,9 +509,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * 1000; - balanceUpdateTimer = new QTimer(this); - connect(balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance); - balanceUpdateTimer->start(BALANCE_UPDATE_INTERVAL_MSECS); + connect(&balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance); + balanceUpdateTimer.start(BALANCE_UPDATE_INTERVAL_MSECS); connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle); @@ -549,14 +547,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent); // send the identity packet for our avatar each second to our avatar mixer - identityPacketTimer = new QTimer(); - connect(identityPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendIdentityPacket); - identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); + connect(&identityPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendIdentityPacket); + identityPacketTimer.start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // send the billboard packet for our avatar every few seconds - billboardPacketTimer = new QTimer(); - connect(billboardPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendBillboardPacket); - billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); + connect(&billboardPacketTimer, &QTimer::timeout, getMyAvatar(), &MyAvatar::sendBillboardPacket); + billboardPacketTimer.start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -818,23 +814,14 @@ void Application::cleanupBeforeQuit() { // first stop all timers directly or by invokeMethod // depending on what thread they run in _avatarUpdate->terminate(); - locationUpdateTimer->stop(); - balanceUpdateTimer->stop(); - identityPacketTimer->stop(); - billboardPacketTimer->stop(); - checkFPStimer->stop(); - idleTimer->stop(); + locationUpdateTimer.stop(); + balanceUpdateTimer.stop(); + identityPacketTimer.stop(); + billboardPacketTimer.stop(); + checkFPStimer.stop(); + idleTimer.stop(); QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); - // and then delete those that got created by "new" - delete locationUpdateTimer; - delete balanceUpdateTimer; - delete identityPacketTimer; - delete billboardPacketTimer; - delete checkFPStimer; - delete idleTimer; - // no need to delete _settingsTimer here as it is no pointer - // save state _settingsThread.quit(); saveSettings(); @@ -964,14 +951,12 @@ void Application::initializeGL() { _entityEditSender.initialize(_enableProcessOctreeThread); // call our timer function every second - checkFPStimer = new QTimer(this); - connect(checkFPStimer, SIGNAL(timeout()), SLOT(checkFPS())); - checkFPStimer->start(1000); + connect(&checkFPStimer, &QTimer::timeout, &Application::checkFPS); + checkFPStimer.start(1000); // call our idle function whenever we can - idleTimer = new QTimer(this); - connect(idleTimer, SIGNAL(timeout()), SLOT(idle())); - idleTimer->start(TARGET_SIM_FRAME_PERIOD_MS); + connect(&idleTimer, &QTimer::timeout, &Application::idle); + idleTimer.start(TARGET_SIM_FRAME_PERIOD_MS); _idleLoopStdev.reset(); // update before the first render From 17edd38cb9e3b2ce0dac32fb2059eb6b77506d5c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 21:12:30 -0700 Subject: [PATCH 100/152] Remove unused variables --- interface/src/Application.cpp | 77 ++++++++++++++++------------------- interface/src/Application.h | 1 - 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1bef9771eb..6d79510cb3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -300,42 +300,42 @@ bool setupEssentials(int& argc, char** argv) { Setting::init(); // Set dependencies - auto addressManager = DependencyManager::set(); - auto nodeList = DependencyManager::set(NodeType::Agent, listenPort); - auto geometryCache = DependencyManager::set(); - auto modelCache = DependencyManager::set(); - auto scriptCache = DependencyManager::set(); - auto soundCache = DependencyManager::set(); - auto faceshift = DependencyManager::set(); - auto ddeFaceTracker = DependencyManager::set(); - auto eyeTracker = DependencyManager::set(); - auto audio = DependencyManager::set(); - auto audioScope = DependencyManager::set(); - auto deferredLightingEffect = DependencyManager::set(); - auto textureCache = DependencyManager::set(); - auto framebufferCache = DependencyManager::set(); - auto animationCache = DependencyManager::set(); - auto modelBlender = DependencyManager::set(); - auto avatarManager = DependencyManager::set(); - auto lodManager = DependencyManager::set(); - auto jsConsole = DependencyManager::set(); - auto dialogsManager = DependencyManager::set(); - auto bandwidthRecorder = DependencyManager::set(); - auto resourceCacheSharedItems = DependencyManager::set(); - auto desktopScriptingInterface = DependencyManager::set(); - auto entityScriptingInterface = DependencyManager::set(); - auto windowScriptingInterface = DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(NodeType::Agent, listenPort); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) - auto speechRecognizer = DependencyManager::set(); + DependencyManager::set(); #endif - auto discoverabilityManager = DependencyManager::set(); - auto sceneScriptingInterface = DependencyManager::set(); - auto offscreenUi = DependencyManager::set(); - auto autoUpdater = DependencyManager::set(); - auto pathUtils = DependencyManager::set(); - auto actionFactory = DependencyManager::set(); - auto assetClient = DependencyManager::set(); - auto userInputMapper = DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); return true; } @@ -965,10 +965,6 @@ void Application::initializeGL() { InfoView::show(INFO_HELP_PATH, true); } -QWindow* getProxyWindow() { - return qApp->getWindow()->windowHandle(); -} - void Application::initializeUi() { AddressBarDialog::registerType(); ErrorDialog::registerType(); @@ -4543,7 +4539,7 @@ qreal Application::getDevicePixelRatio() { return (_window && _window->windowHandle()) ? _window->windowHandle()->devicePixelRatio() : 1.0; } -DisplayPlugin * Application::getActiveDisplayPlugin() { +DisplayPlugin* Application::getActiveDisplayPlugin() { if (nullptr == _displayPlugin) { updateDisplayMode(); Q_ASSERT(_displayPlugin); @@ -4551,7 +4547,7 @@ DisplayPlugin * Application::getActiveDisplayPlugin() { return _displayPlugin.data(); } -const DisplayPlugin * Application::getActiveDisplayPlugin() const { +const DisplayPlugin* Application::getActiveDisplayPlugin() const { return ((Application*)this)->getActiveDisplayPlugin(); } @@ -4559,7 +4555,6 @@ bool _activatingDisplayPlugin{ false }; QVector> _currentDisplayPluginActions; QVector> _currentInputPluginActions; - static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { auto menu = Menu::getInstance(); QString name = displayPlugin->getName(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 8e906c789b..23b173f1ea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -420,7 +420,6 @@ private: UndoStackScriptingInterface _undoStackScriptingInterface; // Frame Rate Measurement - int _frameCount; float _fps; QElapsedTimer _timerStart; From b63df98b8b26972ed39025214c03bccb41c5ec77 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 21:35:50 -0700 Subject: [PATCH 101/152] More unused --- interface/src/Application.cpp | 5 ++--- interface/src/Application.h | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d79510cb3..3cfb10c7bb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -951,11 +950,11 @@ void Application::initializeGL() { _entityEditSender.initialize(_enableProcessOctreeThread); // call our timer function every second - connect(&checkFPStimer, &QTimer::timeout, &Application::checkFPS); + connect(&checkFPStimer, &QTimer::timeout, this, &Application::checkFPS); checkFPStimer.start(1000); // call our idle function whenever we can - connect(&idleTimer, &QTimer::timeout, &Application::idle); + connect(&idleTimer, &QTimer::timeout, this, &Application::idle); idleTimer.start(TARGET_SIM_FRAME_PERIOD_MS); _idleLoopStdev.reset(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 23b173f1ea..c315dde0ea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -37,7 +37,6 @@ #include #include - #include "Bookmarks.h" #include "Camera.h" #include "Environment.h" @@ -119,7 +118,6 @@ public: QSize getDeviceSize() const; bool hasFocus() const; PickRay computePickRay() const; - PickRay computeViewPickRay(float xRatio, float yRatio) const; bool isThrottleRendering() const; From 775994f9d0c2298eeea9aceff3bb5f33c9a41bba Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 22:02:11 -0700 Subject: [PATCH 102/152] Fix for 3DConnection --- interface/src/devices/3DConnexionClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/devices/3DConnexionClient.cpp b/interface/src/devices/3DConnexionClient.cpp index d49fafa3e0..722fedcc3a 100755 --- a/interface/src/devices/3DConnexionClient.cpp +++ b/interface/src/devices/3DConnexionClient.cpp @@ -10,6 +10,7 @@ // #include "3DConnexionClient.h" +#include "Menu.h" #include "UserActivityLogger.h" const float MAX_AXIS = 75.0f; // max forward = 2x speed From 7b25c9d417ac2cdd67725be6efa7c636f52aa349 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Sun, 4 Oct 2015 23:53:34 -0700 Subject: [PATCH 103/152] More header cleanup --- interface/src/Application.cpp | 84 ++++++++++++++--------------------- interface/src/Application.h | 23 +++++----- 2 files changed, 43 insertions(+), 64 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3cfb10c7bb..7d1886f10c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -19,46 +19,34 @@ #include #include -#include -#include +#include +#include #include -#include #include +#include #include #include +#include #include +#include +#include #include -#include #include #include -#include #include #include #include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include #include -#include -#include +#include #include +#include #include -#include -#include -#include #include - #include #include #include @@ -71,6 +59,7 @@ #include #include #include // this should probably be removed +#include #include #include #include @@ -78,80 +67,73 @@ #include #include #include -#include #include #include -#include +#include #include #include #include +#include +#include +#include #include #include #include #include -#include -#include #include #include #include +#include #include #include -#include #include -#include - -#include "AudioClient.h" -#include "CrashHandler.h" -#include "DiscoverabilityManager.h" -#include "GLCanvas.h" -#include "LODManager.h" -#include "Menu.h" -#include "ModelPackager.h" -#include "Stars.h" -#include "Util.h" -#include "InterfaceLogging.h" -#include "InterfaceActionFactory.h" -#include "PluginContainerProxy.h" #include "AnimDebugDraw.h" - -#include "avatar/AvatarManager.h" +#include "AudioClient.h" #include "audio/AudioScope.h" - +#include "avatar/AvatarManager.h" +#include "CrashHandler.h" +#include "devices/3DConnexionClient.h" #include "devices/DdeFaceTracker.h" #include "devices/EyeTracker.h" #include "devices/Faceshift.h" #include "devices/Leapmotion.h" -#include "devices/RealSense.h" #include "devices/MIDIManager.h" -#include "devices/3DConnexionClient.h" - +#include "devices/RealSense.h" +#include "DiscoverabilityManager.h" +#include "GLCanvas.h" +#include "InterfaceActionFactory.h" +#include "InterfaceLogging.h" +#include "LODManager.h" +#include "Menu.h" +#include "ModelPackager.h" +#include "PluginContainerProxy.h" #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" #include "scripting/DesktopScriptingInterface.h" -#include "scripting/HMDScriptingInterface.h" #include "scripting/GlobalServicesScriptingInterface.h" +#include "scripting/HMDScriptingInterface.h" #include "scripting/LocationScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" #include "scripting/SettingsScriptingInterface.h" -#include "scripting/WindowScriptingInterface.h" #include "scripting/WebWindowClass.h" - +#include "scripting/WindowScriptingInterface.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" #endif - +#include "Stars.h" #include "ui/AddressBarDialog.h" #include "ui/AvatarInputs.h" #include "ui/DataWebDialog.h" #include "ui/DialogsManager.h" #include "ui/LoginDialog.h" +#include "ui/overlays/Cube3DOverlay.h" #include "ui/Snapshot.h" #include "ui/StandAloneJSConsole.h" #include "ui/Stats.h" #include "ui/UpdateDialog.h" -#include "ui/overlays/Cube3DOverlay.h" +#include "Util.h" // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU // FIXME seems to be broken. diff --git a/interface/src/Application.h b/interface/src/Application.h index c315dde0ea..ec5133b131 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -33,23 +33,24 @@ #include #include #include +#include #include #include -#include +#include "avatar/AvatarUpdate.h" +#include "avatar/MyAvatar.h" #include "Bookmarks.h" #include "Camera.h" #include "Environment.h" #include "FileLogger.h" +#include "gpu/Context.h" #include "Menu.h" -#include "Physics.h" -#include "avatar/AvatarUpdate.h" -#include "avatar/MyAvatar.h" +#include "octree/OctreePacketProcessor.h" +#include "render/Engine.h" #include "scripting/ControllerScriptingInterface.h" #include "scripting/DialogsManagerScriptingInterface.h" -#include "ui/SnapshotShareDialog.h" -#include "ui/ApplicationOverlay.h" #include "ui/ApplicationCompositor.h" +#include "ui/ApplicationOverlay.h" #include "ui/AudioStatsDialog.h" #include "ui/BandwidthDialog.h" #include "ui/LodToolsDialog.h" @@ -58,14 +59,10 @@ #include "ui/OverlayConductor.h" #include "ui/overlays/Overlays.h" #include "ui/RunningScriptsWidget.h" +#include "ui/SnapshotShareDialog.h" #include "ui/ToolWindow.h" -#include "octree/OctreePacketProcessor.h" #include "UndoStackScriptingInterface.h" -#include "gpu/Context.h" - -#include "render/Engine.h" - class OffscreenGlCanvas; class GLCanvas; class FaceTracker; @@ -372,6 +369,8 @@ private: MyAvatar* getMyAvatar() const; + void checkSkeleton(); + void initializeAcceptedFiles(); int getRenderAmbientLight() const; @@ -500,8 +499,6 @@ private: QTimer _settingsTimer; GLCanvas* _glWidget{ nullptr }; - - void checkSkeleton(); typedef bool (Application::* AcceptURLMethod)(const QString &); QHash _acceptedExtensions; From c745050dea1ab601bf43ba181e9ff9fbb7f66d5c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 12:59:41 -0700 Subject: [PATCH 104/152] Fix QObject::connect warning --- interface/src/Menu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 96f640b96e..9abfd1e34c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -332,8 +332,7 @@ Menu::Menu() { ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight8, 0, false)); ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight9, 0, false)); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ThrottleFPSIfNotFocus, 0, true, - qApp, SLOT(setThrottleFPSEnabled())); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ThrottleFPSIfNotFocus, 0, true); MenuWrapper* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution); QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu); From ed13c02075afdf1f7d7f6989ef62846b7cf552b7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 18:53:42 -0700 Subject: [PATCH 105/152] Fix rebase --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7d1886f10c..b44ac6804d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1077,8 +1077,8 @@ void Application::paintGL() { myAvatar->startCapture(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); cameraMenuChanged(); } From 9079f891e97a5c82d2a4f1137b9dca10e2b7e5a0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Oct 2015 14:09:21 -0700 Subject: [PATCH 106/152] repair broken node bandwidth stats --- libraries/networking/src/LimitedNodeList.cpp | 7 +++++++ libraries/networking/src/NetworkPeer.cpp | 8 ++++---- libraries/networking/src/NetworkPeer.h | 8 ++++---- libraries/networking/src/PacketReceiver.cpp | 2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c13a82f821..41789315c1 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -274,10 +274,14 @@ void LimitedNodeList::fillPacketHeader(const NLPacket& packet, const QUuid& conn qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const Node& destinationNode) { Q_ASSERT(!packet.isPartOfMessage()); + if (!destinationNode.getActiveSocket()) { return 0; } + emit dataSent(destinationNode.getType(), packet.getDataSize()); + destinationNode.recordBytesSent(packet.getDataSize()); + return sendUnreliablePacket(packet, *destinationNode.getActiveSocket(), destinationNode.getConnectionSecret()); } @@ -298,7 +302,10 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr packet, const Node& if (!destinationNode.getActiveSocket()) { return 0; } + emit dataSent(destinationNode.getType(), packet->getDataSize()); + destinationNode.recordBytesSent(packet->getDataSize()); + return sendPacket(std::move(packet), *destinationNode.getActiveSocket(), destinationNode.getConnectionSecret()); } diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index b17656aea0..9253243a7f 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -232,22 +232,22 @@ BandwidthRecorder& getBandwidthRecorder(const QUuid & uuid) { return *PEER_BANDWIDTH[uuid].data(); } -void NetworkPeer::recordBytesSent(int count) { +void NetworkPeer::recordBytesSent(int count) const { auto& bw = getBandwidthRecorder(_uuid); bw.updateOutboundData(0, count); } -void NetworkPeer::recordBytesReceived(int count) { +void NetworkPeer::recordBytesReceived(int count) const { auto& bw = getBandwidthRecorder(_uuid); bw.updateInboundData(0, count); } -float NetworkPeer::getOutboundBandwidth() { +float NetworkPeer::getOutboundBandwidth() const { auto& bw = getBandwidthRecorder(_uuid); return bw.getAverageOutputKilobitsPerSecond(0); } -float NetworkPeer::getInboundBandwidth() { +float NetworkPeer::getInboundBandwidth() const { auto& bw = getBandwidthRecorder(_uuid); return bw.getAverageInputKilobitsPerSecond(0); } diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index 8446586121..c10d44bfa9 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -70,11 +70,11 @@ public: void incrementConnectionAttempts() { ++_connectionAttempts; } void resetConnectionAttempts() { _connectionAttempts = 0; } - void recordBytesSent(int count); - void recordBytesReceived(int count); + void recordBytesSent(int count) const; + void recordBytesReceived(int count) const; - float getOutboundBandwidth(); // in kbps - float getInboundBandwidth(); // in kbps + float getOutboundBandwidth() const; // in kbps + float getInboundBandwidth() const; // in kbps friend QDataStream& operator<<(QDataStream& out, const NetworkPeer& peer); friend QDataStream& operator>>(QDataStream& in, NetworkPeer& peer); diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index 0efb8bba7c..9d25724f6c 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -404,6 +404,8 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr packet) { if (matchingNode) { emit dataReceived(matchingNode->getType(), nlPacket->getDataSize()); + matchingNode->recordBytesReceived(nlPacket->getDataSize()); + QMetaMethod metaMethod = listener.second; static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); From 8a7871e15bbada9f21afc4ea4b4fde99c7dd899b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 14:01:28 -0700 Subject: [PATCH 107/152] rebase fix --- assignment-client/src/octree/OctreeServer.cpp | 2 +- interface/src/scripting/HMDScriptingInterface.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 7899591998..ee0403d57b 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -191,7 +191,7 @@ void OctreeServer::trackPacketSendingTime(float time) { } -void OctreeServer::trackProcessWaitTime(float time) +void OctreeServer::trackProcessWaitTime(float time) { const float MAX_SHORT_TIME = 10.0f; const float MAX_LONG_TIME = 100.0f; if (time == SKIP_TIME) { diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index b3630a4453..f9a8fc1493 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -70,3 +70,7 @@ void HMDScriptingInterface::toggleMagnifier() { bool HMDScriptingInterface::getMagnifier() const { return qApp->getApplicationCompositor().hasMagnifier(); } + +bool HMDScriptingInterface::isHMDMode() const { + return qApp->isHMDMode(); +} From fbf6d166b74b3b033f18ffd002200a2b22ed9d8e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Oct 2015 14:48:28 -0700 Subject: [PATCH 108/152] add wire size to BasePacket --- libraries/networking/src/udt/BasePacket.cpp | 4 ---- libraries/networking/src/udt/BasePacket.h | 5 ++++- libraries/networking/src/udt/Constants.h | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/udt/BasePacket.cpp b/libraries/networking/src/udt/BasePacket.cpp index 0d661ad34a..54342d9cba 100644 --- a/libraries/networking/src/udt/BasePacket.cpp +++ b/libraries/networking/src/udt/BasePacket.cpp @@ -126,10 +126,6 @@ BasePacket& BasePacket::operator=(BasePacket&& other) { return *this; } -qint64 BasePacket::getDataSize() const { - return (_payloadStart - _packet.get()) + _payloadSize; -} - void BasePacket::setPayloadSize(qint64 payloadSize) { if (isWritable()) { Q_ASSERT(payloadSize <= _payloadCapacity); diff --git a/libraries/networking/src/udt/BasePacket.h b/libraries/networking/src/udt/BasePacket.h index cc18c75a80..392a7c4384 100644 --- a/libraries/networking/src/udt/BasePacket.h +++ b/libraries/networking/src/udt/BasePacket.h @@ -48,7 +48,10 @@ public: const char* getData() const { return _packet.get(); } // Returns the size of the packet, including the header - qint64 getDataSize() const; + qint64 getDataSize() const { return (_payloadStart - _packet.get()) + _payloadSize; } + + // Returns the size of the packet, including the header AND the UDP/IP header + qint64 getWireSize() const { return getDataSize() + UDP_IPV4_HEADER_SIZE; } // Returns the size of the payload only qint64 getPayloadSize() const { return _payloadSize; } diff --git a/libraries/networking/src/udt/Constants.h b/libraries/networking/src/udt/Constants.h index 0152444f84..9f5f1db883 100644 --- a/libraries/networking/src/udt/Constants.h +++ b/libraries/networking/src/udt/Constants.h @@ -17,8 +17,9 @@ #include "SequenceNumber.h" namespace udt { + static const int UDP_IPV4_HEADER_SIZE = 28; static const int MAX_PACKET_SIZE_WITH_UDP_HEADER = 1500; - static const int MAX_PACKET_SIZE = MAX_PACKET_SIZE_WITH_UDP_HEADER - 28; + static const int MAX_PACKET_SIZE = MAX_PACKET_SIZE_WITH_UDP_HEADER - UDP_IPV4_HEADER_SIZE; static const int MAX_PACKETS_IN_FLIGHT = 25600; static const int CONNECTION_RECEIVE_BUFFER_SIZE_PACKETS = 8192; static const int CONNECTION_SEND_BUFFER_SIZE_PACKETS = 8192; From 593153deec3e0d53514fd8bdf325fe20804d0761 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Oct 2015 14:58:51 -0700 Subject: [PATCH 109/152] add receive rate and inbound kbps to av stats --- assignment-client/src/avatars/AvatarMixer.cpp | 3 +++ .../src/avatars/AvatarMixerClientData.cpp | 11 +++++++---- assignment-client/src/avatars/AvatarMixerClientData.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 66b924b8ab..820ff09a7f 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -485,10 +485,13 @@ void AvatarMixer::sendStatsPacket() { QJsonObject avatarStats; const QString NODE_OUTBOUND_KBPS_STAT_KEY = "outbound_kbps"; + const QString NODE_INBOUND_KBPS_STAT_KEY = "inbound_kbps"; // add the key to ask the domain-server for a username replacement, if it has it avatarStats[USERNAME_UUID_REPLACEMENT_STATS_KEY] = uuidStringWithoutCurlyBraces(node->getUUID()); + avatarStats[NODE_OUTBOUND_KBPS_STAT_KEY] = node->getOutboundBandwidth(); + avatarStats[NODE_INBOUND_KBPS_STAT_KEY] = node->getInboundBandwidth(); AvatarMixerClientData* clientData = static_cast(node->getLinkedData()); if (clientData) { diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 006f58eb44..0a9be20691 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -40,11 +40,14 @@ uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& node void AvatarMixerClientData::loadJSONStats(QJsonObject& jsonObject) const { jsonObject["display_name"] = _avatar.getDisplayName(); jsonObject["full_rate_distance"] = _fullRateDistance; - jsonObject["max_avatar_distance"] = _maxAvatarDistance; - jsonObject["num_avatars_sent_last_frame"] = _numAvatarsSentLastFrame; - jsonObject["avg_other_avatar_starves_per_second"] = getAvgNumOtherAvatarStarvesPerSecond(); - jsonObject["avg_other_avatar_skips_per_second"] = getAvgNumOtherAvatarSkipsPerSecond(); + jsonObject["max_av_distance"] = _maxAvatarDistance; + jsonObject["num_avs_sent_last_frame"] = _numAvatarsSentLastFrame; + jsonObject["avg_other_av_starves_per_second"] = getAvgNumOtherAvatarStarvesPerSecond(); + jsonObject["avg_other_av_skips_per_second"] = getAvgNumOtherAvatarSkipsPerSecond(); jsonObject["total_num_out_of_order_sends"] = _numOutOfOrderSends; jsonObject[OUTBOUND_AVATAR_DATA_STATS_KEY] = getOutboundAvatarDataKbps(); + jsonObject[INBOUND_AVATAR_DATA_STATS_KEY] = _avatar.getAverageBytesReceivedPerSecond() / (float) BYTES_PER_KILOBIT; + + jsonObject["av_data_receive_rate"] = _avatar.getReceiveRate(); } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 3dbe917ee2..e68a54c265 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -27,6 +27,7 @@ #include const QString OUTBOUND_AVATAR_DATA_STATS_KEY = "outbound_av_data_kbps"; +const QString INBOUND_AVATAR_DATA_STATS_KEY = "inbound_av_data_kbps"; class AvatarMixerClientData : public NodeData { Q_OBJECT From 4c695b179a0a238472dfa5854ffb2a228233e35c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Oct 2015 15:04:48 -0700 Subject: [PATCH 110/152] remove out of order assert in avatar-mixer --- assignment-client/src/avatars/AvatarMixer.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 820ff09a7f..25f23ca580 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -262,14 +262,9 @@ void AvatarMixer::broadcastAvatarData() { AvatarDataSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(otherNode->getUUID()); AvatarDataSequenceNumber lastSeqFromSender = otherNodeData->getLastReceivedSequenceNumber(); - if (lastSeqToReceiver > lastSeqFromSender) { - // Did we somehow get out of order packets from the sender? - // We don't expect this to happen - in RELEASE we add this to a trackable stat - // and in DEBUG we crash on the assert - + if (lastSeqToReceiver > lastSeqFromSender && lastSeqToReceiver != UINT16_MAX) { + // we gout out of order packets from the sender, track it otherNodeData->incrementNumOutOfOrderSends(); - - assert(false); } // make sure we haven't already sent this data from this sender to this receiver From 0db88ba5726bfef27bb21db28e568ccf6e7919c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Oct 2015 15:06:28 -0700 Subject: [PATCH 111/152] fix a typo in comment --- assignment-client/src/avatars/AvatarMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 25f23ca580..833b53b729 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -263,7 +263,7 @@ void AvatarMixer::broadcastAvatarData() { AvatarDataSequenceNumber lastSeqFromSender = otherNodeData->getLastReceivedSequenceNumber(); if (lastSeqToReceiver > lastSeqFromSender && lastSeqToReceiver != UINT16_MAX) { - // we gout out of order packets from the sender, track it + // we got out out of order packets from the sender, track it otherNodeData->incrementNumOutOfOrderSends(); } From 76e0006732c6730abdf6fe1f8acb89a75f9237b9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 15:58:35 -0700 Subject: [PATCH 112/152] Remove forgotten cursorVisible --- examples/libraries/virtualKeyboard.js | 1 - interface/src/scripting/WindowScriptingInterface.cpp | 5 ----- interface/src/scripting/WindowScriptingInterface.h | 1 - 3 files changed, 7 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 7a0ec80a98..eca723dbcc 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -342,7 +342,6 @@ Keyboard = (function(params) { if (HMD.magnifier == visible) { HMD.toggleMagnifier(); } - Window.cursorVisible = !visible; Overlays.editOverlay(tthis.background, { visible: tthis.visible }); for (var i = 0; i < this.keys.length; i++) { this.keys[i].updateVisibility(); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 46edbe7420..a2886c8b77 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -60,11 +60,6 @@ void WindowScriptingInterface::raiseMainWindow() { }); } -void WindowScriptingInterface::setCursorVisible(bool visible) { - QMetaObject::invokeMethod(qApp, "setCursorVisible", Qt::BlockingQueuedConnection, - Q_ARG(bool, visible)); -} - void WindowScriptingInterface::setCursorPosition(int x, int y) { QCursor::setPos(x, y); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 678a66102d..1395639cd0 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -38,7 +38,6 @@ public slots: QScriptValue getCursorPositionX(); QScriptValue getCursorPositionY(); void setCursorPosition(int x, int y); - void setCursorVisible(bool visible); QScriptValue hasFocus(); void setFocus(); void raiseMainWindow(); From 1319642a597e73838dd1b413f8d0a43e863cb6b1 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 6 Oct 2015 15:59:35 -0700 Subject: [PATCH 113/152] fix frame jumping behavior on restart --- libraries/animation/src/AnimationLoop.cpp | 22 +++++++++++++++++++--- libraries/animation/src/AnimationLoop.h | 7 +++++-- libraries/entities/src/ModelEntityItem.cpp | 17 +++++++---------- libraries/entities/src/ModelEntityItem.h | 1 - 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index cd360a79a7..ee07558c4a 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "AnimationCache.h" #include "AnimationLoop.h" @@ -24,7 +26,8 @@ AnimationLoop::AnimationLoop() : _running(false), _frameIndex(0.0f), _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME), - _resetOnRunning(false) + _resetOnRunning(false), + _lastSimulated(usecTimestampNow()) { } @@ -37,7 +40,8 @@ AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : _lastFrame(animationDetails.lastFrame), _running(animationDetails.running), _frameIndex(animationDetails.frameIndex), - _resetOnRunning(false) + _resetOnRunning(false), + _lastSimulated(usecTimestampNow()) { } @@ -51,10 +55,17 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati _lastFrame(lastFrame), _running(running), _frameIndex(frameIndex), - _resetOnRunning(false) + _resetOnRunning(false), + _lastSimulated(usecTimestampNow()) { } +void AnimationLoop::simulateAtTime(quint64 now) { + float deltaTime = (float)(now - _lastSimulated) / (float)USECS_PER_SECOND; + _lastSimulated = now; + simulate(deltaTime); +} + void AnimationLoop::simulate(float deltaTime) { _frameIndex += deltaTime * _fps; @@ -96,5 +107,10 @@ void AnimationLoop::setRunning(bool running) { qDebug() << "resetting _frameIndex:" << _frameIndex << "to _firstFrame:" << _firstFrame; _frameIndex = _firstFrame; } + + // If we just started running, set our + if (_running) { + _lastSimulated = usecTimestampNow(); + } } } diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 6c3df659dc..4fa827768e 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -57,8 +57,10 @@ public: void start() { setRunning(true); } void stop() { setRunning(false); } - void simulate(float deltaTime); - + void simulate(float deltaTime); /// call this with deltaTime if you as the caller are managing the delta time between calls + + void simulateAtTime(quint64 now); /// call this with "now" if you want the animationLoop to handle delta times + private: float _fps; bool _loop; @@ -70,6 +72,7 @@ private: float _frameIndex; float _maxFrameIndexHint; bool _resetOnRunning; + quint64 _lastSimulated; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index b1f306b758..73119f4211 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -35,7 +35,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI _type = EntityTypes::Model; setProperties(properties); - _lastAnimated = usecTimestampNow(); _jointMappingCompleted = false; _lastKnownFrameIndex = -1; _color[0] = _color[1] = _color[2] = 0; @@ -281,18 +280,16 @@ bool ModelEntityItem::needsToCallUpdate() const { } void ModelEntityItem::update(const quint64& now) { + + // only worry about this if we have an animation if (hasAnimation()) { - qDebug() << "ModelEntityItem::update() getAnimationIsPlaying():" << getAnimationIsPlaying(); + // only advance the frame index if we're playing + if (getAnimationIsPlaying()) { + _animationLoop.simulateAtTime(now); + qDebug() << "ModelEntityItem::update() getAnimationIsPlaying():" << getAnimationIsPlaying() << "frame:" << getAnimationFrameIndex(); + } } - // only advance the frame index if we're playing - if (getAnimationIsPlaying()) { - float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; - _lastAnimated = now; - _animationLoop.simulate(deltaTime); - } else { - _lastAnimated = now; - } EntityItem::update(now); // let our base class handle it's updates... } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 66f102fe7a..eece037f2d 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -134,7 +134,6 @@ protected: QString _modelURL; QString _compoundShapeURL; - quint64 _lastAnimated; AnimationPropertyGroup _animationProperties; AnimationLoop _animationLoop; From 016bf4011d4a7e6d1600c7ffa72a973f8afc0ed0 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 6 Oct 2015 16:07:36 -0700 Subject: [PATCH 114/152] cleanup --- .../example/entities/animatedModelExample.js | 20 +-------- libraries/animation/src/AnimationLoop.cpp | 1 - .../src/RenderableModelEntityItem.cpp | 2 - .../entities/src/AnimationPropertyGroup.cpp | 43 ------------------- libraries/entities/src/ModelEntityItem.cpp | 25 ++--------- 5 files changed, 4 insertions(+), 87 deletions(-) diff --git a/examples/example/entities/animatedModelExample.js b/examples/example/entities/animatedModelExample.js index 6c97671463..1e7869559e 100644 --- a/examples/example/entities/animatedModelExample.js +++ b/examples/example/entities/animatedModelExample.js @@ -20,14 +20,6 @@ var yaw = 0.0; var roll = 0.0; var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll); -var animationSettings = JSON.stringify({ - loop: true, - running: true, - fps: 30, - firstFrame: 10, - lastFrame: 20, -}); - var originalProperties = { type: "Model", position: { x: MyAvatar.position.x, @@ -45,12 +37,6 @@ var originalProperties = { modelURL: "http://public.highfidelity.io/cozza13/club/dragon/dragon.fbx", rotation: rotation, - - - animationURL: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", - animationSettings: animationSettings, - //animationIsPlaying: true, - /* animation: { url: "http://public.highfidelity.io/cozza13/club/dragon/flying.fbx", running: true, @@ -59,7 +45,6 @@ var originalProperties = { lastFrame: 20, loop: true } - */ }; var modelID = Entities.addEntity(originalProperties); @@ -120,8 +105,6 @@ function moveModel(deltaTime) { if (somethingChanged) { var newProperties = { - //animationIsPlaying: isPlaying, - //animationFPS: animationFPS, animation: { running: isPlaying, fps: animationFPS @@ -130,7 +113,6 @@ function moveModel(deltaTime) { if (resetFrame) { print("resetting the frame!"); - //newProperties.animationFrameIndex = 0; newProperties.animation.frameIndex = 0; resetFrame = false; } @@ -141,7 +123,7 @@ function moveModel(deltaTime) { // register the call back so it fires before each data send -//Script.update.connect(moveModel); +Script.update.connect(moveModel); Script.scriptEnding.connect(function () { diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index ee07558c4a..59b8e7d209 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -104,7 +104,6 @@ void AnimationLoop::setRunning(bool running) { // If we just set running to true, then also reset the frame to the first frame if (running && (_resetOnRunning)) { // move back to the beginning - qDebug() << "resetting _frameIndex:" << _frameIndex << "to _firstFrame:" << _firstFrame; _frameIndex = _firstFrame; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 54f5c384e0..ed088bc9b5 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -269,7 +269,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (_model) { // handle animations.. if (hasAnimation()) { - //qDebug() << "RenderableModelEntityItem::render() -- hasAnimation()"; if (!jointsMapped()) { QStringList modelJointNames = _model->getJointNames(); mapJoints(modelJointNames); @@ -280,7 +279,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) { QVector frameDataRotations; QVector frameDataTranslations; getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); - qDebug() << "RenderableModelEntityItem::render() -- getAnimationFrame() newFrame:" << newFrame; assert(frameDataRotations.size() == frameDataTranslations.size()); if (newFrame) { for (int i = 0; i < frameDataRotations.size(); i++) { diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index a7e77a75e0..f648c4c06e 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -93,15 +93,6 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setFrameIndex, getFrameIndex); } - /* - if (_animationLoop) { - qDebug() << "copyFromScriptValue() running:" << _animationLoop->getRunning(); - } else { - qDebug() << "copyFromScriptValue() running:" << getRunning(); - } - */ - - } void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { @@ -256,19 +247,6 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF processedBytes += bytesRead; - /* - if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { - qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() DID contain PROP_ANIMATION_PLAYING -----------"; - if (_animationLoop) { - qDebug() << " decodeFromEditPacket() _animationLoop->getRunning:" << _animationLoop->getRunning(); - } else { - qDebug() << " decodeFromEditPacket() getRunning:" << getRunning(); - } - } else { - qDebug() << "AnimationPropertyGroup::decodeFromEditPacket() packet did not contain PROP_ANIMATION_PLAYING"; - } - */ - return true; } @@ -342,12 +320,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } - if (_animationLoop) { - qDebug() << "setProperties() _animationLoop->running:" << _animationLoop->getRunning(); - } else { - qDebug() << "setProperties() running:" << getRunning(); - } - _somethingChanged = somethingChanged; return somethingChanged; @@ -399,15 +371,6 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, getStartAutomatically()); } - - /* - if (_animationLoop) { - qDebug() << "appendSubclassData() running:" << _animationLoop->getRunning(); - } else { - qDebug() << "appendSubclassData() running:" << getRunning(); - } - */ - } int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, @@ -467,11 +430,5 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char - if (_animationLoop) { - qDebug() << "readEntitySubclassDataFromBuffer() _animationLoop->running:" << _animationLoop->getRunning(); - } else { - qDebug() << "readEntitySubclassDataFromBuffer() running:" << getRunning(); - } - return bytesRead; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 73119f4211..1eafc50141 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -80,10 +80,6 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { setLastEdited(properties._lastEdited); } - qDebug() << "ModelEntityItem::setProperties() id:" << getEntityItemID() - << " properties.animation.running:" << properties.getAnimation().getRunning() - << " running:" << getAnimationIsPlaying(); - return somethingChanged; } @@ -114,16 +110,11 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " args.bitstreamVersion:" << args.bitstreamVersion << " VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP:" << VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP; - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); } else { // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() // will automatically read into the animation loop - - qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " calling _animationProperties.readEntitySubclassDataFromBuffer()"; - int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData); @@ -133,8 +124,6 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); - qDebug() << "ModelEntityItem::readEntitySubclassDataFromBuffer() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); - if (_animationProperties.somethingChanged()) { _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; } @@ -174,9 +163,6 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit propertyFlags, propertiesDidntFit, propertyCount, appendState); APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType()); - - //qDebug() << "ModelEntityItem::appendSubclassData() id:" << getEntityItemID() << " running:" << getAnimationIsPlaying(); - } @@ -237,7 +223,6 @@ void ModelEntityItem::getAnimationFrame(bool& newFrame, int frameCount = frames.size(); if (frameCount > 0) { - qDebug() << "getAnimationFrameIndex:" << getAnimationFrameIndex(); int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; if (animationFrameIndex < 0 || animationFrameIndex > frameCount) { animationFrameIndex = 0; @@ -281,13 +266,9 @@ bool ModelEntityItem::needsToCallUpdate() const { void ModelEntityItem::update(const quint64& now) { - // only worry about this if we have an animation - if (hasAnimation()) { - // only advance the frame index if we're playing - if (getAnimationIsPlaying()) { - _animationLoop.simulateAtTime(now); - qDebug() << "ModelEntityItem::update() getAnimationIsPlaying():" << getAnimationIsPlaying() << "frame:" << getAnimationFrameIndex(); - } + // only advance the frame index if we're playing + if (getAnimationIsPlaying()) { + _animationLoop.simulateAtTime(now); } EntityItem::update(now); // let our base class handle it's updates... From 81b88cb096c30ae6c82fe26a4e55badee1f81475 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 16:12:04 -0700 Subject: [PATCH 115/152] Renamed MessagePart > MessagePartNumber --- libraries/networking/src/udt/Connection.cpp | 8 ++++---- libraries/networking/src/udt/Packet.cpp | 14 +++++++------- libraries/networking/src/udt/Packet.h | 8 ++++---- libraries/networking/src/udt/PacketList.cpp | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index c8264a6737..96d73676f0 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -860,16 +860,16 @@ void PendingReceivedMessage::enqueuePacket(std::unique_ptr packet) { if (packet->getPacketPosition() == Packet::PacketPosition::LAST || packet->getPacketPosition() == Packet::PacketPosition::ONLY) { _hasLastPacket = true; - _numPackets = packet->getMessagePart() + 1; + _numPackets = packet->getMessagePartNumber() + 1; } // Insert into the packets list in sorted order. Because we generally expect to receive packets in order, begin // searching from the end of the list. - auto messagePart = packet->getMessagePart(); + auto messagePartNumber = packet->getMessagePartNumber(); auto it = std::find_if(_packets.rbegin(), _packets.rend(), - [&](const std::unique_ptr& value) { return messagePart >= value->getMessagePart(); }); + [&](const std::unique_ptr& value) { return messagePartNumber >= value->getMessagePartNumber(); }); - if (it != _packets.rend() && ((*it)->getMessagePart() == messagePart)) { + if (it != _packets.rend() && ((*it)->getMessagePartNumber() == messagePartNumber)) { qCDebug(networking) << "PendingReceivedMessage::enqueuePacket: This is a duplicate packet"; return; } diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index ebcf4baafd..d06ff9707e 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -15,7 +15,7 @@ using namespace udt; int Packet::localHeaderSize(bool isPartOfMessage) { return sizeof(Packet::SequenceNumberAndBitField) + - (isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) + sizeof(MessagePart) : 0); + (isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) + sizeof(MessagePartNumber) : 0); } int Packet::totalHeaderSize(bool isPartOfMessage) { @@ -109,11 +109,11 @@ Packet& Packet::operator=(Packet&& other) { return *this; } -void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart) { +void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber) { _isPartOfMessage = true; _messageNumber = messageNumber; _packetPosition = position; - _messagePart = messagePart; + _messagePartNumber = messagePartNumber; writeHeader(); } @@ -144,8 +144,8 @@ void Packet::readHeader() const { _messageNumber = *messageNumberAndBitField & MESSAGE_NUMBER_MASK; _packetPosition = static_cast(*messageNumberAndBitField >> PACKET_POSITION_OFFSET); - MessagePart* messagePart = messageNumberAndBitField + 1; - _messagePart = *messagePart; + MessagePartNumber* messagePartNumber = messageNumberAndBitField + 1; + _messagePartNumber = *messagePartNumber; } } @@ -172,7 +172,7 @@ void Packet::writeHeader() const { *messageNumberAndBitField = _messageNumber; *messageNumberAndBitField |= _packetPosition << PACKET_POSITION_OFFSET; - MessagePart* messagePart = messageNumberAndBitField + 1; - *messagePart = _messagePart; + MessagePartNumber* messagePartNumber = messageNumberAndBitField + 1; + *messagePartNumber = _messagePartNumber; } } diff --git a/libraries/networking/src/udt/Packet.h b/libraries/networking/src/udt/Packet.h index 71fb22eb98..24b9144672 100644 --- a/libraries/networking/src/udt/Packet.h +++ b/libraries/networking/src/udt/Packet.h @@ -31,7 +31,7 @@ public: // NOTE: The MessageNumber is only actually 30 bits to leave room for a bit field using MessageNumber = uint32_t; using MessageNumberAndBitField = uint32_t; - using MessagePart = uint32_t; + using MessagePartNumber = uint32_t; // Use same size as MessageNumberAndBitField so we can use the enum with bitwise operations enum PacketPosition : MessageNumberAndBitField { @@ -60,9 +60,9 @@ public: SequenceNumber getSequenceNumber() const { return _sequenceNumber; } MessageNumber getMessageNumber() const { return _messageNumber; } PacketPosition getPacketPosition() const { return _packetPosition; } - MessagePart getMessagePart() const { return _messagePart; } + MessagePartNumber getMessagePartNumber() const { return _messagePartNumber; } - void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart); + void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePartNumber messagePartNumber); void writeSequenceNumber(SequenceNumber sequenceNumber) const; protected: @@ -86,7 +86,7 @@ private: mutable SequenceNumber _sequenceNumber { 0 }; mutable MessageNumber _messageNumber { 0 }; mutable PacketPosition _packetPosition { PacketPosition::ONLY }; - mutable MessagePart _messagePart { 0 }; + mutable MessagePartNumber _messagePartNumber { 0 }; }; } // namespace udt diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index 8f6a65abc9..ffe2b3eeba 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -140,13 +140,13 @@ void PacketList::preparePackets(MessageNumber messageNumber) { } else { const auto second = ++_packets.begin(); const auto last = --_packets.end(); - Packet::MessagePart messagePart = 0; + Packet::MessagePartNumber messagePartNumber = 0; std::for_each(second, last, [&](const PacketPointer& packet) { - packet->writeMessageNumber(messageNumber, Packet::PacketPosition::MIDDLE, ++messagePart); + packet->writeMessageNumber(messageNumber, Packet::PacketPosition::MIDDLE, ++messagePartNumber); }); _packets.front()->writeMessageNumber(messageNumber, Packet::PacketPosition::FIRST, 0); - _packets.back()->writeMessageNumber(messageNumber, Packet::PacketPosition::LAST, ++messagePart); + _packets.back()->writeMessageNumber(messageNumber, Packet::PacketPosition::LAST, ++messagePartNumber); } } From 5ee966261d44d974054adb37b59e5e28cdfe8171 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 16:12:50 -0700 Subject: [PATCH 116/152] Start thread right away --- libraries/networking/src/udt/SendQueue.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 6ba947553a..959dd02a52 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -69,7 +69,9 @@ std::unique_ptr SendQueue::create(Socket* socket, HifiSockAddr destin // Move queue to private thread and start it queue->moveToThread(thread); - return std::move(queue); + thread->start(); + + return queue; } SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : @@ -191,9 +193,6 @@ void SendQueue::sendHandshake() { // we wait for the ACK or the re-send interval to expire static const auto HANDSHAKE_RESEND_INTERVAL = std::chrono::milliseconds(100); _handshakeACKCondition.wait_for(handshakeLock, HANDSHAKE_RESEND_INTERVAL); - - // Once we're here we've either received the handshake ACK or it's going to be time to re-send a handshake. - // Either way let's continue processing - no packets will be sent if no handshake ACK has been received. } } @@ -254,6 +253,9 @@ void SendQueue::run() { // Keep processing events QCoreApplication::sendPostedEvents(this); + + // Once we're here we've either received the handshake ACK or it's going to be time to re-send a handshake. + // Either way let's continue processing - no packets will be sent if no handshake ACK has been received. } while (_state == State::Running) { From ca575bee89f52701cac271649595d4c0a6dcb9a5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 16:15:51 -0700 Subject: [PATCH 117/152] Remove unecessary move --- libraries/networking/src/LimitedNodeList.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c13a82f821..9d1e7abcbb 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -514,7 +514,7 @@ std::unique_ptr LimitedNodeList::constructPingPacket(PingType_t pingTy pingPacket->writePrimitive(pingType); pingPacket->writePrimitive(usecTimestampNow()); - return std::move(pingPacket); + return pingPacket; } std::unique_ptr LimitedNodeList::constructPingReplyPacket(NLPacket& pingPacket) { @@ -529,7 +529,7 @@ std::unique_ptr LimitedNodeList::constructPingReplyPacket(NLPacket& pi replyPacket->writePrimitive(timeFromOriginalPing); replyPacket->writePrimitive(usecTimestampNow()); - return std::move(replyPacket); + return replyPacket; } std::unique_ptr LimitedNodeList::constructICEPingPacket(PingType_t pingType, const QUuid& iceID) { @@ -539,7 +539,7 @@ std::unique_ptr LimitedNodeList::constructICEPingPacket(PingType_t pin icePingPacket->write(iceID.toRfc4122()); icePingPacket->writePrimitive(pingType); - return std::move(icePingPacket); + return icePingPacket; } std::unique_ptr LimitedNodeList::constructICEPingReplyPacket(NLPacket& pingPacket, const QUuid& iceID) { From 867d34b6171d36928621fe784f6dc9799eb1fb83 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 6 Oct 2015 16:33:24 -0700 Subject: [PATCH 118/152] clean up warnings and coding standard issues --- .../entities/src/EntityActionInterface.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/entities/src/EntityActionInterface.cpp b/libraries/entities/src/EntityActionInterface.cpp index c34f072601..d874646b4b 100644 --- a/libraries/entities/src/EntityActionInterface.cpp +++ b/libraries/entities/src/EntityActionInterface.cpp @@ -237,16 +237,16 @@ float EntityActionInterface::extractFloatArgument(QString objectName, QVariantMa return 0.0f; } - QVariant vV = arguments[argumentName]; - bool vOk = true; - float v = vV.toFloat(&vOk); + QVariant variant = arguments[argumentName]; + bool variantOk = true; + float value = variant.toFloat(&variantOk); - if (!vOk || v != v) { + if (!variantOk || std::isnan(value)) { ok = false; return 0.0f; } - return v; + return value; } int EntityActionInterface::extractIntegerArgument(QString objectName, QVariantMap arguments, @@ -259,16 +259,16 @@ int EntityActionInterface::extractIntegerArgument(QString objectName, QVariantMa return 0.0f; } - QVariant vV = arguments[argumentName]; - bool vOk = true; - int v = vV.toInt(&vOk); + QVariant variant = arguments[argumentName]; + bool variantOk = true; + int value = variant.toInt(&variantOk); - if (!vOk || v != v) { + if (!variantOk) { ok = false; return 0; } - return v; + return value; } QString EntityActionInterface::extractStringArgument(QString objectName, QVariantMap arguments, From 3a8deff53e51c86b53df0432ac03e20b797e4412 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 16:38:16 -0700 Subject: [PATCH 119/152] Return if innactive --- libraries/networking/src/udt/SendQueue.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 959dd02a52..d7e3bb2b65 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -278,7 +278,7 @@ void SendQueue::run() { // Either _isRunning will have been set to false and we'll break // Or something happened and we'll keep going if (_state != State::Running || isInactive(sentAPacket)) { - continue; + return; } // sleep as long as we need until next packet send, if we can @@ -398,7 +398,6 @@ bool SendQueue::isInactive(bool sentAPacket) { #endif deactivate(); - return true; } @@ -456,9 +455,6 @@ bool SendQueue::isInactive(bool sentAPacket) { _naks.append(SequenceNumber(_lastACKSequenceNumber) + 1, _currentSequenceNumber); } } - - // skip to the next iteration - return true; } } } From 478848018607653765acd5e0a9c804fc3c0ac730 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 16:48:34 -0700 Subject: [PATCH 120/152] reset balls if they move too far --- examples/toys/basketball/createRack.js | 74 ++++++++++++++++++++++---- unpublishedScripts/masterReset.js | 60 +++++++++++++++++---- 2 files changed, 116 insertions(+), 18 deletions(-) diff --git a/examples/toys/basketball/createRack.js b/examples/toys/basketball/createRack.js index f537a9bdd1..b0f709d81d 100644 --- a/examples/toys/basketball/createRack.js +++ b/examples/toys/basketball/createRack.js @@ -8,7 +8,7 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ Script.include("../../libraries/utils.js"); var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; @@ -17,9 +17,10 @@ var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var collisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_collision_hull.obj"; - var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; +var RESET_DISTANCE = 1; + var GRABBABLE_DATA_KEY = "grabbableKey"; @@ -51,29 +52,34 @@ var rack = Entities.addEntity({ collisionsWillMove: true, ignoreForCollisions: false, collisionSoundURL: collisionSoundURL, - compoundShapeURL: rackCollisionHullURL + compoundShapeURL: rackCollisionHullURL, + // scriptURL: rackScriptURL }); + setEntityCustomData(GRABBABLE_DATA_KEY, rack, { grabbable: false }); var nonCollidingBalls = []; var collidingBalls = []; +var originalBallPositions = []; function createCollidingBalls() { var position = rackStartPosition; + var i; for (i = 0; i < NUMBER_OF_BALLS; i++) { + var ballPosition = { + x: position.x, + y: position.y + DIAMETER * 2, + z: position.z + (DIAMETER) - (DIAMETER * i) + } var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', shapeType: 'Sphere', - position: { - x: position.x, - y: position.y + DIAMETER * 2, - z: position.z + (DIAMETER) - (DIAMETER * i) - }, + position: ballPosition, dimensions: { x: DIAMETER, y: DIAMETER, @@ -91,6 +97,56 @@ function createCollidingBalls() { modelURL: basketballURL, }); collidingBalls.push(collidingBall); + originalBallPositions.push(position); + } + + +} + +function testBallDistanceFromStart() { + var resetCount = 0; + collidingBalls.forEach(function(ball, index) { + var currentPosition = Entities.getEntityProperties(ball, "position").position; + var originalPosition = originalBallPositions[index]; + var distance = Vec3.subtract(originalPosition, currentPosition); + var length = Vec3.length(distance); + if (length > RESET_DISTANCE) { + Script.setTimeout(function() { + var newPosition = Entities.getEntityProperties(ball, "position").position; + var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); + if (moving < 0.05) { + resetCount++; + if (resetCount === NUMBER_OF_BALLS) { + deleteCollidingBalls(); + createCollidingBalls(); + } + } + }, 200) + } + }); +} + +function deleteEntity(entityID) { + if (entityID === rack) { + deleteCollidingBalls(); + Script.clearInterval(distanceCheckInterval); + Entities.deletingEntity.disconnect(deleteEntity); } } -createCollidingBalls(); \ No newline at end of file + +function deleteCollidingBalls() { + while (collidingBalls.length > 0) { + Entities.deleteEntity(collidingBalls.pop()); + } +} + +createCollidingBalls(); +Entities.deletingEntity.connect(deleteEntity); + +var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000); + +function atEnd() { + Script.clearInterval(distanceCheckInterval); +} + +Script.scriptEnding.connect(atEnd); \ No newline at end of file diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 23441dff3a..49ff4a62a4 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -526,6 +526,7 @@ function createBasketballHoop() { function createBasketballRack() { var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; + var RESET_DISTANCE = 1; var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; @@ -571,21 +572,25 @@ function createBasketballRack() { }); var collidingBalls = []; - + var originalBallPositions = []; function createCollidingBalls() { var position = rackStartPosition; var i; - for (i = 0; i < NUMBER_OF_BALLS; i++) { + var ballPosition = { + x: position.x, + y: position.y + DIAMETER * 2, + z: position.z + (DIAMETER) - (DIAMETER * i) + } var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', shapeType: 'Sphere', position: { - x: position.x + (DIAMETER*2) - (DIAMETER * i), + x: position.x + (DIAMETER * 2) - (DIAMETER * i), y: position.y + DIAMETER * 2, - z: position.z + z: position.z }, dimensions: { x: DIAMETER, @@ -601,20 +606,57 @@ function createBasketballRack() { }, collisionsWillMove: true, ignoreForCollisions: false, - collisionSoundURL: basketballCollisionSoundURL, modelURL: basketballURL, }); - collidingBalls.push(collidingBall); + originalBallPositions.push(position); + } - setEntityCustomData(resetKey, collidingBall, { - resetMe: true - }); + } + + function testBallDistanceFromStart() { + var resetCount = 0; + collidingBalls.forEach(function(ball, index) { + var currentPosition = Entities.getEntityProperties(ball, "position").position; + var originalPosition = originalBallPositions[index]; + var distance = Vec3.subtract(originalPosition, currentPosition); + var length = Vec3.length(distance); + if (length > RESET_DISTANCE) { + Script.setTimeout(function() { + var newPosition = Entities.getEntityProperties(ball, "position").position; + var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); + if (moving < 0.05) { + resetCount++; + if (resetCount === NUMBER_OF_BALLS) { + deleteCollidingBalls(); + createCollidingBalls(); + } + } + }, 200) + } + }); + } + + function deleteEntity(entityID) { + if (entityID === rack) { + deleteCollidingBalls(); + Script.clearInterval(distanceCheckInterval); + Entities.deletingEntity.disconnect(deleteEntity); + } + } + + function deleteCollidingBalls() { + while (collidingBalls.length > 0) { + Entities.deleteEntity(collidingBalls.pop()); } } createCollidingBalls(); + Entities.deletingEntity.connect(deleteEntity); + + var distanceCheckInterval = Script.setInterval(testBallDistanceFromStart, 1000); + } From 224fc550339d910b4e29439fa62f1268dcb71bbb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Oct 2015 16:49:29 -0700 Subject: [PATCH 121/152] put IK targets in skeleton's model-frame --- interface/src/avatar/SkeletonModel.cpp | 2 +- .../animation/src/AnimInverseKinematics.cpp | 15 +-------------- libraries/animation/src/AnimInverseKinematics.h | 6 ++---- libraries/animation/src/AnimNode.cpp | 17 ----------------- libraries/animation/src/AnimNode.h | 2 -- libraries/animation/src/AnimSkeleton.cpp | 17 +++++++++++++++++ libraries/animation/src/AnimSkeleton.h | 1 + libraries/animation/src/Rig.cpp | 13 ++++++------- 8 files changed, 28 insertions(+), 45 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index a892447961..312b7cbf44 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -135,7 +135,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { headParams.isInHMD = true; // get HMD position from sensor space into world space, and back into model space - AnimPose avatarToWorld(glm::vec3(1), myAvatar->getOrientation(), myAvatar->getPosition()); + AnimPose avatarToWorld(glm::vec3(1.0f), myAvatar->getOrientation(), myAvatar->getPosition()); glm::mat4 worldToAvatar = glm::inverse((glm::mat4)avatarToWorld); glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); glm::mat4 hmdMat = worldToAvatar * worldHMDMat; diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 4285fd72cc..8a9971f362 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -78,17 +78,6 @@ void AnimInverseKinematics::setTargetVars( } } -static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int index) { - // walk down the skeleton hierarchy to find the joint's root - int rootIndex = -1; - int parentIndex = skeleton->getParentIndex(index); - while (parentIndex != -1) { - rootIndex = parentIndex; - parentIndex = skeleton->getParentIndex(parentIndex); - } - return rootIndex; -} - void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::vector& targets, const AnimPoseVec& underPoses) { // build a list of valid targets from _targetVarVec and animVars _maxTargetIndex = -1; @@ -100,7 +89,6 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: if (jointIndex >= 0) { // this targetVar has a valid joint --> cache the indices targetVar.jointIndex = jointIndex; - targetVar.rootIndex = findRootJointInSkeleton(_skeleton, jointIndex); } else { qCWarning(animation) << "AnimInverseKinematics could not find jointName" << targetVar.jointName << "in skeleton"; removeUnfoundJoints = true; @@ -111,7 +99,6 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); target.setType(animVars.lookup(targetVar.typeVar, QString(""))); - target.rootIndex = targetVar.rootIndex; target.index = targetVar.jointIndex; targets.push_back(target); if (target.index > _maxTargetIndex) { @@ -295,7 +282,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector _constraints; diff --git a/libraries/animation/src/AnimNode.cpp b/libraries/animation/src/AnimNode.cpp index 02d0e1b283..864252ff47 100644 --- a/libraries/animation/src/AnimNode.cpp +++ b/libraries/animation/src/AnimNode.cpp @@ -29,23 +29,6 @@ void AnimNode::setSkeleton(const AnimSkeleton::Pointer skeleton) { } } -const AnimPose AnimNode::getRootPose(int jointIndex) const { - AnimPose pose = AnimPose::identity; - if (_skeleton && jointIndex != -1) { - const AnimPoseVec& poses = getPosesInternal(); - int numJoints = (int)(poses.size()); - if (jointIndex < numJoints) { - int parentIndex = _skeleton->getParentIndex(jointIndex); - while (parentIndex != -1 && parentIndex < numJoints) { - jointIndex = parentIndex; - parentIndex = _skeleton->getParentIndex(jointIndex); - } - pose = poses[jointIndex]; - } - } - return pose; -} - void AnimNode::setCurrentFrame(float frame) { setCurrentFrameInternal(frame); for (auto&& child : _children) { diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index e8c611d3e4..9a21526409 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -75,8 +75,6 @@ public: return evaluate(animVars, dt, triggersOut); } - const AnimPose getRootPose(int jointIndex) const; - protected: void setCurrentFrame(float frame); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 173e387608..e43a55150c 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -93,6 +93,23 @@ const AnimPose& AnimSkeleton::getAbsoluteBindPose(int jointIndex) const { return _absoluteBindPoses[jointIndex]; } +AnimPose AnimSkeleton::getRootAbsoluteBindPoseByChildName(const QString& childName) const { + AnimPose pose = AnimPose::identity; + int jointIndex = nameToJointIndex(childName); + if (jointIndex >= 0) { + int numJoints = (int)(_absoluteBindPoses.size()); + if (jointIndex < numJoints) { + int parentIndex = getParentIndex(jointIndex); + while (parentIndex != -1 && parentIndex < numJoints) { + jointIndex = parentIndex; + parentIndex = getParentIndex(jointIndex); + } + pose = _absoluteBindPoses[jointIndex]; + } + } + return pose; +} + const AnimPose& AnimSkeleton::getRelativeBindPose(int jointIndex) const { return _relativeBindPoses[jointIndex]; } diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 056d8fbd9b..d59719df73 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -57,6 +57,7 @@ public: // absolute pose, not relative to parent const AnimPose& getAbsoluteBindPose(int jointIndex) const; + AnimPose getRootAbsoluteBindPoseByChildName(const QString& childName) const; // relative to parent pose const AnimPose& getRelativeBindPose(int jointIndex) const; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index ee3ac0a05a..7f300fc84a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1036,7 +1036,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { glm::vec3 headPos, neckPos; glm::quat headRot, neckRot; - AnimPose avatarHMDPose(glm::vec3(1), params.localHeadOrientation, params.localHeadPosition); + AnimPose avatarHMDPose(glm::vec3(1.0f), params.localHeadOrientation, params.localHeadPosition); computeHeadNeckAnimVars(_animSkeleton, avatarHMDPose, headPos, headRot, neckPos, neckRot); // debug rendering @@ -1126,18 +1126,17 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { // TODO: figure out how to obtain the yFlip from where it is actually stored glm::quat yFlipHACK = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - int leftHandIndex = _animSkeleton->nameToJointIndex("LeftHand"); - AnimPose rootPose = _animNode->getRootPose(leftHandIndex); + AnimPose rootBindPose = _animSkeleton->getRootAbsoluteBindPoseByChildName("LeftHand"); if (params.isLeftEnabled) { - _animVars.set("leftHandPosition", rootPose.trans + rootPose.rot * yFlipHACK * params.leftPosition); - _animVars.set("leftHandRotation", rootPose.rot * yFlipHACK * params.leftOrientation); + _animVars.set("leftHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.leftPosition); + _animVars.set("leftHandRotation", rootBindPose.rot * yFlipHACK * params.leftOrientation); } else { _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); } if (params.isRightEnabled) { - _animVars.set("rightHandPosition", rootPose.trans + rootPose.rot * yFlipHACK * params.rightPosition); - _animVars.set("rightHandRotation", rootPose.rot * yFlipHACK * params.rightOrientation); + _animVars.set("rightHandPosition", rootBindPose.trans + rootBindPose.rot * yFlipHACK * params.rightPosition); + _animVars.set("rightHandRotation", rootBindPose.rot * yFlipHACK * params.rightOrientation); } else { _animVars.unset("rightHandPosition"); _animVars.unset("rightHandRotation"); From 7aab34975f08ee583fac5c8e4a27e3e761b6f49f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 6 Oct 2015 17:08:51 -0700 Subject: [PATCH 122/152] code quality --- examples/toys/basketball/createRack.js | 10 +++++----- unpublishedScripts/masterReset.js | 15 +++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/toys/basketball/createRack.js b/examples/toys/basketball/createRack.js index b0f709d81d..f764b2ec03 100644 --- a/examples/toys/basketball/createRack.js +++ b/examples/toys/basketball/createRack.js @@ -20,7 +20,7 @@ var rackCollisionHullURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/rack_col var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; var RESET_DISTANCE = 1; - +var MINIMUM_MOVE_LENGTH = 0.05; var GRABBABLE_DATA_KEY = "grabbableKey"; @@ -74,7 +74,8 @@ function createCollidingBalls() { x: position.x, y: position.y + DIAMETER * 2, z: position.z + (DIAMETER) - (DIAMETER * i) - } + }; + var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', @@ -96,11 +97,10 @@ function createCollidingBalls() { ignoreForCollisions: false, modelURL: basketballURL, }); + collidingBalls.push(collidingBall); originalBallPositions.push(position); } - - } function testBallDistanceFromStart() { @@ -114,7 +114,7 @@ function testBallDistanceFromStart() { Script.setTimeout(function() { var newPosition = Entities.getEntityProperties(ball, "position").position; var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); - if (moving < 0.05) { + if (moving < MINIMUM_MOVE_LENGTH) { resetCount++; if (resetCount === NUMBER_OF_BALLS) { deleteCollidingBalls(); diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 49ff4a62a4..8b57aa32c3 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -527,7 +527,7 @@ function createBasketballRack() { var NUMBER_OF_BALLS = 4; var DIAMETER = 0.30; var RESET_DISTANCE = 1; - + var MINIMUM_MOVE_LENGTH = 0.05; var basketballURL = HIFI_PUBLIC_BUCKET + "models/content/basketball2.fbx"; var basketballCollisionSoundURL = HIFI_PUBLIC_BUCKET + "sounds/basketball/basketball.wav"; var rackURL = HIFI_PUBLIC_BUCKET + "models/basketball_hoop/basketball_rack.fbx"; @@ -576,13 +576,15 @@ function createBasketballRack() { function createCollidingBalls() { var position = rackStartPosition; + var i; for (i = 0; i < NUMBER_OF_BALLS; i++) { var ballPosition = { x: position.x, y: position.y + DIAMETER * 2, z: position.z + (DIAMETER) - (DIAMETER * i) - } + }; + var collidingBall = Entities.addEntity({ type: "Model", name: 'Colliding Basketball', @@ -608,32 +610,33 @@ function createBasketballRack() { ignoreForCollisions: false, modelURL: basketballURL, }); + collidingBalls.push(collidingBall); originalBallPositions.push(position); } - - } function testBallDistanceFromStart() { var resetCount = 0; + collidingBalls.forEach(function(ball, index) { var currentPosition = Entities.getEntityProperties(ball, "position").position; var originalPosition = originalBallPositions[index]; var distance = Vec3.subtract(originalPosition, currentPosition); var length = Vec3.length(distance); + if (length > RESET_DISTANCE) { Script.setTimeout(function() { var newPosition = Entities.getEntityProperties(ball, "position").position; var moving = Vec3.length(Vec3.subtract(currentPosition, newPosition)); - if (moving < 0.05) { + if (moving < MINIMUM_MOVE_LENGTH) { resetCount++; if (resetCount === NUMBER_OF_BALLS) { deleteCollidingBalls(); createCollidingBalls(); } } - }, 200) + }, 200); } }); } From c75c31ddc84cbaae22af512274c7c19c66499346 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 18:04:08 -0700 Subject: [PATCH 123/152] Fixing the index Offset issue with instanced shapes from Geometry cache --- libraries/render-utils/src/GeometryCache.cpp | 9 ++++--- libraries/render-utils/src/ModelRender.cpp | 27 +------------------- libraries/render-utils/src/ModelRender.h | 4 --- libraries/render-utils/src/Skinning.slh | 2 -- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 7846d95ec4..3fcd556dbb 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -59,7 +59,8 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); - +static const gpu::Type SHAPE_INDEX_TYPE = gpu::UINT16; +static const uint SHAPE_INDEX_SIZE = sizeof(gpu::uint16); void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, const VertexVector& vertices) { vertexBuffer->append(vertices); @@ -73,13 +74,13 @@ void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, c void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, const IndexVector& indices, const IndexVector& wireIndices) { _indices = indexBuffer; if (!indices.empty()) { - _indexOffset = indexBuffer->getSize(); + _indexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; _indexCount = indices.size(); indexBuffer->append(indices); } if (!wireIndices.empty()) { - _wireIndexOffset = indexBuffer->getSize(); + _wireIndexOffset = indexBuffer->getSize() / SHAPE_INDEX_SIZE; _wireIndexCount = wireIndices.size(); indexBuffer->append(wireIndices); } @@ -88,7 +89,7 @@ void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, con void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); - batch.setIndexBuffer(gpu::UINT16, _indices, 0); + batch.setIndexBuffer(SHAPE_INDEX_TYPE, _indices, 0); } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { diff --git a/libraries/render-utils/src/ModelRender.cpp b/libraries/render-utils/src/ModelRender.cpp index a5419733ff..c614fae67a 100644 --- a/libraries/render-utils/src/ModelRender.cpp +++ b/libraries/render-utils/src/ModelRender.cpp @@ -220,32 +220,10 @@ void ModelRender::RenderPipelineLib::addRenderPipeline(ModelRender::RenderKey ke wireframeState->setFillMode(gpu::State::FILL_LINE); - // create a new RenderPipeline with the same shader side and the mirrorState + // create a new RenderPipeline with the same shader side and the wireframe state auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); } - - // If not a shadow pass, create the mirror version from the same state, just change the FrontFace - if (!key.isShadow()) { - - RenderKey mirrorKey(key.getRaw() | RenderKey::IS_MIRROR); - auto mirrorState = std::make_shared(state->getValues()); - - // create a new RenderPipeline with the same shader side and the mirrorState - auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState)); - insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations))); - - if (!key.isWireFrame()) { - RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME); - auto wireframeState = std::make_shared(state->getValues()); - - wireframeState->setFillMode(gpu::State::FILL_LINE); - - // create a new RenderPipeline with the same shader side and the mirrorState - auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); - insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); - } - } } @@ -274,9 +252,6 @@ void ModelRender::pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, b getRenderPipelineLib(); RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); - if (mode == RenderArgs::MIRROR_RENDER_MODE) { - key = RenderKey(key.getRaw() | RenderKey::IS_MIRROR); - } auto pipeline = _renderPipelineLib.find(key.getRaw()); if (pipeline == _renderPipelineLib.end()) { qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw(); diff --git a/libraries/render-utils/src/ModelRender.h b/libraries/render-utils/src/ModelRender.h index 9748710ab1..1528dcfc87 100644 --- a/libraries/render-utils/src/ModelRender.h +++ b/libraries/render-utils/src/ModelRender.h @@ -59,7 +59,6 @@ public: IS_STEREO_FLAG, IS_DEPTH_ONLY_FLAG, IS_SHADOW_FLAG, - IS_MIRROR_FLAG, //THis means that the mesh is rendered mirrored, not the same as "Rear view mirror" IS_WIREFRAME_FLAG, NUM_FLAGS, @@ -75,7 +74,6 @@ public: IS_STEREO = (1 << IS_STEREO_FLAG), IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG), IS_SHADOW = (1 << IS_SHADOW_FLAG), - IS_MIRROR = (1 << IS_MIRROR_FLAG), IS_WIREFRAME = (1 << IS_WIREFRAME_FLAG), }; typedef unsigned short Flags; @@ -93,7 +91,6 @@ public: bool isStereo() const { return isFlag(IS_STEREO); } bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); } bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing - bool isMirror() const { return isFlag(IS_MIRROR); } bool isWireFrame() const { return isFlag(IS_WIREFRAME); } Flags _flags = 0; @@ -124,7 +121,6 @@ public: | (isWireframe ? IS_WIREFRAME : 0) | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0) | ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_SHADOW : 0) - | ((mode == RenderArgs::MIRROR_RENDER_MODE) ? IS_MIRROR : 0) ) {} RenderKey(int bitmask) : _flags(bitmask) {} diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 747f18ab34..b34ed3ed2b 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -15,8 +15,6 @@ const int MAX_TEXCOORDS = 2; const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; -//uniform mat4 clusterMatrices[MAX_CLUSTERS]; - layout(std140) uniform skinClusterBuffer { mat4 clusterMatrices[MAX_CLUSTERS]; }; From 19fb4e92a6690227f6e4320329a18c609aaa8a1f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 4 Oct 2015 16:26:06 -0700 Subject: [PATCH 124/152] Enabling programmatic access to the IPD scale Conflicts: interface/src/Application.cpp interface/src/avatar/MyAvatar.cpp interface/src/scripting/HMDScriptingInterface.cpp interface/src/scripting/HMDScriptingInterface.h --- examples/example/hmd/ipdScalingTest.js | 42 +++++++++++++++ interface/src/Application.cpp | 48 ++++++++++++----- interface/src/PluginContainerProxy.cpp | 7 +++ interface/src/PluginContainerProxy.h | 3 ++ interface/src/avatar/MyAvatar.cpp | 8 +-- .../src/scripting/HMDScriptingInterface.cpp | 51 +++++++----------- .../src/scripting/HMDScriptingInterface.h | 21 +++----- .../AbstractHMDScriptingInterface.cpp | 52 +++++++++++++++++++ .../AbstractHMDScriptingInterface.h | 39 ++++++++++++++ .../src/display-plugins/DisplayPlugin.h | 17 +++--- .../oculus/OculusBaseDisplayPlugin.cpp | 16 +++--- .../oculus/OculusBaseDisplayPlugin.h | 11 ++-- .../display-plugins/oculus/OculusHelpers.h | 8 +++ .../oculus/OculusLegacyDisplayPlugin.cpp | 4 +- .../oculus/OculusLegacyDisplayPlugin.h | 2 +- .../openvr/OpenVrDisplayPlugin.cpp | 4 +- .../openvr/OpenVrDisplayPlugin.h | 2 +- .../stereo/StereoDisplayPlugin.cpp | 4 -- .../stereo/StereoDisplayPlugin.h | 9 +++- .../plugins/src/plugins/PluginContainer.cpp | 10 ++++ .../plugins/src/plugins/PluginContainer.h | 4 ++ 21 files changed, 271 insertions(+), 91 deletions(-) create mode 100644 examples/example/hmd/ipdScalingTest.js create mode 100644 libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp create mode 100644 libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h diff --git a/examples/example/hmd/ipdScalingTest.js b/examples/example/hmd/ipdScalingTest.js new file mode 100644 index 0000000000..daa11170e4 --- /dev/null +++ b/examples/example/hmd/ipdScalingTest.js @@ -0,0 +1,42 @@ +// +// Created by Bradley Austin Davis on 2015/10/04 +// Copyright 2013-2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +IPDScalingTest = function() { + // Switch every 5 seconds between normal IPD and 0 IPD (in seconds) + this.UPDATE_INTERVAL = 10.0; + this.lastUpdateInterval = 0; + this.scaled = false; + + var that = this; + Script.scriptEnding.connect(function() { + that.onCleanup(); + }); + + Script.update.connect(function(deltaTime) { + that.lastUpdateInterval += deltaTime; + if (that.lastUpdateInterval >= that.UPDATE_INTERVAL) { + that.onUpdate(that.lastUpdateInterval); + that.lastUpdateInterval = 0; + } + }); +} + +IPDScalingTest.prototype.onCleanup = function() { + HMD.setIPDScale(1.0); +} + +IPDScalingTest.prototype.onUpdate = function(deltaTime) { + this.scaled = !this.scaled; + if (this.scaled) { + HMD.ipdScale = 0.0; + } else { + HMD.ipdScale = 1.0; + } +} + +new IPDScalingTest(); \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b44ac6804d..fa9b9f52b2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -281,6 +281,7 @@ bool setupEssentials(int& argc, char** argv) { Setting::init(); // Set dependencies +<<<<<<< HEAD DependencyManager::set(); DependencyManager::set(NodeType::Agent, listenPort); DependencyManager::set(); @@ -306,6 +307,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); #if defined(Q_OS_MAC) || defined(Q_OS_WIN) DependencyManager::set(); #endif @@ -1166,9 +1168,11 @@ void Application::paintGL() { // right eye. There are FIXMEs in the relevant plugins _myCamera.setProjection(displayPlugin->getProjection(Mono, _myCamera.getProjection())); renderArgs._context->enableStereo(true); - mat4 eyeViews[2]; + mat4 eyeOffsets[2]; mat4 eyeProjections[2]; auto baseProjection = renderArgs._viewFrustum->getProjection(); + auto hmdInterface = DependencyManager::get(); + float IPDScale = hmdInterface->getIPDScale(); // FIXME we probably don't need to set the projection matrix every frame, // only when the display plugin changes (or in non-HMD modes when the user // changes the FOV manually, which right now I don't think they can. @@ -1177,14 +1181,24 @@ void Application::paintGL() { // applied to the avatar, so we need to get the difference between the head // pose applied to the avatar and the per eye pose, and use THAT as // the per-eye stereo matrix adjustment. - mat4 eyePose = displayPlugin->getEyePose(eye); + mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // Grab the translation + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); + eyeOffsets[eye] = eyeOffsetTransform; + + // Tell the plugin what pose we're using to render. In this case we're just using the + // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it + // for rotational timewarp. If we move to support positonal timewarp, we need to + // ensure this contains the full pose composed with the eye offsets. mat4 headPose = displayPlugin->getHeadPose(); - mat4 eyeView = glm::inverse(eyePose) * headPose; - eyeViews[eye] = eyeView; + displayPlugin->setEyeRenderPose(eye, headPose); + eyeProjections[eye] = displayPlugin->getProjection(eye, baseProjection); }); renderArgs._context->setStereoProjections(eyeProjections); - renderArgs._context->setStereoViews(eyeViews); + renderArgs._context->setStereoViews(eyeOffsets); } displaySide(&renderArgs, _myCamera); renderArgs._context->enableStereo(false); @@ -3930,7 +3944,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Paths", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("HMD", &HMDScriptingInterface::getInstance()); + scriptEngine->registerGlobalObject("HMD", DependencyManager::get().data()); scriptEngine->registerFunction("HMD", "getHUDLookAtPosition2D", HMDScriptingInterface::getHUDLookAtPosition2D, 0); scriptEngine->registerFunction("HMD", "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); @@ -4740,19 +4754,25 @@ mat4 Application::getEyeProjection(int eye) const { mat4 Application::getEyePose(int eye) const { if (isHMDMode()) { - return getActiveDisplayPlugin()->getEyePose((Eye)eye); + auto hmdInterface = DependencyManager::get(); + float IPDScale = hmdInterface->getIPDScale(); + auto displayPlugin = getActiveDisplayPlugin(); + mat4 headPose = displayPlugin->getHeadPose(); + mat4 eyeToHead = displayPlugin->getEyeToHeadTransform((Eye)eye); + { + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); + eyeToHead[3] = vec4(eyeOffset, 1.0); + } + return eyeToHead * headPose; } - return mat4(); } mat4 Application::getEyeOffset(int eye) const { - if (isHMDMode()) { - mat4 identity; - return getActiveDisplayPlugin()->getView((Eye)eye, identity); - } - - return mat4(); + // FIXME invert? + return getActiveDisplayPlugin()->getEyeToHeadTransform((Eye)eye); } mat4 Application::getHMDSensorPose() const { diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 4126b7b9bd..19bb6ab8de 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -16,6 +16,9 @@ PluginContainerProxy::PluginContainerProxy() { Plugin::setContainer(this); } +PluginContainerProxy::~PluginContainerProxy() { +} + bool PluginContainerProxy::isForeground() { return qApp->isForeground() && !qApp->getWindow()->isMinimized(); } @@ -151,3 +154,7 @@ void PluginContainerProxy::showDisplayPluginsTools() { QGLWidget* PluginContainerProxy::getPrimarySurface() { return qApp->_glWidget; } + +const DisplayPlugin* PluginContainerProxy::getActiveDisplayPlugin() const { + return qApp->getActiveDisplayPlugin(); +} diff --git a/interface/src/PluginContainerProxy.h b/interface/src/PluginContainerProxy.h index 95865609c8..79f8287b66 100644 --- a/interface/src/PluginContainerProxy.h +++ b/interface/src/PluginContainerProxy.h @@ -11,6 +11,7 @@ class PluginContainerProxy : public QObject, PluginContainer { Q_OBJECT PluginContainerProxy(); + virtual ~PluginContainerProxy(); virtual void addMenu(const QString& menuName) override; virtual void removeMenu(const QString& menuName) override; virtual QAction* addMenuItem(const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override; @@ -23,6 +24,8 @@ class PluginContainerProxy : public QObject, PluginContainer { virtual void requestReset() override; virtual QGLWidget* getPrimarySurface() override; virtual bool isForeground() override; + virtual const DisplayPlugin* getActiveDisplayPlugin() const override; + QRect _savedGeometry{ 10, 120, 800, 600 }; friend class Application; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0105d1b648..322c83fcc0 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1342,11 +1342,13 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl if (qApp->isHMDMode()) { glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); - glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyePose(Eye::Left); + glm::mat4 headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose(); + glm::mat4 leftEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); + leftEyePose = leftEyePose * headPose; glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]); - glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyePose(Eye::Right); + glm::mat4 rightEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right); + rightEyePose = rightEyePose * headPose; glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]); - glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); glm::vec3 headPosition = glm::vec3(headPose[3]); getHead()->renderLookAts(renderArgs, diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index f9a8fc1493..f6bf7f8b3c 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -13,64 +13,53 @@ #include -#include - -#include "Application.h" #include "display-plugins/DisplayPlugin.h" +#include +#include "Application.h" -HMDScriptingInterface& HMDScriptingInterface::getInstance() { - static HMDScriptingInterface sharedInstance; - return sharedInstance; -} - -bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { - Camera* camera = qApp->getCamera(); - glm::vec3 position = camera->getPosition(); - glm::quat orientation = camera->getOrientation(); - - glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); - - const auto& compositor = qApp->getApplicationCompositor(); - - return compositor.calculateRayUICollisionPoint(position, direction, result); +HMDScriptingInterface::HMDScriptingInterface() { } QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) { - glm::vec3 hudIntersection; - - if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(hudIntersection)) { + auto instance = DependencyManager::get(); + if (instance->getHUDLookAtPosition3D(hudIntersection)) { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition(); glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); glm::vec3 eulers = ::safeEulerAngles(rotation); - return qScriptValueFromValue(engine, qApp->getApplicationCompositor() - .sphericalToOverlay(glm::vec2(eulers.y, -eulers.x))); + return qScriptValueFromValue(engine, Application::getInstance()->getApplicationCompositor() + .sphericalToOverlay(glm::vec2(eulers.y, -eulers.x))); } return QScriptValue::NullValue; } QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine) { glm::vec3 result; - if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(result)) { + auto instance = DependencyManager::get(); + if (instance->getHUDLookAtPosition3D(result)) { return qScriptValueFromValue(engine, result); } return QScriptValue::NullValue; } -float HMDScriptingInterface::getIPD() const { - return qApp->getActiveDisplayPlugin()->getIPD(); -} - void HMDScriptingInterface::toggleMagnifier() { qApp->getApplicationCompositor().toggleMagnifier(); } bool HMDScriptingInterface::getMagnifier() const { - return qApp->getApplicationCompositor().hasMagnifier(); + return Application::getInstance()->getApplicationCompositor().hasMagnifier(); } -bool HMDScriptingInterface::isHMDMode() const { - return qApp->isHMDMode(); +bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { + Camera* camera = Application::getInstance()->getCamera(); + glm::vec3 position = camera->getPosition(); + glm::quat orientation = camera->getOrientation(); + + glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); + + const auto& compositor = Application::getInstance()->getApplicationCompositor(); + + return compositor.calculateRayUICollisionPoint(position, direction, result); } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index b118fab62b..c097cde5e3 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -13,22 +13,19 @@ #define hifi_HMDScriptingInterface_h #include - -#include - class QScriptContext; class QScriptEngine; +#include +#include +#include -class HMDScriptingInterface : public QObject { + +class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) - Q_PROPERTY(bool active READ isHMDMode) - Q_PROPERTY(float ipd READ getIPD) - public: - static HMDScriptingInterface& getInstance(); - + HMDScriptingInterface(); static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine); static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine); @@ -36,11 +33,7 @@ public slots: void toggleMagnifier(); private: - HMDScriptingInterface() = default; - bool getMagnifier() const; - bool isHMDMode() const; - float getIPD() const; - + bool getMagnifier() const; bool getHUDLookAtPosition3D(glm::vec3& result) const; }; diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp new file mode 100644 index 0000000000..9987ae345c --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp @@ -0,0 +1,52 @@ +// +// Created by Bradley Austin Davis on 2015/10/04 +// Copyright 2013-2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AbstractHMDScriptingInterface.h" + +#include + +#include "DisplayPlugin.h" +#include +#include + +static Setting::Handle IPD_SCALE_HANDLE("hmd.ipdScale", 1.0f); + +AbstractHMDScriptingInterface::AbstractHMDScriptingInterface() { + _IPDScale = IPD_SCALE_HANDLE.get(); +} + +float AbstractHMDScriptingInterface::getIPD() const { + return PluginContainer::getInstance().getActiveDisplayPlugin()->getIPD(); +} + +float AbstractHMDScriptingInterface::getEyeHeight() const { + // FIXME update the display plugin interface to expose per-plugin settings + return OVR_DEFAULT_EYE_HEIGHT; +} + +float AbstractHMDScriptingInterface::getPlayerHeight() const { + // FIXME update the display plugin interface to expose per-plugin settings + return OVR_DEFAULT_PLAYER_HEIGHT; +} + +float AbstractHMDScriptingInterface::getIPDScale() const { + return _IPDScale; +} + +void AbstractHMDScriptingInterface::setIPDScale(float IPDScale) { + IPDScale = glm::clamp(IPDScale, -1.0f, 3.0f); + if (IPDScale != _IPDScale) { + _IPDScale = IPDScale; + IPD_SCALE_HANDLE.set(IPDScale); + emit IPDScaleChanged(); + } +} + +bool AbstractHMDScriptingInterface::isHMDMode() const { + return PluginContainer::getInstance().getActiveDisplayPlugin()->isHmd(); +} diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h new file mode 100644 index 0000000000..5df58ce677 --- /dev/null +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.h @@ -0,0 +1,39 @@ +// +// Created by Bradley Austin Davis on 2015/10/04 +// Copyright 2013-2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_AbstractHMDScriptingInterface_h +#define hifi_AbstractHMDScriptingInterface_h + +#include + +class AbstractHMDScriptingInterface : public QObject { + Q_OBJECT + Q_PROPERTY(bool active READ isHMDMode) + Q_PROPERTY(float ipd READ getIPD) + Q_PROPERTY(float eyeHeight READ getEyeHeight) + Q_PROPERTY(float playerHeight READ getPlayerHeight) + Q_PROPERTY(float ipdScale READ getIPDScale WRITE setIPDScale NOTIFY IPDScaleChanged) + +public: + AbstractHMDScriptingInterface(); + float getIPD() const; + float getEyeHeight() const; + float getPlayerHeight() const; + float getIPDScale() const; + void setIPDScale(float ipdScale); + bool isHMDMode() const; + +signals: + void IPDScaleChanged(); + +private: + float _IPDScale{ 1.0 }; +}; + +#endif // hifi_AbstractHMDScriptingInterface_h diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index 8b9d249bd4..b4ae6be97f 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -46,6 +46,8 @@ void for_each_eye(F f, FF ff) { class QWindow; +#define AVERAGE_HUMAN_IPD 0.064f + class DisplayPlugin : public Plugin { Q_OBJECT public: @@ -107,21 +109,22 @@ public: return baseProjection; } - virtual glm::mat4 getView(Eye eye, const glm::mat4& baseView) const { - return glm::inverse(getEyePose(eye)) * baseView; - } - // HMD specific methods // TODO move these into another class? - virtual glm::mat4 getEyePose(Eye eye) const { - static const glm::mat4 pose; return pose; + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const { + static const glm::mat4 transform; return transform; } virtual glm::mat4 getHeadPose() const { static const glm::mat4 pose; return pose; } - virtual float getIPD() const { return 0.0f; } + // Needed for timewarp style features + virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) { + // NOOP + } + + virtual float getIPD() const { return AVERAGE_HUMAN_IPD; } virtual void abandonCalibration() {} virtual void resetSensors() {} diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp index f2a7b06510..859a4a810a 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp @@ -19,7 +19,6 @@ void OculusBaseDisplayPlugin::preRender() { #if (OVR_MAJOR_VERSION >= 6) ovrFrameTiming ftiming = ovr_GetFrameTiming(_hmd, _frameIndex); _trackingState = ovr_GetTrackingState(_hmd, ftiming.DisplayMidpointSeconds); - ovr_CalcEyePoses(_trackingState.HeadPose.ThePose, _eyeOffsets, _eyePoses); #endif } @@ -33,14 +32,19 @@ void OculusBaseDisplayPlugin::resetSensors() { #endif } -glm::mat4 OculusBaseDisplayPlugin::getEyePose(Eye eye) const { - return toGlm(_eyePoses[eye]); +glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const { + return glm::translate(mat4(), toGlm(_eyeOffsets[eye])); } glm::mat4 OculusBaseDisplayPlugin::getHeadPose() const { return toGlm(_trackingState.HeadPose.ThePose); } +void OculusBaseDisplayPlugin::setEyeRenderPose(Eye eye, const glm::mat4& pose) { + _eyePoses[eye] = ovrPoseFromGlm(pose); +} + + bool OculusBaseDisplayPlugin::isSupported() const { #if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { @@ -151,9 +155,9 @@ void OculusBaseDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sce } float OculusBaseDisplayPlugin::getIPD() const { - float result = 0.0f; + float result = OVR_DEFAULT_IPD; #if (OVR_MAJOR_VERSION >= 6) - result = ovr_GetFloat(_hmd, OVR_KEY_IPD, OVR_DEFAULT_IPD); + result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result); #endif return result; -} \ No newline at end of file +} diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h index d879085b8f..6307f6bbf9 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h @@ -29,8 +29,9 @@ public: virtual glm::uvec2 getRecommendedRenderSize() const override final; virtual glm::uvec2 getRecommendedUiSize() const override final { return uvec2(1920, 1080); } virtual void resetSensors() override final; - virtual glm::mat4 getEyePose(Eye eye) const override final; + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override final; virtual glm::mat4 getHeadPose() const override final; + virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) override final; virtual float getIPD() const override final; protected: @@ -39,6 +40,7 @@ protected: protected: ovrPosef _eyePoses[2]; + ovrVector3f _eyeOffsets[2]; mat4 _eyeProjections[3]; mat4 _compositeEyeProjections[2]; @@ -50,13 +52,12 @@ protected: ovrHmd _hmd; float _ipd{ OVR_DEFAULT_IPD }; ovrEyeRenderDesc _eyeRenderDescs[2]; - ovrVector3f _eyeOffsets[2]; ovrFovPort _eyeFovs[2]; - ovrHmdDesc _hmdDesc; - ovrLayerEyeFov _sceneLayer; + ovrHmdDesc _hmdDesc; + ovrLayerEyeFov _sceneLayer; #endif #if (OVR_MAJOR_VERSION == 7) - ovrGraphicsLuid _luid; + ovrGraphicsLuid _luid; #endif }; diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h b/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h index df0a6c5228..5a6999075b 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h @@ -79,3 +79,11 @@ inline ovrQuatf ovrFromGlm(const glm::quat & q) { return{ q.x, q.y, q.z, q.w }; } +inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) { + glm::vec3 translation = glm::vec3(m[3]) / m[3].w; + glm::quat orientation = glm::quat_cast(m); + ovrPosef result; + result.Orientation = ovrFromGlm(orientation); + result.Position = ovrFromGlm(translation); + return result; +} diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp index ade34afcae..1ad61513d6 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp @@ -59,11 +59,11 @@ void OculusLegacyDisplayPlugin::resetSensors() { #endif } -glm::mat4 OculusLegacyDisplayPlugin::getEyePose(Eye eye) const { +glm::mat4 OculusLegacyDisplayPlugin::getEyeToHeadTransform(Eye eye) const { #if (OVR_MAJOR_VERSION == 5) return toGlm(_eyePoses[eye]); #else - return WindowOpenGLDisplayPlugin::getEyePose(eye); + return WindowOpenGLDisplayPlugin::getEyeToHeadTransform(eye); #endif } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h index 5bce032948..9e2e47f434 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h @@ -31,7 +31,7 @@ public: virtual glm::uvec2 getRecommendedRenderSize() const override; virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); } virtual void resetSensors() override; - virtual glm::mat4 getEyePose(Eye eye) const override; + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; virtual glm::mat4 getHeadPose() const override; protected: diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp index fab9cc5dd4..faf5a7b781 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp @@ -160,8 +160,8 @@ void OpenVrDisplayPlugin::resetSensors() { _sensorResetMat = glm::inverse(cancelOutRollAndPitch(_trackedDevicePoseMat4[0])); } -glm::mat4 OpenVrDisplayPlugin::getEyePose(Eye eye) const { - return getHeadPose() * _eyesData[eye]._eyeOffset; +glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const { + return _eyesData[eye]._eyeOffset; } glm::mat4 OpenVrDisplayPlugin::getHeadPose() const { diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h index afe024e72b..7849623552 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.h @@ -29,7 +29,7 @@ public: virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override; virtual void resetSensors() override; - virtual glm::mat4 getEyePose(Eye eye) const override; + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; virtual glm::mat4 getHeadPose() const override; protected: diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 77906d1857..2ea79ed2e0 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -61,10 +61,6 @@ glm::mat4 StereoDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProje return eyeProjection; } -glm::mat4 StereoDisplayPlugin::getEyePose(Eye eye) const { - return mat4(); -} - std::vector _screenActions; void StereoDisplayPlugin::activate() { auto screens = qApp->screens(); diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h index 86f35c1260..33b0b09b0d 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h @@ -21,7 +21,14 @@ public: virtual float getRecommendedAspectRatio() const override; virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override; - virtual glm::mat4 getEyePose(Eye eye) const override; + + // NOTE, because Stereo displays don't include head tracking, and therefore + // can't include roll or pitch, the eye separation is embedded into the projection + // matrix. However, this eliminates the possibility of easily mainpulating + // the IPD at the Application level, the way we now allow with HMDs. + // If that becomes an issue then we'll need to break up the functionality similar + // to the HMD plugins. + // virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; protected: void updateScreen(); diff --git a/libraries/plugins/src/plugins/PluginContainer.cpp b/libraries/plugins/src/plugins/PluginContainer.cpp index b27f076eb6..8afac745f3 100644 --- a/libraries/plugins/src/plugins/PluginContainer.cpp +++ b/libraries/plugins/src/plugins/PluginContainer.cpp @@ -9,7 +9,17 @@ static PluginContainer* INSTANCE{ nullptr }; +PluginContainer& PluginContainer::getInstance() { + Q_ASSERT(INSTANCE); + return *INSTANCE; +} + PluginContainer::PluginContainer() { Q_ASSERT(!INSTANCE); INSTANCE = this; }; + +PluginContainer::~PluginContainer() { + Q_ASSERT(INSTANCE == this); + INSTANCE = nullptr; +}; diff --git a/libraries/plugins/src/plugins/PluginContainer.h b/libraries/plugins/src/plugins/PluginContainer.h index f938758161..f013bfe3bf 100644 --- a/libraries/plugins/src/plugins/PluginContainer.h +++ b/libraries/plugins/src/plugins/PluginContainer.h @@ -13,10 +13,13 @@ class QAction; class QGLWidget; class QScreen; +class DisplayPlugin; class PluginContainer { public: + static PluginContainer& getInstance(); PluginContainer(); + virtual ~PluginContainer(); virtual void addMenu(const QString& menuName) = 0; virtual void removeMenu(const QString& menuName) = 0; virtual QAction* addMenuItem(const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0; @@ -29,4 +32,5 @@ public: virtual void requestReset() = 0; virtual QGLWidget* getPrimarySurface() = 0; virtual bool isForeground() = 0; + virtual const DisplayPlugin* getActiveDisplayPlugin() const = 0; }; From bac69c73a8d2a4192263e89f31d0876acf6b6657 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 6 Oct 2015 18:57:08 -0700 Subject: [PATCH 125/152] Fixing bug in application compositor transform --- interface/src/ui/ApplicationCompositor.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index cb4ae9990c..044d858412 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -285,7 +286,10 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int mat4 camMat; _cameraBaseTransform.getMatrix(camMat); - camMat = camMat * qApp->getEyePose(eye); + auto displayPlugin = qApp->getActiveDisplayPlugin(); + auto headPose = displayPlugin->getHeadPose(); + auto eyeToHead = displayPlugin->getEyeToHeadTransform((Eye)eye); + camMat = (headPose * eyeToHead) * camMat; batch.setViewportTransform(renderArgs->_viewport); batch.setViewTransform(camMat); From 6e5847bb1c773c7f790a90b3bd65b9b6cbab04e5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 6 Oct 2015 19:58:25 -0700 Subject: [PATCH 126/152] make Hand Input Mouse off by default --- interface/src/Application.cpp | 2 +- interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 2 +- interface/src/ui/ApplicationCompositor.cpp | 7 ++++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b44ac6804d..3ac667f7b4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2745,7 +2745,7 @@ void Application::update(float deltaTime) { Hand* hand = DependencyManager::get()->getMyAvatar()->getHand(); setPalmData(hand, leftHand, deltaTime, LEFT_HAND_INDEX, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK)); setPalmData(hand, rightHand, deltaTime, RIGHT_HAND_INDEX, userInputMapper->getActionState(UserInputMapper::RIGHT_HAND_CLICK)); - if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK), userInputMapper->getActionState(UserInputMapper::SHIFT), LEFT_HAND_INDEX); emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::RIGHT_HAND_CLICK), diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9abfd1e34c..ae41ca2493 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -464,7 +464,7 @@ Menu::Menu() { MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandMouseInput, 0, true); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true, qApp, SLOT(setLowVelocityFilter(bool))); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 33ce659a51..4c9c3ef7b5 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -204,7 +204,7 @@ namespace MenuOption { const QString FrameTimer = "Show Timer"; const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowWhenSpeaking = "Glow When Speaking"; - const QString HandMouseInput = "Enable Hand Mouse Input"; + const QString EnableHandMouseInput = "Enable Hand Controller Mouse Input"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString InputMenu = "Avatar>Input Devices"; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index cb4ae9990c..7a90e30e53 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -313,8 +313,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int glm::mat4 overlayXfm; _modelTransform.getMatrix(overlayXfm); - // Only render the hand pointers if the HandMouseInput is enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + // Only render the hand pointers if the EnableHandMouseInput is enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { PalmData& palm = myAvatar->getHand()->getPalms()[i]; @@ -435,7 +435,8 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) { _magActive[MOUSE] = _magnifier; _reticleActive[LEFT_CONTROLLER] = false; _reticleActive[RIGHT_CONTROLLER] = false; - } else if (qApp->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + } else if (qApp->getLastMouseMoveWasSimulated() + && Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { //only render controller pointer if we aren't already rendering a mouse pointer _reticleActive[MOUSE] = false; _magActive[MOUSE] = false; From 028935f831070a33f727d2fe96f60a3b632627ab Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 6 Oct 2015 20:03:46 -0700 Subject: [PATCH 127/152] Removing deprecated function usage --- interface/src/Application.cpp | 1 - interface/src/avatar/MyAvatar.cpp | 6 +++--- interface/src/scripting/HMDScriptingInterface.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fa9b9f52b2..3a9b4dba52 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -281,7 +281,6 @@ bool setupEssentials(int& argc, char** argv) { Setting::init(); // Set dependencies -<<<<<<< HEAD DependencyManager::set(); DependencyManager::set(NodeType::Agent, listenPort); DependencyManager::set(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 322c83fcc0..7592aad061 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1342,11 +1342,11 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl if (qApp->isHMDMode()) { glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); - glm::mat4 headPose = Application::getInstance()->getActiveDisplayPlugin()->getHeadPose(); - glm::mat4 leftEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); + glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); + glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); leftEyePose = leftEyePose * headPose; glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]); - glm::mat4 rightEyePose = Application::getInstance()->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right); + glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right); rightEyePose = rightEyePose * headPose; glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]); glm::vec3 headPosition = glm::vec3(headPose[3]); diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index f6bf7f8b3c..3d39bdd143 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -29,7 +29,7 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* conte glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); glm::vec3 eulers = ::safeEulerAngles(rotation); - return qScriptValueFromValue(engine, Application::getInstance()->getApplicationCompositor() + return qScriptValueFromValue(engine, qApp->getApplicationCompositor() .sphericalToOverlay(glm::vec2(eulers.y, -eulers.x))); } return QScriptValue::NullValue; @@ -49,17 +49,17 @@ void HMDScriptingInterface::toggleMagnifier() { } bool HMDScriptingInterface::getMagnifier() const { - return Application::getInstance()->getApplicationCompositor().hasMagnifier(); + return qApp->getApplicationCompositor().hasMagnifier(); } bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { - Camera* camera = Application::getInstance()->getCamera(); + Camera* camera = qApp->getCamera(); glm::vec3 position = camera->getPosition(); glm::quat orientation = camera->getOrientation(); glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); - const auto& compositor = Application::getInstance()->getApplicationCompositor(); + const auto& compositor = qApp->getApplicationCompositor(); return compositor.calculateRayUICollisionPoint(position, direction, result); } From eff5a4c395958027b5d686337a9cf0cc4d7db8f4 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 6 Oct 2015 22:56:48 -0700 Subject: [PATCH 128/152] Picking fixes in the HMD --- examples/example/hmd/pickerTest.js | 103 ++++++++++++++++++ interface/src/Application.cpp | 9 +- interface/src/ui/ApplicationCompositor.cpp | 32 +++--- .../render-utils/src/OffscreenQmlSurface.cpp | 4 +- 4 files changed, 122 insertions(+), 26 deletions(-) create mode 100644 examples/example/hmd/pickerTest.js diff --git a/examples/example/hmd/pickerTest.js b/examples/example/hmd/pickerTest.js new file mode 100644 index 0000000000..96ffc6d21d --- /dev/null +++ b/examples/example/hmd/pickerTest.js @@ -0,0 +1,103 @@ +Script.include("../../libraries/utils.js"); + + +PickerTest = function() { + // Switch every 5 seconds between normal IPD and 0 IPD (in seconds) + this.UPDATE_INTERVAL = 10.0; + this.lastUpdateInterval = 0; + + this.ballId = Overlays.addOverlay("sphere", { + position: { x: 0, y: 0, z: 0 }, + color: { red: 0, green: 255, blue: 0 }, + size: 0.1, + solid: true, + alpha: 1.0, + visible: true, + }); + + this.ballId2 = Overlays.addOverlay("sphere", { + position: { x: 0, y: 0, z: 0 }, + color: { red: 255, green: 0, blue: 0 }, + size: 0.05, + solid: true, + alpha: 1.0, + visible: true, + }); + + var that = this; + Script.scriptEnding.connect(function() { + that.onCleanup(); + }); + + Script.update.connect(function(deltaTime) { + that.lastUpdateInterval += deltaTime; + if (that.lastUpdateInterval >= that.UPDATE_INTERVAL) { + that.onUpdate(that.lastUpdateInterval); + that.lastUpdateInterval = 0; + } + }); + + Controller.mousePressEvent.connect(function(event) { + that.onMousePress(event); + }); + + Controller.mouseMoveEvent.connect(function(event) { + that.onMouseMove(event); + }); + + Controller.mouseReleaseEvent.connect(function(event) { + that.onMouseRelease(event); + }); +}; + +PickerTest.prototype.onCleanup = function() { + Overlays.deleteOverlay(this.ballId) + Overlays.deleteOverlay(this.ballId2) +} + +PickerTest.prototype.updateOverlays = function() { + var pickRay = Camera.computePickRay(this.x, this.y); + var origin = pickRay.origin; + var direction = pickRay.direction; + var position = Vec3.sum(origin, direction) + Overlays.editOverlay(this.ballId, { + position: position + }); + + Overlays.editOverlay(this.ballId2, { + position: origin + }); +} + +PickerTest.prototype.onUpdate = function(deltaTime) { + if (this.clicked) { + this.updateOverlays(); + } +} + +PickerTest.prototype.onMousePress = function(event) { + if (event.button !== "LEFT") { + return + } + this.clicked = true; + this.x = event.x; + this.y = event.y; + this.updateOverlays(); +} + +PickerTest.prototype.onMouseRelease = function(event) { + if (event.button !== "LEFT") { + return + } + this.clicked = false; +} + +PickerTest.prototype.onMouseMove = function(event) { + if (this.clicked) { + this.x = event.x; + this.y = event.y; + this.updateOverlays(); + } +} + +var PickerTest = new PickerTest(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b44ac6804d..72945d63fe 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3175,14 +3175,13 @@ int Application::getBoundaryLevelAdjust() const { } PickRay Application::computePickRay(float x, float y) const { - glm::vec2 size = getCanvasSize(); - x /= size.x; - y /= size.y; + vec2 pickPoint{ x, y }; PickRay result; if (isHMDMode()) { - getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); + getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction); } else { - getViewFrustum()->computePickRay(x, y, result.origin, result.direction); + pickPoint /= getCanvasSize(); + getViewFrustum()->computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); } return result; } diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index cb4ae9990c..86add90283 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -346,31 +346,28 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int void ApplicationCompositor::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const { - cursorPos *= qApp->getCanvasSize(); - const glm::vec2 projection = screenToSpherical(cursorPos); + const glm::vec2 projection = overlayToSpherical(cursorPos); // The overlay space orientation of the mouse coordinates - const glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f)); - // FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE. - // Now we need to account for the actual camera position relative to the overlay - glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT); + const glm::quat cursorOrientation(glm::vec3(-projection.y, projection.x, 0.0f)); + // The orientation and position of the HEAD, not the overlay + glm::vec3 worldSpaceHeadPosition = qApp->getCamera()->getPosition(); + glm::quat worldSpaceOrientation = qApp->getCamera()->getOrientation(); - // We need the RAW camera orientation and position, because this is what the overlay is - // rendered relative to - glm::vec3 overlayPosition = qApp->getCamera()->getPosition(); - glm::quat overlayOrientation = qApp->getCamera()->getRotation(); + auto headPose = qApp->getHMDSensorPose(); + auto headOrientation = glm::quat_cast(headPose); + auto headTranslation = extractTranslation(headPose); + auto overlayOrientation = worldSpaceOrientation * glm::inverse(headOrientation); + auto overlayPosition = worldSpaceHeadPosition - (overlayOrientation * headTranslation); if (Menu::getInstance()->isOptionChecked(MenuOption::StandingHMDSensorMode)) { overlayPosition = _modelTransform.getTranslation(); overlayOrientation = _modelTransform.getRotation(); } - // Intersection UI overlay space - glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection; - glm::vec3 worldSpaceIntersection = (glm::normalize(worldSpaceDirection) * _oculusUIRadius) + overlayPosition; - glm::vec3 worldSpaceHeadPosition = (overlayOrientation * extractTranslation(qApp->getHMDSensorPose())) + overlayPosition; - // Intersection in world space + glm::vec3 worldSpaceIntersection = ((overlayOrientation * (cursorOrientation * Vectors::FRONT)) * _oculusUIRadius) + overlayPosition; + origin = worldSpaceHeadPosition; direction = glm::normalize(worldSpaceIntersection - worldSpaceHeadPosition); } @@ -682,7 +679,6 @@ glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) { result.y = (screenPos.y / screenSize.y - 0.5f); result.x *= MOUSE_YAW_RANGE; result.y *= MOUSE_PITCH_RANGE; - return result; } @@ -701,13 +697,13 @@ glm::vec2 ApplicationCompositor::sphericalToOverlay(const glm::vec2& sphericalP result /= _textureFov; result.x /= _textureAspectRatio; result += 0.5f; - result *= qApp->getCanvasSize(); + result *= qApp->getUiSize(); return result; } glm::vec2 ApplicationCompositor::overlayToSpherical(const glm::vec2& overlayPos) const { glm::vec2 result = overlayPos; - result /= qApp->getCanvasSize(); + result /= qApp->getUiSize(); result -= 0.5f; result *= _textureFov; result.x *= _textureAspectRatio; diff --git a/libraries/render-utils/src/OffscreenQmlSurface.cpp b/libraries/render-utils/src/OffscreenQmlSurface.cpp index 3f940d8569..6c68b60f42 100644 --- a/libraries/render-utils/src/OffscreenQmlSurface.cpp +++ b/libraries/render-utils/src/OffscreenQmlSurface.cpp @@ -497,9 +497,7 @@ QPointF OffscreenQmlSurface::mapWindowToUi(const QPointF& sourcePosition, QObjec } QPointF OffscreenQmlSurface::mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget) { - QPointF transformedPos = _mouseTranslator(originalPoint); - transformedPos = mapWindowToUi(transformedPos, originalWidget); - return transformedPos; + return _mouseTranslator(originalPoint); } From dd2aa36a119293baa17ad8b027781a25def23f57 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 6 Oct 2015 23:10:03 -0700 Subject: [PATCH 129/152] FIx the shiny objects by actually using the specular map as it should be... --- libraries/fbx/src/FBXReader_Material.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/fbx/src/FBXReader_Material.cpp b/libraries/fbx/src/FBXReader_Material.cpp index 6da53dbede..e947a0356e 100644 --- a/libraries/fbx/src/FBXReader_Material.cpp +++ b/libraries/fbx/src/FBXReader_Material.cpp @@ -107,6 +107,8 @@ void FBXReader::consolidateFBXMaterials() { if (!specularTextureID.isNull()) { specularTexture = getTexture(specularTextureID); detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity()); + + material.specularTexture = specularTexture; } FBXTexture emissiveTexture; From ad5a6fac626b1c6d5a119842c7c8c622687ce340 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Oct 2015 15:10:40 +0200 Subject: [PATCH 130/152] - applying of new qApp accessing method. - Some magic constant replacements with Helper "glm::vec3(matrix[3])" -> "extractTranslation(matrix)" --- interface/src/avatar/MyAvatar.cpp | 6 +++--- interface/src/scripting/HMDScriptingInterface.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7592aad061..7baa6cf66f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1345,11 +1345,11 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); leftEyePose = leftEyePose * headPose; - glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]); + glm::vec3 leftEyePosition = extractTranslation(leftEyePose); glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right); rightEyePose = rightEyePose * headPose; - glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]); - glm::vec3 headPosition = glm::vec3(headPose[3]); + glm::vec3 rightEyePosition = extractTranslation(rightEyePose); + glm::vec3 headPosition = extractTranslation(headPose); getHead()->renderLookAts(renderArgs, cameraPosition + getOrientation() * (leftEyePosition - headPosition), diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index f8a0ba7ed6..28d358fa39 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -70,14 +70,14 @@ glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { } glm::vec3 HMDScriptingInterface::getPosition() const { - if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + if (qApp->getActiveDisplayPlugin()->isHmd()) { return extractTranslation(getWorldHMDMatrix()); } return glm::vec3(); } glm::quat HMDScriptingInterface::getOrientation() const { - if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + if (qApp->getActiveDisplayPlugin()->isHmd()) { return glm::normalize(glm::quat_cast(getWorldHMDMatrix())); } return glm::quat(); From 4624649b1b66dc1c3f6df7eb88de4b0acb895736 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 7 Oct 2015 08:57:55 -0700 Subject: [PATCH 131/152] Sanitize particle properties, fix crashes --- examples/example/entities/particlesTest.js | 2 +- .../entities/src/EntityItemProperties.cpp | 4 +- .../entities/src/EntityItemPropertiesMacros.h | 4 + .../entities/src/ParticleEffectEntityItem.cpp | 248 +++++++++++++++--- .../entities/src/ParticleEffectEntityItem.h | 58 ++-- 5 files changed, 261 insertions(+), 55 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index bfa4a47ffb..5f2cbc0849 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -28,7 +28,7 @@ FAST_EMIT_SPEED = 1.0, GRAVITY_EMIT_ACCELERATON = { x: 0.0, y: -0.3, z: 0.0 }, ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 }, - PI = 3.141593, + PI = 3.141592, DEG_TO_RAD = PI / 180.0, NUM_PARTICLE_EXAMPLES = 18; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 61e369cf96..3326cde9aa 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -694,7 +694,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(textColor, xColor, setTextColor); COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundColor, xColor, setBackgroundColor); COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(shapeType, ShapeType); - COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles); + COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, quint32, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); @@ -1401,7 +1401,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 731e49b388..659b3bd14c 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -160,6 +160,10 @@ typedef QVector qVectorVec3; typedef QVector qVectorFloat; inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); } inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); } +inline quint32 quint32_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + // Use QString::toUInt() so that isValid is set to false if the number is outside the quint32 range. + return v.toString().toUInt(&isValid); +} inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 40d3853c39..869c39db97 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -1,4 +1,3 @@ - // // ParticleEffectEntityItem.cpp // libraries/entities/src @@ -31,8 +30,6 @@ #include #include -#include - #include #include #include @@ -46,30 +43,56 @@ const glm::vec3 X_AXIS = glm::vec3(1.0f, 0.0f, 0.0f); const glm::vec3 Z_AXIS = glm::vec3(0.0f, 0.0f, 1.0f); +const float SCRIPT_MAXIMUM_PI = 3.1416f; // Round up so that reasonable property values work + const xColor ParticleEffectEntityItem::DEFAULT_COLOR = { 255, 255, 255 }; const xColor ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = DEFAULT_ALPHA; const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = DEFAULT_ALPHA; +const float ParticleEffectEntityItem::MINIMUM_ALPHA = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_ALPHA = 1.0f; const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; const bool ParticleEffectEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; +const quint32 ParticleEffectEntityItem::MINIMUM_MAX_PARTICLES = 1; +const quint32 ParticleEffectEntityItem::MAXIMUM_MAX_PARTICLES = 10000; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; +const float ParticleEffectEntityItem::MINIMUM_LIFESPAN = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_LIFESPAN = 86400.0f; // 1 day const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; +const float ParticleEffectEntityItem::MINIMUM_EMIT_RATE = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_RATE = 1000.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_SPEED = 5.0f; +const float ParticleEffectEntityItem::MINIMUM_EMIT_SPEED = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_SPEED = 1000.0f; // Approx mach 3 const float ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD = 1.0f; const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); // Vertical const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_DIMENSIONS = glm::vec3(0.0f, 0.0f, 0.0f); // Emit from point +const float ParticleEffectEntityItem::MINIMUM_EMIT_DIMENSION = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_DIMENSION = (float)TREE_SCALE; const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitDimensions > 0) +const float ParticleEffectEntityItem::MINIMUM_EMIT_RADIUS_START = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_RADIUS_START = 1.0f; +const float ParticleEffectEntityItem::MINIMUM_POLAR = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_POLAR = SCRIPT_MAXIMUM_PI; const float ParticleEffectEntityItem::DEFAULT_POLAR_START = 0.0f; // Emit along z-axis const float ParticleEffectEntityItem::DEFAULT_POLAR_FINISH = 0.0f; // "" +const float ParticleEffectEntityItem::MINIMUM_AZIMUTH = -SCRIPT_MAXIMUM_PI; +const float ParticleEffectEntityItem::MAXIMUM_AZIMUTH = SCRIPT_MAXIMUM_PI; const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH = PI; // "" const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); +const float ParticleEffectEntityItem::MINIMUM_EMIT_ACCELERATION = -100.0f; // ~ 10g +const float ParticleEffectEntityItem::MAXIMUM_EMIT_ACCELERATION = 100.0f; const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); +const float ParticleEffectEntityItem::MINIMUM_ACCELERATION_SPREAD = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_ACCELERATION_SPREAD = 100.0f; const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; +const float ParticleEffectEntityItem::MINIMUM_PARTICLE_RADIUS = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_PARTICLE_RADIUS = (float)TREE_SCALE; const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS; const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS; @@ -114,37 +137,177 @@ ParticleEffectEntityItem::~ParticleEffectEntityItem() { } +void ParticleEffectEntityItem::setAlpha(float alpha) { + if (MINIMUM_ALPHA <= alpha && alpha <= MAXIMUM_ALPHA) { + _alpha = alpha; + } +} + +void ParticleEffectEntityItem::setAlphaStart(float alphaStart) { + if (MINIMUM_ALPHA <= alphaStart && alphaStart <= MAXIMUM_ALPHA) { + _alphaStart = alphaStart; + _isAlphaStartInitialized = true; + } +} + +void ParticleEffectEntityItem::setAlphaFinish(float alphaFinish) { + if (MINIMUM_ALPHA <= alphaFinish && alphaFinish <= MAXIMUM_ALPHA) { + _alphaFinish = alphaFinish; + _isAlphaFinishInitialized = true; + } +} + +void ParticleEffectEntityItem::setAlphaSpread(float alphaSpread) { + if (MINIMUM_ALPHA <= alphaSpread && alphaSpread <= MAXIMUM_ALPHA) { + _alphaSpread = alphaSpread; + } +} + +void ParticleEffectEntityItem::setLifespan(float lifespan) { + if (MINIMUM_LIFESPAN <= lifespan && lifespan <= MAXIMUM_LIFESPAN) { + _lifespan = lifespan; + } +} + +void ParticleEffectEntityItem::setEmitRate(float emitRate) { + if (MINIMUM_EMIT_RATE <= emitRate && emitRate <= MAXIMUM_EMIT_RATE) { + _emitRate = emitRate; + } +} + void ParticleEffectEntityItem::setEmitSpeed(float emitSpeed) { - _emitSpeed = emitSpeed; - computeAndUpdateDimensions(); + if (MINIMUM_EMIT_SPEED <= emitSpeed && emitSpeed <= MAXIMUM_EMIT_SPEED) { + _emitSpeed = emitSpeed; + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setSpeedSpread(float speedSpread) { - _speedSpread = speedSpread; - computeAndUpdateDimensions(); + if (MINIMUM_EMIT_SPEED <= speedSpread && speedSpread <= MAXIMUM_EMIT_SPEED) { + _speedSpread = speedSpread; + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setEmitOrientation(const glm::quat& emitOrientation) { - _emitOrientation = emitOrientation; + _emitOrientation = glm::normalize(emitOrientation); computeAndUpdateDimensions(); } - void ParticleEffectEntityItem::setEmitDimensions(const glm::vec3& emitDimensions) { - _emitDimensions = emitDimensions; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.x && emitDimensions.x <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.x = emitDimensions.x; + updated = true; + } + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.y && emitDimensions.y <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.y = emitDimensions.y; + updated = true; + } + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.z && emitDimensions.z <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.z = emitDimensions.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } +} + +void ParticleEffectEntityItem::setEmitRadiusStart(float emitRadiusStart) { + if (MINIMUM_EMIT_RADIUS_START <= emitRadiusStart && emitRadiusStart <= MAXIMUM_EMIT_RADIUS_START) { + _emitRadiusStart = emitRadiusStart; + } +} + +void ParticleEffectEntityItem::setPolarStart(float polarStart) { + if (MINIMUM_POLAR <= polarStart && polarStart <= MAXIMUM_POLAR) { + _polarStart = polarStart; + } +} + +void ParticleEffectEntityItem::setPolarFinish(float polarFinish) { + if (MINIMUM_POLAR <= polarFinish && polarFinish <= MAXIMUM_POLAR) { + _polarFinish = polarFinish; + } +} + +void ParticleEffectEntityItem::setAzimuthStart(float azimuthStart) { + if (MINIMUM_AZIMUTH <= azimuthStart && azimuthStart <= MAXIMUM_AZIMUTH) { + _azimuthStart = azimuthStart; + } +} + +void ParticleEffectEntityItem::setAzimuthFinish(float azimuthFinish) { + if (MINIMUM_AZIMUTH <= azimuthFinish && azimuthFinish <= MAXIMUM_AZIMUTH) { + _azimuthFinish = azimuthFinish; + } } void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) { - _emitAcceleration = emitAcceleration; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.x && emitAcceleration.x <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.x = emitAcceleration.x; + updated = true; + } + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.y && emitAcceleration.y <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.y = emitAcceleration.y; + updated = true; + } + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.z && emitAcceleration.z <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.z = emitAcceleration.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setAccelerationSpread(const glm::vec3& accelerationSpread){ - _accelerationSpread = accelerationSpread; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.x && accelerationSpread.x <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.x = accelerationSpread.x; + updated = true; + } + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.y && accelerationSpread.y <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.y = accelerationSpread.y; + updated = true; + } + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.z && accelerationSpread.z <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.z = accelerationSpread.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } } +void ParticleEffectEntityItem::setParticleRadius(float particleRadius) { + if (MINIMUM_PARTICLE_RADIUS <= particleRadius && particleRadius <= MAXIMUM_PARTICLE_RADIUS) { + _particleRadius = particleRadius; + } +} + +void ParticleEffectEntityItem::setRadiusStart(float radiusStart) { + if (MINIMUM_PARTICLE_RADIUS <= radiusStart && radiusStart <= MAXIMUM_PARTICLE_RADIUS) { + _radiusStart = radiusStart; + _isRadiusStartInitialized = true; + } +} + +void ParticleEffectEntityItem::setRadiusFinish(float radiusFinish) { + if (MINIMUM_PARTICLE_RADIUS <= radiusFinish && radiusFinish <= MAXIMUM_PARTICLE_RADIUS) { + _radiusFinish = radiusFinish; + _isRadiusFinishInitialized = true; + } +} + +void ParticleEffectEntityItem::setRadiusSpread(float radiusSpread) { + if (MINIMUM_PARTICLE_RADIUS <= radiusSpread && radiusSpread <= MAXIMUM_PARTICLE_RADIUS) { + _radiusSpread = radiusSpread; + } +} + + void ParticleEffectEntityItem::computeAndUpdateDimensions() { const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error @@ -639,12 +802,12 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _particleLifetimes[i] -= deltaTime; // if particle has died. - if (_particleLifetimes[i] <= 0.0f) { + if (_particleLifetimes[i] <= 0.0f || _lifespan == 0.0f) { // move head forward _particleHeadIndex = (_particleHeadIndex + 1) % _maxParticles; } else { - float age = (1.0f - _particleLifetimes[i] / _lifespan); // 0.0 .. 1.0 + float age = 1.0f - _particleLifetimes[i] / _lifespan; // 0.0 .. 1.0 updateRadius(i, age); updateColor(i, age); updateAlpha(i, age); @@ -654,7 +817,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } // emit new particles, but only if animation is playing - if (getAnimationIsPlaying()) { + if (getAnimationIsPlaying() && _emitRate > 0.0f && _lifespan > 0.0f && _polarStart <= _polarFinish) { float timeLeftInFrame = deltaTime; while (_timeUntilNextEmit < timeLeftInFrame) { @@ -672,10 +835,18 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _radiusMiddles[i] =_particleRadius; _radiusFinishes[i] = getRadiusFinish(); } else { - float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1.0f) * _radiusSpread / _particleRadius; - _radiusStarts[i] = spreadMultiplier * getRadiusStart(); - _radiusMiddles[i] = spreadMultiplier * _particleRadius; - _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); + float spreadMultiplier; + if (_particleRadius > 0.0f) { + spreadMultiplier = 1.0f + randFloatInRange(-1.0f, 1.0f) * _radiusSpread / _particleRadius; + } else { + spreadMultiplier = 1.0f; + } + _radiusStarts[i] = + glm::clamp(spreadMultiplier * getRadiusStart(), MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); + _radiusMiddles[i] = + glm::clamp(spreadMultiplier * _particleRadius, MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); + _radiusFinishes[i] = + glm::clamp(spreadMultiplier * getRadiusFinish(), MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); } updateRadius(i, 0.0f); @@ -684,8 +855,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { // Emit along z-axis from position _particlePositions[i] = getPosition(); _particleVelocities[i] = - (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + (_emitSpeed + randFloatInRange(-1.0f, 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); + _particleAccelerations[i] = _emitAcceleration + randFloatInRange(-1.0f, 1.0f) * _accelerationSpread; } else { // Emit around point or from ellipsoid @@ -701,15 +872,14 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { if (_azimuthFinish >= _azimuthStart) { azimuth = _azimuthStart + (_azimuthFinish - _azimuthStart) * randFloat(); } else { - azimuth = _azimuthStart + (2.0f * PI + _azimuthFinish - _azimuthStart) * randFloat(); + azimuth = _azimuthStart + (TWO_PI + _azimuthFinish - _azimuthStart) * randFloat(); } - + glm::vec3 emitDirection; if (_emitDimensions == glm::vec3()) { // Point - emitDirection = glm::angleAxis(PI_OVER_TWO - elevation, X_AXIS) * Z_AXIS; - emitDirection = glm::angleAxis(azimuth, Z_AXIS) * emitDirection; + emitDirection = glm::quat(glm::vec3(PI_OVER_TWO - elevation, 0.0f, azimuth)) * Z_AXIS; _particlePositions[i] = getPosition(); } else { @@ -717,7 +887,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { float radiusScale = 1.0f; if (_emitRadiusStart < 1.0f) { float emitRadiusStart = glm::max(_emitRadiusStart, EPSILON); // Avoid math complications at center - float randRadius = emitRadiusStart + (1.0f - emitRadiusStart) * randFloat(); + float randRadius = + emitRadiusStart + randFloatInRange(0.0f, MAXIMUM_EMIT_RADIUS_START - emitRadiusStart); radiusScale = 1.0f - std::pow(1.0f - randRadius, 3.0f); } @@ -736,8 +907,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } _particleVelocities[i] = - (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + (_emitSpeed + randFloatInRange(-1.0f, 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); + _particleAccelerations[i] = _emitAcceleration + randFloatInRange(-1.0f, 1.0f) * _accelerationSpread; } integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); @@ -752,10 +923,13 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { xColor middleColor = getXColor(); xColor finishColor = getColorFinish(); - float spread = 2.0f * randFloat() - 1.0f; - float spreadMultiplierRed = 1.0f + spread * (float)_colorSpread.red / (float)middleColor.red; - float spreadMultiplierGreen = 1.0f + spread * (float)_colorSpread.green / (float)middleColor.green; - float spreadMultiplierBlue = 1.0f + spread * (float)_colorSpread.blue / (float)middleColor.blue; + float spread = randFloatInRange(-1.0f, 1.0f); + float spreadMultiplierRed = + middleColor.red > 0 ? 1.0f + spread * (float)_colorSpread.red / (float)middleColor.red : 1.0f; + float spreadMultiplierGreen = + middleColor.green > 0 ? 1.0f + spread * (float)_colorSpread.green / (float)middleColor.green : 1.0f; + float spreadMultiplierBlue = + middleColor.blue > 0 ? 1.0f + spread * (float)_colorSpread.blue / (float)middleColor.blue : 1.0f; _colorStarts[i].red = (int)glm::clamp(spreadMultiplierRed * (float)startColor.red, 0.0f, 255.0f); _colorStarts[i].green = (int)glm::clamp(spreadMultiplierGreen * (float)startColor.green, 0.0f, 255.0f); @@ -777,7 +951,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _alphaMiddles[i] = _alpha; _alphaFinishes[i] = getAlphaFinish(); } else { - float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1) * _alphaSpread / _alpha; + float spreadMultiplier = 1.0f + randFloatInRange(-1.0f, 1.0f) * _alphaSpread / _alpha; _alphaStarts[i] = spreadMultiplier * getAlphaStart(); _alphaMiddles[i] = spreadMultiplier * _alpha; _alphaFinishes[i] = spreadMultiplier * getAlphaFinish(); @@ -799,7 +973,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { - if (_maxParticles != maxParticles) { + if (_maxParticles != maxParticles && MINIMUM_MAX_PARTICLES <= maxParticles && maxParticles <= MAXIMUM_MAX_PARTICLES) { _maxParticles = maxParticles; // TODO: try to do something smart here and preserve the state of existing particles. diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 6d5b8761b0..d4a9da40c6 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -12,6 +12,7 @@ #define hifi_ParticleEffectEntityItem_h #include + #include "EntityItem.h" class ParticleEffectEntityItem : public EntityItem { @@ -68,22 +69,25 @@ public: void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } + static const float MAXIMUM_ALPHA; + static const float MINIMUM_ALPHA; + static const float DEFAULT_ALPHA; - void setAlpha(float alpha) { _alpha = alpha; } + void setAlpha(float alpha); float getAlpha() const { return _alpha; } static const float DEFAULT_ALPHA_START; bool _isAlphaStartInitialized = false; - void setAlphaStart(float alphaStart) { _alphaStart = alphaStart; _isAlphaStartInitialized = true; } + void setAlphaStart(float alphaStart); float getAlphaStart() const { return _isAlphaStartInitialized ? _alphaStart : _alpha; } static const float DEFAULT_ALPHA_FINISH; bool _isAlphaFinishInitialized = false; - void setAlphaFinish(float alphaFinish) { _alphaFinish = alphaFinish; _isAlphaFinishInitialized = true; } + void setAlphaFinish(float alphaFinish); float getAlphaFinish() const { return _isAlphaFinishInitialized ? _alphaFinish : _alpha; } static const float DEFAULT_ALPHA_SPREAD; - void setAlphaSpread(float alphaSpread) { _alphaSpread = alphaSpread; } + void setAlphaSpread(float alphaSpread); float getAlphaSpread() const { return _alphaSpread; } void updateShapeType(ShapeType type); @@ -117,18 +121,26 @@ public: float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } static const quint32 DEFAULT_MAX_PARTICLES; + static const quint32 MINIMUM_MAX_PARTICLES; + static const quint32 MAXIMUM_MAX_PARTICLES; void setMaxParticles(quint32 maxParticles); quint32 getMaxParticles() const { return _maxParticles; } static const float DEFAULT_LIFESPAN; - void setLifespan(float lifespan) { _lifespan = lifespan; } + static const float MINIMUM_LIFESPAN; + static const float MAXIMUM_LIFESPAN; + void setLifespan(float lifespan); float getLifespan() const { return _lifespan; } static const float DEFAULT_EMIT_RATE; - void setEmitRate(float emitRate) { _emitRate = emitRate; } + static const float MINIMUM_EMIT_RATE; + static const float MAXIMUM_EMIT_RATE; + void setEmitRate(float emitRate); float getEmitRate() const { return _emitRate; } static const float DEFAULT_EMIT_SPEED; + static const float MINIMUM_EMIT_SPEED; + static const float MAXIMUM_EMIT_SPEED; void setEmitSpeed(float emitSpeed); float getEmitSpeed() const { return _emitSpeed; } @@ -141,53 +153,69 @@ public: const glm::quat& getEmitOrientation() const { return _emitOrientation; } static const glm::vec3 DEFAULT_EMIT_DIMENSIONS; + static const float MINIMUM_EMIT_DIMENSION; + static const float MAXIMUM_EMIT_DIMENSION; void setEmitDimensions(const glm::vec3& emitDimensions); const glm::vec3& getEmitDimensions() const { return _emitDimensions; } static const float DEFAULT_EMIT_RADIUS_START; - void setEmitRadiusStart(float emitRadiusStart) { _emitRadiusStart = emitRadiusStart; } + static const float MINIMUM_EMIT_RADIUS_START; + static const float MAXIMUM_EMIT_RADIUS_START; + void setEmitRadiusStart(float emitRadiusStart); float getEmitRadiusStart() const { return _emitRadiusStart; } + static const float MINIMUM_POLAR; + static const float MAXIMUM_POLAR; + static const float DEFAULT_POLAR_START; - void setPolarStart(float polarStart) { _polarStart = polarStart; } + void setPolarStart(float polarStart); float getPolarStart() const { return _polarStart; } static const float DEFAULT_POLAR_FINISH; - void setPolarFinish(float polarFinish) { _polarFinish = polarFinish; } + void setPolarFinish(float polarFinish); float getPolarFinish() const { return _polarFinish; } + static const float MINIMUM_AZIMUTH; + static const float MAXIMUM_AZIMUTH; + static const float DEFAULT_AZIMUTH_START; - void setAzimuthStart(float azimuthStart) { _azimuthStart = azimuthStart; } + void setAzimuthStart(float azimuthStart); float getAzimuthStart() const { return _azimuthStart; } static const float DEFAULT_AZIMUTH_FINISH; - void setAzimuthFinish(float azimuthFinish) { _azimuthFinish = azimuthFinish; } + void setAzimuthFinish(float azimuthFinish); float getAzimuthFinish() const { return _azimuthFinish; } static const glm::vec3 DEFAULT_EMIT_ACCELERATION; + static const float MINIMUM_EMIT_ACCELERATION; + static const float MAXIMUM_EMIT_ACCELERATION; void setEmitAcceleration(const glm::vec3& emitAcceleration); const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; } static const glm::vec3 DEFAULT_ACCELERATION_SPREAD; + static const float MINIMUM_ACCELERATION_SPREAD; + static const float MAXIMUM_ACCELERATION_SPREAD; void setAccelerationSpread(const glm::vec3& accelerationSpread); const glm::vec3& getAccelerationSpread() const { return _accelerationSpread; } static const float DEFAULT_PARTICLE_RADIUS; - void setParticleRadius(float particleRadius) { _particleRadius = particleRadius; } + static const float MINIMUM_PARTICLE_RADIUS; + static const float MAXIMUM_PARTICLE_RADIUS; + void setParticleRadius(float particleRadius); float getParticleRadius() const { return _particleRadius; } static const float DEFAULT_RADIUS_START; bool _isRadiusStartInitialized = false; - void setRadiusStart(float radiusStart) { _radiusStart = radiusStart; _isRadiusStartInitialized = true; } + void setRadiusStart(float radiusStart); float getRadiusStart() const { return _isRadiusStartInitialized ? _radiusStart : _particleRadius; } static const float DEFAULT_RADIUS_FINISH; bool _isRadiusFinishInitialized = false; - void setRadiusFinish(float radiusFinish) { _radiusFinish = radiusFinish; _isRadiusFinishInitialized = true; } + void setRadiusFinish(float radiusFinish); float getRadiusFinish() const { return _isRadiusFinishInitialized ? _radiusFinish : _particleRadius; } static const float DEFAULT_RADIUS_SPREAD; - void setRadiusSpread(float radiusSpread) { _radiusSpread = radiusSpread; } + void setRadiusSpread(float radiusSpread); float getRadiusSpread() const { return _radiusSpread; } void computeAndUpdateDimensions(); From 05da9d94cd3b0762d8783c644d548f03655d599c Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 7 Oct 2015 11:20:11 -0700 Subject: [PATCH 132/152] fixing the depth stencil texture case --- libraries/gpu/src/gpu/GLBackendOutput.cpp | 2 +- libraries/gpu/src/gpu/GLBackendTexture.cpp | 41 ++++++++-------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index 70e4b18b0f..2bcd7e31d8 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -109,7 +109,7 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); } else { attachement = GL_DEPTH_STENCIL_ATTACHMENT; - glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachement, GL_RENDERBUFFER, gltexture->_texture); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); } (void) CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index ee5e1d3bc6..7916f1c0d8 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -66,7 +66,7 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_BYTE; + texel.type = GL_UNSIGNED_INT_24_8; texel.format = GL_DEPTH_STENCIL; texel.internalFormat = GL_DEPTH24_STENCIL8; break; @@ -160,8 +160,8 @@ public: } case gpu::FLOAT: { texel.internalFormat = GL_DEPTH_COMPONENT32F; - break; - } + break; + } case gpu::UINT16: case gpu::INT16: case gpu::NUINT16: @@ -199,7 +199,7 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_BYTE; + texel.type = GL_UNSIGNED_INT_24_8; texel.format = GL_DEPTH_STENCIL; texel.internalFormat = GL_DEPTH24_STENCIL8; break; @@ -341,32 +341,19 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { auto semantic = texture.getTexelFormat().getSemantic(); - if (semantic == gpu::DEPTH_STENCIL) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &object->_texture); + glTexImage2D(GL_TEXTURE_2D, 0, + texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, + texelFormat.format, texelFormat.type, bytes); - glGenRenderbuffers(1, &object->_texture); - glBindRenderbuffer(GL_RENDERBUFFER, object->_texture); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, texture.getWidth(), texture.getHeight()); - // At this point the mip pixels have been loaded, we can notify - texture.notifyMipFaceGPULoaded(0, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - } else { - glTexImage2D(GL_TEXTURE_2D, 0, - texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, - texelFormat.format, texelFormat.type, bytes); - - if (bytes && texture.isAutogenerateMips()) { - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - - object->_target = GL_TEXTURE_2D; - - syncSampler(texture.getSampler(), texture.getType(), object); + if (bytes && texture.isAutogenerateMips()) { + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } + object->_target = GL_TEXTURE_2D; + + syncSampler(texture.getSampler(), texture.getType(), object); + // At this point the mip pixels have been loaded, we can notify texture.notifyMipFaceGPULoaded(0, 0); From 6eeb64b03234569b67be21a55c4fa917bb952dfe Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 7 Oct 2015 11:23:24 -0700 Subject: [PATCH 133/152] CR feedback --- examples/html/entityProperties.html | 1 - libraries/animation/src/AnimationHandle.h | 2 +- libraries/animation/src/AnimationLoop.cpp | 8 ++++---- libraries/animation/src/AnimationLoop.h | 1 - libraries/entities/src/ModelEntityItem.h | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 9ea1933dfb..eff4d50b26 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -50,7 +50,6 @@ var properties = {}; properties[group] = {}; properties[group][propertyName] = this.checked; - //debugPrint(" about to emitWebEvent() properties:" + JSON.stringify(properties)); EventBridge.emitWebEvent( JSON.stringify({ type: "update", diff --git a/libraries/animation/src/AnimationHandle.h b/libraries/animation/src/AnimationHandle.h index 4ecbac74d8..cc17a380df 100644 --- a/libraries/animation/src/AnimationHandle.h +++ b/libraries/animation/src/AnimationHandle.h @@ -92,7 +92,7 @@ public: float getLastFrame() const { return _animationLoop.getLastFrame(); } void setRunning(bool running, bool restoreJoints = true); - bool isRunning() const { return _animationLoop.isRunning(); } + bool isRunning() const { return _animationLoop.getRunning(); } void setFrameIndex(float frameIndex) { _animationLoop.setFrameIndex(frameIndex); } float getFrameIndex() const { return _animationLoop.getFrameIndex(); } diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 59b8e7d209..8556128ae8 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -26,7 +26,7 @@ AnimationLoop::AnimationLoop() : _running(false), _frameIndex(0.0f), _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME), - _resetOnRunning(false), + _resetOnRunning(true), _lastSimulated(usecTimestampNow()) { } @@ -40,7 +40,7 @@ AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : _lastFrame(animationDetails.lastFrame), _running(animationDetails.running), _frameIndex(animationDetails.frameIndex), - _resetOnRunning(false), + _resetOnRunning(true), _lastSimulated(usecTimestampNow()) { } @@ -55,7 +55,7 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati _lastFrame(lastFrame), _running(running), _frameIndex(frameIndex), - _resetOnRunning(false), + _resetOnRunning(true), _lastSimulated(usecTimestampNow()) { } @@ -91,7 +91,7 @@ void AnimationLoop::simulate(float deltaTime) { } void AnimationLoop::setStartAutomatically(bool startAutomatically) { - if ((_startAutomatically = startAutomatically) && !isRunning()) { + if ((_startAutomatically = startAutomatically) && !getRunning()) { start(); } } diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 4fa827768e..6e6220310b 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -47,7 +47,6 @@ public: void setResetOnRunning(bool resetOnRunning) { _resetOnRunning = resetOnRunning; } void setRunning(bool running); bool getRunning() const { return _running; } - bool isRunning() const { return _running; } void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); } float getFrameIndex() const { return _frameIndex; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index eece037f2d..83e98c21eb 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -107,7 +107,7 @@ public: void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); bool jointsMapped() const { return _jointMappingCompleted; } - bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } + bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } From 57cc7adbfe8ac4f2c1abc2c24ef5b9ca573bd322 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 7 Oct 2015 12:27:12 -0700 Subject: [PATCH 134/152] standardize somethingChanged - CR feedback --- .../src/RenderableModelEntityItem.cpp | 6 ++-- .../src/RenderableModelEntityItem.h | 3 +- .../src/RenderableZoneEntityItem.cpp | 6 ++-- .../src/RenderableZoneEntityItem.h | 3 +- .../entities/src/AnimationPropertyGroup.cpp | 33 ++----------------- .../entities/src/AnimationPropertyGroup.h | 21 ++---------- .../entities/src/AtmospherePropertyGroup.cpp | 4 ++- .../entities/src/AtmospherePropertyGroup.h | 3 +- libraries/entities/src/BoxEntityItem.cpp | 3 +- libraries/entities/src/BoxEntityItem.h | 3 +- libraries/entities/src/EntityItem.cpp | 3 +- libraries/entities/src/EntityItem.h | 5 +-- .../entities/src/EntityItemPropertiesMacros.h | 1 + libraries/entities/src/EntityTree.cpp | 2 -- libraries/entities/src/LightEntityItem.cpp | 3 +- libraries/entities/src/LightEntityItem.h | 3 +- libraries/entities/src/LineEntityItem.cpp | 4 +-- libraries/entities/src/LineEntityItem.h | 3 +- libraries/entities/src/ModelEntityItem.cpp | 9 +++-- libraries/entities/src/ModelEntityItem.h | 3 +- .../entities/src/ParticleEffectEntityItem.cpp | 3 +- .../entities/src/ParticleEffectEntityItem.h | 3 +- libraries/entities/src/PolyLineEntityItem.cpp | 6 ++-- libraries/entities/src/PolyLineEntityItem.h | 3 +- libraries/entities/src/PolyVoxEntityItem.cpp | 3 +- libraries/entities/src/PolyVoxEntityItem.h | 3 +- libraries/entities/src/PropertyGroup.h | 10 ++---- .../entities/src/SkyboxPropertyGroup.cpp | 4 ++- libraries/entities/src/SkyboxPropertyGroup.h | 3 +- libraries/entities/src/SphereEntityItem.cpp | 3 +- libraries/entities/src/SphereEntityItem.h | 3 +- libraries/entities/src/StagePropertyGroup.cpp | 4 ++- libraries/entities/src/StagePropertyGroup.h | 3 +- libraries/entities/src/TextEntityItem.cpp | 3 +- libraries/entities/src/TextEntityItem.h | 3 +- libraries/entities/src/WebEntityItem.cpp | 3 +- libraries/entities/src/WebEntityItem.h | 3 +- libraries/entities/src/ZoneEntityItem.cpp | 9 ++--- libraries/entities/src/ZoneEntityItem.h | 3 +- 39 files changed, 93 insertions(+), 103 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ed088bc9b5..5627338ebf 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -46,10 +46,12 @@ bool RenderableModelEntityItem::setProperties(const EntityItemProperties& proper int RenderableModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { QString oldModelURL = getModelURL(); int bytesRead = ModelEntityItem::readEntitySubclassDataFromBuffer(data, bytesLeftToRead, - args, propertyFlags, overwriteLocalData); + args, propertyFlags, + overwriteLocalData, somethingChanged); if (oldModelURL != getModelURL()) { _needsModelReload = true; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 509b842c08..9673a378f6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -39,7 +39,8 @@ public: virtual bool setProperties(const EntityItemProperties& properties); virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual void somethingChangedNotification() { // FIX ME: this is overly aggressive. We only really need to simulate() if something about diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index c8088b7406..ff56bef46b 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -61,11 +61,13 @@ bool RenderableZoneEntityItem::setProperties(const EntityItemProperties& propert int RenderableZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; changeProperties([&]() { bytesRead = ZoneEntityItem::readEntitySubclassDataFromBuffer(data, bytesLeftToRead, - args, propertyFlags, overwriteLocalData); + args, propertyFlags, + overwriteLocalData, somethingChanged); }); return bytesRead; } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index f455ea34de..92de136df6 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -30,7 +30,8 @@ public: virtual bool setProperties(const EntityItemProperties& properties); virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual void render(RenderArgs* args); virtual bool contains(const glm::vec3& point) const; diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index f648c4c06e..8b5d64b387 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -212,6 +212,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF int bytesRead = 0; bool overwriteLocalData = true; + bool somethingChanged = false; READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setURL); @@ -320,8 +321,6 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, setStartAutomatically); } - _somethingChanged = somethingChanged; - return somethingChanged; } @@ -375,15 +374,8 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - - float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); - bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); - float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); - float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); - bool loop = _animationLoop ? _animationLoop->getLoop() : getLoop(); - bool hold = _animationLoop ? _animationLoop->getHold() : getHold(); - bool startAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; @@ -411,24 +403,5 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, setStartAutomatically); } - float newFPS = _animationLoop ? _animationLoop->getFPS() : getFPS(); - bool newRunning = _animationLoop ? _animationLoop->getRunning() : getRunning(); - float newFirstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); - float newLastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); - bool newLoop = _animationLoop ? _animationLoop->getLoop() : getLoop(); - bool newHold = _animationLoop ? _animationLoop->getHold() : getHold(); - bool newStartAutomatically = _animationLoop ? _animationLoop->getStartAutomatically() : getStartAutomatically(); - - // NOTE: we don't check frameIndex because that is assumed to always be changing. - _somethingChanged = newFPS != fps || - newRunning != running || - newFirstFrame != firstFrame || - newLastFrame != lastFrame || - newLoop != loop || - newHold != hold || - newStartAutomatically != startAutomatically; - - - return bytesRead; } diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 5612c1a99e..60f57ef491 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -10,24 +10,6 @@ // -// FIXME - TODO -// DONE - 1) make EntityItemProperties support old versions of animation properties -// DONE - 2) rename the group animationSettings -// DONE - 3) make sure that setting properties and reading from stream actually set the animationLoop object properly -// 4) test it! -// DONE - a) toybox/windmill -// DONE - b) toybox "put me down" doll -// c) asana bugs about animations -// d) spray paint can (particles) -// e) grenade -// -// DONE - 5) update all scripts -// DONE - 6) remove all remnants of old member variables -// DONE - 7) research and remove animation settings from Particle Effect -// DONE - 8) make sure animations start properly when entering a domain... with previously running animations -// 9) debug running property -// - #ifndef hifi_AnimationPropertyGroup_h #define hifi_AnimationPropertyGroup_h @@ -88,7 +70,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString); DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float); diff --git a/libraries/entities/src/AtmospherePropertyGroup.cpp b/libraries/entities/src/AtmospherePropertyGroup.cpp index 676a214b81..e24dc5791b 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.cpp +++ b/libraries/entities/src/AtmospherePropertyGroup.cpp @@ -88,6 +88,7 @@ bool AtmospherePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& property int bytesRead = 0; bool overwriteLocalData = true; + bool somethingChanged = false; READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, glm::vec3, setCenter); READ_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, float, setInnerRadius); @@ -194,7 +195,8 @@ void AtmospherePropertyGroup::appendSubclassData(OctreePacketData* packetData, E int AtmospherePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/AtmospherePropertyGroup.h b/libraries/entities/src/AtmospherePropertyGroup.h index 715b923feb..50ed56ef87 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.h +++ b/libraries/entities/src/AtmospherePropertyGroup.h @@ -87,7 +87,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); DEFINE_PROPERTY_REF(PROP_ATMOSPHERE_CENTER, Center, center, glm::vec3); diff --git a/libraries/entities/src/BoxEntityItem.cpp b/libraries/entities/src/BoxEntityItem.cpp index 4f30060207..97a9d77236 100644 --- a/libraries/entities/src/BoxEntityItem.cpp +++ b/libraries/entities/src/BoxEntityItem.cpp @@ -65,7 +65,8 @@ bool BoxEntityItem::setProperties(const EntityItemProperties& properties) { int BoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/BoxEntityItem.h b/libraries/entities/src/BoxEntityItem.h index cc3bba4823..6c1b5b2312 100644 --- a/libraries/entities/src/BoxEntityItem.h +++ b/libraries/entities/src/BoxEntityItem.h @@ -39,7 +39,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index c4f5ad0061..a8f3adc12e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -403,6 +403,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef bool overwriteLocalData = true; // assume the new content overwrites our local data quint64 now = usecTimestampNow(); + bool somethingChanged = false; // _created { @@ -715,7 +716,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData, somethingChanged); //////////////////////////////////// // WARNING: Do not add stream content here after the subclass. Always add it before the subclass diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index d11ffadc75..23892c6fc3 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -179,8 +179,9 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) - { return 0; } + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) + { somethingChanged = false; return 0; } virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges) { return false; } // by default entity items don't add to scene diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 8e0b968fcb..39d8a38380 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -42,6 +42,7 @@ if (overwriteLocalData) { \ S(fromBuffer); \ } \ + somethingChanged = true; \ } #define SKIP_ENTITY_PROPERTY(P,T) \ diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 44183d76de..c4c02d364f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -583,8 +583,6 @@ int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* edi case PacketType::EntityAdd: case PacketType::EntityEdit: { - qCDebug(entities) << "EntityTree::processEditPacketData()... EntityAdd/EntityEdit"; - quint64 startDecode = 0, endDecode = 0; quint64 startLookup = 0, endLookup = 0; quint64 startUpdate = 0, endUpdate = 0; diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 1d2e358799..376b84921a 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -119,7 +119,8 @@ bool LightEntityItem::setProperties(const EntityItemProperties& properties) { int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index 0590955700..9f8d340852 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -41,7 +41,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); const rgbColor& getColor() const { return _color; } xColor getXColor() const { diff --git a/libraries/entities/src/LineEntityItem.cpp b/libraries/entities/src/LineEntityItem.cpp index 856d443a44..ab9b656963 100644 --- a/libraries/entities/src/LineEntityItem.cpp +++ b/libraries/entities/src/LineEntityItem.cpp @@ -121,7 +121,8 @@ bool LineEntityItem::setLinePoints(const QVector& points) { int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; @@ -129,7 +130,6 @@ int LineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth); READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector, setLinePoints); - return bytesRead; } diff --git a/libraries/entities/src/LineEntityItem.h b/libraries/entities/src/LineEntityItem.h index b462cd804c..b20587637f 100644 --- a/libraries/entities/src/LineEntityItem.h +++ b/libraries/entities/src/LineEntityItem.h @@ -39,7 +39,8 @@ class LineEntityItem : public EntityItem { virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 1eafc50141..6f426a539e 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -85,10 +85,12 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) { int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; + bool animationPropertiesChanged = false; READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); @@ -116,7 +118,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() // will automatically read into the animation loop int bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData, animationPropertiesChanged); bytesRead += bytesFromAnimation; dataAt += bytesFromAnimation; @@ -124,8 +126,9 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); - if (_animationProperties.somethingChanged()) { + if (animationPropertiesChanged) { _dirtyFlags |= EntityItem::DIRTY_UPDATEABLE; + somethingChanged = true; } return bytesRead; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 83e98c21eb..cbd54a6acd 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -42,7 +42,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual void update(const quint64& now); virtual bool needsToCallUpdate() const; diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index ace0edb0e1..a0a79996c9 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -246,7 +246,8 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 44cfb76a02..3f8fe5bf51 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -40,7 +40,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual void update(const quint64& now); virtual bool needsToCallUpdate() const; diff --git a/libraries/entities/src/PolyLineEntityItem.cpp b/libraries/entities/src/PolyLineEntityItem.cpp index a01c2ce17b..fbb8250882 100644 --- a/libraries/entities/src/PolyLineEntityItem.cpp +++ b/libraries/entities/src/PolyLineEntityItem.cpp @@ -184,8 +184,10 @@ bool PolyLineEntityItem::setLinePoints(const QVector& points) { int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { - QWriteLocker lock(&_quadReadWriteLock); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { + + QWriteLocker lock(&_quadReadWriteLock); int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/PolyLineEntityItem.h b/libraries/entities/src/PolyLineEntityItem.h index e20a0b1c93..86a1dfb6e0 100644 --- a/libraries/entities/src/PolyLineEntityItem.h +++ b/libraries/entities/src/PolyLineEntityItem.h @@ -39,7 +39,8 @@ class PolyLineEntityItem : public EntityItem { virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 70ae25c65c..368954b891 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -152,7 +152,8 @@ bool PolyVoxEntityItem::setProperties(const EntityItemProperties& properties) { int PolyVoxEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 8a781bf127..9070ad250f 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -39,7 +39,8 @@ class PolyVoxEntityItem : public EntityItem { virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); // never have a ray intersection pick a PolyVoxEntityItem. virtual bool supportsDetailedRayIntersection() const { return true; } diff --git a/libraries/entities/src/PropertyGroup.h b/libraries/entities/src/PropertyGroup.h index d030400993..ea73f8656a 100644 --- a/libraries/entities/src/PropertyGroup.h +++ b/libraries/entities/src/PropertyGroup.h @@ -81,10 +81,6 @@ public: /// has changed. This will be called with properties change or when new data is loaded from a stream virtual void somethingChangedNotification() { } - /// set to true or false after setProperties() and readEntitySubclassDataFromBuffer() if something in the state has changed. - bool somethingChanged() const { return _somethingChanged; } - - virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const = 0; virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, @@ -97,10 +93,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) = 0; - -protected: - bool _somethingChanged = false; + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) = 0; }; #endif // hifi_PropertyGroup_h diff --git a/libraries/entities/src/SkyboxPropertyGroup.cpp b/libraries/entities/src/SkyboxPropertyGroup.cpp index 261e050387..d3ed82274a 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.cpp +++ b/libraries/entities/src/SkyboxPropertyGroup.cpp @@ -56,6 +56,7 @@ bool SkyboxPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlag int bytesRead = 0; bool overwriteLocalData = true; + bool somethingChanged = false; READ_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, xColor, setColor); READ_ENTITY_PROPERTY(PROP_SKYBOX_URL, QString, setURL); @@ -121,7 +122,8 @@ void SkyboxPropertyGroup::appendSubclassData(OctreePacketData* packetData, Encod int SkyboxPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/SkyboxPropertyGroup.h b/libraries/entities/src/SkyboxPropertyGroup.h index 995c87e1db..6e8d4340fe 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.h +++ b/libraries/entities/src/SkyboxPropertyGroup.h @@ -67,7 +67,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); glm::vec3 getColorVec3() const { const quint8 MAX_COLOR = 255; diff --git a/libraries/entities/src/SphereEntityItem.cpp b/libraries/entities/src/SphereEntityItem.cpp index 1d0b2db5b3..3f41ef6d91 100644 --- a/libraries/entities/src/SphereEntityItem.cpp +++ b/libraries/entities/src/SphereEntityItem.cpp @@ -63,7 +63,8 @@ bool SphereEntityItem::setProperties(const EntityItemProperties& properties) { int SphereEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/SphereEntityItem.h b/libraries/entities/src/SphereEntityItem.h index 81a6cf704c..e1e31d4839 100644 --- a/libraries/entities/src/SphereEntityItem.h +++ b/libraries/entities/src/SphereEntityItem.h @@ -38,7 +38,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); const rgbColor& getColor() const { return _color; } xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } diff --git a/libraries/entities/src/StagePropertyGroup.cpp b/libraries/entities/src/StagePropertyGroup.cpp index a8b7705a73..bab68c7a4b 100644 --- a/libraries/entities/src/StagePropertyGroup.cpp +++ b/libraries/entities/src/StagePropertyGroup.cpp @@ -101,6 +101,7 @@ bool StagePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags int bytesRead = 0; bool overwriteLocalData = true; + bool somethingChanged = false; READ_ENTITY_PROPERTY(PROP_STAGE_SUN_MODEL_ENABLED, bool, setSunModelEnabled); READ_ENTITY_PROPERTY(PROP_STAGE_LATITUDE, float, setLatitude); @@ -206,7 +207,8 @@ void StagePropertyGroup::appendSubclassData(OctreePacketData* packetData, Encode int StagePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/StagePropertyGroup.h b/libraries/entities/src/StagePropertyGroup.h index 0f1cbf5a89..208eff479c 100644 --- a/libraries/entities/src/StagePropertyGroup.h +++ b/libraries/entities/src/StagePropertyGroup.h @@ -67,7 +67,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); static const bool DEFAULT_STAGE_SUN_MODEL_ENABLED; static const float DEFAULT_STAGE_LATITUDE; diff --git a/libraries/entities/src/TextEntityItem.cpp b/libraries/entities/src/TextEntityItem.cpp index dec4f4b4da..d19e3be4c9 100644 --- a/libraries/entities/src/TextEntityItem.cpp +++ b/libraries/entities/src/TextEntityItem.cpp @@ -84,7 +84,8 @@ bool TextEntityItem::setProperties(const EntityItemProperties& properties) { int TextEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/TextEntityItem.h b/libraries/entities/src/TextEntityItem.h index 0874651302..d205e9d01e 100644 --- a/libraries/entities/src/TextEntityItem.h +++ b/libraries/entities/src/TextEntityItem.h @@ -43,7 +43,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/entities/src/WebEntityItem.cpp b/libraries/entities/src/WebEntityItem.cpp index d6fc0e2148..496f2b412d 100644 --- a/libraries/entities/src/WebEntityItem.cpp +++ b/libraries/entities/src/WebEntityItem.cpp @@ -68,7 +68,8 @@ bool WebEntityItem::setProperties(const EntityItemProperties& properties) { int WebEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; diff --git a/libraries/entities/src/WebEntityItem.h b/libraries/entities/src/WebEntityItem.h index 7046051b8e..425d89de76 100644 --- a/libraries/entities/src/WebEntityItem.h +++ b/libraries/entities/src/WebEntityItem.h @@ -42,7 +42,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 137ad55303..69357426ed 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -129,7 +129,8 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData) { + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged) { int bytesRead = 0; const unsigned char* dataAt = data; @@ -139,7 +140,7 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_KEYLIGHT_DIRECTION, glm::vec3, setKeyLightDirection); int bytesFromStage = _stageProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData, somethingChanged); bytesRead += bytesFromStage; dataAt += bytesFromStage; @@ -149,13 +150,13 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode); int bytesFromAtmosphere = _atmosphereProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData, somethingChanged); bytesRead += bytesFromAtmosphere; dataAt += bytesFromAtmosphere; int bytesFromSkybox = _skyboxProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData); + propertyFlags, overwriteLocalData, somethingChanged); bytesRead += bytesFromSkybox; dataAt += bytesFromSkybox; diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 96b0f9cbeb..a81cc97c2f 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -43,7 +43,8 @@ public: virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, - EntityPropertyFlags& propertyFlags, bool overwriteLocalData); + EntityPropertyFlags& propertyFlags, bool overwriteLocalData, + bool& somethingChanged); xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; } void setKeyLightColor(const xColor& value) { From 7a85e5b7a7215203cd3d25111d7b1fb54daf9643 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 7 Oct 2015 13:02:58 -0700 Subject: [PATCH 135/152] rename frameIndex to currentFrame --- .../src/avatars/ScriptableAvatar.cpp | 16 ++--- examples/dancing_bot.js | 6 +- examples/entityScripts/portal.js | 4 +- .../ZZZ-MOVE-TO_DOCS-animationStateExample.js | 2 +- .../example/entities/animatedModelExample.js | 2 +- examples/example/entities/butterflies.js | 2 +- examples/html/entityProperties.html | 4 +- examples/libraries/entityPropertyDialogBox.js | 14 ++--- examples/toys/doll/doll.js | 15 ++--- libraries/animation/src/AnimationCache.cpp | 8 +-- libraries/animation/src/AnimationCache.h | 4 +- libraries/animation/src/AnimationHandle.cpp | 16 ++--- libraries/animation/src/AnimationHandle.h | 6 +- libraries/animation/src/AnimationLoop.cpp | 24 ++++---- libraries/animation/src/AnimationLoop.h | 8 +-- .../entities/src/AnimationPropertyGroup.cpp | 59 ++++++++++--------- .../entities/src/AnimationPropertyGroup.h | 2 +- .../entities/src/EntityItemProperties.cpp | 2 +- libraries/entities/src/ModelEntityItem.cpp | 27 +++++---- libraries/entities/src/ModelEntityItem.h | 6 +- 20 files changed, 115 insertions(+), 112 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 36a527009e..161be954ff 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -61,17 +61,17 @@ void ScriptableAvatar::update(float deltatime) { _jointData.resize(modelJoints.size()); } - float frameIndex = _animationDetails.frameIndex + deltatime * _animationDetails.fps; - if (_animationDetails.loop || frameIndex < _animationDetails.lastFrame) { - while (frameIndex >= _animationDetails.lastFrame) { - frameIndex -= (_animationDetails.lastFrame - _animationDetails.firstFrame); + float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps; + if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) { + while (currentFrame >= _animationDetails.lastFrame) { + currentFrame -= (_animationDetails.lastFrame - _animationDetails.firstFrame); } - _animationDetails.frameIndex = frameIndex; + _animationDetails.currentFrame = currentFrame; const int frameCount = _animation->getFrames().size(); - const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(frameIndex) % frameCount); - const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(frameIndex) % frameCount); - const float frameFraction = glm::fract(frameIndex); + const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount); + const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount); + const float frameFraction = glm::fract(currentFrame); for (int i = 0; i < modelJoints.size(); i++) { int mapping = animationJoints.indexOf(modelJoints[i]); diff --git a/examples/dancing_bot.js b/examples/dancing_bot.js index 2c0a35adb7..3e8912074f 100644 --- a/examples/dancing_bot.js +++ b/examples/dancing_bot.js @@ -19,7 +19,7 @@ Agent.isAvatar = true; var jointMapping; -var frameIndex = 0.0; +var currentFrame = 0.0; var FRAME_RATE = 30.0; // frames per second @@ -35,9 +35,9 @@ Script.update.connect(function(deltaTime) { jointMapping[i] = animationJointNames.indexOf(avatarJointNames[i]); } } - frameIndex += deltaTime * FRAME_RATE; + currentFrame += deltaTime * FRAME_RATE; var frames = animation.frames; - var rotations = frames[Math.floor(frameIndex) % frames.length].rotations; + var rotations = frames[Math.floor(currentFrame) % frames.length].rotations; for (var j = 0; j < jointMapping.length; j++) { var rotationIndex = jointMapping[j]; if (rotationIndex != -1) { diff --git a/examples/entityScripts/portal.js b/examples/entityScripts/portal.js index 879c1f9197..7fc195fbee 100644 --- a/examples/entityScripts/portal.js +++ b/examples/entityScripts/portal.js @@ -32,7 +32,7 @@ this.leaveEntity = function(entityID) { Entities.editEntity(entityID, { - animation: { url: animationURL, frameIndex: 1, running: false } + animation: { url: animationURL, currentFrame: 1, running: false } }); playSound(); @@ -40,7 +40,7 @@ this.hoverEnterEntity = function(entityID) { Entities.editEntity(entityID, { - animation: { url: animationURL, fps: 24, firstFrame: 1, lastFrame: 25, frameIndex: 1, running: true, hold: true } + animation: { url: animationURL, fps: 24, firstFrame: 1, lastFrame: 25, currentFrame: 1, running: true, hold: true } }); }; }) \ No newline at end of file diff --git a/examples/example/entities/ZZZ-MOVE-TO_DOCS-animationStateExample.js b/examples/example/entities/ZZZ-MOVE-TO_DOCS-animationStateExample.js index c6987c8626..8e71308768 100644 --- a/examples/example/entities/ZZZ-MOVE-TO_DOCS-animationStateExample.js +++ b/examples/example/entities/ZZZ-MOVE-TO_DOCS-animationStateExample.js @@ -18,7 +18,7 @@ function displayAnimationDetails(deltaTime) { print("count =" + count + " deltaTime=" + deltaTime); count++; var animationDetails = MyAvatar.getAnimationDetailsByRole("idle"); - print("animationDetails.frameIndex=" + animationDetails.frameIndex); + print("animationDetails.currentFrame=" + animationDetails.currentFrame); } function scriptEnding() { diff --git a/examples/example/entities/animatedModelExample.js b/examples/example/entities/animatedModelExample.js index 1e7869559e..5c2e1530aa 100644 --- a/examples/example/entities/animatedModelExample.js +++ b/examples/example/entities/animatedModelExample.js @@ -113,7 +113,7 @@ function moveModel(deltaTime) { if (resetFrame) { print("resetting the frame!"); - newProperties.animation.frameIndex = 0; + newProperties.animation.currentFrame = 0; resetFrame = false; } diff --git a/examples/example/entities/butterflies.js b/examples/example/entities/butterflies.js index 2eac9d6258..3a78a2fc1c 100644 --- a/examples/example/entities/butterflies.js +++ b/examples/example/entities/butterflies.js @@ -89,7 +89,7 @@ function addButterfly() { url: "http://public.highfidelity.io/models/content/butterfly/butterfly.fbx", firstFrame: 0, fps: newFrameRate, - frameIndex: 0, + currentFrame: 0, hold: false, lastFrame: 10000, loop: true, diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index eff4d50b26..268e95010c 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -522,7 +522,7 @@ elModelAnimationURL.value = properties.animation.url; elModelAnimationPlaying.checked = properties.animation.running; elModelAnimationFPS.value = properties.animation.fps; - elModelAnimationFrame.value = properties.animation.frameIndex; + elModelAnimationFrame.value = properties.animation.currentFrame; elModelAnimationFirstFrame.value = properties.animation.firstFrame; elModelAnimationLastFrame.value = properties.animation.lastFrame; elModelAnimationLoop.checked = properties.animation.loop; @@ -777,7 +777,7 @@ elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url')); elModelAnimationPlaying.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation','running')); elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation','fps')); - elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'frameIndex')); + elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'currentFrame')); elModelAnimationFirstFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'firstFrame')); elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame')); elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop')); diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index a9e2e05445..4fd24756e0 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -26,7 +26,7 @@ EntityPropertyDialogBox = (function () { var rescalePercentage; var editModelID = -1; var previousAnimationIsPlaying; - var previousAnimationFrameIndex; + var previousAnimationCurrentFrame; that.cleanup = function () { }; @@ -62,8 +62,8 @@ EntityPropertyDialogBox = (function () { index++; array.push({ label: "Animation FPS:", value: properties.animation.fps }); index++; - array.push({ label: "Animation Frame:", value: properties.animation.frameIndex }); - previousAnimationFrameIndex = properties.animation.frameIndex; + array.push({ label: "Animation Frame:", value: properties.animation.currentFrame }); + previousAnimationCurrentFrame = properties.animation.currentFrame; index++; array.push({ label: "Textures:", value: properties.textures }); index++; @@ -319,11 +319,11 @@ EntityPropertyDialogBox = (function () { properties.animation.fps = array[index++].value; - var newAnimationFrameIndex = array[index++].value; - if (previousAnimationFrameIndex != newAnimationFrameIndex) { - properties.animation.frameIndex = newAnimationFrameIndex; + var newAnimationCurrentFrame = array[index++].value; + if (previousAnimationCurrentFrame != newAnimationCurrentFrame) { + properties.animation.currentFrame = newAnimationCurrentFrame; } else { - delete properties.animation.frameIndex; + delete properties.animation.currentFrame; } properties.textures = array[index++].value; diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 19a7dacda9..8f8a8cd840 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -35,8 +35,10 @@ startNearGrab: function() { Entities.editEntity(this.entityID, { - animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", - animationFrameIndex: 0 + animation: { + url: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", + currentFrame: 0 + } }); Entities.editEntity(_this.entityID, { @@ -65,11 +67,10 @@ if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); Entities.editEntity(this.entityID, { - animationFrameIndex: 0 - }); - - Entities.editEntity(this.entityID, { - animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx" + animation: { + url: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + currentFrame: 0 + } }); this.isGrabbed = false; diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index dfe1f2cbed..bf5ad233d6 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -130,15 +130,15 @@ void Animation::animationParseError(int error, QString str) { AnimationDetails::AnimationDetails() : role(), url(), fps(0.0f), priority(0.0f), loop(false), hold(false), - startAutomatically(false), firstFrame(0.0f), lastFrame(0.0f), running(false), frameIndex(0.0f) + startAutomatically(false), firstFrame(0.0f), lastFrame(0.0f), running(false), currentFrame(0.0f) { } AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float frameIndex) : + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame) : role(role), url(url), fps(fps), priority(priority), loop(loop), hold(hold), startAutomatically(startAutomatically), firstFrame(firstFrame), lastFrame(lastFrame), - running(running), frameIndex(frameIndex) + running(running), currentFrame(currentFrame) { } @@ -155,7 +155,7 @@ QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const Animatio obj.setProperty("firstFrame", details.firstFrame); obj.setProperty("lastFrame", details.lastFrame); obj.setProperty("running", details.running); - obj.setProperty("frameIndex", details.frameIndex); + obj.setProperty("currentFrame", details.currentFrame); return obj; } diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index 3a8fbf3a61..6143d9b42e 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -97,7 +97,7 @@ class AnimationDetails { public: AnimationDetails(); AnimationDetails(QString role, QUrl url, float fps, float priority, bool loop, - bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float frameIndex); + bool hold, bool startAutomatically, float firstFrame, float lastFrame, bool running, float currentFrame); QString role; QUrl url; @@ -109,7 +109,7 @@ public: float firstFrame; float lastFrame; bool running; - float frameIndex; + float currentFrame; }; Q_DECLARE_METATYPE(AnimationDetails); QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event); diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index cee182afc8..93ce3613e7 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -53,7 +53,7 @@ void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) { void AnimationHandle::setRunning(bool running, bool doRestoreJoints) { if (running && isRunning() && (getFadePerSecond() >= 0.0f)) { // if we're already running, this is the same as a restart -- unless we're fading out. - setFrameIndex(getFirstFrame()); + setCurrentFrame(getFirstFrame()); return; } _animationLoop.setRunning(running); @@ -82,7 +82,7 @@ AnimationHandle::AnimationHandle(RigPointer rig) : AnimationDetails AnimationHandle::getAnimationDetails() const { AnimationDetails details(_role, _url, getFPS(), _priority, getLoop(), getHold(), - getStartAutomatically(), getFirstFrame(), getLastFrame(), isRunning(), getFrameIndex()); + getStartAutomatically(), getFirstFrame(), getLastFrame(), isRunning(), getCurrentFrame()); return details; } @@ -97,7 +97,7 @@ void AnimationHandle::setAnimationDetails(const AnimationDetails& details) { setFirstFrame(details.firstFrame); setLastFrame(details.lastFrame); setRunning(details.running); - setFrameIndex(details.frameIndex); + setCurrentFrame(details.currentFrame); // NOTE: AnimationDetails doesn't support maskedJoints //setMaskedJoints(const QStringList& maskedJoints); @@ -160,19 +160,19 @@ void AnimationHandle::simulate(float deltaTime) { } // blend between the closest two frames - applyFrame(getFrameIndex()); + applyFrame(getCurrentFrame()); } -void AnimationHandle::applyFrame(float frameIndex) { +void AnimationHandle::applyFrame(float currentFrame) { if (!_animation || !_animation->isLoaded()) { return; } const FBXGeometry& animationGeometry = _animation->getGeometry(); int frameCount = animationGeometry.animationFrames.size(); - const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(frameIndex) % frameCount); - const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at((int)glm::ceil(frameIndex) % frameCount); - float frameFraction = glm::fract(frameIndex); + const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(currentFrame) % frameCount); + const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at((int)glm::ceil(currentFrame) % frameCount); + float frameFraction = glm::fract(currentFrame); for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); diff --git a/libraries/animation/src/AnimationHandle.h b/libraries/animation/src/AnimationHandle.h index cc17a380df..7492d3fa48 100644 --- a/libraries/animation/src/AnimationHandle.h +++ b/libraries/animation/src/AnimationHandle.h @@ -94,8 +94,8 @@ public: void setRunning(bool running, bool restoreJoints = true); bool isRunning() const { return _animationLoop.getRunning(); } - void setFrameIndex(float frameIndex) { _animationLoop.setFrameIndex(frameIndex); } - float getFrameIndex() const { return _animationLoop.getFrameIndex(); } + void setCurrentFrame(float currentFrame) { _animationLoop.setCurrentFrame(currentFrame); } + float getCurrentFrame() const { return _animationLoop.getCurrentFrame(); } AnimationDetails getAnimationDetails() const; void setAnimationDetails(const AnimationDetails& details); @@ -103,7 +103,7 @@ public: void setJointMappings(QVector jointMappings); QVector getJointMappings(); // computing if necessary void simulate(float deltaTime); - void applyFrame(float frameIndex); + void applyFrame(float currentFrame); void replaceMatchingPriorities(float newPriority); void restoreJoints(); void clearJoints() { _jointMappings.clear(); } diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 8556128ae8..1e04af5dfa 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -24,7 +24,7 @@ AnimationLoop::AnimationLoop() : _firstFrame(0.0f), _lastFrame(MAXIMUM_POSSIBLE_FRAME), _running(false), - _frameIndex(0.0f), + _currentFrame(0.0f), _maxFrameIndexHint(MAXIMUM_POSSIBLE_FRAME), _resetOnRunning(true), _lastSimulated(usecTimestampNow()) @@ -39,14 +39,14 @@ AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : _firstFrame(animationDetails.firstFrame), _lastFrame(animationDetails.lastFrame), _running(animationDetails.running), - _frameIndex(animationDetails.frameIndex), + _currentFrame(animationDetails.currentFrame), _resetOnRunning(true), _lastSimulated(usecTimestampNow()) { } AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame, - float lastFrame, bool running, float frameIndex) : + float lastFrame, bool running, float currentFrame) : _fps(fps), _loop(loop), _hold(hold), @@ -54,7 +54,7 @@ AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomati _firstFrame(firstFrame), _lastFrame(lastFrame), _running(running), - _frameIndex(frameIndex), + _currentFrame(currentFrame), _resetOnRunning(true), _lastSimulated(usecTimestampNow()) { @@ -67,25 +67,25 @@ void AnimationLoop::simulateAtTime(quint64 now) { } void AnimationLoop::simulate(float deltaTime) { - _frameIndex += deltaTime * _fps; + _currentFrame += deltaTime * _fps; // If we knew the number of frames from the animation, we'd consider using it here // animationGeometry.animationFrames.size() float maxFrame = _maxFrameIndexHint; float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f)); float startFrameIndex = qMin(_firstFrame, endFrameIndex); - if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) { + if ((!_loop && (_currentFrame < startFrameIndex || _currentFrame > endFrameIndex)) || startFrameIndex == endFrameIndex) { // passed the end; apply the last frame - _frameIndex = glm::clamp(_frameIndex, startFrameIndex, endFrameIndex); + _currentFrame = glm::clamp(_currentFrame, startFrameIndex, endFrameIndex); if (!_hold) { stop(); } } else { // wrap within the the desired range - if (_frameIndex < startFrameIndex) { - _frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex); - } else if (_frameIndex > endFrameIndex) { - _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); + if (_currentFrame < startFrameIndex) { + _currentFrame = endFrameIndex - glm::mod(endFrameIndex - _currentFrame, endFrameIndex - startFrameIndex); + } else if (_currentFrame > endFrameIndex) { + _currentFrame = startFrameIndex + glm::mod(_currentFrame - startFrameIndex, endFrameIndex - startFrameIndex); } } } @@ -104,7 +104,7 @@ void AnimationLoop::setRunning(bool running) { // If we just set running to true, then also reset the frame to the first frame if (running && (_resetOnRunning)) { // move back to the beginning - _frameIndex = _firstFrame; + _currentFrame = _firstFrame; } // If we just started running, set our diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 6e6220310b..10664c47e7 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -21,7 +21,7 @@ public: AnimationLoop(); AnimationLoop(const AnimationDetails& animationDetails); AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame, - float lastFrame, bool running, float frameIndex); + float lastFrame, bool running, float currentFrame); void setFPS(float fps) { _fps = fps; } float getFPS() const { return _fps; } @@ -48,8 +48,8 @@ public: void setRunning(bool running); bool getRunning() const { return _running; } - void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); } - float getFrameIndex() const { return _frameIndex; } + void setCurrentFrame(float currentFrame) { _currentFrame = glm::clamp(currentFrame, _firstFrame, _lastFrame); } + float getCurrentFrame() const { return _currentFrame; } void setMaxFrameIndexHint(float value) { _maxFrameIndexHint = glm::clamp(value, 0.0f, MAXIMUM_POSSIBLE_FRAME); } float getMaxFrameIndexHint() const { return _maxFrameIndexHint; } @@ -68,7 +68,7 @@ private: float _firstFrame; float _lastFrame; bool _running; - float _frameIndex; + float _currentFrame; float _maxFrameIndexHint; bool _resetOnRunning; quint64 _lastSimulated; diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 8b5d64b387..3c22707869 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -35,7 +35,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire if (_animationLoop) { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FPS, Animation, animation, FPS, fps, _animationLoop->getFPS); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex, _animationLoop->getFPS); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame, _animationLoop->getFPS); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_PLAYING, Animation, animation, Running, running, _animationLoop->getRunning); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop, _animationLoop->getLoop); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame, _animationLoop->getFirstFrame); @@ -44,7 +44,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ANIMATION_START_AUTOMATICALLY, Animation, animation, StartAutomatically, startAutomatically, _animationLoop->getStartAutomatically); } else { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); - COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); + COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_PLAYING, Animation, animation, Running, running); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); @@ -64,7 +64,7 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo if (_animationLoop) { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, _animationLoop->setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, _animationLoop->setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, _animationLoop->setCurrentFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, _animationLoop->setRunning); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, _animationLoop->setLoop); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, _animationLoop->setFirstFrame); @@ -75,11 +75,11 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, _animationLoop->setFPS, _animationLoop->getFPS); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, _animationLoop->setRunning, _animationLoop->getRunning); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setFrameIndex, _animationLoop->getFrameIndex); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, _animationLoop->setCurrentFrame, _animationLoop->getCurrentFrame); } else { COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, fps, float, setFPS); - COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, frameIndex, float, setFrameIndex); + COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, currentFrame, float, setCurrentFrame); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, running, bool, setRunning); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, loop, bool, setLoop); COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame); @@ -90,18 +90,18 @@ void AnimationPropertyGroup::copyFromScriptValue(const QScriptValue& object, boo // legacy property support COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS); COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationIsPlaying, bool, setRunning, getRunning); - COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setFrameIndex, getFrameIndex); + COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFrameIndex, float, setCurrentFrame, getCurrentFrame); } } void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and + // if it includes fps, currentFrame, or running, those values will be parsed out and // will over ride the regular animation settings float fps = _animationLoop ? _animationLoop->getFPS() : getFPS(); - float frameIndex = _animationLoop ? _animationLoop->getFrameIndex() : getFrameIndex(); + float currentFrame = _animationLoop ? _animationLoop->getCurrentFrame() : getCurrentFrame(); bool running = _animationLoop ? _animationLoop->getRunning() : getRunning(); float firstFrame = _animationLoop ? _animationLoop->getFirstFrame() : getFirstFrame(); float lastFrame = _animationLoop ? _animationLoop->getLastFrame() : getLastFrame(); @@ -117,8 +117,9 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { fps = settingsMap["fps"].toFloat(); } + // old settings had frameIndex if (settingsMap.contains("frameIndex")) { - frameIndex = settingsMap["frameIndex"].toFloat(); + currentFrame = settingsMap["frameIndex"].toFloat(); } if (settingsMap.contains("running")) { @@ -126,11 +127,11 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { } if (settingsMap.contains("firstFrame")) { - frameIndex = settingsMap["firstFrame"].toFloat(); + firstFrame = settingsMap["firstFrame"].toFloat(); } if (settingsMap.contains("lastFrame")) { - frameIndex = settingsMap["lastFrame"].toFloat(); + lastFrame = settingsMap["lastFrame"].toFloat(); } if (settingsMap.contains("loop")) { @@ -147,7 +148,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { if (_animationLoop) { _animationLoop->setFPS(fps); - _animationLoop->setFrameIndex(frameIndex); + _animationLoop->setCurrentFrame(currentFrame); _animationLoop->setRunning(running); _animationLoop->setFirstFrame(firstFrame); _animationLoop->setLastFrame(lastFrame); @@ -156,7 +157,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) { _animationLoop->setStartAutomatically(startAutomatically); } else { setFPS(fps); - setFrameIndex(frameIndex); + setCurrentFrame(currentFrame); setRunning(running); setFirstFrame(firstFrame); setLastFrame(lastFrame); @@ -171,7 +172,7 @@ void AnimationPropertyGroup::debugDump() const { qDebug() << " AnimationPropertyGroup: ---------------------------------------------"; qDebug() << " url:" << getURL() << " has changed:" << urlChanged(); qDebug() << " fps:" << getFPS() << " has changed:" << fpsChanged(); - qDebug() << "frameIndex:" << getFrameIndex() << " has changed:" << frameIndexChanged(); + qDebug() << "currentFrame:" << getCurrentFrame() << " has changed:" << currentFrameChanged(); } bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, @@ -186,7 +187,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); @@ -195,7 +196,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); @@ -218,7 +219,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF if (_animationLoop) { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); @@ -227,7 +228,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); @@ -238,7 +239,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FPS, FPS); - DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, FrameIndex); + DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FRAME_INDEX, CurrentFrame); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_PLAYING, Running); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LOOP, Loop); DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame); @@ -254,7 +255,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF void AnimationPropertyGroup::markAllChanged() { _urlChanged = true; _fpsChanged = true; - _frameIndexChanged = true; + _currentFrameChanged = true; _runningChanged = true; } @@ -263,7 +264,7 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, url); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, fps); - CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, frameIndex); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, currentFrame); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, running); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LOOP, loop); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame); @@ -278,7 +279,7 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, URL, getURL); if (_animationLoop) { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, _animationLoop->getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, _animationLoop->getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, _animationLoop->getCurrentFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, _animationLoop->getRunning); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, _animationLoop->getLoop); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, _animationLoop->getFirstFrame); @@ -287,7 +288,7 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, StartAutomatically, _animationLoop->getStartAutomatically); } else { COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FPS, getFPS); - COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FrameIndex, getFrameIndex); + COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, CurrentFrame, getCurrentFrame); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Running, getRunning); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Loop, getLoop); COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame); @@ -303,7 +304,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, URL, url, setURL); if (_animationLoop) { SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, _animationLoop->setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, _animationLoop->setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, _animationLoop->setCurrentFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, _animationLoop->setRunning); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, _animationLoop->setLoop); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, _animationLoop->setFirstFrame); @@ -312,7 +313,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, StartAutomatically, startAutomatically, _animationLoop->setStartAutomatically); } else { SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FPS, fps, setFPS); - SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FrameIndex, frameIndex, setFrameIndex); + SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, CurrentFrame, currentFrame, setCurrentFrame); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Running, running, setRunning); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Loop, loop, setLoop); SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame); @@ -353,7 +354,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_URL, getURL()); if (_animationLoop) { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, _animationLoop->getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, _animationLoop->getCurrentFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, _animationLoop->getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, _animationLoop->getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, _animationLoop->getFirstFrame()); @@ -362,7 +363,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En APPEND_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, _animationLoop->getStartAutomatically()); } else { APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FPS, getFPS()); - APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getFrameIndex()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, getCurrentFrame()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, getRunning()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, getLoop()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame()); @@ -385,7 +386,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char if (_animationLoop) { // apply new properties to our associated AnimationLoop READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationLoop->setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationLoop->setCurrentFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationLoop->setRunning); READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, _animationLoop->setLoop); READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, _animationLoop->setFirstFrame); @@ -394,7 +395,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char READ_ENTITY_PROPERTY(PROP_ANIMATION_START_AUTOMATICALLY, bool, _animationLoop->setStartAutomatically); } else { READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setCurrentFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setRunning); READ_ENTITY_PROPERTY(PROP_ANIMATION_LOOP, bool, setLoop); READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame); diff --git a/libraries/entities/src/AnimationPropertyGroup.h b/libraries/entities/src/AnimationPropertyGroup.h index 60f57ef491..76782a85cd 100644 --- a/libraries/entities/src/AnimationPropertyGroup.h +++ b/libraries/entities/src/AnimationPropertyGroup.h @@ -75,7 +75,7 @@ public: DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, URL, url, QString); DEFINE_PROPERTY(PROP_ANIMATION_FPS, FPS, fps, float); - DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, FrameIndex, frameIndex, float); + DEFINE_PROPERTY(PROP_ANIMATION_FRAME_INDEX, CurrentFrame, currentFrame, float); DEFINE_PROPERTY(PROP_ANIMATION_PLAYING, Running, running, bool); // was animationIsPlaying DEFINE_PROPERTY(PROP_ANIMATION_LOOP, Loop, loop, bool); // was animationSettings.loop DEFINE_PROPERTY(PROP_ANIMATION_FIRST_FRAME, FirstFrame, firstFrame, float); // was animationSettings.firstFrame diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 387032f58c..b17ca41e9b 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -823,7 +823,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_URL, Animation, animation, URL, url); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FPS, Animation, animation, FPS, fps); - ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, Animation, animation, FrameIndex, frameIndex); + ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_PLAYING, Animation, animation, Running, running); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop); ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 6f426a539e..bcf2318a0d 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -36,7 +36,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI _type = EntityTypes::Model; setProperties(properties); _jointMappingCompleted = false; - _lastKnownFrameIndex = -1; + _lastKnownCurrentFrame = -1; _color[0] = _color[1] = _color[2] = 0; } @@ -106,7 +106,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setAnimationURL); READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationCurrentFrame); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); } @@ -226,17 +226,17 @@ void ModelEntityItem::getAnimationFrame(bool& newFrame, int frameCount = frames.size(); if (frameCount > 0) { - int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; - if (animationFrameIndex < 0 || animationFrameIndex > frameCount) { - animationFrameIndex = 0; + int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; + if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) { + animationCurrentFrame = 0; } - if (animationFrameIndex != _lastKnownFrameIndex) { - _lastKnownFrameIndex = animationFrameIndex; + if (animationCurrentFrame != _lastKnownCurrentFrame) { + _lastKnownCurrentFrame = animationCurrentFrame; newFrame = true; - const QVector& rotations = frames[animationFrameIndex].rotations; - const QVector& translations = frames[animationFrameIndex].translations; + const QVector& rotations = frames[animationCurrentFrame].rotations; + const QVector& translations = frames[animationCurrentFrame].translations; _lastKnownFrameDataRotations.resize(_jointMapping.size()); _lastKnownFrameDataTranslations.resize(_jointMapping.size()); @@ -327,7 +327,7 @@ void ModelEntityItem::setAnimationURL(const QString& url) { void ModelEntityItem::setAnimationSettings(const QString& value) { // the animations setting is a JSON string that may contain various animation settings. - // if it includes fps, frameIndex, or running, those values will be parsed out and + // if it includes fps, currentFrame, or running, those values will be parsed out and // will over ride the regular animation settings QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); @@ -338,8 +338,9 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { setAnimationFPS(fps); } + // old settings used frameIndex if (settingsMap.contains("frameIndex")) { - float frameIndex = settingsMap["frameIndex"].toFloat(); + float currentFrame = settingsMap["frameIndex"].toFloat(); #ifdef WANT_DEBUG if (isAnimatingSomething()) { qCDebug(entities) << "ModelEntityItem::setAnimationSettings() calling setAnimationFrameIndex()..."; @@ -347,11 +348,11 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { qCDebug(entities) << " animation URL:" << getAnimationURL(); qCDebug(entities) << " settings:" << value; qCDebug(entities) << " settingsMap[frameIndex]:" << settingsMap["frameIndex"]; - qCDebug(entities" frameIndex: %20.5f", frameIndex); + qCDebug(entities" currentFrame: %20.5f", currentFrame); } #endif - setAnimationFrameIndex(frameIndex); + setAnimationCurrentFrame(currentFrame); } if (settingsMap.contains("running")) { diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index cbd54a6acd..187cad48eb 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -85,7 +85,7 @@ public: const QString& getAnimationURL() const { return _animationProperties.getURL(); } void setAnimationURL(const QString& url); - void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); } + void setAnimationCurrentFrame(float value) { _animationLoop.setCurrentFrame(value); } void setAnimationIsPlaying(bool value); void setAnimationFPS(float value); @@ -109,7 +109,7 @@ public: bool jointsMapped() const { return _jointMappingCompleted; } bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } - float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } + float getAnimationCurrentFrame() const { return _animationLoop.getCurrentFrame(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } static const QString DEFAULT_TEXTURES; @@ -126,7 +126,7 @@ private: protected: QVector _lastKnownFrameDataRotations; QVector _lastKnownFrameDataTranslations; - int _lastKnownFrameIndex; + int _lastKnownCurrentFrame; bool isAnimatingSomething() const; From b09ae1755e50041ad7ea7614c02fcb213812a064 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 7 Oct 2015 13:59:00 -0700 Subject: [PATCH 136/152] fix formatting of macros --- .../entities/src/EntityItemPropertiesMacros.h | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 39d8a38380..eb9a75259d 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -132,17 +132,17 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) properties.setProperty(#g, groupProperties); \ } -#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(X,G,g,P,p,M) \ - if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ - (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ - QScriptValue groupProperties = properties.property(#g); \ - if (!groupProperties.isValid()) { \ - groupProperties = engine->newObject(); \ - } \ - QScriptValue V = convertScriptValue(engine, M()); \ - groupProperties.setProperty(#p, V); \ - properties.setProperty(#g, groupProperties); \ - } +#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_GETTER(X,G,g,P,p,M) \ + if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \ + (!skipDefaults || defaultEntityProperties.get##G().get##P() != get##P())) { \ + QScriptValue groupProperties = properties.property(#g); \ + if (!groupProperties.isValid()) { \ + groupProperties = engine->newObject(); \ + } \ + QScriptValue V = convertScriptValue(engine, M()); \ + groupProperties.setProperty(#p, V); \ + properties.setProperty(#g, groupProperties); \ + } #define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \ if ((_desiredProperties.isEmpty() || _desiredProperties.getHasProperty(p)) && \ @@ -165,7 +165,7 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) if (!skipDefaults || defaultEntityProperties._##P != _##P) { \ QScriptValue V = convertScriptValue(engine, G); \ properties.setProperty(#P, V); \ - } + } typedef glm::vec3 glmVec3; typedef glm::quat glmQuat; @@ -266,55 +266,55 @@ inline xColor xColor_convertFromScriptValue(const QScriptValue& v, bool& isValid } -#define COPY_PROPERTY_FROM_QSCRIPTVALUE(P, T, S) \ - { \ - QScriptValue V = object.property(#P); \ - if (V.isValid()) { \ - bool isValid = false; \ - T newValue = T##_convertFromScriptValue(V, isValid); \ +#define COPY_PROPERTY_FROM_QSCRIPTVALUE(P, T, S) \ + { \ + QScriptValue V = object.property(#P); \ + if (V.isValid()) { \ + bool isValid = false; \ + T newValue = T##_convertFromScriptValue(V, isValid); \ if (isValid && (_defaultSettings || newValue != _##P)) { \ - S(newValue); \ - } \ - } \ + S(newValue); \ + } \ + } \ } -#define COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(P, T, S, G) \ -{ \ - QScriptValue V = object.property(#P); \ - if (V.isValid()) { \ - bool isValid = false; \ - T newValue = T##_convertFromScriptValue(V, isValid); \ +#define COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(P, T, S, G) \ +{ \ + QScriptValue V = object.property(#P); \ + if (V.isValid()) { \ + bool isValid = false; \ + T newValue = T##_convertFromScriptValue(V, isValid); \ if (isValid && (_defaultSettings || newValue != G())) { \ - S(newValue); \ - } \ - }\ + S(newValue); \ + } \ + } \ } -#define COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(P, T, S) \ -{ \ - QScriptValue V = object.property(#P); \ - if (V.isValid()) { \ - bool isValid = false; \ +#define COPY_PROPERTY_FROM_QSCRIPTVALUE_NOCHECK(P, T, S) \ +{ \ + QScriptValue V = object.property(#P); \ + if (V.isValid()) { \ + bool isValid = false; \ T newValue = T##_convertFromScriptValue(V, isValid); \ - if (isValid && (_defaultSettings)) { \ - S(newValue); \ - } \ - }\ + if (isValid && (_defaultSettings)) { \ + S(newValue); \ + } \ + } \ } -#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(G, P, T, S) \ - { \ - QScriptValue G = object.property(#G); \ - if (G.isValid()) { \ - QScriptValue V = G.property(#P); \ - if (V.isValid()) { \ - bool isValid = false; \ - T newValue = T##_convertFromScriptValue(V, isValid); \ +#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(G, P, T, S) \ + { \ + QScriptValue G = object.property(#G); \ + if (G.isValid()) { \ + QScriptValue V = G.property(#P); \ + if (V.isValid()) { \ + bool isValid = false; \ + T newValue = T##_convertFromScriptValue(V, isValid); \ if (isValid && (_defaultSettings || newValue != _##P)) { \ - S(newValue); \ - } \ - } \ - } \ + S(newValue); \ + } \ + } \ + } \ } #define COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(P, S) \ @@ -330,12 +330,12 @@ inline xColor xColor_convertFromScriptValue(const QScriptValue& v, bool& isValid _##n(V), \ _##n##Changed(false) -#define DEFINE_PROPERTY_GROUP(N, n, T) \ - public: \ +#define DEFINE_PROPERTY_GROUP(N, n, T) \ + public: \ const T& get##N() const { return _##n; } \ - T& get##N() { return _##n; } \ - private: \ - T _##n; \ + T& get##N() { return _##n; } \ + private: \ + T _##n; \ static T _static##N; #define ADD_PROPERTY_TO_MAP(P, N, n, T) \ From 6c2a94fddb1be1cde5885c3c0c8dcfa1b540ab85 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:23:53 -0700 Subject: [PATCH 137/152] remove unused method declarations --- libraries/animation/src/Rig.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index ef802e925d..6d9f7b4688 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -132,7 +132,6 @@ public: bool getJointStateTranslation(int index, glm::vec3& translation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority); JointState getJointState(int jointIndex) const; // XXX - bool getVisibleJointState(int index, glm::quat& rotation) const; void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); @@ -154,9 +153,6 @@ public: bool getJointRotation(int jointIndex, glm::quat& rotation) const; bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; - bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position, - glm::vec3 translation, glm::quat rotation) const; - bool getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result, glm::quat rotation) const; glm::mat4 getJointTransform(int jointIndex) const; glm::mat4 getJointVisibleTransform(int jointIndex) const; void setJointVisibleTransform(int jointIndex, glm::mat4 newTransform); @@ -179,7 +175,6 @@ public: float priority, float mix = 1.0f); bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; glm::quat getJointDefaultRotationInParentFrame(int jointIndex); - void updateVisibleJointStates(); void clearJointStatePriorities(); virtual void updateJointState(int index, glm::mat4 rootTransform) = 0; From 76264ae704ab962fbc40875370e83fc252ce02a9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:24:27 -0700 Subject: [PATCH 138/152] fix formatting --- libraries/physics/src/DynamicCharacterController.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/libraries/physics/src/DynamicCharacterController.cpp index 163cba6aae..604326168c 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/libraries/physics/src/DynamicCharacterController.cpp @@ -35,9 +35,8 @@ public: if (rayResult.m_collisionObject == _me) { return 1.0f; } - return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace - ); -} + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); + } protected: btRigidBody* _me; }; From 0680be0422d1d30548448ecb9407a9167967513b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:25:05 -0700 Subject: [PATCH 139/152] save sixense settings and some UI cleanup --- interface/src/Application.cpp | 1 + interface/src/ui/PreferencesDialog.cpp | 5 -- interface/ui/preferencesDialog.ui | 34 -------- .../src/input-plugins/InputPlugin.cpp | 6 ++ .../src/input-plugins/SixenseManager.cpp | 47 ++++++++--- .../src/input-plugins/SixenseManager.h | 19 ++--- libraries/plugins/src/plugins/Plugin.cpp | 2 + libraries/plugins/src/plugins/Plugin.h | 12 +++ .../plugins/src/plugins/PluginManager.cpp | 6 ++ libraries/plugins/src/plugins/PluginManager.h | 1 + libraries/shared/src/SettingHandle.cpp | 83 +++++++++++++++++++ libraries/shared/src/SettingHandle.h | 15 +++- 12 files changed, 168 insertions(+), 63 deletions(-) create mode 100644 libraries/shared/src/SettingHandle.cpp diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 70cc189ad6..5f61c6d978 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2351,6 +2351,7 @@ void Application::saveSettings() { Menu::getInstance()->saveSettings(); getMyAvatar()->saveData(); + PluginManager::getInstance()->saveSettings(); } bool Application::importEntities(const QString& urlOrFilename) { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index f90bac234d..4ba248c76c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -200,9 +200,6 @@ void PreferencesDialog::loadPreferences() { ui.sixenseReticleMoveSpeedSpin->setValue(InputDevice::getReticleMoveSpeed()); - SixenseManager& sixense = SixenseManager::getInstance(); - ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons()); - // LOD items auto lodManager = DependencyManager::get(); ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS()); @@ -276,9 +273,7 @@ void PreferencesDialog::savePreferences() { qApp->getApplicationCompositor().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value()); - SixenseManager& sixense = SixenseManager::getInstance(); InputDevice::setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); - sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked()); auto audio = DependencyManager::get(); MixedProcessedAudioStream& stream = audio->getReceivedAudioStream(); diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 53b71fb507..a1137a2bf2 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -2768,40 +2768,6 @@ - - - - 7 - - - 7 - - - - - - 0 - 40 - - - - - Arial - - - - Invert Mouse Buttons - - - - 0 - 0 - - - - - - diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index ea1639ec66..227bd12e1b 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -37,3 +37,9 @@ InputPluginList getInputPlugins() { } return result; } + +void saveInputPluginSettings(const InputPluginList& plugins) { + foreach (auto inputPlugin, plugins) { + inputPlugin->saveSettings(); + } +} diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index e900e8779e..bc64ec4ccc 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "NumericalConstants.h" @@ -38,7 +39,7 @@ const unsigned int RIGHT_MASK = 1U << 1; #ifdef HAVE_SIXENSE const int CALIBRATION_STATE_IDLE = 0; -const int CALIBRATION_STATE_X = 1; +const int CALIBRATION_STATE_IN_PROGRESS = 1; const int CALIBRATION_STATE_COMPLETE = 2; const glm::vec3 DEFAULT_AVATAR_POSITION(-0.25f, -0.35f, -0.3f); // in hydra frame @@ -56,25 +57,23 @@ typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData #endif const QString SixenseManager::NAME = "Sixense"; +const QString SixenseManager::HYDRA_ID_STRING = "Razer Hydra"; const QString MENU_PARENT = "Avatar"; const QString MENU_NAME = "Sixense"; const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; const QString TOGGLE_SMOOTH = "Smooth Sixense Movement"; +const float DEFAULT_REACH_LENGTH = 1.5f; -SixenseManager& SixenseManager::getInstance() { - static SixenseManager sharedInstance; - return sharedInstance; -} SixenseManager::SixenseManager() : InputDevice("Hydra"), #ifdef __APPLE__ _sixenseLibrary(NULL), #endif + _reachLength(DEFAULT_REACH_LENGTH), _hydrasConnected(false) { - } bool SixenseManager::isSupported() const { @@ -92,7 +91,7 @@ void SixenseManager::activate() { CONTAINER->addMenu(MENU_PATH); CONTAINER->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, - [this] (bool clicked) { this->setFilter(clicked); }, + [this] (bool clicked) { this->setSixenseFilter(clicked); }, true, true); #ifdef __APPLE__ @@ -120,6 +119,7 @@ void SixenseManager::activate() { SixenseBaseFunction sixenseInit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseInit"); #endif + loadSettings(); sixenseInit(); #endif } @@ -144,7 +144,7 @@ void SixenseManager::deactivate() { #endif } -void SixenseManager::setFilter(bool filter) { +void SixenseManager::setSixenseFilter(bool filter) { #ifdef HAVE_SIXENSE #ifdef __APPLE__ SixenseTakeIntFunction sixenseSetFilterEnabled = (SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseSetFilterEnabled"); @@ -282,6 +282,7 @@ void SixenseManager::updateCalibration(void* controllersX) { glm::vec3 xAxis = glm::normalize(_reachRight - _reachLeft); glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, Vectors::UNIT_Y)); xAxis = glm::normalize(glm::cross(Vectors::UNIT_Y, zAxis)); + _reachLength = glm::dot(xAxis, _reachRight - _reachLeft); _avatarRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, Vectors::UNIT_Y, zAxis))); const float Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR = -0.3f; _avatarPosition.y += Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR; @@ -317,7 +318,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _lastDistance = reach; _lockExpiry = usecTimestampNow() + LOCK_DURATION; // move to next state - _calibrationState = CALIBRATION_STATE_X; + _calibrationState = CALIBRATION_STATE_IN_PROGRESS; } return; } @@ -327,7 +328,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _averageLeft = 0.9f * _averageLeft + 0.1f * positionLeft; _averageRight = 0.9f * _averageRight + 0.1f * positionRight; - if (_calibrationState == CALIBRATION_STATE_X) { + if (_calibrationState == CALIBRATION_STATE_IN_PROGRESS) { // compute new sliding average float distance = glm::distance(_averageLeft, _averageRight); if (fabsf(distance - _lastDistance) > MAXIMUM_NOISE_LEVEL) { @@ -340,7 +341,6 @@ void SixenseManager::updateCalibration(void* controllersX) { // lock has expired so clamp the data and move on _lockExpiry = now + LOCK_DURATION; _lastDistance = 0.0f; - _reachUp = 0.5f * (_reachLeft + _reachRight); _calibrationState = CALIBRATION_STATE_COMPLETE; qCDebug(inputplugins, "success: sixense calibration: left"); } @@ -543,6 +543,31 @@ void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { } +// virtual +void SixenseManager::saveSettings() const { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + settings.setVec3Value(QString("avatarPosition"), _avatarPosition); + settings.setQuatValue(QString("avatarRotation"), _avatarRotation); + settings.setValue(QString("reachLength"), QVariant(_reachLength)); + } + settings.endGroup(); +} + +void SixenseManager::loadSettings() { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + settings.getVec3ValueIfValid(QString("avatarPosition"), _avatarPosition); + settings.getQuatValueIfValid(QString("avatarRotation"), _avatarRotation); + settings.getFloatValueIfValid(QString("reachLength"), _reachLength); + } + settings.endGroup(); +} + UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) { return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON); } diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/libraries/input-plugins/src/input-plugins/SixenseManager.h index 5e3815cd20..9fa7f84a86 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.h +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.h @@ -58,12 +58,11 @@ public: SixenseManager(); - static SixenseManager& getInstance(); - // Plugin functions virtual bool isSupported() const override; virtual bool isJointController() const override { return true; } const QString& getName() const override { return NAME; } + const QString& getID() const override { return HYDRA_ID_STRING; } virtual void activate() override; virtual void deactivate() override; @@ -77,15 +76,15 @@ public: virtual void update(float deltaTime, bool jointsCaptured) override; virtual void focusOutEvent() override; - bool getInvertButtons() const { return _invertButtons; } - void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; } - UserInputMapper::Input makeInput(unsigned int button, int index); UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index); UserInputMapper::Input makeInput(JointChannel joint); + virtual void saveSettings() const override; + virtual void loadSettings() override; + public slots: - void setFilter(bool filter); + void setSixenseFilter(bool filter); private: void handleButtonEvent(unsigned int buttons, int index); @@ -99,7 +98,7 @@ private: // these are calibration results glm::vec3 _avatarPosition; // in hydra-frame glm::quat _avatarRotation; // in hydra-frame - float _armLength; + float _reachLength; // these are measured values used to compute the calibration results quint64 _lockExpiry; @@ -107,9 +106,8 @@ private: glm::vec3 _averageRight; glm::vec3 _reachLeft; glm::vec3 _reachRight; - glm::vec3 _reachUp; - glm::vec3 _reachForward; float _lastDistance; + bool _useSixenseFilter = true; #ifdef __APPLE__ QLibrary* _sixenseLibrary; @@ -117,9 +115,8 @@ private: bool _hydrasConnected; - bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS; - static const QString NAME; + static const QString HYDRA_ID_STRING; }; #endif // hifi_SixenseManager_h diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index ffcc682ebd..2c0b9fa5cf 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,6 +9,8 @@ PluginContainer* Plugin::CONTAINER{ nullptr }; +QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); + void Plugin::setContainer(PluginContainer* container) { CONTAINER = container; } diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index eac355b47d..68e012b8e1 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -7,6 +7,8 @@ // #pragma once +#include + #include #include @@ -14,7 +16,12 @@ class Plugin : public QObject { public: + /// \return human-readable name virtual const QString& getName() const = 0; + + /// \return string ID (not necessarily human-readable) + virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } + virtual bool isSupported() const; static void setContainer(PluginContainer* container); @@ -37,6 +44,11 @@ public: */ virtual void idle(); + virtual void saveSettings() const {} + virtual void loadSettings() {} + protected: static PluginContainer* CONTAINER; + static QString UNKNOWN_PLUGIN_ID; + }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 3a71700c9e..2deb41fb13 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -8,6 +8,8 @@ #include "PluginManager.h" #include +#include "Forward.h" + PluginManager* PluginManager::getInstance() { static PluginManager _manager; return &_manager; @@ -16,6 +18,7 @@ PluginManager* PluginManager::getInstance() { // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); +extern void saveInputPluginSettings(const InputPluginList& plugins); const DisplayPluginList& PluginManager::getDisplayPlugins() { static DisplayPluginList displayPlugins; @@ -35,3 +38,6 @@ const InputPluginList& PluginManager::getInputPlugins() { return inputPlugins; } +void PluginManager::saveSettings() { + saveInputPluginSettings(getInputPlugins()); +} diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index b7ec453814..09dcc9d107 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -15,4 +15,5 @@ public: const DisplayPluginList& getDisplayPlugins(); const InputPluginList& getInputPlugins(); + void saveSettings(); }; diff --git a/libraries/shared/src/SettingHandle.cpp b/libraries/shared/src/SettingHandle.cpp new file mode 100644 index 0000000000..19239b3cf7 --- /dev/null +++ b/libraries/shared/src/SettingHandle.cpp @@ -0,0 +1,83 @@ +// +// SettingHandle.h +// +// +// Created by AndrewMeadows 2015.10.05 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "SettingHandle.h" + +#include + + +void Settings::getFloatValueIfValid(const QString& name, float& f) { + const QVariant badDefaultValue = NAN; + bool ok = true; + float tempFloat = value(name, badDefaultValue).toFloat(&ok); + if (ok && !isnan(tempFloat)) { + f = tempFloat; + } +} + +void Settings::getBoolValue(const QString& name, bool& b) { + const QVariant defaultValue = false; + b = value(name, defaultValue).toBool(); +} + + +void Settings::setVec3Value(const QString& name, const glm::vec3& v) { + beginGroup(name); + { + setValue(QString("x"), v.x); + setValue(QString("y"), v.y); + setValue(QString("z"), v.z); + } + endGroup(); +} + +void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { + beginGroup(name); + { + bool ok = true; + const QVariant badDefaultValue = NAN; + float x = value(QString("x"), badDefaultValue).toFloat(&ok); + float y = value(QString("y"), badDefaultValue).toFloat(&ok); + float z = value(QString("z"), badDefaultValue).toFloat(&ok); + if (ok && (!isnan(x) && !isnan(y) && !isnan(z))) { + v = glm::vec3(x, y, z); + } + } + endGroup(); +} + +void Settings::setQuatValue(const QString& name, const glm::quat& q) { + beginGroup(name); + { + setValue(QString("x"), q.x); + setValue(QString("y"), q.y); + setValue(QString("z"), q.z); + setValue(QString("w"), q.w); + } + endGroup(); +} + +void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { + beginGroup(name); + { + bool ok = true; + const QVariant badDefaultValue = NAN; + float x = value(QString("x"), badDefaultValue).toFloat(&ok); + float y = value(QString("y"), badDefaultValue).toFloat(&ok); + float z = value(QString("z"), badDefaultValue).toFloat(&ok); + float w = value(QString("w"), badDefaultValue).toFloat(&ok); + if (ok && (!isnan(x) && !isnan(y) && !isnan(z) && !isnan(w))) { + q = glm::quat(w, x, y, z); + } + } + endGroup(); +} + diff --git a/libraries/shared/src/SettingHandle.h b/libraries/shared/src/SettingHandle.h index 761e41d321..b86422bcfb 100644 --- a/libraries/shared/src/SettingHandle.h +++ b/libraries/shared/src/SettingHandle.h @@ -18,11 +18,22 @@ #include #include +#include +#include + #include "SettingInterface.h" // TODO: remove class Settings : public QSettings { - +public: + void getFloatValueIfValid(const QString& name, float& f); + void getBoolValue(const QString& name, bool& b); + + void setVec3Value(const QString& name, const glm::vec3& v); + void getVec3ValueIfValid(const QString& name, glm::vec3& v); + + void setQuatValue(const QString& name, const glm::quat& q); + void getQuatValueIfValid(const QString& name, glm::quat& q); }; namespace Setting { @@ -65,4 +76,4 @@ namespace Setting { } } -#endif // hifi_SettingHandle_h \ No newline at end of file +#endif // hifi_SettingHandle_h From 464ef2293da0694216ce622b17b3c8cb354bd97d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Oct 2015 10:52:47 -0700 Subject: [PATCH 140/152] more descriptive variable names --- libraries/shared/src/SettingHandle.cpp | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libraries/shared/src/SettingHandle.cpp b/libraries/shared/src/SettingHandle.cpp index 19239b3cf7..4a2c0cf04b 100644 --- a/libraries/shared/src/SettingHandle.cpp +++ b/libraries/shared/src/SettingHandle.cpp @@ -14,32 +14,32 @@ #include -void Settings::getFloatValueIfValid(const QString& name, float& f) { +void Settings::getFloatValueIfValid(const QString& name, float& floatValue) { const QVariant badDefaultValue = NAN; bool ok = true; float tempFloat = value(name, badDefaultValue).toFloat(&ok); if (ok && !isnan(tempFloat)) { - f = tempFloat; + floatValue = tempFloat; } } -void Settings::getBoolValue(const QString& name, bool& b) { +void Settings::getBoolValue(const QString& name, bool& boolValue) { const QVariant defaultValue = false; - b = value(name, defaultValue).toBool(); + boolValue = value(name, defaultValue).toBool(); } -void Settings::setVec3Value(const QString& name, const glm::vec3& v) { +void Settings::setVec3Value(const QString& name, const glm::vec3& vecValue) { beginGroup(name); { - setValue(QString("x"), v.x); - setValue(QString("y"), v.y); - setValue(QString("z"), v.z); + setValue(QString("x"), vecValue.x); + setValue(QString("y"), vecValue.y); + setValue(QString("z"), vecValue.z); } endGroup(); } -void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { +void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& vecValue) { beginGroup(name); { bool ok = true; @@ -48,24 +48,24 @@ void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { float y = value(QString("y"), badDefaultValue).toFloat(&ok); float z = value(QString("z"), badDefaultValue).toFloat(&ok); if (ok && (!isnan(x) && !isnan(y) && !isnan(z))) { - v = glm::vec3(x, y, z); + vecValue = glm::vec3(x, y, z); } } endGroup(); } -void Settings::setQuatValue(const QString& name, const glm::quat& q) { +void Settings::setQuatValue(const QString& name, const glm::quat& quatValue) { beginGroup(name); { - setValue(QString("x"), q.x); - setValue(QString("y"), q.y); - setValue(QString("z"), q.z); - setValue(QString("w"), q.w); + setValue(QString("x"), quatValue.x); + setValue(QString("y"), quatValue.y); + setValue(QString("z"), quatValue.z); + setValue(QString("w"), quatValue.w); } endGroup(); } -void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { +void Settings::getQuatValueIfValid(const QString& name, glm::quat& quatValue) { beginGroup(name); { bool ok = true; @@ -75,7 +75,7 @@ void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { float z = value(QString("z"), badDefaultValue).toFloat(&ok); float w = value(QString("w"), badDefaultValue).toFloat(&ok); if (ok && (!isnan(x) && !isnan(y) && !isnan(z) && !isnan(w))) { - q = glm::quat(w, x, y, z); + quatValue = glm::quat(w, x, y, z); } } endGroup(); From 0a351a8a0c2a7504beff9c71874f571ed97e9b70 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 7 Oct 2015 14:26:33 -0700 Subject: [PATCH 141/152] FIx the problem with cauterizedClusterMatrices in the case rear view mirror is used. Clean the way to define the depth stencil format for texture --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 20 ++++++++-------- .../render-utils/src/FramebufferCache.cpp | 2 +- .../render-utils/src/MeshPartPayload.cpp | 6 ++++- libraries/render-utils/src/Model.cpp | 24 +++++++++++-------- libraries/render-utils/src/Model.h | 2 ++ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 7916f1c0d8..b72fadafa0 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -50,6 +50,11 @@ public: case gpu::DEPTH: texel.internalFormat = GL_DEPTH_COMPONENT; break; + case gpu::DEPTH_STENCIL: + texel.type = GL_UNSIGNED_INT_24_8; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; + break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -65,11 +70,6 @@ public: case gpu::RGBA: texel.internalFormat = GL_RG; break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -182,6 +182,11 @@ public: } } break; + case gpu::DEPTH_STENCIL: + texel.type = GL_UNSIGNED_INT_24_8; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; + break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -198,11 +203,6 @@ public: case gpu::RGBA: texel.internalFormat = GL_RG; break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index cd81a21f9a..7b20a3696a 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -71,7 +71,7 @@ void FramebufferCache::createPrimaryFramebuffer() { auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); - auto stencilFormat = gpu::Element(gpu::VEC2, gpu::UINT32, gpu::DEPTH_STENCIL); + auto stencilFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format _primaryStencilTexture = gpu::TexturePointer(gpu::Texture::create2D(stencilFormat, width, height, defaultSampler)); _primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index d1db4e6c7f..54b0bacf6e 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -212,7 +212,11 @@ void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locati Transform transform; if (state.clusterBuffer) { - batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); + if (model->_cauterizeBones) { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.cauterizedClusterBuffer); + } else { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); + } } else { if (model->_cauterizeBones) { transform = Transform(state.cauterizedClusterMatrices[0]); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2fe95ef64f..38f5ffdabe 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -167,9 +167,7 @@ bool Model::updateGeometry() { MeshState state; state.clusterMatrices.resize(mesh.clusters.size()); state.cauterizedClusterMatrices.resize(mesh.clusters.size()); - if (mesh.clusters.size() > 1) { - state.clusterBuffer = std::make_shared(mesh.clusters.size() * sizeof(glm::mat4), nullptr); - } + _meshStates.append(state); auto buffer = std::make_shared(); @@ -1006,15 +1004,21 @@ void Model::updateClusterMatrices() { } } - // Once computed the cluster matrices, update the buffer - if (state.clusterBuffer) { - const float* bones; - if (_cauterizeBones) { - bones = (const float*)state.cauterizedClusterMatrices.constData(); + // Once computed the cluster matrices, update the buffer(s) + if (mesh.clusters.size() > 1) { + if (!state.clusterBuffer) { + state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); } else { - bones = (const float*)state.clusterMatrices.constData(); + state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); + } + + if (!_cauterizeBoneSet.empty() && (state.cauterizedClusterMatrices.size() > 1)) { + if (!state.cauterizedClusterBuffer) { + state.cauterizedClusterBuffer = std::make_shared(state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + } else { + state.cauterizedClusterBuffer->setSubData(0, state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + } } - state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) bones); } } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 98341e1a3d..e3a9ce9ac3 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -256,6 +256,8 @@ protected: QVector clusterMatrices; QVector cauterizedClusterMatrices; gpu::BufferPointer clusterBuffer; + gpu::BufferPointer cauterizedClusterBuffer; + }; QVector _meshStates; From bfd014203e796d807c32b1b1403d739456dd6b1c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 7 Oct 2015 14:48:42 -0700 Subject: [PATCH 142/152] fix a bunch of warnings --- interface/src/Application.cpp | 18 ------------------ interface/src/Application.h | 1 - .../entities/src/AnimationPropertyGroup.cpp | 2 ++ .../entities/src/AtmospherePropertyGroup.cpp | 2 ++ libraries/entities/src/SkyboxPropertyGroup.cpp | 2 ++ libraries/entities/src/StagePropertyGroup.cpp | 2 ++ libraries/networking/src/udt/PacketQueue.cpp | 2 +- 7 files changed, 9 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 70cc189ad6..e64d4a9bd5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4750,24 +4750,6 @@ mat4 Application::getEyeProjection(int eye) const { return _viewFrustum.getProjection(); } -mat4 Application::getEyePose(int eye) const { - if (isHMDMode()) { - auto hmdInterface = DependencyManager::get(); - float IPDScale = hmdInterface->getIPDScale(); - auto displayPlugin = getActiveDisplayPlugin(); - mat4 headPose = displayPlugin->getHeadPose(); - mat4 eyeToHead = displayPlugin->getEyeToHeadTransform((Eye)eye); - { - vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // Apply IPD scaling - mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * IPDScale); - eyeToHead[3] = vec4(eyeOffset, 1.0); - } - return eyeToHead * headPose; - } - return mat4(); -} - mat4 Application::getEyeOffset(int eye) const { // FIXME invert? return getActiveDisplayPlugin()->getEyeToHeadTransform((Eye)eye); diff --git a/interface/src/Application.h b/interface/src/Application.h index ec5133b131..0b75a94232 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -198,7 +198,6 @@ public: // TODO: carry that information on the Camera as a setting bool isHMDMode() const; glm::mat4 getHMDSensorPose() const; - glm::mat4 getEyePose(int eye) const; glm::mat4 getEyeOffset(int eye) const; glm::mat4 getEyeProjection(int eye) const; diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 3c22707869..48cedfbf5d 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -249,6 +249,8 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF processedBytes += bytesRead; + Q_UNUSED(somethingChanged); + return true; } diff --git a/libraries/entities/src/AtmospherePropertyGroup.cpp b/libraries/entities/src/AtmospherePropertyGroup.cpp index e24dc5791b..0f0e68ce72 100644 --- a/libraries/entities/src/AtmospherePropertyGroup.cpp +++ b/libraries/entities/src/AtmospherePropertyGroup.cpp @@ -108,6 +108,8 @@ bool AtmospherePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& property processedBytes += bytesRead; + Q_UNUSED(somethingChanged); + return true; } diff --git a/libraries/entities/src/SkyboxPropertyGroup.cpp b/libraries/entities/src/SkyboxPropertyGroup.cpp index d3ed82274a..b79b535d8e 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.cpp +++ b/libraries/entities/src/SkyboxPropertyGroup.cpp @@ -66,6 +66,8 @@ bool SkyboxPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlag processedBytes += bytesRead; + Q_UNUSED(somethingChanged); + return true; } diff --git a/libraries/entities/src/StagePropertyGroup.cpp b/libraries/entities/src/StagePropertyGroup.cpp index bab68c7a4b..7110f0481d 100644 --- a/libraries/entities/src/StagePropertyGroup.cpp +++ b/libraries/entities/src/StagePropertyGroup.cpp @@ -121,6 +121,8 @@ bool StagePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags processedBytes += bytesRead; + Q_UNUSED(somethingChanged); + return true; } diff --git a/libraries/networking/src/udt/PacketQueue.cpp b/libraries/networking/src/udt/PacketQueue.cpp index 1c104e1427..bc3a1796e2 100644 --- a/libraries/networking/src/udt/PacketQueue.cpp +++ b/libraries/networking/src/udt/PacketQueue.cpp @@ -55,7 +55,7 @@ PacketQueue::PacketPointer PacketQueue::takePacket() { } unsigned int PacketQueue::nextIndex() { - _currentIndex = (++_currentIndex) % _channels.size(); + _currentIndex = (_currentIndex + 1) % _channels.size(); return _currentIndex; } From 946d289a992f042c05ed5c32695cb6d45015df72 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 13:05:43 -0700 Subject: [PATCH 143/152] Display name have a arc size instead of pixel size --- interface/src/avatar/Avatar.cpp | 159 +++++++++++--------------------- interface/src/avatar/Avatar.h | 4 +- 2 files changed, 58 insertions(+), 105 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ddee5dfc1f..538d9fb4eb 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -549,7 +549,12 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto cameraMode = qApp->getCamera()->getMode(); if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { - renderDisplayName(batch, *renderArgs->_viewFrustum, renderArgs->_viewport); + auto& frustum = *renderArgs->_viewFrustum; + auto textPosition = getDisplayNamePosition(); + + if (frustum.pointInFrustum(textPosition)) { + renderDisplayName(batch, frustum, textPosition); + } } endRender(); } @@ -716,85 +721,29 @@ glm::vec3 Avatar::getDisplayNamePosition() const { return namePosition; } -Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const { - Transform result; - // We assume textPosition is whithin the frustum - glm::vec3 textPosition = getDisplayNamePosition(); - - // Compute viewProjection matrix - glm::mat4 projMat, viewMat; - Transform view; - frustum.evalProjectionMatrix(projMat); - frustum.evalViewTransform(view); - glm::mat4 viewProj = projMat * view.getInverseMatrix(viewMat); - - // Used to determine correct scale - glm::vec3 testPoint0 = textPosition; - glm::vec3 testPoint1 = testPoint0 + glm::normalize(frustum.getUp()); - // testPoints projections - glm::vec4 p0 = viewProj * glm::vec4(testPoint0, 1.0); - glm::vec4 p1 = viewProj * glm::vec4(testPoint1, 1.0); - - float windowSizeY = viewport.w; - - const float DESIRED_HIGHT_ON_SCREEN = 20; // In pixels (this is double on retinas) - - // Projected point are between -1.0f and 1.0f, hence 0.5f * windowSizeY - float pixelHeight = 0.5f * windowSizeY * glm::abs((p1.y / p1.w) - (p0.y / p0.w)); // - // Handles pixel density (especially for macs retina displays) - float devicePixelRatio = (float)qApp->getDevicePixelRatio() * qApp->getRenderResolutionScale(); // pixels / unit - - // Compute correct scale to apply - float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio; -#ifdef DEBUG - // TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed. - // Problem is probably due to an invalid getDisplayNamePosition(). See extra logging above. - if (scale == 0.0f || glm::isnan(scale) || glm::isinf(scale)) { - if (scale == 0.0f) { - qDebug() << "ASSERT because scale == 0.0f"; - } - if (glm::isnan(scale)) { - qDebug() << "ASSERT because isnan(scale)"; - } - if (glm::isinf(scale)) { - qDebug() << "ASSERT because isinf(scale)"; - } - qDebug() << "textPosition =" << textPosition; - qDebug() << "projMat =" << projMat; - qDebug() << "viewMat =" << viewMat; - qDebug() << "viewProj =" << viewProj; - qDebug() << "windowSizeY =" << windowSizeY; - qDebug() << "p1 =" << p1; - qDebug() << "p0 =" << p0; - qDebug() << "qApp->getDevicePixelRatio() =" << qApp->getDevicePixelRatio(); - qDebug() << "fontSize =" << fontSize; - qDebug() << "pixelHeight =" << pixelHeight; - qDebug() << "devicePixelRatio =" << devicePixelRatio; - } -#endif - - // Compute pixel alignment offset - float clipToPix = 0.5f * windowSizeY / p1.w; // Got from clip to pixel coordinates - glm::vec4 screenPos = clipToPix * p1; // in pixels coords - glm::vec4 screenOffset = (glm::round(screenPos) - screenPos) / clipToPix; // in clip coords - glm::vec3 worldOffset = glm::vec3(screenOffset.x, screenOffset.y, 0.0f) / (float)pixelHeight; +Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { + Q_ASSERT_X(frustum.pointInFrustum(textPosition), "Avatar::calculateDisplayNameTransform", + "Text not in viewfrustum."); + glm::vec3 dPosition = frustum.getPosition() - textPosition; // Compute orientation - glm::vec3 dPosition = frustum.getPosition() - getPosition(); - // If x and z are 0, atan(x, z) is undefined, so default to 0 degrees - float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z); + // If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees + const float yawRotation = (dPosition.x == 0.0f && dPosition.z == 0.0f) ? 0.0f : glm::atan(dPosition.x, dPosition.z); glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); - // Set transform (The order IS important) + // Compute correct scale to apply + static const float DESIRED_HIGHT_RAD = glm::radians(2.0f); + float scale = glm::length(dPosition) * glm::tan(DESIRED_HIGHT_RAD); + + // Set transform + Transform result; result.setTranslation(textPosition); result.setRotation(orientation); // Always face the screen - result.postTranslate(worldOffset); // Pixel alignment result.setScale(scale); return result; - } -void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const { +void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const { bool shouldShowReceiveStats = DependencyManager::get()->shouldShowReceiveStats() && !isMyAvatar(); // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return @@ -818,39 +767,43 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co } // Compute display name extent/position offset - glm::vec2 extent = renderer->computeExtent(renderedDisplayName); - QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y); - const int text_x = -nameDynamicRect.width() / 2; - const int text_y = -nameDynamicRect.height() / 2; - - // Compute background position/size - static const float SLIGHTLY_IN_FRONT = 0.1f; - const int border = 0.1f * nameDynamicRect.height(); - const int left = text_x - border; - const int bottom = text_y - border; - const int width = nameDynamicRect.width() + 2.0f * border; - const int height = nameDynamicRect.height() + 2.0f * border; - const int bevelDistance = 0.1f * height; - - // Display name and background colors - glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); - glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f, - (_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA); - - // Compute display name transform - auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize(), viewport); - batch.setModelTransform(textTransform); - - DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); - DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, - bevelDistance, backgroundColor); - // Render actual name - QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); - - // Render text slightly in front to avoid z-fighting - textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); - batch.setModelTransform(textTransform); - renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); + const glm::vec2 extent = renderer->computeExtent(renderedDisplayName); + if (!glm::any(glm::isCompNull(extent, EPSILON))) { + const QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y); + const int text_x = -nameDynamicRect.width() / 2; + const int text_y = -nameDynamicRect.height() / 2; + + // Compute background position/size + static const float SLIGHTLY_IN_FRONT = 0.1f; + const int border = 0.1f * nameDynamicRect.height(); + const int left = text_x - border; + const int bottom = text_y - border; + const int width = nameDynamicRect.width() + 2.0f * border; + const int height = nameDynamicRect.height() + 2.0f * border; + const int bevelDistance = 0.1f * height; + + // Display name and background colors + glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); + glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f, + (_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA); + + // Compute display name transform + auto textTransform = calculateDisplayNameTransform(frustum, textPosition); + // Test on extent above insures abs(height) > 0.0f + textTransform.postScale(1.0f / height); + batch.setModelTransform(textTransform); + + DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); + DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, + bevelDistance, backgroundColor); + // Render actual name + QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); + + // Render text slightly in front to avoid z-fighting + textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); + batch.setModelTransform(textTransform); + renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); + } } void Avatar::setSkeletonOffset(const glm::vec3& offset) { diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 1800f4fdd1..534aefd3cb 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -217,8 +217,8 @@ protected: float getPelvisFloatingHeight() const; glm::vec3 getDisplayNamePosition() const; - Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const; - void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const; + Transform calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const; + void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const; virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f); virtual bool shouldRenderHead(const RenderArgs* renderArgs) const; virtual void fixupModelsInScene(); From 91b46203f3b039c9d8f59d0ecfb42303e9f66581 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 13:56:58 -0700 Subject: [PATCH 144/152] Don't take keyhole into account --- interface/src/avatar/Avatar.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 538d9fb4eb..5b13d6991f 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -552,7 +552,13 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto& frustum = *renderArgs->_viewFrustum; auto textPosition = getDisplayNamePosition(); - if (frustum.pointInFrustum(textPosition)) { + // In the view frustum + auto keyhole = frustum.getKeyholeRadius(); + frustum.setKeyholeRadius(-1.0f); + auto inFrustum = frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE; + frustum.setKeyholeRadius(keyhole); + + if (inFrustum) { renderDisplayName(batch, frustum, textPosition); } } @@ -722,8 +728,8 @@ glm::vec3 Avatar::getDisplayNamePosition() const { } Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { - Q_ASSERT_X(frustum.pointInFrustum(textPosition), "Avatar::calculateDisplayNameTransform", - "Text not in viewfrustum."); + Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, + "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); glm::vec3 dPosition = frustum.getPosition() - textPosition; // Compute orientation From 79b280f73337389c5321aeaaf68917a90f4c6289 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 14:27:04 -0700 Subject: [PATCH 145/152] Update getDisplayNamePosition debug --- interface/src/avatar/Avatar.cpp | 55 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5b13d6991f..4ee9a1bbb8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -696,34 +696,51 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { } float Avatar::getBillboardSize() const { - return _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); + return _scale * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); } +#ifdef DEBUG +void debugValue(const QString& str, const glm::vec3& value) { + if (glm::any(glm::isnan(value)) || glm::any(glm::isinf(value))) { + qCWarning(interfaceapp) << "debugValue() " << str << value; + } +}; +void debugValue(const QString& str, const float& value) { + if (glm::isnan(value) || glm::isinf(value)) { + qCWarning(interfaceapp) << "debugValue() " << str << value; + } +}; +#define DEBUG_VALUE(str, value) debugValue(str, value) +#else +#define DEBUG_VALUE(str, value) +#endif + glm::vec3 Avatar::getDisplayNamePosition() const { glm::vec3 namePosition(0.0f); + glm::vec3 bodyUpDirection = getBodyUpDirection(); + DEBUG_VALUE("bodyUpDirection =", bodyUpDirection); + if (getSkeletonModel().getNeckPosition(namePosition)) { - namePosition += getBodyUpDirection() * getHeadHeight() * 1.1f; + float headHeight = getHeadHeight(); + DEBUG_VALUE("namePosition =", namePosition); + DEBUG_VALUE("headHeight =", headHeight); + + namePosition += bodyUpDirection * headHeight * 1.1f; } else { const float HEAD_PROPORTION = 0.75f; - namePosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION); + float billboardSize = getBillboardSize(); + + DEBUG_VALUE("_position =", _position); + DEBUG_VALUE("billboardSize =", billboardSize); + namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION); } -#ifdef DEBUG - // TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed. - // See other TODO below. - if (glm::isnan(namePosition.x) || glm::isnan(namePosition.y) || glm::isnan(namePosition.z) - || glm::isinf(namePosition.x) || glm::isinf(namePosition.y) || glm::isinf(namePosition.z)) { - qDebug() << "namePosition =" << namePosition; - glm::vec3 tempPosition(0.0f); - if (getSkeletonModel().getNeckPosition(tempPosition)) { - qDebug() << "getBodyUpDirection() =" << getBodyUpDirection(); - qDebug() << "getHeadHeight() =" << getHeadHeight(); - } else { - qDebug() << "_position =" << _position; - qDebug() << "getBodyUpDirection() =" << getBodyUpDirection(); - qDebug() << "getBillboardSize() =" << getBillboardSize(); - } + + if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) { + qCWarning(interfaceapp) << "Invalid display name position" << namePosition + << ", setting is to (0.0f, 0.5f, 0.0f)"; + namePosition = glm::vec3(0.0f, 0.5f, 0.0f); } -#endif + return namePosition; } From fd6f0213ef1a6801b6727c6318adbd2544251c02 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 17:23:54 -0700 Subject: [PATCH 146/152] CR --- interface/src/avatar/Avatar.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4ee9a1bbb8..ad714fefc8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -725,7 +725,8 @@ glm::vec3 Avatar::getDisplayNamePosition() const { DEBUG_VALUE("namePosition =", namePosition); DEBUG_VALUE("headHeight =", headHeight); - namePosition += bodyUpDirection * headHeight * 1.1f; + static const float SLIGHTLY_ABOVE = 1.1f; + namePosition += bodyUpDirection * headHeight * SLIGHTLY_ABOVE; } else { const float HEAD_PROPORTION = 0.75f; float billboardSize = getBillboardSize(); @@ -747,16 +748,16 @@ glm::vec3 Avatar::getDisplayNamePosition() const { Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); - glm::vec3 dPosition = frustum.getPosition() - textPosition; + glm::vec3 toFrustum = frustum.getPosition() - textPosition; // Compute orientation // If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees - const float yawRotation = (dPosition.x == 0.0f && dPosition.z == 0.0f) ? 0.0f : glm::atan(dPosition.x, dPosition.z); + const float yawRotation = (toFrustum.x == 0.0f && toFrustum.z == 0.0f) ? 0.0f : glm::atan(toFrustum.x, toFrustum.z); glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); // Compute correct scale to apply - static const float DESIRED_HIGHT_RAD = glm::radians(2.0f); - float scale = glm::length(dPosition) * glm::tan(DESIRED_HIGHT_RAD); + static const float DESIRED_HEIGHT_RAD = glm::radians(2.0f); + float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD); // Set transform Transform result; @@ -770,7 +771,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co bool shouldShowReceiveStats = DependencyManager::get()->shouldShowReceiveStats() && !isMyAvatar(); // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return - const float CLIP_DISTANCE = 0.2f; + static const float CLIP_DISTANCE = 0.2f; if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f || (glm::dot(frustum.getDirection(), getDisplayNamePosition() - frustum.getPosition()) <= CLIP_DISTANCE)) { return; @@ -798,12 +799,14 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co // Compute background position/size static const float SLIGHTLY_IN_FRONT = 0.1f; - const int border = 0.1f * nameDynamicRect.height(); + static const float BORDER_RELATIVE_SIZE = 0.1f; + static const float BEVEL_FACTOR = 0.1f; + const int border = BORDER_RELATIVE_SIZE * nameDynamicRect.height(); const int left = text_x - border; const int bottom = text_y - border; const int width = nameDynamicRect.width() + 2.0f * border; const int height = nameDynamicRect.height() + 2.0f * border; - const int bevelDistance = 0.1f * height; + const int bevelDistance = BEVEL_FACTOR * height; // Display name and background colors glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); From 14a18606709edd4e74116fbc68deab74f7236ca4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 18:08:30 -0700 Subject: [PATCH 147/152] Do not change keyhole radius --- interface/src/avatar/Avatar.cpp | 10 ++-------- libraries/octree/src/ViewFrustum.cpp | 13 +++++++------ libraries/octree/src/ViewFrustum.h | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ad714fefc8..ac55f6de83 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -552,13 +552,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto& frustum = *renderArgs->_viewFrustum; auto textPosition = getDisplayNamePosition(); - // In the view frustum - auto keyhole = frustum.getKeyholeRadius(); - frustum.setKeyholeRadius(-1.0f); - auto inFrustum = frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE; - frustum.setKeyholeRadius(keyhole); - - if (inFrustum) { + if (frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE) { renderDisplayName(batch, frustum, textPosition); } } @@ -746,7 +740,7 @@ glm::vec3 Avatar::getDisplayNamePosition() const { } Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { - Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, + Q_ASSERT_X(frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE, "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); glm::vec3 toFrustum = frustum.getPosition() - textPosition; diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index 820ab32b67..fd175a8e5b 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -241,20 +241,21 @@ ViewFrustum::location ViewFrustum::boxInKeyhole(const AABox& box) const { return result; } -ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const { +ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point, bool ignoreKeyhole) const { ViewFrustum::location regularResult = INSIDE; ViewFrustum::location keyholeResult = OUTSIDE; // If we have a keyholeRadius, check that first, since it's cheaper - if (_keyholeRadius >= 0.0f) { + if (!ignoreKeyhole && _keyholeRadius >= 0.0f) { keyholeResult = pointInKeyhole(point); - } - if (keyholeResult == INSIDE) { - return keyholeResult; + + if (keyholeResult == INSIDE) { + return keyholeResult; + } } // If we're not known to be INSIDE the keyhole, then check the regular frustum - for(int i=0; i < 6; i++) { + for(int i = 0; i < 6; ++i) { float distance = _planes[i].distance(point); if (distance < 0) { return keyholeResult; // escape early will be the value from checking the keyhole diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index fe40cfd53c..596d042506 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -79,7 +79,7 @@ public: typedef enum {OUTSIDE, INTERSECT, INSIDE} location; - ViewFrustum::location pointInFrustum(const glm::vec3& point) const; + ViewFrustum::location pointInFrustum(const glm::vec3& point, bool ignoreKeyhole = false) const; ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const; ViewFrustum::location cubeInFrustum(const AACube& cube) const; ViewFrustum::location boxInFrustum(const AABox& box) const; From efeeaa7ea7a2dc147d0cba11d92cafc733e2d972 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 7 Oct 2015 15:14:06 -0700 Subject: [PATCH 148/152] Make display names 25% smaller --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ac55f6de83..0511e5d871 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -750,7 +750,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); // Compute correct scale to apply - static const float DESIRED_HEIGHT_RAD = glm::radians(2.0f); + static const float DESIRED_HEIGHT_RAD = glm::radians(1.5f); float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD); // Set transform From fb284448b5f07edc05e03cb2ecda7c2820f4b2d1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 7 Oct 2015 15:21:35 -0700 Subject: [PATCH 149/152] Raise display name not to collide with heads --- interface/src/avatar/Avatar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0511e5d871..c0636314b5 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -758,6 +758,9 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons result.setTranslation(textPosition); result.setRotation(orientation); // Always face the screen result.setScale(scale); + // raise by half the scale up so that textPosition be the bottom + result.postTranslate(Vectors::UP / 2.0f); + return result; } From 7a918eb2883c8ee3b96c28d7dbab99d8f1b2cf4b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Oct 2015 15:25:07 -0700 Subject: [PATCH 150/152] fix variable names in header --- libraries/shared/src/SettingHandle.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/shared/src/SettingHandle.h b/libraries/shared/src/SettingHandle.h index b86422bcfb..c0b6de7bd4 100644 --- a/libraries/shared/src/SettingHandle.h +++ b/libraries/shared/src/SettingHandle.h @@ -26,14 +26,14 @@ // TODO: remove class Settings : public QSettings { public: - void getFloatValueIfValid(const QString& name, float& f); - void getBoolValue(const QString& name, bool& b); + void getFloatValueIfValid(const QString& name, float& floatValue); + void getBoolValue(const QString& name, bool& boolValue); - void setVec3Value(const QString& name, const glm::vec3& v); - void getVec3ValueIfValid(const QString& name, glm::vec3& v); + void setVec3Value(const QString& name, const glm::vec3& vecValue); + void getVec3ValueIfValid(const QString& name, glm::vec3& vecValue); - void setQuatValue(const QString& name, const glm::quat& q); - void getQuatValueIfValid(const QString& name, glm::quat& q); + void setQuatValue(const QString& name, const glm::quat& quatValue); + void getQuatValueIfValid(const QString& name, glm::quat& quatValue); }; namespace Setting { From 0cebeb7fe9a6d3d917cdd3d491124f9937033cbd Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 7 Oct 2015 15:32:10 -0700 Subject: [PATCH 151/152] Separated AvatarMixer inbound and outbound bandwidth on stats overlay Also, small bug fix to BandwidthRecorder. It would incorrectly calculate outbound pps if the input pps was 0. --- interface/resources/qml/Stats.qml | 11 +++++++++-- interface/src/ui/Stats.cpp | 16 ++++++++-------- interface/src/ui/Stats.h | 12 ++++++++---- libraries/networking/src/BandwidthRecorder.cpp | 4 ++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index eb39fbc70f..780f9cb89f 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -142,8 +142,15 @@ Item { color: root.fontColor; font.pixelSize: root.fontSize visible: root.expanded; - text: "Avatar Mixer: " + root.avatarMixerKbps + " kbps, " + - root.avatarMixerPps + "pps"; + text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " + + root.avatarMixerInPps + "pps"; + } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + visible: root.expanded; + text: "Avatar Mixer Out: " + root.avatarMixerOutKbps + " kbps, " + + root.avatarMixerOutPps + "pps"; } Text { color: root.fontColor; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 5e73e62832..7e2143c454 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -167,15 +167,15 @@ void Stats::updateStats(bool force) { if (_expanded || force) { SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { - STAT_UPDATE(avatarMixerKbps, roundf( - bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer) + - bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); - STAT_UPDATE(avatarMixerPps, roundf( - bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer) + - bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInKbps, roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); } else { - STAT_UPDATE(avatarMixerKbps, -1); - STAT_UPDATE(avatarMixerPps, -1); + STAT_UPDATE(avatarMixerInKbps, -1); + STAT_UPDATE(avatarMixerInPps, -1); + STAT_UPDATE(avatarMixerOutKbps, -1); + STAT_UPDATE(avatarMixerOutPps, -1); } SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); if (audioMixerNode || force) { diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index d6aa255dc6..f1426a9e37 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -47,8 +47,10 @@ class Stats : public QQuickItem { STATS_PROPERTY(QVector3D, position, QVector3D(0, 0, 0) ) STATS_PROPERTY(float, velocity, 0) STATS_PROPERTY(float, yaw, 0) - STATS_PROPERTY(int, avatarMixerKbps, 0) - STATS_PROPERTY(int, avatarMixerPps, 0) + STATS_PROPERTY(int, avatarMixerInKbps, 0) + STATS_PROPERTY(int, avatarMixerInPps, 0) + STATS_PROPERTY(int, avatarMixerOutKbps, 0) + STATS_PROPERTY(int, avatarMixerOutPps, 0) STATS_PROPERTY(int, audioMixerKbps, 0) STATS_PROPERTY(int, audioMixerPps, 0) STATS_PROPERTY(int, downloads, 0) @@ -122,8 +124,10 @@ signals: void positionChanged(); void velocityChanged(); void yawChanged(); - void avatarMixerKbpsChanged(); - void avatarMixerPpsChanged(); + void avatarMixerInKbpsChanged(); + void avatarMixerInPpsChanged(); + void avatarMixerOutKbpsChanged(); + void avatarMixerOutPpsChanged(); void audioMixerKbpsChanged(); void audioMixerPpsChanged(); void downloadsChanged(); diff --git a/libraries/networking/src/BandwidthRecorder.cpp b/libraries/networking/src/BandwidthRecorder.cpp index a415a9f477..5db987b236 100644 --- a/libraries/networking/src/BandwidthRecorder.cpp +++ b/libraries/networking/src/BandwidthRecorder.cpp @@ -27,9 +27,9 @@ float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() { } float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() { - float delt = _input.getEventDeltaAverage(); + float delt = _output.getEventDeltaAverage(); if (delt > 0.0f) { - return (1.0f / _output.getEventDeltaAverage()); + return (1.0f / delt); } return 0.0f; } From 00f3b7b1b5ff7b5af0a6f450a16f9b0a9d29a77e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 7 Oct 2015 15:46:42 -0700 Subject: [PATCH 152/152] Renamed delt to averageTimeBetweenPackets --- libraries/networking/src/BandwidthRecorder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/BandwidthRecorder.cpp b/libraries/networking/src/BandwidthRecorder.cpp index 5db987b236..d43d4cf21f 100644 --- a/libraries/networking/src/BandwidthRecorder.cpp +++ b/libraries/networking/src/BandwidthRecorder.cpp @@ -19,17 +19,17 @@ BandwidthRecorder::Channel::Channel() { } float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() { - float delt = _input.getEventDeltaAverage(); - if (delt > 0.0f) { - return (1.0f / delt); + float averageTimeBetweenPackets = _input.getEventDeltaAverage(); + if (averageTimeBetweenPackets > 0.0f) { + return (1.0f / averageTimeBetweenPackets); } return 0.0f; } float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() { - float delt = _output.getEventDeltaAverage(); - if (delt > 0.0f) { - return (1.0f / delt); + float averageTimeBetweenPackets = _output.getEventDeltaAverage(); + if (averageTimeBetweenPackets > 0.0f) { + return (1.0f / averageTimeBetweenPackets); } return 0.0f; }