animationphys
Animation 3D - Documentation

Cette page explique :


Comment lancer l'application ?

Répertoire des données : gkit2light/data/

  • gkit2light/data/ textures : textures pour les maillages
  • gkit2light/data/ CreateMesh : programme pour créer des maillages ou convertir .obj/.off
  • gkit2light/data/ drap10 : tissu 10x10 particules
  • gkit2light/data/ drap70 : tissu 70x70 particules
  • gkit2light/data/ vache / sphere / bunny : objets rigides

Fichiers dans ces répertoires

  • faceset.eti : connectivité triangulaire de l'objet
  • masses.eti : masses des sommets (0 = sommet épinglé/fixe)
  • points.eti : coordonnées (x,y,z) des sommets
  • texcoord.eti : coordonnées de texture des sommets

Fichiers de paramètres : gkit2light/animationphys/exec/

  • Fichier_Param.simu : paramètres globaux de la simulation
    • viscosite : coefficient d'amortissement du milieu (0.99 = quasi sans frottement)
    • gx, gy, gz : composantes du vecteur gravité
    • nbiter : nombre de pas de simulation par image rendu
    • objet1, objet2, ... : type de chaque objet (mss, particule, rigid, sph, pbd)
  • Fichier_Param.objetN : paramètres de l'objet N
    • Clés communes : points, masses, interaction
    • MSS/PBD : faceset, textures, usetexture, k, nu, integration, dt
    • Implicite uniquement : nbitervitimpl
    • PBD uniquement : nbiter_pbd
    • SPH : rho0, bulk, h, max_particles, box_xmin/ymin/zmin, box_xmax/ymax/zmax, restitution, friction_wall
    • Corps rigide : positionx/y/z, rotationx/y/z/angle, quantitemouv x/y/z, momentcinetique x/y/z
Note
Format du fichier de paramètres : une clé par ligne (cle = valeur). Les commentaires #, ! ou // en début de ligne sont ignorés. Les commentaires inline après # sont aussi supportés. Le point-virgule final est optionnel.

Lancer l'application

Depuis le répertoire gkit2light :

./animationphys/bin/animationphys 1 ./animationphys/exec/Fichier_Param.simu ./animationphys/exec/Fichier_Param.objet1

Syntaxe générale :

<executable> NbObjets <Fichier_Param.simu> <Fichier_Param.objet1> [<Fichier_Param.objet2> ...]

Viewer de l'application

La fenêtre, le contexte OpenGL et la boucle d'événements sont gérés explicitement dans main.cpp qui instancie aussi le Viewer.

