void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIndex, int nextPoseIndex, float* prevDeltaTimeOut, float* nextDeltaTimeOut, Triggers& triggersOut) { const float FRAMES_PER_SECOND = 30.0f; auto prevClipNode = std::dynamic_pointer_cast<AnimClip>(_children[prevPoseIndex]); assert(prevClipNode); auto nextClipNode = std::dynamic_pointer_cast<AnimClip>(_children[nextPoseIndex]); assert(nextClipNode); float v0 = _characteristicSpeeds[prevPoseIndex]; float n0 = (prevClipNode->getEndFrame() - prevClipNode->getStartFrame()) + 1.0f; float v1 = _characteristicSpeeds[nextPoseIndex]; float n1 = (nextClipNode->getEndFrame() - nextClipNode->getStartFrame()) + 1.0f; // rate of change in phase space, necessary to achive desired speed. float omega = (_desiredSpeed * FRAMES_PER_SECOND) / ((1.0f - alpha) * v0 * n0 + alpha * v1 * n1); float f0 = prevClipNode->getStartFrame() + _phase * n0; prevClipNode->setCurrentFrame(f0); float f1 = nextClipNode->getStartFrame() + _phase * n1; nextClipNode->setCurrentFrame(f1); // integrate phase forward in time. _phase += omega * dt; // detect loop trigger events if (_phase >= 1.0f) { triggersOut.push_back(_id + "Loop"); _phase = glm::fract(_phase); } *prevDeltaTimeOut = omega * dt * (n0 / FRAMES_PER_SECOND); *nextDeltaTimeOut = omega * dt * (n1 / FRAMES_PER_SECOND); }
size_t Model::alignFromReference(size_t refFrame) const { if (!m_alignment) { if (m_sourceModel) return m_sourceModel->alignFromReference(refFrame); else return refFrame; } size_t frame = m_alignment->fromReference(refFrame); if (frame > getEndFrame()) frame = getEndFrame(); return frame; }
void AnimBlendLinearMove::setCurrentFrameInternal(float frame) { assert(_children.size() > 0); auto clipNode = std::dynamic_pointer_cast<AnimClip>(_children.front()); assert(clipNode); const float NUM_FRAMES = (clipNode->getEndFrame() - clipNode->getStartFrame()) + 1.0f; _phase = fmodf(frame, NUM_FRAMES); }
void CAnimatedMeshSceneNode::useAnimationSet(u32 set_num) { if (m_animation_set.empty()) { setFrameLoop(getStartFrame(), getEndFrame()); return; } setFrameLoop(m_animation_set[set_num * 2], m_animation_set[set_num * 2 + 1]); }
void Model::toXml(QTextStream &stream, QString indent, QString extraAttributes) const { stream << indent; stream << QString("<model id=\"%1\" name=\"%2\" sampleRate=\"%3\" start=\"%4\" end=\"%5\" %6/>\n") .arg(getObjectExportId(this)) .arg(encodeEntities(objectName())) .arg(getSampleRate()) .arg(getStartFrame()) .arg(getEndFrame()) .arg(extraAttributes); }
void PointsFileSystem::navigateToNextFrame() { int current_frame = getDisplayFirstFrame()->getFrame(); if (current_frame == getEndFrame()) return; int next_frame = current_frame + 1; hideAndShowPointCloud(current_frame, next_frame); return; }
bool GAFAnimation::playSequence(const char * name, bool looped, bool _resume, AnimSetSequenceHint hint) { if (!m_asset) { return false; } if (!name) { return false; } int s = getStartFrame(name); int e = getEndFrame(name); if (-1 == s || -1 == e) { return false; } m_currentSequenceStart = s; m_currentSequenceEnd = e; if (_currentFrameIndex < m_currentSequenceStart || _currentFrameIndex >m_currentSequenceEnd) { _currentFrameIndex = m_currentSequenceStart; } else { if (hint == ASSH_RESTART) { _currentFrameIndex = m_currentSequenceStart; } else { // new hints may appear } } setLooped(looped); if (_resume) { resumeAnimation(); } else { stop(); } return true; }
bool GAFObject::playSequence(const std::string& name, bool looped, bool resume /*= true*/) { if (!m_asset || !m_timeline) { return false; } if (name.empty()) { return false; } uint32_t s = getStartFrame(name); uint32_t e = getEndFrame(name); if (IDNONE == s || IDNONE == e) { return false; } m_currentSequenceStart = s; m_currentSequenceEnd = e; m_currentFrame = m_isReversed ? (e - 1) : (s); setLooped(looped, false); if (resume) { resumeAnimation(); } else { stop(); } return true; }
//! updates the absolute position based on the relative and the parents position void CAnimatedMeshSceneNode::updateAbsolutePosition() { if ( 0 == Mesh || Mesh->getMeshType() != EAMT_MD3 ) { IAnimatedMeshSceneNode::updateAbsolutePosition(); return; } SMD3QuaterionTag parent; if ( Parent && Parent->getType () == ESNT_ANIMATED_MESH) { parent = ((IAnimatedMeshSceneNode*) Parent)->getAbsoluteTransformation ( MD3Special.Tagname ); } SMD3QuaterionTag relative( RelativeTranslation, RelativeRotation ); SMD3QuaterionTagList *taglist; taglist = ( (IAnimatedMeshMD3*) Mesh )->getTagList ( getFrameNr(),255,getStartFrame (),getEndFrame () ); if ( taglist ) { MD3Special.AbsoluteTagList.Container.set_used ( taglist->size () ); for ( u32 i = 0; i!= taglist->size (); ++i ) { MD3Special.AbsoluteTagList[i].position = parent.position + (*taglist)[i].position + relative.position; MD3Special.AbsoluteTagList[i].rotation = parent.rotation * (*taglist)[i].rotation * relative.rotation; } } }
//! renders the node. void CAnimatedMeshSceneNode::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if (!Mesh || !driver) return; bool isTransparentPass = SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; ++PassCount; s32 frame = getFrameNr(); scene::IMesh* m = Mesh->getMesh(frame, 255, StartFrame, EndFrame); if ( 0 == m ) { #ifdef _DEBUG os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING); #endif } driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); u32 i,g; // update all dummy transformation nodes if (!JointChildSceneNodes.empty() && Mesh && (Mesh->getMeshType() == EAMT_MS3D || Mesh->getMeshType() == EAMT_X || Mesh->getMeshType() == EAMT_B3D )) { IAnimatedMeshMS3D* amm = (IAnimatedMeshMS3D*)Mesh; core::matrix4* m; for ( i=0; i< JointChildSceneNodes.size(); ++i) if (JointChildSceneNodes[i]) { m = amm->getMatrixOfJoint(i, frame); if (m) JointChildSceneNodes[i]->getRelativeTransformationMatrix() = *m; } } if (Shadow && PassCount==1) Shadow->setMeshToRenderFrom(m); // for debug purposes only: u32 renderMeshes = 1; video::SMaterial mat; if (DebugDataVisible && PassCount==1) { // overwrite half transparency if ( DebugDataVisible & scene::EDS_HALF_TRANSPARENCY ) { for ( g=0; g<m->getMeshBufferCount(); ++g) { mat = Materials[g]; mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; driver->setMaterial(mat); driver->drawMeshBuffer ( m->getMeshBuffer ( g ) ); } renderMeshes = 0; } } // render original meshes if ( renderMeshes ) { for ( i=0; i<m->getMeshBufferCount(); ++i) { video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); bool transparent = (rnd && rnd->isTransparent()); // only render transparent buffer if this is the transparent render pass // and solid only in solid pass if (transparent == isTransparentPass) { scene::IMeshBuffer* mb = m->getMeshBuffer(i); driver->setMaterial(Materials[i]); driver->drawMeshBuffer(mb); } } } // for debug purposes only: if (DebugDataVisible && PassCount==1) { mat.Lighting = false; driver->setMaterial(mat); // show bounding box if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS ) { for ( g=0; g< m->getMeshBufferCount(); ++g) { driver->draw3DBox( m->getMeshBuffer(g)->getBoundingBox(), video::SColor(0,190,128,128) ); } } if ( DebugDataVisible & scene::EDS_BBOX ) driver->draw3DBox(Box, video::SColor(0,255,255,255)); // show skeleton if ( DebugDataVisible & scene::EDS_SKELETON ) { if (Mesh->getMeshType() == EAMT_X) { // draw skeleton const core::array<core::vector3df>* ds = ((IAnimatedMeshX*)Mesh)->getDrawableSkeleton(frame); for ( g=0; g < ds->size(); g +=2 ) driver->draw3DLine((*ds)[g], (*ds)[g+1], video::SColor(0,51,66,255)); } // show tag for quake3 models if (Mesh->getMeshType() == EAMT_MD3 ) { IAnimatedMesh * arrow = SceneManager->addArrowMesh ( "__tag_show", 4, 8, 5.f, 4.f, 0.5f, 1.f, 0xFF0000FF, 0xFF000088 ); if ( 0 == arrow ) { arrow = SceneManager->getMesh ( "__tag_show" ); } IMesh *arrowMesh = arrow->getMesh ( 0 ); video::SMaterial material; material.Lighting = false; driver->setMaterial(material); core::matrix4 m; SMD3QuaterionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList ( getFrameNr(), 255, getStartFrame (), getEndFrame () ); if ( taglist ) { for ( u32 g = 0; g != taglist->size(); ++g ) { (*taglist)[g].setto ( m ); driver->setTransform(video::ETS_WORLD, m ); for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a ) driver->drawMeshBuffer ( arrowMesh->getMeshBuffer ( a ) ); } } } } // show normals if ( DebugDataVisible & scene::EDS_NORMALS ) { IAnimatedMesh * arrow = SceneManager->addArrowMesh ( "__debugnormal", 4, 8, 1.f, 0.6f, 0.05f, 0.3f, 0xFFECEC00, 0xFF999900 ); if ( 0 == arrow ) { arrow = SceneManager->getMesh ( "__debugnormal" ); } IMesh *mesh = arrow->getMesh ( 0 ); // find a good scaling factor core::matrix4 m2; // draw normals for ( g=0; g<m->getMeshBufferCount(); ++g) { scene::IMeshBuffer* mb = m->getMeshBuffer(g); const u32 vSize = mb->getVertexPitch(); const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices(); for ( i = 0; i != mb->getVertexCount(); ++i ) { AlignToUpVector ( m2, v->Normal ); AbsoluteTransformation.transformVect ( m2.pointer(), v->Pos ); driver->setTransform(video::ETS_WORLD, m2 ); for ( u32 a = 0; a != mesh->getMeshBufferCount(); ++a ) driver->drawMeshBuffer ( mesh->getMeshBuffer ( a ) ); v = (const video::S3DVertex*) ( (u8*) v + vSize ); } } driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); } // show mesh if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY ) { mat.Lighting = false; mat.Wireframe = true; driver->setMaterial(mat); for ( g=0; g<m->getMeshBufferCount(); ++g) { driver->drawMeshBuffer ( m->getMeshBuffer ( g ) ); } } } }