TLDR: Ao fazer o componente consistir em várias malhas, para começar.
Eu concordo com Asakeron / Byte56 / Laurent em que outro nível de indireção é necessário entre os pares de malha / material e a própria entidade. Em vez de ver o GraphicsComponent como vértices e materiais, pense nele como uma gota de pixels na varredura final - como ele chega lá é um detalhe de implementação e nada mais.
Eu pensei muito sobre isso no meu projeto e acho que a solução ideal é tornar o GraphicsComponent um componente de nível muito mais alto, abrangendo grande parte da funcionalidade do objeto tradicional 'Model' - porque essa funcionalidade não é opcional! Para renderizar esses polígonos muito mais do que apenas os dados do buffer e o sombreador, são necessários:
- Posição que você mencionou
- Dados de esfola / animação
- O passe atual (por exemplo, se estiver usando dois passes alfa)
- Informações de projeção de sombra (se você estiver fazendo isso)
- Informações sobre como e quando atualizar o material
- Funcionalidade de descarte
E isso é apenas para recursos 3D, sem considerar sistemas de partículas, outdoors etc. Mas tudo isso é pertinente apenas ao código de gráficos / renderização - não afeta a física, o som ou o script, por isso faz sentido que ele se encaixe o componente Gráficos / Renderização.
Acabei com:
Model : Entity, IHasGraphicsComponent, IHasSkeleton, IHasAnimationStore //This is the 'game object' - it is passed to the GraphicsController
ModelComponent : GraphicsComponent //This is the actual graphics component, used by the GraphicsController in the context of the game object.
ModelComponentPart : GraphicsComponent //This is also a graphics component
Mesh //These are implementation details
Material
ModelComponentPart : GraphicsComponent
Mesh
Material
Skeleton
Animations
Nisso:
Modelo é qualquer ativo do jogo que possui um componente gráfico.
O ModelComponent é análogo ao modelo tradicional e, de fato, é para ativos 3D. O controlador GraphicsComponent (se você usar o padrão Model-View-Controller) é responsável por descobrir que tipo de ativo gráfico é e desenhá-lo corretamente (observe que ModelComponent é uma subclasse de GraphicsComponent).
Havia também alguns compromissos meus por questões de simplicidade e compatibilidade com versões anteriores, como cada GraphicsComponent também é uma Entidade, e a Entidade armazena os dados de Posição diretamente para que sejam calculados apenas em um lugar, mas a ideia é a mesma: GraphicsComponent lida com o que é necessário para desenhar o item - tudo o que é necessário - e não apenas o que vem do modelador.