2009-08-16 5 views
1

Je dois utiliser OGRE3D pour un projet universitaire, cependant, nous ne sommes pas autorisés à utiliser des bibliothèques tierces pour la physique ou la détection de collision. Cela inclut l'utilisation de la détection de collision intégrée d'OGRE.Intégrer des classes de physique personnalisées avec OGRE 3D?

J'ai quelques difficultés avec la bonne façon d'aborder l'ajout de mes propres routines physiques personnalisées aux entités intégrées d'OGRE. OGRE utilise les objets "Entité" comme les plus élémentaires des blocs de construction et pour la physique, vous avez besoin d'objets ayant des attributs de masse, de vélocité, etc. Ce qui m'embrouille, c'est que les boucles de rendu/logique d'OGRE semblent être cachées à l'utilisateur à l'intérieur du moteur OGRE. C'est un problème parce que je dois être en mesure d'obtenir toutes les entités dans OGRE et d'effectuer des calculs de détection de collision et de physique avec mon moteur physique personnalisé que je construis.

Comment puis-je intégrer mes propres classes de moteur physique/collisions avec OGRE?

Mise à jour: Prendre les conseils ci-dessous je l'ai sous-classé OGRE :: Entité, à savoir:

class PhysicsEntity : public Ogre::Entity; 

PhysicsEntity *ent1 = (PhysicsEntity*)mSceneMgr->createEntity("PhysicsNinja", "ninja.mesh");; 
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode1"); 
node2->attachObject((Ogre::Entity*)ent1); 

L'état des commentaires ce n'est pas la meilleure façon de Comform à OO, et je suis d'accord je ne peux cependant pas voir une meilleure moyen à ce stade? Que pensez-vous et avez-vous de meilleures idées parce que je ne suis pas totalement heureux de le faire.

Répondre

4

La réponse de Jason Williams montre le bon chemin. Une façon possible est d'introduire une classe indépendante représentant votre GameObject. (Appelons-le donc pour le reste de la réponse, même si vous ne créez pas un jeu)

Cette classe GameObject encapsule tous les aspects pertinents de votre Ninja et de vos boîtes et de tout ce qui cache les aspects physiques et graphiques par la composition de d'autres classes les représentant. Par exemple. GraphicalObject, PhysicalObject.

Voici un exemple grossièrement simplifié:

class GameObject 
{ 
public: 
    void setPosition(Vector3 pos) 
    { 
     m_position = pos; 
     m_graphical->setPosition(pos); 
     m_physical->setPosition(pos); 
    } 

private: 
    GraphicalObject m_graphical; 
    PhysicalObject m_physical; 
    Vector3 m_position; 
} 

maintenant GraphicalObject encapsule un ogre :: SceneNode avec son Ogre :: Entité ci-joint. PhysicalObject encapsule votre classe de corps physique. PhysicalObject et GraphicalObjects peuvent partager une classe de base commune qui définit l'interface avec la classe GameObject. Ci-dessus, j'ai utilisé des fonctions réelles comme setPosition, mais je recommande généralement une interface de message plus générique, mais il ne doit probablement pas être trop compliqué dans votre cas.

Un problème reste que vous voulez que la position de GameObject réponde aux changements de votre étape de simulation physique. Cela dépend grandement de la façon dont votre moteur physique est conçu. Mais si vous avez une sorte de système de rappel, enregistrez votre PhysicalObject en tant qu'auditeur pour tous les événements à ce sujet et changez de position à partir de leur. Idem pour l'orientation ou la transformation en général, si vous ne faites pas de distinction entre la position et l'orientation en particulier.

Vous souhaitez probablement dériver les propriétés du corps physique (appelons-le Corps pour cette réponse) du maillage représentant les graphiques. Dans le cas du Ninja, sa forme devrait ressembler à celle du treillis ninja. Je le ferais avec une classe d'aide simple en dehors de la hiérarchie des classes. Par exemple une BodyFactory. Ces fonctions créent une représentation physique appropriée de votre moteur physique à partir des données de maillage. Dans le cas simple, ils utilisent simplement la boîte englobante, ou pour des corps plus sophistiqués, ils évaluent les données de vertex réelles, cela n'a pas d'importance. Peut-être vous pouvez étendre l'interface pour les attributs physiques non stockés dans le maillage (poids spécifique, modificateurs d'inertie (creux, solides, etc.))

Un conseil général encore quand vous utilisez Ogre (ou tout moteur graphique pur): Utilisez-le seulement pour les graphiques. Je comprends que l'implémentation SceneGraph d'Ogre soit utilisée pour la gestion de votre propre scène, mais vous vous attachez tellement au moteur, vous surchargez vos interfaces avec des choses dont ils n'ont pas besoin et dont vous ne voulez pas qu'ils dépendent. (Interface Segregation Principle) Il ne vaut tout simplement pas la peine. Garder les choses séparées est vraiment plus facile à gérer et à maintenir.

+0

Merci pour votre réponse, beaucoup de bonnes informations dans votre réponse, je reviendrai à vous sur celui-ci dans les prochains jours pendant que j'essaye de l'implémenter. Merci +1 –

2

Souvent, vous voulez un objet physique sans graphiques, un objet physique avec plusieurs graphiques ou un objet graphique représenté par plusieurs objets physiques. Pour cette raison (et pour d'autres raisons, comme la possibilité d'échanger différents moteurs physiques/graphiques), la plupart des moteurs gardent les deux systèmes séparés, en utilisant simplement des références/liens entre le système graphique et le système physique (donc que les objets physiques peuvent mettre à jour les entités graphiques après avoir effectué une étape de simulation)

1

Dès que j'ai lu votre question, j'allais vous diriger vers OgreODE, qui fournit un bon pont entre Ogre3D et ODE. Si vous ne pouvez pas utiliser ODE, peut-être devriez-vous néanmoins jeter un coup d'œil, pour obtenir quelques conseils sur la façon de le faire? Il y a aussi OgreNewt, un moteur similaire.

Je pense que vous devez installer un FrameListener, il est appelé après le rendu d'un Frame. Ensuite, vous pouvez accéder à SceneManager et ses SceneNodes, et lire et modifier leurs positions. Cependant, les maillages, à moins qu'ils ne soient des formes de base, ne sont pas très viables comme modèle pour la détection de collision, si vous voulez obtenir une performance décente. C'est pourquoi je pense que vous devriez coupler vos entités avec quelques formes de base (cube, sphère, etc.) et travailler avec celles-ci au lieu des maillages Entity. Sous-classer les entités Ogre3D et leur donner une collection de formes de base et un accesseur à eux. Votre FrameListener obtient alors les formes de base de chaque SceneNode et fait ses calculs.

+0

Ozan, votre commentaire a beaucoup de sens et m'a beaucoup aidé :) J'ai fait ce que vous avez dit, mais j'ai une autre question. Comment puis-je m'assurer que je ne traite que les nœuds concernés sans vérifier les collisions contre tout? Autrement dit, existe-t-il un moyen d'accéder aux nœuds d'une certaine partie du quadrillage d'OGRE? +1 –

+0

Je ne sais pas si c'est possible, en plus vous aurez un problème quand deux objets se rencontrent à la frontière de ces parties. Je vous suggère de prendre votre question sur les forums ogre http://www.ogre3d.org/forums/ – Ozan

+0

Sous-classe Ogre :: Entité n'est pas une bonne idée à mon humble avis. Cela n'a pas de sens à partir d'une perspective OO, la relation entre en entité et sa forme n'est pas is_a. En outre Entity a une interface massive qui devrait être maintenue séparée. – haffax

Questions connexes