|
animationphys
|
Cette page explique :
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 renduobjet1, objet2, ... : type de chaque objet (mss, particule, rigid, sph, pbd)points, masses, interactionfaceset, textures, usetexture, k, nu, integration, dtnbitervitimplnbiter_pbdrho0, bulk, h, max_particles, box_xmin/ymin/zmin, box_xmax/ymax/zmax, restitution, friction_wallpositionx/y/z, rotationx/y/z/angle, quantitemouv x/y/z, momentcinetique x/y/zcle = 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.Depuis le répertoire gkit2light :
Syntaxe générale :
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.
init() - appelée une fois après create_context().render() - appelée à chaque image. Effectue dans l'ordre :CAPS + flèches)m + flèches)nbiter pas)update_camera)quit() - nettoyage.| 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 est défini dans la classe Viewer par la variable _Simu de type Scene.
initObjetSimule, Simulation, Collision, Interaction) à tous les objets attachés.Voici une vue de la hiérarchie des classes principales :
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.
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.
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 :
à chaque pas de temps, pour un objet donné :
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.
\[a_i = \frac{\vec{f}_i}{m_i}\]
\[ \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. \]
\[dt < \frac{2}{\omega} = 2\sqrt{\frac{m}{k}}\]
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.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.
\[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)\]
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).
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.
Algorithme à chaque pas :
\[ \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).nbiter_pbd contrôle la rigidité (5=souple, 20=normal, 50=quasi-rigide).ObjetSimuleSPH est implémentée pour une simulation de fluide incompressible employant la méthode SPH (Smoothed Particle Hydrodynamics).
\[W(r,h) = \frac{4}{\pi h^8}(h^2-r^2)^3,\quad r<h\]
\[\rho_i = \sum_j m_j\,W(r_{ij},h)\]
\[\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).
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 |
Pour une facette \((A,B,C)\) :
\[\vec{n} = \frac{\overrightarrow{AB}\wedge\overrightarrow{AC}} {\|\overrightarrow{AB}\wedge\overrightarrow{AC}\|}\]
Le lissage est recalculé à chaque pas par setNormals() dans ObjetSimuleMesh.