void SCAnimationDirector::navigateToPage(int index) { if (m_pageEffectRunner) { m_pageEffectRunner->finish(); finishAnimations(); // finish on first step m_timeLine.stop(); } else if (m_timeLine.state() == QTimeLine::Running) { // there are still shape animations running finishAnimations(); m_timeLine.stop(); } m_pageIndex = index; KoPAPage *page = m_pages[m_pageIndex]; m_stepIndex = 0; updateActivePage(page); updatePageAnimation(); updateStepAnimation(); // trigger a repaint m_canvas->update(); if (hasAnimation()) { startTimeLine(m_animations.at(m_stepIndex)->totalDuration()); } }
bool SpriteAnimationCollection::operator == (const SpriteAnimationCollection & s) const { if(m_animations.size() != s.m_animations.size()) { return false; } for(unsigned int i=0;i<s.m_animations.size();i++) { if(!hasAnimation(*s.m_animations[i])) { return false; } } return true; }
/** * This method will add an animation path to the given node. */ void OSGExp::addAnimation(INode* node, TimeValue t, osg::Node* osgNode){ if (!hasAnimation(node)) return; osg::AnimationPath* animationPath = createAnimationPath(node,t); if(animationPath){ osgNode->setUpdateCallback(new osg::AnimationPathCallback(animationPath)); osgNode->setDataVariance(osg::Object::DYNAMIC); // TSTR string; // if (node->GetUserPropString("animation",string)) // osgNode->setName(string.data()); } }
// ---------------------------------------------------------------------------- void Flyable::restoreState(BareNetworkString *buffer, int count) { btTransform t; Vec3 lv, av; CompressNetworkBody::decompress(buffer, &t, &lv, &av); if (!hasAnimation()) { m_body->setWorldTransform(t); m_motion_state->setWorldTransform(t); m_body->setInterpolationWorldTransform(t); m_body->setLinearVelocity(lv); m_body->setAngularVelocity(av); m_body->setInterpolationLinearVelocity(lv); m_body->setInterpolationAngularVelocity(av); setTrans(t); } m_ticks_since_thrown = buffer->getUInt16(); m_has_server_state = true; } // restoreState
void SCAnimationDirector::paint(QPainter &painter, const QRectF &paintRect) { if (m_pageEffectRunner) { bool finished = m_pageEffectRunner->isFinished(); if (!m_pageEffectRunner->paint(painter)) { delete m_pageEffectRunner; m_pageEffectRunner = 0; // check if there where a animation to start if (hasAnimation()) { if (finished) { QRect clipRect = m_pageRect.intersected(paintRect.toRect()); painter.setClipRect(clipRect); painter.setRenderHint(QPainter::Antialiasing); paintStep(painter); } else { // start the animations startTimeLine(m_animations.at(m_stepIndex)->totalDuration()); } } } } else { QRect clipRect = m_pageRect.intersected(paintRect.toRect()); painter.setClipRect(clipRect); painter.setRenderHint(QPainter::Antialiasing); paintStep(painter); } // This is needed as otherwise on some ATI graphic cards it leads to // 100% CPU load of the x server and no more key events are received // until the page effect is finished. With it is made sure that key // events still get through so that it is possible to cancel the // events. It looks like this is not a problem with nvidia graphic // cards. KApplication::kApplication()->syncX(); }
void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { // if we don't have animation, or we're already joint mapped then bail early if (!hasAnimation() || jointsMapped()) { return; } if (!_animation || _animation->getURL().toString() != getAnimationURL()) { _animation = DependencyManager::get<AnimationCache>()->getAnimation(getAnimationURL()); } if (_animation && _animation->isLoaded()) { QStringList animationJointNames = _animation->getJointNames(); if (modelJointNames.size() > 0 && animationJointNames.size() > 0) { _jointMapping.resize(modelJointNames.size()); for (int i = 0; i < modelJointNames.size(); i++) { _jointMapping[i] = animationJointNames.indexOf(modelJointNames[i]); } _jointMappingCompleted = true; _jointMappingURL = _animationProperties.getURL(); } } }
/** * This method will create and return an animation path. */ osg::AnimationPath* OSGExp::createAnimationPath(INode *node, TimeValue t){ // Get the controllers from the node. Control* pC = node->GetTMController()->GetPositionController(); Control* rC = node->GetTMController()->GetRotationController(); Control* sC = node->GetTMController()->GetScaleController(); // Are we using TCB, Linear, and Bezier keyframe controllers. if (isExportable(pC) && isExportable(rC) && isExportable(sC)) { if (pC->NumKeys() || rC->NumKeys() || sC->NumKeys()) { // Create the animation path. osg::AnimationPath* animationPath = new osg::AnimationPath(); animationPath->setLoopMode(osg::AnimationPath::LOOP); exportPosKeys(animationPath, pC); return animationPath; } } // Or are we using other kinds of animations which can be sampled lineary. if(hasAnimation(node)){ return sampleNode(node); } return NULL; }
SCAnimationDirector::SCAnimationDirector(KoPAView * view, KoPACanvas * canvas, const QList<KoPAPage*> &pages, KoPAPage* currentPage) : m_view(view) , m_canvas(canvas) , m_pages(pages) , m_pageEffectRunner(0) , m_stepIndex(0) , m_maxShapeDuration(0) , m_hasAnimation(false) , m_animationCache(0) { Q_ASSERT(!m_pages.empty()); m_animationCache = new SCAnimationCache(); if(!currentPage || !pages.contains(currentPage)) updateActivePage(m_pages[0]); else updateActivePage(currentPage); m_pageIndex = m_pages.indexOf(m_view->activePage()); // updatePageAnimation was called from updateZoom() [updateActivePage()] connect(&m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animate())); // this is needed as after a call to m_canvas->showFullScreen the canvas is not made fullscreen right away connect(m_canvas, SIGNAL(sizeChanged(const QSize &)), this, SLOT(updateZoom(const QSize &))); m_timeLine.setCurveShape(QTimeLine::LinearCurve); m_timeLine.setUpdateInterval(20); // set the animation strategy in the KoShapeManagers m_canvas->shapeManager()->setPaintingStrategy(new SCShapeManagerAnimationStrategy(m_canvas->shapeManager(), m_animationCache, new SCPageSelectStrategyActive(m_view->kopaCanvas()))); // m_canvas->masterShapeManager()->setPaintingStrategy(new SCShapeManagerAnimationStrategy(m_canvas->masterShapeManager(), m_animationCache, // new SCPageSelectStrategyActive(m_view->kopaCanvas()))); if (hasAnimation()) { startTimeLine(m_animations.at(m_stepIndex)->totalDuration()); } }
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) { 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 (needsSimulation() && _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; } // TODO: should we allow entityItems to have alpha on their models? Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; 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"); _model->render(alpha, modelRenderMode, 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); Application::getInstance()->getDeferredLightingEffect()->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); Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size); glPopMatrix(); } } glPopMatrix(); } else { glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]); glPushMatrix(); glTranslatef(position.x, position.y, position.z); Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size); glPopMatrix(); } }
/** Updates this flyable. It calls Moveable::update. If this function returns * true, the flyable will be deleted by the projectile manager. * \param dt Time step size. * \returns True if this object can be deleted. */ bool Flyable::updateAndDelete(int ticks) { if (m_undo_creation) return false; if (hasAnimation()) { if (!RewindManager::get()->isRewinding()) { m_animation->update(ticks); Moveable::update(ticks); } return false; } // if animation m_ticks_since_thrown += ticks; if(m_max_lifespan > -1 && m_ticks_since_thrown > m_max_lifespan) hit(NULL); if(m_has_hit_something) return true; //Vec3 xyz=getBody()->getWorldTransform().getOrigin(); const Vec3 &xyz=getXYZ(); // Check if the flyable is outside of the track. If so, explode it. const Vec3 *min, *max; Track::getCurrentTrack()->getAABB(&min, &max); // I have seen that the bullet AABB can be slightly different from the // one computed here - I assume due to minor floating point errors // (e.g. 308.25842 instead of 308.25845). To avoid a crash with a bullet // assertion (see bug 3058932) I add an epsilon here - but admittedly // that does not really explain the bullet crash, since bullet tests // against its own AABB, and should therefore not cause the assertion. // But since we couldn't reproduce the problem, and the epsilon used // here does not hurt, I'll leave it in. float eps = 0.1f; assert(!std::isnan(xyz.getX())); assert(!std::isnan(xyz.getY())); assert(!std::isnan(xyz.getZ())); if(xyz[0]<(*min)[0]+eps || xyz[2]<(*min)[2]+eps || xyz[1]<(*min)[1]+eps || xyz[0]>(*max)[0]-eps || xyz[2]>(*max)[2]-eps || xyz[1]>(*max)[1]-eps ) { hit(NULL); // flyable out of track boundary return true; } if (m_do_terrain_info) { Vec3 towards = getBody()->getGravity(); towards.normalize(); // Add the position offset so that the flyable can adjust its position // (usually to do the raycast from a slightly higher position to avoid // problems finding the terrain in steep uphill sections). // Towards is a unit vector. so we can multiply -towards to offset the // position by one unit. TerrainInfo::update(xyz + m_position_offset*(-towards), towards); // Make flyable anti-gravity when the it's projected on such surface const Material* m = TerrainInfo::getMaterial(); if (m && m->hasGravity()) { getBody()->setGravity(TerrainInfo::getNormal() * -70.0f); } else { getBody()->setGravity(Vec3(0, 1, 0) * -70.0f); } } if(m_adjust_up_velocity) { float hat = (xyz - getHitPoint()).length(); // Use the Height Above Terrain to set the Z velocity. // HAT is clamped by min/max height. This might be somewhat // unphysical, but feels right in the game. float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height); Vec3 v = getVelocity(); assert(!std::isnan(v.getX())); assert(!std::isnan(v.getX())); assert(!std::isnan(v.getX())); float heading = atan2f(v.getX(), v.getZ()); assert(!std::isnan(heading)); float pitch = getTerrainPitch(heading); float vel_up = m_force_updown*(delta); if (hat < m_max_height) // take into account pitch of surface vel_up += v.length_2d()*tanf(pitch); assert(!std::isnan(vel_up)); v.setY(vel_up); setVelocity(v); } // if m_adjust_up_velocity Moveable::update(ticks); return false; } // updateAndDelete
// 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); } } }
bool RenderableModelEntityItem::getAnimationFrame() { bool newFrame = false; if (!_model || !_model->isActive() || !_model->isLoaded() || _needsInitialSimulation) { return false; } if (!hasAnimation() || !_jointMappingCompleted) { return false; } AnimationPointer myAnimation = getAnimation(_animationProperties.getURL()); // FIXME: this could be optimized if (myAnimation && myAnimation->isLoaded()) { const QVector<FBXAnimationFrame>& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy auto& fbxJoints = myAnimation->getGeometry().joints; int frameCount = frames.size(); if (frameCount > 0) { int animationCurrentFrame = (int)(glm::floor(getAnimationCurrentFrame())) % frameCount; if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) { animationCurrentFrame = 0; } if (animationCurrentFrame != _lastKnownCurrentFrame) { _lastKnownCurrentFrame = animationCurrentFrame; newFrame = true; resizeJointArrays(); if (_jointMapping.size() != _model->getJointStateCount()) { qDebug() << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch" << _jointMapping.size() << _model->getJointStateCount(); assert(false); return false; } const QVector<glm::quat>& rotations = frames[animationCurrentFrame].rotations; const QVector<glm::vec3>& translations = frames[animationCurrentFrame].translations; for (int j = 0; j < _jointMapping.size(); j++) { int index = _jointMapping[j]; if (index >= 0) { glm::mat4 translationMat; if (index < translations.size()) { translationMat = glm::translate(translations[index]); } glm::mat4 rotationMat(glm::mat4::_null); if (index < rotations.size()) { rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); } else { rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * fbxJoints[index].postRotation); } glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform * rotationMat * fbxJoints[index].postTransform); _absoluteJointTranslationsInObjectFrame[j] = extractTranslation(finalMat); _absoluteJointTranslationsInObjectFrameSet[j] = true; _absoluteJointTranslationsInObjectFrameDirty[j] = true; _absoluteJointRotationsInObjectFrame[j] = glmExtractRotation(finalMat); _absoluteJointRotationsInObjectFrameSet[j] = true; _absoluteJointRotationsInObjectFrameDirty[j] = true; } } } } } return newFrame; }
// 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); }
void RenderableModelEntityItem::render(RenderArgs* args) { PerformanceTimer perfTimer("RMEIrender"); assert(getType() == EntityTypes::Model); bool drawAsModel = hasModel(); glm::vec3 position = getPosition(); glm::vec3 dimensions = getDimensions(); float size = glm::length(dimensions); bool highlightSimulationOwnership = false; if (args->_debugFlags & RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP) { auto nodeList = DependencyManager::get<NodeList>(); const QUuid& myNodeID = nodeList->getSessionUUID(); highlightSimulationOwnership = (getSimulatorID() == myNodeID); } if (drawAsModel && !highlightSimulationOwnership) { 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(); bool movingOrAnimating = isMoving() || isAnimatingSomething(); if ((movingOrAnimating || _needsInitialSimulation) && _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 (movingOrAnimating) { _model->renderInScene(alpha, args); } } else { _model->renderInScene(alpha, args); } } else { // if we couldn't get a model, then just draw a cube glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f); glPushMatrix(); glTranslatef(position.x, position.y, position.z); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color); glPopMatrix(); } } else { // if we couldn't get a model, then just draw a cube glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f); glPushMatrix(); glTranslatef(position.x, position.y, position.z); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color); glPopMatrix(); } } glPopMatrix(); } else { glm::vec4 color(getColor()[RED_INDEX]/255, getColor()[GREEN_INDEX]/255, getColor()[BLUE_INDEX]/255, 1.0f); glPushMatrix(); glTranslatef(position.x, position.y, position.z); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(size, color); glPopMatrix(); } }
/** * Export Transform node (and related animations) */ osg::ref_ptr<osg::Group> Transform::exporta(MObject &obj) { MFnDependencyNode dn(obj); MFnTransform trfn(obj); MMatrix mat = trfn.transformationMatrix(); osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(); osg::Matrix osgmat; mat.get( (double(*)[4]) osgmat.ptr() ); trans->setMatrix(osgmat); if ( Config::instance()->getAnimTransformType() == Config::OSG_ANIMATION ) { Animation::mapInputConnections(obj , trans ) ; } else { /// Check if there is any animation connected to this Transform MFn::Type anim_type; if( Config::instance()->getExportAnimations() && hasAnimation(obj,anim_type)){ #ifdef _DEBUG std::cout << "Transform " << dn.name().asChar() << " is animated" << std::endl; #endif // Check the Transform parameters double shear[3]; trfn.getShear(shear); // std::cout << "SHEAR: " << shear[0] << " " << shear[1] << " " << shear[2] << std::endl; MPoint sp = trfn.scalePivot(MSpace::kTransform); // std::cout << "SCALE PIVOT: " << sp.x << " " << sp.y << " " << sp.z << " " << sp.w << std::endl; MVector spt = trfn.scalePivotTranslation(MSpace::kTransform); // std::cout << "SCALE PIVOT TRANSLATION: " << spt.x << " " << spt.y << " " << spt.z << std::endl; MPoint rp = trfn.rotatePivot(MSpace::kTransform); // std::cout << "ROTATE PIVOT: " << rp.x << " " << rp.y << " " << rp.z << " " << rp.w << std::endl; MVector rpt = trfn.rotatePivotTranslation(MSpace::kTransform); // std::cout << "ROTATE PIVOT TRANSLATION: " << rpt.x << " " << rpt.y << " " << rpt.z << std::endl; if( shear[0]!=0 || shear[1]!=0 || shear[2]!=0 ){ std::cerr << "WARNING (" << dn.name().asChar() << ") - shear value not supported in animated Transforms (" << shear[0] << ", " << shear[1] << ", " << shear[2] << ")" << std::endl; } if( sp.x != 0 || sp.y != 0 || sp.z != 0 || sp.w != 1 ){ std::cerr << "WARNING (" << dn.name().asChar() << ") - scale pivot not supported in animated Transforms ; SP=(" << sp.x << ", " << sp.y << ", " << sp.z << ", " << sp.w << ")" << std::endl; } if( spt.x != 0 || spt.y != 0 || spt.z != 0 ){ std::cerr << "WARNING (" << dn.name().asChar() << ") - scale pivot translation not supported in animated Transforms ; SPT=(" << spt.x << ", " << spt.y << ", " << spt.z << ")" << std::endl; } if( rp.x != 0 || rp.y != 0 || rp.z != 0 || rp.w != 1 ){ std::cerr << "WARNING (" << dn.name().asChar() << ") - rotate pivot not supported in animated Transforms ; RP=(" << rp.x << ", " << rp.y << ", " << rp.z << ", " << rp.w << ")" << std::endl; } if( rpt.x != 0 || rpt.y != 0 || rpt.z != 0 ){ std::cerr << "WARNING (" << dn.name().asChar() << ") - rotate pivot translation not supported in animated Transforms ; RPT=(" << rpt.x << ", " << rpt.y << ", " << rpt.z << ")" << std::endl; } // Create a callback to bind the animation to this transform osg::ref_ptr< osg::AnimationPath > ap; #ifdef GENERIC_EXPORTER // New code to create the animation path. Independent of kind of animation. // It bakes any animation, not only animCurves and motionPaths, but also expressions or whatever ap = animatedTransform2AnimationPath(obj); #else switch(anim_type){ case MFn::kAnimCurve: ap = animCurve2AnimationPath(obj); break; case MFn::kMotionPath: ap = motionPath2AnimationPath(obj); break; } #endif trans->setUpdateCallback( new osg::AnimationPathCallback( ap.get() )); } } // ANIMATION_PATH return (osg::Group *)trans.get(); }