Integration d'euler instable
slt...
Je codes un moteur physique je m'attaques au soft-body mais un problème ce pose devine avec quoi ... L'integration d'euler que j'ai utilisé j'ai chargé un objet mis tout les ressorts et des qu'ils touche le sol il tremble et le système s'effondre et les triangles du mesh par dans tout les sens ...
Apres quelque recherche j'ai decouvert qu'il y avait une alternative l'integration de RK4 mais toute les implementations que j'ai vu c'est pour des cas particulier comme des pendules, ...
Et je voudrais que quelqu'un m'aiguilles pour que j'implementes mon truc pour un cas général voilà pour l'instant comment j'ai fais avec euler ...
Je disposes de l'ancienne position d'un particule de sa position courante et de sa masse ainsi que les forces exterieur qui s'applique sur cette dernière ... :
Code:
1 2 3 4 5 6 7 8 9 10 11
|
// Definition d'une particule
// Particle definition
struct E_Particule
{
fVector3D curPos; // Position courante de la particule
fVector3D oldPos; // Position precedente de la particule
fVector3D force; // Vecteur force des forces accumuler par la particule
float mass; // Masse de la particule
bool Static; // Particule static
}; |
et un ressort :
Code:
1 2 3 4 5 6 7 8 9 10
|
// Un beau ressort
// A beautiful spring
struct E_Spring
{
size_t A; // Index de la première particule
size_t B; // Index de la seconde particule
float Length; // Distance entre les 2 particules
float Ks; // Facteur d'elasticité du ressort
}; |
Et voilà ma manière dont j'implemente ça :
l'integration :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
// Integration
void Integrate(float dt)
{
// recuperer le nombre de particule
size_t S = ArrPrtcl.GetSize();
// Appliquer l'integration à toute les particules
for(size_t i = 0; i < S; ++i)
{
// recuperer une particule indexé en i E_Particule p = ArrPrtcl.GetParticuleAt(i);
// verifier si la particule n'est pas statique if(p.Static == false)
{
fVector3D curPos = p.curPos;
p.curPos += p.curPos - p.oldPos + p.force * dt * dt;
p.oldPos = curPos;
// Affecter la particule
ArrPrtcl.SetParticuleAt(i, p);
}
}
} |
et la satisfaction des contraintes [ressorts] ... :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
// Satisfaire les contraites de ressort
void SatisfSpring()
{
// Recuperer le nombre de ressort
size_t S = ArrSprng.GetSize();
for(size_t i = 0; i < S; ++i)
{
// recuperer la particule indexé en i
E_Spring s = ArrSprng.GetSpringAt(i);
// recuperer les particules
E_Particule p1 = ArrPrtcl.GetParticuleAt(s.A);
E_Particule p2 = ArrPrtcl.GetParticuleAt(s.B);
// distance entre les 2 particules
fVector3D delta = p2.curPos - p1.curPos;
float deltaLengh = delta.Length();
// difference entre la longueur en repos et la courante
float diff = (deltaLengh - s.Length) / deltaLengh;
// ...
fVector3D off = delta * 0.5f * diff * s.Ks;
p1.curPos += off;
p2.curPos -= off;
if(p1.Static == false)
{
ArrPrtcl.SetParticuleAt((s.A), p1);
}
if(p2.Static == false)
{
ArrPrtcl.SetParticuleAt((s.B), p2);
}
}
} |
Enfin voilà je donnes pas tout ca pour que vous me fassiez tout mais juste pour me montrer sur quoi je boss et j'aimerais votre aide merci pour vos futur reponse ...