osgAnimation 애니메이션 관리자
5299 단어 OSGosgAnimation
간단한 소개
이전 osgAnimation의 역할 대상에 대한 글에서 UpdateMatrixTransform 예시에서 우리는 UpdateCallback을 추가함으로써 애니메이션을 실현했다. 사실상 osgAnimation는 우리에게 기본적인 애니메이션 처리 클래스인 BasicAnimation Manager를 제공했다. 이 클래스는 NodeCallback에서 계승하여 여러 개의 애니메이션 대상의 관리를 맡았다. 이제 어떻게 실현되는지 살펴보자.
애니메이션 관리자
애니메이션 관리자에는 다음과 같은 몇 가지 종류가 있는데 그것이 바로 LinkVisitor,AnimationManagerBase,BasicAnimationManager이다. 다음은 이런 종류의 실현을 살펴보자.
LinkVisitor
Animation Manager Base에 사용되는 내부 보조 클래스는 하위 장면 아래의 역할 대상(Update Matrix Transform 등)을 훑어보는 데 사용된다. 우리는 개발 코드에서 이 클래스를 직접 사용하지 않는다. 다음은 이 클래스의 역할을 중점적으로 살펴본다. 코드는 다음과 같다.
void LinkVisitor::apply(osg::Node& node)
{
osg::StateSet* st = node.getStateSet();
if (st)
handle_stateset(st);
osg::NodeCallback* cb = node.getUpdateCallback();
while (cb)
{
osgAnimation::AnimationUpdateCallbackBase* cba = dynamic_cast<osgAnimation::AnimationUpdateCallbackBase*>(cb);
if (cba)
link(cba);
cb = cb->getNestedCallback();
}
traverse(node);
}
void LinkVisitor::apply(osg::Geode& node)
{
for (unsigned int i = 0; i < node.getNumDrawables(); i++)
{
osg::Drawable* drawable = node.getDrawable(i);
if (drawable && drawable->getStateSet())
handle_stateset(drawable->getStateSet());
}
apply(static_cast<osg::Node&>(node));
}
NodeVisitor는 NodeVisitor입니다. 이것은 우리가 그것이 작용 대상을 수집하는 데 사용되고, 작용 대상과Animation을 링크로 하는 것을 실현합니다. (실질적으로 채널과 작용 대상을 링크로 진행했습니다.) 즉 채널에서 연산 결과를 저장하는 데 사용되는 Target 대상을 작용 대상 중 그룹의 요소로 설정하는 Target (Stacked Transform Element의 target을 채널에 저장할 예정입니다)
AnimationManagerBase
AnimationManagerBase는 애니메이션 관리자의 기본 클래스로 애니메이션 관리자가 필요로 하는 기본 기능을 제공합니다. 이 클래스는 가상 기본 클래스이고 파생 클래스가 업데이트 구성원 함수를 실현해야 합니다.이 클래스는 NodeCallback이기 때문에 Operator () 조작부호를 다시 불러올 것입니다. 그 안에 무엇을 했는지 살펴보겠습니다.
void AnimationManagerBase::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
if (needToLink())
{
link(node);
}
const osg::FrameStamp* fs = nv->getFrameStamp();
update(fs->getSimulationTime());
}
traverse(node,nv);
}
osgAnimation의 작용 대상에서 UpdateMatrixTransform의 예를 비교해 보면 PlayCallback은 이런 종류와 유사하다는 것을 알 수 있다. 이 업데이트(fs->getsimulationTime() 호출은 전체Animation 애니메이션을 구동하고 전체 애니메이션을 한 프레임 한 프레임 움직이게 한다.또한 osgAnimation의 역할 대상에서 UpdateMatrixTransform의 예에서 PlayCallback을 애니메이션 서브 장면(구 노드)의 부모 노드로 설정하고 장면이 애니메이션 서브 노드에 이르기 전에 플레이Callback을 통해 애니메이션 서브 노드 위에 있는 MatrixTransform의 행렬 값을 업데이트하여 애니메이션 서브 장면을 두루 돌아다닐 때 서브 장면의 위치를 변동시키는 효과를 실현한다.같은 이치로 여기AnimationManagerBase도 이렇게 할 수 있겠지!맞아요, 바로 그렇습니다.위 코드에서 링크 (node) 는 이렇게 하는 것입니다. 실현을 살펴보겠습니다.
void AnimationManagerBase::link(osg::Node* subgraph)
{
LinkVisitor* linker = getOrCreateLinkVisitor();
linker->getAnimationList().clear();
linker->getAnimationList() = _animations;
subgraph->accept(*linker);
_needToLink = false;
buildTargetReference();
}
LinkVisitor를 통해 모든 StackedTransform Element의 Target를Channel에 설정하고 업데이트(fs->getsimulationTime())를 통해 모든 Channel의 Target 값을 업데이트합니다.업데이트 (fs->getsimulationTime ()) 가 도대체 무엇을 했는지 이어서 읽어 주십시오.BasicAnimationManager
이 클래스는 Animation ManagerBase 클래스를 통합하고 업데이트 방법을 다시 작성한 것입니다. 이것은 코드에서 가장 자주 사용하는 관리자 클래스입니다. 업데이트에서 무엇을 했는지 보십시오.
void BasicAnimationManager::update (double time)
{
_lastUpdate = time;
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); ++it)
(*it).get()->reset();
// std::map , ,
for( AnimationLayers::reverse_iterator iterAnim = _animationsPlaying.rbegin(); iterAnim != _animationsPlaying.rend(); ++iterAnim )
{
std::vector<int> toremove;
int priority = iterAnim->first;
AnimationList& list = iterAnim->second;
for (unsigned int i = 0; i < list.size(); i++)
{
if (! list[i]->update(time, priority))
{
toremove.push_back(i);
}
}
while (!toremove.empty())
{
list.erase(list.begin() + toremove.back());
toremove.pop_back();
}
}
}
여기의AnimationLayers는 이렇게 정의합니다. typedef std::map총결산
상술한 분석을 결합하여 우리는 관리자가 하는 일은 실제적으로 업데이트 리셋 구동 데이터를 사용하여 업데이트를 완성하는 것임을 알았다.다음과 같은 절차가 필요합니다.
1. 장면에서의 작용 대상(UpdateMatrixTransform)의 요소(즉 StackedTransformElement)의Target를Channel에 설정하여Target가 데이터를 전송하는 유대를 구축한다.이 절차는 LinkVisitor를 통해 수행됩니다.
2. 리셋 중 업데이트의 호출을 업데이트합니다. 이 업데이트의 호출은 일련의 연쇄 반응을 일으켜 Animation의 모든 채널의 업데이트를 한 번 호출합니다. 실질적으로 채널에 있는 모든 Target의 업데이트를 호출하여 데이터의 업데이트를 완성합니다. 이 과정은 BasicAnimationManager의 업데이트에서 완성됩니다.
이 수업의 인스턴스는 osg Examples의 osganimationsolid 예를 참조하십시오.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
osgAnimation 애니메이션 관리자이 클래스는 NodeCallback에서 계승하여 여러 개의 애니메이션 대상의 관리를 맡았다. (실질적으로 채널과 작용 대상을 링크로 진행했습니다.) 즉 채널에서 연산 결과를 저장하는 데 사용되는 Target 대상을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.