게임브리오에서 노드들의 위치 및 경계구(Bounding sphere)를 업데이트하는 함수는 NiAVObject에 있는 Update 함수입니다.
초기 게임브리오 엔진(NetImmerse)에서는 Update 함수가 애니메이션을 항상 업데이트하게 되어 있었습니다. 그러나 지금은 애니메이션을 필요에 따라서 할 수 있습니다. 그 외에도 여러가지 형태로 Update를 제공하고 있습니다만, 기본적으로 비슷합니다.
가장 많이 헷갈리는 것이 바로 Update(0.0f)의 의미입니다.
Update(0.0f)는 초기화과정으로 반드시 루트노드(Root node or top node)는 이 과정을 거쳐야 합니다. 이 과정이 없으면 프로그램은 정상적으로 동작하지 않으며, 심각한 오류를 발생시킵니다. 루트노드가 아니라면? 굳이 안 하셔도 됩니다. 그러나 Directional light 등은 그 자체가 루트 노드가 되기 때문에 반드시 해주셔야 합니다.
Update 함수는 기본적으로 애니메이션이 들어간 경우와 노드의 추가 삭제가 발생한 경우 불려져야 합니다. Update 함수의 시간은 현재시간을 불러주면 되지만, 이 시간 함수는 애니메이션에만 적용되는 것이므로 애니메이션이 없는 경우에는 특별하게 이 값에 신경쓰시지 않아도 됩니다. 그리고 애니메이션마다 애니메이션 속도 컨트롤이 들어간다면, 이 값은 꼭 현재시간이라고 볼 수 없습니다.
Update 함수가 불리게 되면, Downward pass와 Upward pass에 대해서 수행하게 됩니다. Update 함수는 기본적으로 가상 함수가 아니지만, Downward pass 함수는 가상 함수로서 NiNode인 경우에는 다르게 동작합니다. Upward pass는 NiNode에만 존재하죠.
Downward pass가 먼저 실행이 되며, 이 때, 컨트롤러 업데이트를 하고 나서 데이터 업데이트를 하고 그 후에 경계구 설정을 합니다. Upward pass는 그 후에 진행이 되며, 현재 노드의 상위노드쪽으로만 경계구 업데이트를 하게 됩니다.
경계구는 추려내기(culling)에서 중요한 역할을 하므로, Update 함수는 매우 중요합니다. 그러나 위치가 가변적인 경우가 아닐 때에는 굳이 Update 함수를 매번 호출할 필요가 없습니다. 예를 들어서 총 노드의 개수가 1000개인 씬그래프가 있다고 한다면, 씬 그래프 루트 노드에서 Update를 호출하면 총 1000번의 Update가 호출되게 됩니다. 점점 복잡해지는 노드의 복잡도를 생각한다면 이는 비효율적인 방법이겠죠.
오브젝트가 추가되는 경우라면 Update는 거의 필수적입니다. 이 때에는 오브젝트의 다운워드 패스는 추가되는 오브젝트의 노드수에 비례하게 되며, 위로 가는 경우에는 현재의 노드의 뎁스에 비례하게 될 뿐입니다. 그러므로 추가되는 경우의 업데이트는 상대적으로 작아집니다.
그래서 애니메이션하는 노드들은 미리 모아놓고 그것들에 대해서만 따로 업데이트를 하는 것이 좋을것입니다.
간단하게 다음과 같은 코드가 있다면,
NiNodePtr spNode = (NiNode *)kStream.GetAt(0);
spSceneRoot->AttachChild(spNode);
자 여기서 업데이트가 필요한데, 어떤 코드가 유리할까요?
(1) spNode->Update(fTime);
(2) spSceneRoot->Update(fTime);
제가 보았을 때에는 (1) 코드가 유리합니다. (2) 코드와 (1) 코드는 똑같은 결과를 얻어내지만, (2) 코드는 훨씬 많은 작업이 이루어집니다.
업데이트와 관련해서는 이정도로 정리해보도록 합니다.
'Game Engine > Gamebryo' 카테고리의 다른 글
성능향상을 위한 방법들 (0) | 2011.09.24 |
---|---|
트리구조 (0) | 2011.09.24 |
트리구조 (0) | 2011.09.23 |
렌더러 생성 (0) | 2011.09.19 |
스마트포인터 (0) | 2011.09.19 |
댓글