2009년 12월 17일
Integrating Physics with the game engine
오늘자 Sweng-Gamedev mailing list에 "물리 시스템의 게임 엔진에의 통합"과 관련한 답변으로 Jon Watte씨가 올린 글입니다.
물리 시스템은 대부분 Havoc, PhysX 등의 외부 미들웨어를 통합하는 방식을 취하고 있는데, 이 경우에도 참고하면 많은 도움이 되는 내용입니다.
아래 내용만으로는 부족하다면 Nebula2의 Mangalore 부분에서 ODE 물리 엔진을 어떻게 통합하고 있는지 아래 내용을 코드와 함께 보기 바랍니다. 쉽게 이해하는데 도움이 됩니다. 반대로 Nebula에서 물리 엔진이나 기타 시스템의 통합을 *왜*이러한 방법으로 하는지가 궁금하셨던 분들에게도 나름의 답이 될 수 있겠군요.
어느 정도 감을 잡았다면 Nebula3의 Raknet 네트워크 시스템의 통합도 같이 살펴 보길 권합니다. 방법은 거의 동일합니다.
그리고 아래 내용의 세 번째 항목에서 언급한 데이터와 관련한 내용, 사실 이 내용은 통합과는 직접적인 관련이 없을지 몰라도 외부 물리 시스템 사용시 제일 중요한 내용이라고 봅니다. 최근에는 PhysX 쪽도 3dsmax 2010용 플러그인(베타)이 나왔더군요. 시스템의 사용은 그리 어렵지 않지만 데이터를 생산하는 적절한 방법이 함께 고려되지 않으면 반쪽짜리 해결책이 되거나 사용하지 않으니만 못할 수 도 있기 때문입니다.
Integrating Physics with the game engine
I am not making a physics engine, just implementing 'as-much' physics as
required for my game
Once you start doing proxy-against-concave-mesh, and
multiple-contact-constraints, the difference will start to diminish.
Especially the "handle multiple contacts" part ends up more or less leading
you to actually write a physics engine. If you want physics without writing
a physics engine, use either an open source physics engine (Bullet, ODE) or
a "free for PC" commercial physics engine (NVIDIA PhysX, Havok Physics).
Regarding structure, I find that each subsystem should have its own data
structures, optimized for that subsystem. Thus, you may have a RigidBody
with some BodyCollisionShapes on it. Separately, you have an AnimatableMesh
with some Materials and Animations on it. You may also have a SoundSource
with some PlayingCues, and one or more SpecialEffects, and maybe even an
InputListener. Each of those are for a separate subsystem (physics,
animation, sound, scene graph, input in these cases).
The "game object" as such is the union of all these sub-components. There
are a few ways of doing that union:
1) Each subsystem allow *you* to define the ID of each subsystem object. You
say "create a rigid body, and call it '3'." A game entity is then just the
ID, and it's created as a collective hallucination of all the subsystems
that happen to have an object with that ID.
2) There's a bit struct with a pointer to every kind of component: struct
Entity { RigidBody *body; AnimatedMesh *animated; ... }; An entity comes to
life with NULL everywhere, and you populate it as appropriate.
3) You build an abstraction for "being a component" and for "containing
components." The entity is then a container for components. You write
component wrappers for each of rigid body, animated mesh, sound source, etc.
The entity is then created as a component container with whatever components
in it that you need. If you want editor support for arbitrary component
packages, for a fancy designer-built world, then this approach, plus XML
serialization, will get you there. The container will generally contain a
message bus, reflection support, etc.
The main problem you have to solve is how to get data from "here" to
"there." For example, the physics object collides with a wall, and thus
needs to adjust the animation to not penetrate an arm. Or the graphics scene
graph node moves, and you need the sound emitter to move as well. Generally,
this kind of data ends up in the "entity" component, so the "pure" ID
approach is not too common. However, if each of the subsystems can accept
some kind of "pull" input for common data like position, and the
authoritative source of that information can "push" it, then it can still be
done reliably and without pain.
Sincerely,
jw
물리 시스템은 대부분 Havoc, PhysX 등의 외부 미들웨어를 통합하는 방식을 취하고 있는데, 이 경우에도 참고하면 많은 도움이 되는 내용입니다.
아래 내용만으로는 부족하다면 Nebula2의 Mangalore 부분에서 ODE 물리 엔진을 어떻게 통합하고 있는지 아래 내용을 코드와 함께 보기 바랍니다. 쉽게 이해하는데 도움이 됩니다. 반대로 Nebula에서 물리 엔진이나 기타 시스템의 통합을 *왜*이러한 방법으로 하는지가 궁금하셨던 분들에게도 나름의 답이 될 수 있겠군요.
어느 정도 감을 잡았다면 Nebula3의 Raknet 네트워크 시스템의 통합도 같이 살펴 보길 권합니다. 방법은 거의 동일합니다.
그리고 아래 내용의 세 번째 항목에서 언급한 데이터와 관련한 내용, 사실 이 내용은 통합과는 직접적인 관련이 없을지 몰라도 외부 물리 시스템 사용시 제일 중요한 내용이라고 봅니다. 최근에는 PhysX 쪽도 3dsmax 2010용 플러그인(베타)이 나왔더군요. 시스템의 사용은 그리 어렵지 않지만 데이터를 생산하는 적절한 방법이 함께 고려되지 않으면 반쪽짜리 해결책이 되거나 사용하지 않으니만 못할 수 도 있기 때문입니다.
Integrating Physics with the game engine
I am not making a physics engine, just implementing 'as-much' physics as
required for my game
Once you start doing proxy-against-concave-mesh, and
multiple-contact-constraints, the difference will start to diminish.
Especially the "handle multiple contacts" part ends up more or less leading
you to actually write a physics engine. If you want physics without writing
a physics engine, use either an open source physics engine (Bullet, ODE) or
a "free for PC" commercial physics engine (NVIDIA PhysX, Havok Physics).
Regarding structure, I find that each subsystem should have its own data
structures, optimized for that subsystem. Thus, you may have a RigidBody
with some BodyCollisionShapes on it. Separately, you have an AnimatableMesh
with some Materials and Animations on it. You may also have a SoundSource
with some PlayingCues, and one or more SpecialEffects, and maybe even an
InputListener. Each of those are for a separate subsystem (physics,
animation, sound, scene graph, input in these cases).
The "game object" as such is the union of all these sub-components. There
are a few ways of doing that union:
1) Each subsystem allow *you* to define the ID of each subsystem object. You
say "create a rigid body, and call it '3'." A game entity is then just the
ID, and it's created as a collective hallucination of all the subsystems
that happen to have an object with that ID.
2) There's a bit struct with a pointer to every kind of component: struct
Entity { RigidBody *body; AnimatedMesh *animated; ... }; An entity comes to
life with NULL everywhere, and you populate it as appropriate.
3) You build an abstraction for "being a component" and for "containing
components." The entity is then a container for components. You write
component wrappers for each of rigid body, animated mesh, sound source, etc.
The entity is then created as a component container with whatever components
in it that you need. If you want editor support for arbitrary component
packages, for a fancy designer-built world, then this approach, plus XML
serialization, will get you there. The container will generally contain a
message bus, reflection support, etc.
The main problem you have to solve is how to get data from "here" to
"there." For example, the physics object collides with a wall, and thus
needs to adjust the animation to not penetrate an arm. Or the graphics scene
graph node moves, and you need the sound emitter to move as well. Generally,
this kind of data ends up in the "entity" component, so the "pure" ID
approach is not too common. However, if each of the subsystems can accept
some kind of "pull" input for common data like position, and the
authoritative source of that information can "push" it, then it can still be
done reliably and without pain.
Sincerely,
jw
# by | 2009/12/17 14:16 | Development | 트랙백 | 덧글(0)
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]