Пример #1
0
void ModelEntityItem::setAnimationSettings(const QString& value) {
    // the animations setting is a JSON string that may contain various animation settings.
    // 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());
    QJsonObject settingsAsJsonObject = settingsAsJson.object();
    QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
    if (settingsMap.contains("fps")) {
        float fps = settingsMap["fps"].toFloat();
        setAnimationFPS(fps);
    }

    // old settings used frameIndex
    if (settingsMap.contains("frameIndex")) {
        float currentFrame = settingsMap["frameIndex"].toFloat();
#ifdef WANT_DEBUG
        if (isAnimatingSomething()) {
            qCDebug(entities) << "ModelEntityItem::setAnimationSettings() calling setAnimationFrameIndex()...";
            qCDebug(entities) << "    model URL:" << getModelURL();
            qCDebug(entities) << "    animation URL:" << getAnimationURL();
            qCDebug(entities) << "    settings:" << value;
            qCDebug(entities) << "    settingsMap[frameIndex]:" << settingsMap["frameIndex"];
            qCDebug(entities"    currentFrame: %20.5f", currentFrame);
        }
#endif

        setAnimationCurrentFrame(currentFrame);
    }

    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);
    }

    _dirtyFlags |= Simulation::DIRTY_UPDATEABLE;
}
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::update(const quint64& now) {

    float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
     _lastAnimated = now;

    // only advance the frame index if we're playing
    if (getAnimationIsPlaying()) {
        _animationLoop.simulate(deltaTime);
    }

    if (isAnimatingSomething()) {
        stepSimulation(deltaTime);
    }

    EntityItem::update(now); // let our base class handle it's updates...
}
void RenderableModelEntityItem::updateModelBounds() {
    if (!hasModel() || !_model) {
        return;
    }
    bool movingOrAnimating = isMovingRelativeToParent() || isAnimatingSomething();
    glm::vec3 dimensions = getDimensions();
    if ((movingOrAnimating ||
         _needsInitialSimulation ||
         _needsJointSimulation ||
         _model->getTranslation() != getPosition() ||
         _model->getScaleToFitDimensions() != dimensions ||
         _model->getRotation() != getRotation() ||
         _model->getRegistrationPoint() != getRegistrationPoint())
        && _model->isActive() && _dimensionsInitialized) {
        doInitialModelSimulation();
        _needsJointSimulation = false;
    }
}
Пример #5
0
void ParticleEffectEntityItem::update(const quint64& now) {

    float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
     _lastAnimated = now;

    // only advance the frame index if we're playing
    if (getAnimationIsPlaying()) {
        _animationLoop.simulate(deltaTime);
    }

    if (isAnimatingSomething()) {
        stepSimulation(deltaTime);

        // update the dimensions
        glm::vec3 dims;
        dims.x = glm::max(glm::abs(_particleMinBound.x), glm::abs(_particleMaxBound.x)) * 2.0f;
        dims.y = glm::max(glm::abs(_particleMinBound.y), glm::abs(_particleMaxBound.y)) * 2.0f;
        dims.z = glm::max(glm::abs(_particleMinBound.z), glm::abs(_particleMaxBound.z)) * 2.0f;
        setDimensions(dims);
    }

    EntityItem::update(now); // let our base class handle it's updates...
}
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;
}
Пример #7
0
void ModelOverlay::update(float deltatime) {
    if (_updateModel) {
        _updateModel = false;
        _model->setSnapModelToCenter(true);
        Transform transform = evalRenderTransform();
        if (_scaleToFit) {
            _model->setScaleToFit(true, transform.getScale() * getDimensions());
        } else {
            _model->setScale(transform.getScale());
        }
        _model->setRotation(transform.getRotation());
        _model->setTranslation(transform.getTranslation());
        _model->setURL(_url);
        _model->simulate(deltatime, true);
    } else {
        _model->simulate(deltatime);
    }
    _isLoaded = _model->isActive();

    if (isAnimatingSomething()) {
        if (!jointsMapped()) {
            mapAnimationJoints(_model->getJointNames());
        }
        animate();
    }

    // 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 = qApp->getMain3DScene();
    render::Transaction transaction;
    if (_model->needsFixupInScene()) {
        emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelRemovedFromScene(getID(), NestableType::Overlay, _model);
        _model->removeFromScene(scene, transaction);
        _model->addToScene(scene, transaction);

        auto newRenderItemIDs{ _model->fetchRenderItemIDs() };
        transaction.updateItem<Overlay>(getRenderItemID(), [newRenderItemIDs](Overlay& data) {
            auto modelOverlay = static_cast<ModelOverlay*>(&data);
            modelOverlay->setSubRenderItemIDs(newRenderItemIDs);
        });
        processMaterials();
        emit DependencyManager::get<scriptable::ModelProviderFactory>()->modelAddedToScene(getID(), NestableType::Overlay, _model);
    }
    if (_visibleDirty) {
        _visibleDirty = false;
        // don't show overlays in mirrors or spectator-cam unless _isVisibleInSecondaryCamera is true
        _model->setVisibleInScene(getVisible(), scene,
                                  render::ItemKey::TAG_BITS_0 |
                                  (_isVisibleInSecondaryCamera ? render::ItemKey::TAG_BITS_1 : render::ItemKey::TAG_BITS_NONE),
                                  false);
    }
    if (_drawInFrontDirty) {
        _drawInFrontDirty = false;
        _model->setLayeredInFront(getDrawInFront(), scene);
    }
    if (_drawInHUDDirty) {
        _drawInHUDDirty = false;
        _model->setLayeredInHUD(getDrawHUDLayer(), scene);
    }
    scene->enqueueTransaction(transaction);

    if (!_texturesLoaded && _model->getGeometry() && _model->getGeometry()->areTexturesLoaded()) {
        _texturesLoaded = true;
        _model->updateRenderItems();
    }
}
Пример #8
0
void RenderableModelEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RMEIrender");
    assert(getType() == EntityTypes::Model);
    
    bool drawAsModel = hasModel();

    glm::vec3 position = getPosition() * (float)TREE_SCALE;
    float size = getSize() * (float)TREE_SCALE;
    glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
    
    if (drawAsModel) {
        remapTextures();
        glPushMatrix();
        {
            float alpha = getLocalRenderAlpha();

            if (!_model || _needsModelReload) {
                // TODO: this getModel() appears to be about 3% of model render time. We should optimize
                PerformanceTimer perfTimer("getModel");
                EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
                getModel(renderer);
            }
            
            if (_model) {
                // handle animations..
                if (hasAnimation()) {
                    if (!jointsMapped()) {
                        QStringList modelJointNames = _model->getJointNames();
                        mapJoints(modelJointNames);
                    }

                    if (jointsMapped()) {
                        QVector<glm::quat> frameData = getAnimationFrame();
                        for (int i = 0; i < frameData.size(); i++) {
                            _model->setJointState(i, true, frameData[i]);
                        }
                    }
                }

                glm::quat rotation = getRotation();
                if (needsToCallUpdate() && _model->isActive()) {
                    _model->setScaleToFit(true, dimensions);
                    _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
                    _model->setRotation(rotation);
                    _model->setTranslation(position);
                    
                    // make sure to simulate so everything gets set up correctly for rendering
                    {
                        PerformanceTimer perfTimer("_model->simulate");
                        _model->simulate(0.0f);
                    }
                    _needsInitialSimulation = false;
                }

                if (_model->isActive()) {
                    // TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
                    // is significantly more expensive. Is there a way to call this that doesn't cost us as much? 
                    PerformanceTimer perfTimer("model->render");
                    // filter out if not needed to render
                    if (args && (args->_renderMode == RenderArgs::SHADOW_RENDER_MODE)) {
                        if (isMoving() || isAnimatingSomething()) {
                            _model->renderInScene(alpha, args);
                        }
                    } else {
                        _model->renderInScene(alpha, args);
                    }
                } else {
                    // if we couldn't get a model, then just draw a cube
                    glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
                    glPushMatrix();
                        glTranslatef(position.x, position.y, position.z);
                        DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size);
                    glPopMatrix();
                }
            } else {
                // if we couldn't get a model, then just draw a cube
                glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
                glPushMatrix();
                    glTranslatef(position.x, position.y, position.z);
                    DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size);
                glPopMatrix();
            }
        }
        glPopMatrix();
    } else {
        glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
        glPushMatrix();
        glTranslatef(position.x, position.y, position.z);
        DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size);
        glPopMatrix();
    }
}
Пример #9
0
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles
// the per frame simulation/update that might be required if the models properties changed.
void RenderableModelEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RMEIrender");
    assert(getType() == EntityTypes::Model);

    if (hasModel()) {
        if (_model) {
            // check if the URL has changed
            auto& currentURL = getParsedModelURL();
            if (currentURL != _model->getURL()) {
                qCDebug(entitiesrenderer).noquote() << "Updating model URL: " << currentURL.toDisplayString();
                _model->setURL(currentURL);
            }

            render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();

            // 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
            bool shouldShowCollisionHull = (args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS) > 0;
            if (_model->needsFixupInScene() || _showCollisionHull != shouldShowCollisionHull) {
                _showCollisionHull = shouldShowCollisionHull;
                render::PendingChanges pendingChanges;

                _model->removeFromScene(scene, pendingChanges);

                render::Item::Status::Getters statusGetters;
                makeEntityItemStatusGetters(getThisPointer(), statusGetters);
                _model->addToScene(scene, pendingChanges, statusGetters, _showCollisionHull);

                scene->enqueuePendingChanges(pendingChanges);
            }

            // FIXME: this seems like it could be optimized if we tracked our last known visible state in
            //        the renderable item. As it stands now the model checks it's visible/invisible state
            //        so most of the time we don't do anything in this function.
            _model->setVisibleInScene(getVisible(), scene);
        }


        remapTextures();
        {
            // float alpha = getLocalRenderAlpha();

            if (!_model || _needsModelReload) {
                // TODO: this getModel() appears to be about 3% of model render time. We should optimize
                PerformanceTimer perfTimer("getModel");
                EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
                getModel(renderer);
            }

            if (_model) {
                if (hasAnimation()) {
                    if (!jointsMapped()) {
                        QStringList modelJointNames = _model->getJointNames();
                        mapJoints(modelJointNames);
                    }
                }

                _jointDataLock.withWriteLock([&] {
                    getAnimationFrame();

                    // relay any inbound joint changes from scripts/animation/network to the model/rig
                    for (int index = 0; index < _absoluteJointRotationsInObjectFrame.size(); index++) {
                        if (_absoluteJointRotationsInObjectFrameDirty[index]) {
                            glm::quat rotation = _absoluteJointRotationsInObjectFrame[index];
                            _model->setJointRotation(index, true, rotation, 1.0f);
                            _absoluteJointRotationsInObjectFrameDirty[index] = false;
                        }
                    }
                    for (int index = 0; index < _absoluteJointTranslationsInObjectFrame.size(); index++) {
                        if (_absoluteJointTranslationsInObjectFrameDirty[index]) {
                            glm::vec3 translation = _absoluteJointTranslationsInObjectFrame[index];
                            _model->setJointTranslation(index, true, translation, 1.0f);
                            _absoluteJointTranslationsInObjectFrameDirty[index] = false;
                        }
                    }
                });

                bool movingOrAnimating = isMoving() || isAnimatingSomething();
                if ((movingOrAnimating ||
                     _needsInitialSimulation ||
                     _model->getTranslation() != getPosition() ||
                     _model->getRotation() != getRotation() ||
                     _model->getRegistrationPoint() != getRegistrationPoint())
                    && _model->isActive() && _dimensionsInitialized) {
                    _model->setScaleToFit(true, getDimensions());
                    _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
                    _model->setRotation(getRotation());
                    _model->setTranslation(getPosition());

                    // make sure to simulate so everything gets set up correctly for rendering
                    {
                        PerformanceTimer perfTimer("_model->simulate");
                        _model->simulate(0.0f);
                    }

                    _needsInitialSimulation = false;
                }
            }
        }
    } else {
        static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
        gpu::Batch& batch = *args->_batch;
        bool success;
        auto shapeTransform = getTransformToCenter(success);
        if (success) {
            batch.setModelTransform(Transform()); // we want to include the scale as well
            DependencyManager::get<GeometryCache>()->renderWireCubeInstance(batch, shapeTransform, greenColor);
        }
    }
}
Пример #10
0
bool ModelEntityItem::needsToCallUpdate() const {
    return isAnimatingSomething() || EntityItem::needsToCallUpdate();
}
Пример #11
0
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles
// the per frame simulation/update that might be required if the models properties changed.
void RenderableModelEntityItem::render(RenderArgs* args) {
    PerformanceTimer perfTimer("RMEIrender");
    assert(getType() == EntityTypes::Model);

    if (hasModel()) {
        if (_model) {
            if (getModelURL() != _model->getURL().toString()) {
                qDebug() << "Updating model URL: " << getModelURL();
                _model->setURL(getModelURL());
            }

            render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();

            // 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
            if (_model->needsFixupInScene()) {
                render::PendingChanges pendingChanges;

                _model->removeFromScene(scene, pendingChanges);

                render::Item::Status::Getters statusGetters;
                makeEntityItemStatusGetters(this, statusGetters);
                _model->addToScene(scene, pendingChanges, statusGetters);

                scene->enqueuePendingChanges(pendingChanges);
            }

            // FIXME: this seems like it could be optimized if we tracked our last known visible state in
            //        the renderable item. As it stands now the model checks it's visible/invisible state
            //        so most of the time we don't do anything in this function.
            _model->setVisibleInScene(getVisible(), scene);
        }


        remapTextures();
        {
            // float alpha = getLocalRenderAlpha();

            if (!_model || _needsModelReload) {
                // TODO: this getModel() appears to be about 3% of model render time. We should optimize
                PerformanceTimer perfTimer("getModel");
                EntityTreeRenderer* renderer = static_cast<EntityTreeRenderer*>(args->_renderer);
                getModel(renderer);
            }
            
            if (_model) {
                // handle animations..
                if (hasAnimation()) {
                    if (!jointsMapped()) {
                        QStringList modelJointNames = _model->getJointNames();
                        mapJoints(modelJointNames);
                    }

                    if (jointsMapped()) {
                        bool newFrame;
                        QVector<glm::quat> frameDataRotations;
                        QVector<glm::vec3> frameDataTranslations;
                        getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations);
                        assert(frameDataRotations.size() == frameDataTranslations.size());
                        if (newFrame) {
                            for (int i = 0; i < frameDataRotations.size(); i++) {
                                _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f);
                            }
                        }
                    }
                }

                bool movingOrAnimating = isMoving() || isAnimatingSomething();
                if ((movingOrAnimating || _needsInitialSimulation) && _model->isActive() && _dimensionsInitialized) {
                    _model->setScaleToFit(true, getDimensions());
                    _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
                    _model->setRotation(getRotation());
                    _model->setTranslation(getPosition());
                    
                    // make sure to simulate so everything gets set up correctly for rendering
                    {
                        PerformanceTimer perfTimer("_model->simulate");
                        _model->simulate(0.0f);
                    }
                    
                    _needsInitialSimulation = false;
                }
            }
        }
    } else {
        glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
        RenderableDebugableEntityItem::renderBoundingBox(this, args, 0.0f, greenColor);
    }

    RenderableDebugableEntityItem::render(this, args);
}
Пример #12
0
bool ParticleEffectEntityItem::needsToCallUpdate() const {
    return isAnimatingSomething() ? true : EntityItem::needsToCallUpdate();
}