Window window = create_window(1024, 768);
Context context = create_context(window);
// ...
Viewer viewer(Fichier_Param, NbObj);
viewer.init();
while (events(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
viewer.render(); // simulation + dessin
SDL_GL_SwapWindow(window);
}
viewer.quit();
Definition Viewer.h:47
  • Méthodes principales :
    • init() - appelée une fois après create_context().
      • Initialise la caméra
      • crée les maillages de scène fixes (grille, axe, sphère, plan)
      • puis construit les SimuRenderer pour chaque objet simulé avec la création des maillages des objets simulés.
    • render() - appelée à chaque image. Effectue dans l'ordre :
      1. Déplacement de la lumière (CAPS + flèches)
      2. Interaction clavier (m + flèches)
      3. Simulation (un pas ou nbiter pas)
      4. Mise à jour des maillages des objets déformables
      5. Paramètres d'affichage et dessin de la scène fixe
      6. Dessin des objets simulés
      7. Mouvement caméra (update_camera)
    • quit() - nettoyage.
  • Raccourcis clavier :
Touche Action
h Aide
c Activer/désactiver GL_CULL_FACE
w Wireframe on/off
n Debug normales on/off
a Axes on/off
g Grille on/off
CTRL + flèches Déplacer la lumière (axes X/Z monde)
CTRL + PgUp/PgDn Déplacer la lumière (axe Y monde)
CAPS + flèches Déplacer la lumière (relatif caméra)
m + flèches Déplacer le point d'interaction
Flèches / souris Caméra
  • Séparation stricte simulation / rendu :

    Les classes de simulation n'ont aucun objet Mesh et n'incluent pas Viewer.h. Le Viewer possède tous les maillages via un vecteur de SimuRenderer (un par objet simulé). Il lit les données de simulation via des getters en lecture seule (positions(), getNormals(), getIndices(), etc.).


Le graphe de scène

Le graphe de scène est défini dans la classe Viewer par la variable _Simu de type Scene.

  • Scene contient la liste des Noeud de la scène. Elle diffuse les appels de simulation (initObjetSimule, Simulation, Collision, Interaction) à tous les objets attachés.
  • La gravité et la viscosité sont définies dans Scene (paramètres globaux).

Hiérarchie des classes de simulation

Voici une vue de la hiérarchie des classes principales :

Noeud <-- graphe de scène (P, interface virtuelle)
|___ ObjetSimule <-- données physiques (V, A, Force, M) + helpers fichiers
|------ ObjetSimuleMesh <-- géométrie (faces, normales, MSS particules, getters rendu)
| |------ ObjetSimuleMSS <-- ressorts + solveurs (explicite / implicite)
| | |___ ObjetSimulePBD <-- PBD tissu (contraintes de distance)
| |___ ObjetSimuleRigidBody <-- corps rigide (x, R, P, L)
|------ ObjetSimuleFluide <-- base fluides (boîte, collision parois, solveur explicite)
| |___ ObjetSimuleSPH <-- fluide SPH
|___ ObjetSimuleParticule <-- nuage de particules indépendantes
Classe de base d un systeme masses-ressorts. Il est constitue d un ensemble de particules et de resso...
Definition MSS.h:274
Classe de base pour tous les éléments simulés de la scène.
Definition Noeuds.h:26
Definition ObjetSimuleFluide.h:24
Definition ObjetSimuleMSS.h:21
Definition ObjetSimuleMesh.h:31
Definition ObjetSimulePBD.h:17
Definition ObjetSimuleParticule.h:17
Definition ObjetSimuleRigidBody.h:21
Definition ObjetSimuleSPH.h:18
Données physiques communes (V, A, Force, M) et helpers de chargement.
Definition ObjetSimule.h:44

ObjetSimuleMesh :

  • Classe intermédiaire entre ObjetSimule et les classes qui utilisent un maillage triangulaire.
  • Elle regroupe : fichier de faces, coordonnées de texture, normales, indices de connectivité, le MSS pour les particules, et les getters permettant au Viewer de construire ses propres maillages de rendu.

ObjetSimuleRigidBody hérite de ObjetSimuleMesh. Un corps rigide utilise le maillage pour sa géométrie initiale et son rendu. (Mais n'utilisera pas le systèmes messes-ressorts).

ObjetSimuleMSS hérite de ObjetSimuleMesh. Elle utilisera le système masses-ressorts pour effectuer la déformation de l'objet.

ObjetSimuleFluide : Base commune pour les simulations de fluides à particules. Elle contient la boîte de simulation configurable (_box_min, _box_max), les coefficients de collision (_restitution, _friction_wall), le solveur explicite et les densités SPH.


Représentation d'un objet pour la visualisation

Les structures de données géométriques sont dans ObjetSimuleMesh :

  • _VIndices : indices des sommets du maillage. Taille = _VISize = 3xnombre de facettes.
  • _vectNormals : normales lissées des sommets (calculées par setNormals()).
  • _vectTexture : coordonnées UV des sommets.
  • P (dans Noeud) : positions 3D des sommets.

Ces structures sont exposées via des getters (getNormals(), getIndices(), etc.) et utilisées par le Viewer dans buildMeshObj..() et updateMeshObj..() pour construire et mettre à jour les objets Mesh de rendu.


Données physiques d'un objet simulé

Les tableaux physiques sont dans ObjetSimule :

  • P (dans Noeud) : positions des particules. Mis à jour à chaque pas.
  • V : vitesses des particules. Initialisé à zéro.
  • A : accélérations. Initialisé à zéro.
  • Force : forces appliquées. Réinitialisé après chaque calcul d'accélération.
  • M : masses. Chargées depuis le fichier. M[i]=0 épingle la particule i (fixe).

Les helpers protégés loadPoints(), loadMasses(), initParticleArrays() factorisent le chargement des fichiers de données.

Pour un objet ObjetSimuleMSS, le système masses-ressorts _SystemeMasseRessort (de type MSS) contient :

  • Une liste de Particule (identifiant, position, liste de ressorts rattachés).
  • Une liste de Ressort (définition géométrique : deux particules + Spring).
  • Un objet Spring commun à tous les ressorts d'un objet (raideur k, amortissement ν, longueur au repos calculée à l'initialisation).

Algorithmes de simulation

Boucle de simulation

à chaque pas de temps, pour un objet donné :

  1. Calcul des forces (Calcul des forces)
  2. Calcul des accélérations (Calcul des accélérations)
  3. Calcul des vitesses et positions (Calcul des vitesses et des positions)
  4. Gestion des collisions

Calcul des forces - pour une simulation MSS

La force appliquée à la particule i vaut :

\[ \vec{f}_i(t) = \sum_{j|(i,j)\in E} \left[k_{ij}\bigl(\|\vec{x}_{ij}\| - l_{ij}\bigr)\,\vec{u}_{ij}(t) + \nu_{ij}\,\bigl(\vec{v}_j(t)-\vec{v}_i(t)\bigr)\cdot\vec{u}_{ij}(t)\,\vec{u}_{ij}(t) \right] + m_i\,\vec{g} \]

avec \(\vec{u}_{ij}(t) = \frac{\vec{x}_j(t)-\vec{x}_i(t)}{\|\vec{x}_j(t)-\vec{x}_i(t)\|}\).

La gravité est ajoutée dans le calcul des accélérations pour des raisons d'implémentation.

Calcul des accélérations

\[a_i = \frac{\vec{f}_i}{m_i}\]

  • Particule épinglée (M[i]=0) : \(a_i = \vec{0}\).
  • Le vecteur Force est réinitialisé à zéro après ce calcul.

Calcul des vitesses et des positions

  • Schéma Leap-Frog Verlet (solveur explicite) :

    \[ \left\{\begin{array}{lcl} v\!\left(t+\frac{h}{2}\right) &=& v\!\left(t-\frac{h}{2}\right) + h\,a(t)\\ x(t+h) &=& x(t) + h\,v\!\left(t+\frac{h}{2}\right) \end{array}\right. \]

  • Stabilité du solveur explicite : pour un ressort de raideur k et des particules de masse m, le pas de temps doit satisfaire :

    \[dt < \frac{2}{\omega} = 2\sqrt{\frac{m}{k}}\]


Solveurs numériques

Solveur explicite

SolveurExpl intègre les vitesses et positions par Leap-Frog.

  • CalculAccel_ForceGravite : ajoute \(m_i\vec{g}\) aux forces, calcule \(a_i = f_i/m_i\), réinitialise Force à zéro.
  • Solve : intégration Leap-Frog.

Solveur implicite

SolveurImpl implémente la méthode d'Euler implicite de Baraff-Witkin (1998) par gradient conjugué. Inconditionnellement stable - permet de grands pas de temps et des raideurs élevées.

  • Système résolu : \(H\,\Delta V = Y\) où :

    \[H = M - h\frac{\partial f}{\partial v} - h^2\frac{\partial f}{\partial x}, \quad Y = h\,f(t) + h^2\frac{\partial f}{\partial x}v(t)\]

  • Propriété clé : la Jacobienne des forces de ressort a un terme diagonal négatif \((\partial f_i/\partial x_i = -\sum_j k_{ij}\vec{u}_{ij}\vec{u}_{ij}^T)\) et des termes hors-diagonal positifs \((\partial f_i/\partial x_j = +k_{ij}\vec{u}_{ij}\vec{u}_{ij}^T)\). Ainsi \(H_{ii} = M_i + h^2\sum_j k_{ij}\vec{u}\vec{u}^T\) est toujours positif, ce qui garantit que H est définie positive et que le gradient conjugué converge.
  • Particules épinglées (M[i]=0) dans le système linéaire :
  • \(Y[\text{épinglée}] = \vec{0}\) - aucune force ne change leur vitesse.
  • \(H[\text{épinglée}][\text{épinglée}] = 1\), \(H[\text{épinglée}][j] = 0\) - le GC produit \(\Delta V[\text{épinglée}] = \vec{0}\) par construction.
  • \(H[\text{libre}][\text{épinglée}] = 0\) - découplage. Sans ce traitement, le GC calculerait \(\Delta V[\text{libre}]\) en supposant que l'épinglée bouge, annulant l'effet des ressorts.

Paramètres recommandés pour l'implicite :

Objectif k dt nbitervitimpl
Tissu souple 50 000 0.033 15
Tissu normal 200 000 0.033 20
Quasi-rigide 1 000 000 0.05 30

La règle pratique est \(dt^2 k \gg M\) (le terme de rigidité domine dans H).


Simulation PBD

ObjetSimulePBD est basée sur la méthode PBD (Position Based Dynamics, Müller et al. 2006) pour simuler un tissu en projetant directement les positions pour satisfaire des contraintes de distance.

  • Elle hérite de ObjetSimuleMSS pour réutiliser la topologie des ressorts.

Algorithme à chaque pas :

  1. Forces externes → vitesses : \(v_i \mathrel{+}= h\,g\)
  2. Positions prédites : \(p^*_i = x_i + h\,v_i\)
  3. Projection des contraintes (nbiter_pbd itérations) : pour chaque ressort \((i,j,L_0)\),

    \[ \Delta p = (||p^*_j - p^*_i|| - L_0)\,\frac{p^*_j - p^*_i}{||p^*_j - p^*_i||} \]

    \[ p^*_i \mathrel{+}= \frac{w_i}{w_i+w_j}\Delta p,\quad p^*_j \mathrel{-}= \frac{w_j}{w_i+w_j}\Delta p \]

    avec \(w_i = 1/m_i\) ( \(w_i=0\) si particule épinglée).
  4. Collisions : clamp de \(p^*_i\).
  5. Mise à jour : \(v_i = (p^*_i - x_i)/h\), \(x_i = p^*_i\).
  • Avantages : stable à grands pas de temps, pas d'overshoot, épinglage automatique.
  • Paramètres : nbiter_pbd contrôle la rigidité (5=souple, 20=normal, 50=quasi-rigide).

Simulation SPH

ObjetSimuleSPH est implémentée pour une simulation de fluide incompressible employant la méthode SPH (Smoothed Particle Hydrodynamics).

  • Noyau de densité (Poly6) :

    \[W(r,h) = \frac{4}{\pi h^8}(h^2-r^2)^3,\quad r<h\]

  • Densité :

    \[\rho_i = \sum_j m_j\,W(r_{ij},h)\]

  • Forces de pression et viscosité :

    \[\vec{f}_i = \sum_{j\neq i}\left[ \frac{p_i + p_j}{\rho_i\rho_j}\,\nabla W_{ij} + \nu\,\frac{\vec{v}_j - \vec{v}_i}{\rho_i\rho_j}\,W_{ij} \right]\]

avec \(p_i = \max(0,\, k(\rho_i - \rho_0))\) (clamp pour éviter l'instabilité tensile : les forces de pression sont toujours répulsives).

  • Boîte de simulation : à implémnter pour faire une boîte configurable par box_xmin/ymin/zmin et box_xmax/ymax/zmax.

Paramètres recommandés :

Paramètre Valeur typique Effet
h 0.15 - 0.30 Rayon d'influence (>h = moins de particules)
rho0 1000.0 Densité de référence
bulk 200 - 500 Rigidité du fluide
dt 0.003 - 0.005 Doit satisfaire \(dt < h/\sqrt{bulk/\rho_0}\)
max_particles 500 - 3000 Budget CPU

Calculs effectués pour la visualisation

Normale d'une face

Pour une facette \((A,B,C)\) :

\[\vec{n} = \frac{\overrightarrow{AB}\wedge\overrightarrow{AC}} {\|\overrightarrow{AB}\wedge\overrightarrow{AC}\|}\]

Lissage des normales des sommets

  1. Initialiser à zéro la normale de chaque sommet.
  2. Pour chaque facette : calculer sa normale et l'ajouter aux normales de ses trois sommets.
  3. Normaliser chaque normale de sommet.

Le lissage est recalculé à chaque pas par setNormals() dans ObjetSimuleMesh.