2010-08-26 23 views
1

Ma scène contient plusieurs piles d'objets dynamiques. Lorsque la simulation commence, il faut un certain temps pour qu'ils "résolvent" avant qu'ils ne deviennent des îles endormies. Cela affecte les performances de manière significative pendant les premières secondes. Y a-t-il des techniques pour organiser les piles de manière à ce qu'elles dorment immédiatement?Empilement instantané d'une pile d'objets dynamiques

J'utilise PhysX.

+0

pouvez-vous ajouter plus de détails? –

+0

Imaginez une scène avec une pile de cubes. quand la simulation commence, les cubes rebondissent tous ensemble un peu, jusqu'à ce que les cubes atteignent finalement un état de repos. puis la collection de cubes est marquée comme "dormant" par le simulateur de physique, de sorte que le coût de la simulation diminue de manière significative. Je me demande s'il y a des approches pour que les cubes «résolvent» immédiatement leur état de sommeil. – eed

Répondre

0

Je ne suis pas familier avec PhysX, mais je peux faire quelques suppositions éclairées sur la façon dont cela fonctionne. Voici une ou deux idées qui peuvent ou ne peuvent pas fonctionner selon, par exemple, comment PhysX décide de déclarer un objet "résolu":

Si les blocs sont réellement en mouvement, c'est probablement parce qu'il y a une certaine imprécision dans leur emplacement initial, ce qui leur donne la place pour s'installer. Il existe peut-être un moyen de réduire cette imprécision, par exemple en sauvegardant une configuration résolue au lieu de s'appuyer sur une configuration papier. Puisqu'ils s'arrêtent finalement, il doit y avoir une force dissipative au travail (par exemple la friction), et il doit avoir un paramètre. Alors, augmentez-le d'abord, comme si les blocs étaient immergés dans du miel, puis composez le bas.

Qu'ils se déplacent réellement ou non, un bloc au sommet d'une grosse tour de blocs ne peut pas s'installer jusqu'à ce que tous les blocs en dessous l'aient fait, donc tout le calcul pour simuler son tremblement est complètement perdu - pour ne rien dire de la façon dont son incertitude peut perturber les blocs ci-dessous. Alors essayez d'être un maçon, en plaçant les objets du dessous en premier, en les laissant se résoudre, puis en progressant (en "cours", comme on dit).

Si vous ne pouvez pas l'éliminer, couvrez-le; peut-être vous pouvez cacher les blocs pendant les premières secondes, puis lever le rideau une fois qu'ils sont résolus. Cela ne rend pas les choses plus rapides mais cela peut rendre les choses plus présentables.

1

Vous pouvez utiliser

NxActor::putToSleep(); 

au démarrage. Cela augmentera considérablement les performances de la scène. Cependant, s'il y a des objets mal placés sur votre pile (c'est-à-dire un cube volant), ils ne tomberont pas tant que d'autres objets dynamiques ne se seront pas écrasés dessus.

Cette approche ne semble pas fonctionner sur des objets en mouvement. Par exemple, si mon objet dynamique se déplace avec la vitesse 5m/s sur ma scène et si je tente de le forcer à dormir, putToSleep ne fonctionnera pas (même si je fais d'abord mettre la vitesse de l'objet à 0, puis sleep)

Voici une solution de contournement si vous devez forcer le sommeil et désactiver un acteur dynamique.

void setDynamicActorState(NxActor& actor, bool disabled) 
{ 
    if (nxActor.getNbShapes() > 1) 
    { 
     for (int i = 0; i < nxActor.getNbShapes(); i++) 
     {     
      nxActor.getShapes()[i]->setFlag(NX_SF_DISABLE_COLLISION, disabled); 
     }    
    } 
    else 
    { 
     if (disabled) 
      nxActor.raiseActorFlag(NX_AF_DISABLE_COLLISION); 
     else 
      nxActor.clearActorFlag(NX_AF_DISABLE_COLLISION); 
    } 

    for (int i = 0; i < nxActor.getNbShapes(); i++) 
    { 
     nxActor.getShapes()[i]->setFlag(NX_SF_DISABLE_SCENE_QUERIES, disabled); 
    } 

    if (disabled) 
    { 
     nxActor.raiseBodyFlag(NX_BF_KINEMATIC); 
     nxActor.putToSleep(); 
    } 
    else 
    { 
     nxActor.clearBodyFlag(NX_BF_KINEMATIC); 
     nxActor.wakeUp(); 
    } 
} 

Désactivera tout pour l'acteur, les collisions, les requêtes de scène etc. J'utilise cette stratégie pour précharger tous les acteurs de la scène et de cacher des objets inactifs. Quand leur tour arrive, activez-les, désactivez les autres. Méfiez-vous que charger tous les acteurs à la fois peut consommer la mémoire.