In this file we discuss some ideas (design ideas, possible features, possible implementations...) that are not mature enought to be part of the stable design and therefore must be
Els objectes haurien de poder estar relacionats segons una jerarquia de sistemes de coordenades... Qui té RefSys?
- Universe: Pq em dóna la gana (i tb per poder localitzar universos en el metaunivers :)
- Object: Pq ha de ser comunes a tots els possibles Model que el representin.
- Alguns Model poden voler tenir el seu RefSys, però aquest SEMPRE penjarà del de l'Object a què representen.
- Ex: Rigid té el seu propi RefSys (centrat al CM i tal...) dinàmic.
- Un RefSys pot tenir un altre RefSys com a pare (o NULL).
- Els RefSys dels Object no es mouen per motius físics, només degut a l'animació cinemàtica o al control.
- L'aniuament de RefSys, de moment, només tindrà sentit a nivell d'Object... no es consideraran Objects que estiguin penjant d'un RefSys que correspongui a un Model directament.
Això pot afectar a la integració amb motors externs (si tenen graf d'escena amb transform nodes...), i no és imprescindible ara mateix, o sigui que ho aplaço per quan ho vegi clar (com quasi tot :)
Object podria ser una mena de representant d'un objecte físic, i tenir associat a cada instant un cert Model que representaria el model físic concret de l'objecte en aquell moment (partícula, rígid, deformable, etc...)
Això permetria canvis de model dinàmics (quan interactuin o passi alguna cosa especial) però mantenint la "identitat" dels objectes.
Els Controllers, Sensors i Constraints haurien de manipular-se EXTERNAMENT des del nivell Object únicament, no pas Model, encara que possiblement a nivell intern caldrà tenir rèpliques dels objectes específiques per cada Model, però això HA de ser transparent a l'aplicació!!
La multiplicitat de Models per un Object és una mica complicada de gestionar... el més elegant, crec, seria que hi haguessin algo així com Model Proxies, que encapsulessin un Model de tipus A pq funcionés com si fos de tipus B, ocultant tota la complexitat de sincronització (sincronització sota demanda?)
El ModelProxyAB seria un ModelA que internament gestiona un ModelB. ModelProxyAB hauria d'heretar de ModelA per oferir-ne tota la funcionalitat i tenir internament un ModelB a partir del qual s'inicialitzaria i amb el que podria sincronitzar-se en ambdós sentits (mètodes SyncProxy() i SyncInternal() de ModelProxy?)
Això pot semblar que implica una explosió combinatòria (totes les parelles de Models?) però en realitat el num de Models compatibles serà petit.
De fet, la idea dels ModelProxy es pot portar més enllà, i fer-los servir per controlar Models complexos (algo semblant a usar Deformers simples/intuitius per deformar malles complexes en Maya :)
Un Model complex podria ser controlat per un altre del mateix tipus però amb menys resolució (roba amb menys partícules, model articulat amb menys juntes, etc...)
Això admetria, de fet, allò de què parlava a les propostes per RACINE: Fer previews d'animacions complexes mitjançant models més simples (ModelProxy) que capturessin bona part de l'essència del model complex però fossin més fàcils de simular
Ho deixo com a bona idea, de moment, però crec que aquesta idea s'adaptaria bastant bé en l'arquitectura que tinc més o menys decidida.
Un Object es crearà amb un cert Model concret, el "model natural". Els DOF de l'Objecte sempre seran els d'aquest Model (la Shape, els Controllers i els Sensors sempre els han de poder llegir)
Això no implica que els DOF del Model que està representant l'Object actualment no es pugui consultar o controlar de forma específica (veure discussió sobre els possibles usos alternatius dels ModelProxy en algun altre lloc d'aquesta documentació)
Motius per canviar de Model:
- Interactions entre Objects amb Models diferents podrà fer que calgui generar un Model alternatiu per un dels Objects que permeti tractar la interacció.
- Tècnica de Simulation-LOD, ja que en per un mateix objecte diversos models tindràn costos computacionals diferents. Un exemple d'això seria la conversió entre DeformableSolid, RigidSolid i Particle, que correspondria a sacrificar qualitat/precissió per eficiència.
Els canvis de Model només s'han de poder fer des de l'app en certs punts de sincronització. (segurament, fora del pas de simulació)
Cal veure entre quines parelles de models es poden fer transicions i definir com es faran virtual Model::CreateFrom(Model *p_model) i Model::UpdateFrom() amb polimorfisme per cada subclasse de model?
TOTS els Models s'haurien de poder transformar a Particle, o a Rigid si es vol orientació...
Segurament seria útil poder tenir objectes lleugers per als tipus d'objectes físics usats massivament (partícules i sòlids rígids principalment). Aquests objectes lleugers es diferenciarien de la resta en:
- Requeririen menys memòria
- Tindrien moltes menys dependències/objectes relacionats
- No podrien canviar de Model
Bàsicament, es tractaria de combinar un Object i un Model concret en una mateixa classe i minimitzar tota la complexitat de bookkeeping que el sistema d'Objectes amb Model variable genera.
Hi ha una mica d'esquizofrènia entre model dinàmic i forma de l'objecte... una superfície implícita rígida i un sòlid rígid comparteixen el model dinàmic però la superfície té equs de forma que permetrien "enganxar-hi" restriccions i el sòlid no!
Model = Model matemàtic d'un objecte físic:
- Estat
- Equacions diferencials
- Equacions de forma:
- Rígida:
- Superfície/Corba implícita
- Superfície/Corba paramètrica
- Deformable: ...
El més lògic i simple és associar una Shape (forma física) a un Object... La Shape pot dependre dels DOF de l'Objecte o no (a nivell global segur, per la posició i orientació com a mínim, però a nivell local si és una shape rígida no dependrà de res més).
L'Object no dependrà per res de la Shape... si hi ha alguna dependència entre la dinàmica i la forma de l'Object, llavors aquesta relació serà a través dels DOF de la dinàmica interna de l'Object, no pas dels paràmetres que defineixen la Shape.
Alguns tipus de Connectors, però, si que podran dependre de la Shape, i indirectament, de l'Object (DOF)
- Object és un representant de l'objecte físic, i sempre té com a DOF els del seu Model natural, als quals es pot associar la Shape.
- N Shape <- 1 Object(DOF) <- 1 Object(pos + ori) com a mínim
- N Connector <- 1 Shape (PointOnSurface, PointOnCurve...) <- 1 Object (PointOnRigid, VectorOnRigid...)
Alguns Model serien (S = estat)
- Particle: S = [x,p]
- Rigid: S = [x,Q,p,L]
- DeformableSolid:
- MassAndSpringSolid: S = [x_1,x_2,...,x_N , v_1,..., v_N]
- ElasticSolid
- KinematicSolid
- DeformableSurface
- Cloth
- MassAndSpringSurface: S = [x_1,x_2,...,x_N , v_1,..., v_N]
- ElasticSurface
- KinematicSurface
- DeformableCurve
- Rope
- MassAndSpringCurve: S = [x_1,x_2,...,x_N , v_1,..., v_N]
- ElasticCurve
- KinematicVertexCurve
- ArticulatedSolid (per impl Featherstone eficientment?)
- Car (en coords generalitzades eficientment) ...
In this first stage entities are created and initialized. The main actions that need to be performed are:
- Universes:
- Systems:
- Create in a certain Universe
- Configure simulation scheme used
- Objects:
- Create in a certain Universe and with a certain natural Model
- Initialize physics data/state
- Add to a certain System in which it will be naturally simulated
- Shapes:
- Create
- Attach to a certain Object
- Connectors:
- Interactions:
- Create on 1 or several Connectors
- Constraint/Joint
- Setup Joint internals (motors, damping, etc...)
- Controller:
- Create
- Attach to certain Object(s)
- Setup
- Sensor:
- Create
- Attach to certain Object(s)
Every timestep the following actions must/may be performed:
- Advance a dt in time (the actual seq of actions depends on the sim scheme)
- Update External Forces (per object)
- Update Controllers (per object)
- Constraint force solving (per system)
- Update State (Integrate, Interpolate, Extrapolate...) (per system or object)
- Collision/Contact Detection (intra and inter system)
- Constrain/Collision/Contact Solving (per system and interacting systems)
- Query simulation results/state from the App: (through the API)
- Any useful query should be easily answered... object states, total energy, etc...
- Edit the simulated world from the App: (through the API)
- Universes:
- Systems:
- Destroy
- Configure simulation scheme used
- Objects:
- Destroy
- Change physics data/state
- Add to a certain System in which it will be naturally simulated
- Shapes:
- Connectors:
- Interactions:
- Destroy
- Constraint/Joint
- Setup Joint internals (motors, damping, etc...)
- Controller:
- Sensor:
Enumerar Tasks i Subsystems
Task: Acció que transforma uns inputs fixos (DB) en uns outputs fixos (DB). Ex: Calcular dSdt a partir de S(t) i F(t)
Subsystem: Subsistema encarregat de fer Task complexa (Ex: CollDet)
Composició de Tasks => Animació
- Composició Fixa: codificada en cada Kernel
- Composició Configurable: DAG de Processing & Data Blocks
- Permetria suport per Tasks externes, cosa que convertiria Saphyre2 en un petit SO en temps real que podria fer scheduling basat en dependències entre Tasks
TODO:
- Definir Tasks, dependències de dades i interfície. (veure pipeline Karma)
- Definir pipeline d'animació i punts de sincronització (barreres) per cada mètode/esquema (Baraff, Timestepping, Jakobsen, etc...)
Karma Pipeline Illegally Ripped from the User Guide
Cada Task es podria assignar a un cert processador.
La GPU seria un cas especial de processador, que podria fer algunes tasques també... cal veure quines i quina interfície caldria per minimitzar la transferència de memòria entre CPU(s) i GPU. => A Favoritos/GPU hi ha un link a articles sobre càlculs que es poden en la GPU, com resoldre S.Eq linials, simulacions de PDE, etc...
La pipeline es podria paral·lelitzar tenint en compte les branques disjuntes de la seqüència de càlculs que s'hagi de fer, i fins i tot es podrien balancejar els processadors usant estimacions conservadores sobre la duració de cada sub-seqüència de càlculs i els punts de sincronització entre aquestes!!
Ex de Tasks i paralelització:
- Actualitzar un System (fins a la detecció de colisions, que requereix tots els System tot i que segurament es poden fer estimacions basades en les BBox i les velocitats màximes que permetin descartar-les MOLT ràpid) és una tasca amb granularitat gruixuda.
- Actualitzar estat dels obj degut als controladors és una tasca molt paral·lela, amb granularitat d'objecte.
- Calcular derivades i omplir vector d'estat del S2_Partition és una tasca també molt paralela i posterior a l'anterior, i té granularitat d'objecte però al final ha d'escriure en un vector compartit (estat obj de la partició).
- Actualitzar els obj d'una partició és una tasca atòmica, però amb granularitat de "cjt d'objectes", molt més gruixuda que l'anterior. Per tant, és un punt de sincronització/ barrera entre tots els càlculs previs necessaris per actualitzar els objectes involucrats.
- Actualitzar els obj d'un S2_System és el mateix que actualitzar les S2_Partition de l'S2_System, però té una granularitat més gran que aquest encara, i tb marca un punt de sincronització entre tots els S2_Partition.
- Actualitzar Dinàmica i fer detecció de colisions són tasques clarament paralelitzables per a grups d'objectes que no interactuen.... de forma segmentada, per cada obj/grup es faria calcularia la dinàmica i després es faria servir interpolació per detectar colisions mentre, paralelament, es calcula la dinàmica d'altres objectes/grups.
REDUNDANT... PARLAR-NE A composició de Tasks configurable a Tasks & Subsystems
A cada pas de temps l'animació requereix l'actualització ordenada de tots els objectes (o almenys d'aquells que depenguin d'altres objectes que han estat actualitzats) degut a les segons relacions de dependència de dades. Aquestes dependències es poden modelar amb un graf dirigit (DG), tal com ho fa Maya.
Casos difícils:
- RK: Cal suportar integradors del tipus Runge-Kutta i semblants, que necessiten avaluacions de les derivades de l'estat dSdt en diversos instants de temps entre t i t+dt... això complicarà una mica la pipeline...
- Afortunadament, el nombre de re-evaluacions és fixe.
- Bracketing: Per detectar l'instant de colisió amb la precissió desitjada. Rs pot fer per re-integració fins al t_min actual o bé per interpolació entre S(t) i S(t+dt)... el primer cas ho complica una mica pq no es tracta només de fer un càlcul sobre els estats ja calculats sinó de re-executar part de la seqüència de càlculs amb un dt diferent.
- El nombre de re-evaluacions no és fixe, però es pot posar una fita superior.
- Freq d'actualització variable per cada S2_System + interpolació: Cada S2_System pot requerir una freq diferent per assolir l'estabilitat/precissió desitjada, de manera que es poden simular a freqs diferents i sincronitzar mitjançant interpolació.
- Això permetria, a més, usar "timewarp", és a dir, fer avançar sistemes a la velocitat més elevada possible sempre que no hi hagi cap event que ho invalidi (xocs, events de control, etc...)
- Freq d'actualització variable per cada S2_System + interpolació: Cada S2_System pot requerir una freq diferent per assolir l'estabilitat/precissió desitjada, de manera que es poden simular a freqs diferents i sincronitzar mitjançant interpolació.
- Això permetria, a més, usar "timewarp", és a dir, fer avançar sistemes a la velocitat més elevada possible sempre que no hi hagi cap event que ho invalidi (xocs, events de control, etc...)
Even though the actual implementation of useful/high-level controllers for animated objects is beyond the scope of Saphyre2, controllers should be easily built on top of Saphyre2 public functionality (API)
Several control paradigms on the animated objects should be supported:
- Direct control: The control scheme acts directly on the animated object DOFs. We can find several subclasses:
- Keyframes with interpolation on DOFs (position control)
- Animation curves for each controlled DOF (position control)
- Procedural control for each DOF (path following, etc...)
- Interactive Control (user-in-the-loop)
- Position control (DOF control)
- Velocity control (generalized velocity control)
- Force control (generalized force control)
- Indirect control: The control scheme is objective-based, and does not manipulate the object's DOFs directly, but rather specifies conditions that we'd like them to satisfy (strictly or aproximately)
- Constraints on DOFs or Connectors
- Attractors on DOFs or Connectors (PD-Controllers)
- (IK on Connectors?)
Regarding Connectors ("geometric features"), they can be classified according to 2 categories:
- Attached to an Object's (or Shape) DOF or Free
- Static or Animated.
This can be formalized saying that the Connector definition can be object-dependent and time-dependent: a( q_i, t )
For control purposes, the interesting uses of Connectors are:
- Constraint between an object-dependent Connector a(q_i,t) and any other compatible Connector b(q_j,t).
- Attractor between an object-dependent Connector a(q_i,t) and any other compatible Connector b(q_j,t).
Where any of the involved time-dependent Connectors can be controlled/animated externally by any of the Direct Control methods (including Interactive Control)
Thus, time-dependent Connectors should offer their outputs as animable DOF to the controllers.
- Note:
- Should allow COUPLING between time dependency and Object-DOF dependency?? => This has a low impact on the implementation, so by now the only supported Connectors are:
- Uncontrolled (time-independent) dof-dependent Connectors => a(q_i)
- Uncontrolled (time-independent) dof-independent Connectors => a(·)
- Controlled (time-dependent) dof-independent Connectors => a(t)
As some control strategies may try to drive the system into illegal configurations (constraint violation, for example), an error/event notification mechanism is needed to allow Saphyre2 report this kind of situations to the controllers.
Estaria MOLT bé poder tenir control de cada DOF independent i definible per l'aplicació... algo en plan DAG del maya (o connect del Nebula2). Ex: Usar Animation Curve per controlar 1 sol DOF
Una manera de fer-ho seria que cada Object tingués un cert cjt de Controladors que han de ser considerats abans d'actualitzar-lo, i cadascun d'aquest pogués afectar a un o diversos DOF.
- Note:
- RESTRICTION: Each DOF can only be controlled by a single Controller at given time.
RESTRICTION: Only the DOFs can be directly controlled.
Caldria algun mecanisme per saber quins DOF controla cada Controlador:
- Màscara associada a cada Controlador que indiqui a quins DOF afecta.
- Un Controlador pot controlar un cert tipus de dada (Real, P3D, V3D, Angle, EulerAngles, Quat, etc...) i una màscara indica quins DOF Real interns controla i quins no. Aquest tipus de controladors podrien consultar el valor de la dada que modifiquen (sencer, però tindrien màscara que els indicaria quins poden modificar i quins no)
Pensar-hi una mica més i decidir el grau de generalitat i complexitat que es vol, pq es podrien fer més coses com fer que els controladors depenguin uns dels altres, definir ordre d'aplicació (si canvien dades de l'obj que altres Controladors han de consultar l'ordre IMPORTA), etc... => Ja hi he pensat i NO consideraré aquest cas. L'ordre és indefinit, de moment.
Pensant en els objectes deformables i els esqueletals, el número de DOF és generalment elevat. Lo més flexible seria que cada DOF pogués estar controlat independentment (cada vèrtex d'un deformable podria ser cinemàtic o dinàmic)... probablement seria ineficient que fos així (MOLTS Controllers per un sol objecte), però en general això no passarà. Lo important és no fer que es cridi un Controller per cada DOF controlat sinó que es cridin "tots els Controllers de l'objecte" i una màscara indiqui quins són controlats i quins no... però en general no caldrà saber quin és el Controller que controla cada DOF sinó al revés, cada Controllers ha de saber quins DOF controla (passant-li un ptr al vector estat o un DOF_ID o algo així??) => Probablement és molt millor usar un DOF_ID que es mapegi fàcilment a l'estat que no un ptr, que ho limita a una variable concreta. => El DOF_ID pot ser un índex base en el vector estat de Reals, de manera que si el Controller modifica un V3D, la seva sortida s'escriurà en les posicions DOF_ID, DOF_ID+1 i DOF_ID+2 del vector estat.
==> M'imagino que això dels DOF_ID és lo que fa el Maya amb els Handlers de DOF... potser m'hauria de mirar el Maya amb més detall no ?-)
- A l'hora de resoldre les restriccions, cal saber quins DOF són lliures i quins controlats cinemàticament (aquests últims NO han de considerar-se variables en el Solver sinó dades! => Augmenta complexitat gestió però disminueix el tamany del problema a resoldre :)
- DOF controlats per Constraint ?
- DOF controlats per Attractor ?
ALERTA: Els canvis en el tipus de gestió de cada DOF (simulat, animat, controlat, etc...) poden ser MOLT costosos (requerir reformar tota una matriu de resolució de restriccions quan un DOF passa de dinàmic a controlat cinemàticament, per exemple)
=> Per tant, en la majoria dels casos no crec que tingui gaire sentit admetre canvis incrementals/arbitraris, és molt més senzill reformar el que calgui tot de cop a partir de la nova situació (el control de diversos DOF pot haver canviat) => Reformar matriu sencera amb els nous DOF dinàmics, no afegir/treure files/columnes per cada DOF que canvia de gestió!
Animar els Object cinemàticament ha de ser fàcil i intuitiu. Caldria admetre:
- Corbes d'animació per cada DOF (en plan Maya)
- Keyframes de posició i orientació
- Generació d'animacions (procedural)
- Mixing per cada DOF o cjt de DOF (fade in, fade out, blending, transició, etc...)
- Malles animades per vèrtex (KinematicVertexMesh??)
- Un controller que ho faci + derivació numèrica si es demanen les velocitats?
- INTERPOLACIO
L'animació cinemàtica s'hauria de poder usar:
- Per si sola, objectes cinemàtics de comportament predefinit.
- Només cal poder reproduir-la
- Com a atractor de l'animació dinàmica:
- PD controllers que empenyen l'estat cap a l'objectiu.
- Considerar altres sistemes de control possibles...(per velocitat objectiu, per exemple)
- Com a restricció de l'animació dinàmica:
- Constraints per cada corba d'animació o per posició i orientació...
Si es vol integrar animació keyframed a Saphyre2 potser caldria donar suport a l'animació (keyframes, interpolació, etc...) d'atributs que no siguin estrictament DOF cinemàtics...
Several control schemes must be supported, but their final effect on the dynamics can be abstracted into a small set of cases:
- DOF/Position/q_i Control (Keyframes, Animation curves...)
- Generalized Velocity/q_i' Control (Ex: Interactive Control of characters)
- Generalized Force/mq_i'' Control (PD-Controllers...)
- Constraints:
- On Positions/q_i
- On velocities/q_i'
The Saphyre2 Core will only have knowledge of this low-level control schemes. For performance reasons, however, it may be useful to integrate redundant control schemes into the Core (PD-Controllers, for example, can be implemented on top of Force Control, but managing them internally would be faster in most cases)
The bookkeeping overhead produced by the single DOF level control support should be minimized, and several very common cases must be efficiently handled:
- Uncontrolled objects
- Single Controller all-DOFs controlled objects (keyframed mainly)
- Multi-DOF controllers on common DOF groups (like 3DOF-position, 3DOF-velocity, Orientation)
Following the PayPerSim (tm) efficiency requirement, a possible implementation would be to have an optional ControlDescriptor structure attached that would be NULL for uncontrolled Objects.
class S2::Object::ControlDescriptor:
- For each DOF:
- Who controls it
- Which kind of low-level control scheme is applied to it (position | velocity | force,...)
- ? The last (target) value set by the controller ?
Under 2nd order dynamics hypothesis:
- Force Control scheme can be integrated in the "standard" simulation pipeline. [OSCAR]: HOW do external forces (gravity!) integrate with this??
- Velocity Control will need a mechanism to compute acceleration/q'' if controlled objects are allowed to interact with force controlled/simulated objects.
- Position Control will need a mechanism to compute velocity/q' and acceleration/q'' for the same reason.
Again, the 1st and 2nd derivative computation mechanism should NOT add a significant overhead when not used.
As a programming simplification feature, attaching a general multi-DOF controller (3D velocity-controller, for example) should not fail if part of the DOFs that it tries to control are already controlled, but override their previous control scheme if it was less direct (q,q',q'' in decreasing directness order)
The "pattern" used in the S2::ControlDescriptor situation (it must have a name, sure... I'll call it Optional Members and feel incredibly witty all about it until I find the actual name ok ?-) can be applied to other situations:
- Cache: Some derived data may be cached in each Object for better performance (rotation matrix, inverse rotation matrix, global frame inertia tensor.
- History: For interpolation and numerical derivation purposes, some Objects may store their recent path in phase-space in an optional member.
- To reduce the Entities' "weight" in memory some redundant data can be stored in a per-category fashion. For example, Mass and inertia tensor of massively used objects can be stored only once in some kind of CategoryDescriptor and queried by any category-instance when needed. The same happens with Material Parameters (friction coeffs, etc...) (I think this would make the internal numerical methods more cache-friendly)
Hi ha una mica d'ambiguitat entre el que es pot fer amb els objectes (Object, Constraint, Controller, etc...) des de dins de Saphyre2 i des de l'aplicació, i segurament seria millor oferir a l'App una API que només permetés fer les accions necessàries, amagant la interfície interna que pot ser fins i tot inconsistent usar des de l'app. (o això a cal gestionar molt rígidament els permisos de crida dels mètodes (usar private i friend a saco), que tampoc m'agrada.
Saphyre1 tenia una API desastrosa, pq obligava a les Apps a fer subclasses dels objectes de simulació. Això s'ha d'evitar a tota costa (usar Saphyre2 per agregació, no per herència!)
ODE té una API en C molt desacoblada de la implementació i bastant senzilla i coherent, però una mica engorrosa pel meu gust, pq obliga a usar ID's d'objectes i funcions que treballen sobre tipus concrets d'objectes... La trobo coherent però rústica, i no m'agrada com queda escrit el codi.
Mathengine té una API similar a la de ODE, també en C i bastant farragosa des del meu punt de vista.
La pregunta és, quines característiques vull que tingui la API de S2?
- C o C++ ?
- Us de tipus de dades propis/interns ?
Una idea:
- Cada Model té una classe ModelAPI associada que és la que s'usa des de l'App per crear, consultar i modificar un objecte. Cada ModelAPI tindria internament un Object que tindria com a model natural el Model que representa el ModelAPI (Particle, Rigid, etc...). Els mètodes de cada ModelAPI haurien de permetre:
- Inicialitzar
- Consultar
- Modificar dades i paràmetres de funcionament
- La resta d'entitats que tingui sentit poder voler inicialitzar, consultar i modificar des de l'App (System, Constraint, etc...) també tindrien objectes API associats de forma similar, de manera que globalment hi hauria una capa addicional entre l'App i S2, l'API, formada per un conjunt de classes XXXXAPI que donarien accés a totes les funcionalitats de la llibreria d'una forma segura/robusta però mantenint alhora els aventatges de l'OO (cosa que NO passa amb Mathengine/ODE)
En resum, els XXXXAPI oferirien a l'App les funcionalitats i la interfície més còmoda i simple possible, ocultant tota la complexitat interna de S2. Afegiria una mica d'overhead d'interfície/crides a funcions i de conversió de dades, però això no hauria de ser greu pq només es farà com a molt 1 cop per cada objecte per cada dt. Molts mètodes podran ser directament crides a mètodes dels objectes interns.
Aquesta API tb és la que s'hauria de poder accedir des d'scripts, però de moment d'això passo.
Veure Saphyre2 API.
[OSCAR]: Això està més o menys resolt si s'implementa bé S2API. Els canvis que l'App vol fer al món simulat es podran analitzar en S2API i demanar a S2 que faci les sincronitzacions necessàries (com per exemple testejar si una posició "editada" d'un objecte generaria interseccions, si una velocitat "editada" violaria les restriccions, etc...)
Inicialització i canvis de valors físics des de l'aplicació:
- Caldria establir una manera consistent de modificar valors interns de la simulació sense afectar al funcionament d'aquesta... no pot ser que un callback d'IA modifiqui a saco una posició d'un objecte a mitja actualització... de fet, durant els càlculs de física ningú extern hauria de poder canviar les dades físiques. Només s'hauria de poder fer abans i després de cada frame...
Això és molt important, pq un canvi de posició, per exemple, pot fer que 2 objectes que no xocaven dins Saphyre2 passin a estar intersectant-se fent un canvi extern "discontinu" de posició. El mateix passa amb les velocitats, que si es canvien "a saco" des de fora poden passar a violar les restriccions.
Per tant cal:
- Fixar on es poden canviar dades dels objectes
- Comprovar si hi ha hagut canvis abans de cada actualització i actualitzar les dades internes de S2 conseqüentment.
- Fer una mena de S2_Object->Touch() que indiqui canvis externs en l'objecte.
- El touch es propagaria a Systems si l'obj tocat està connecta a algun altre mitjançant una Interaction.
- Els canvis de dades específiques d'un tipus de Model concret no es faran a traves de la interfície d'Object sinó de la de Model, obtenint-lo abans del seu Object amb GetParticle, GetRigid, etc...
- Els canvis que facin els Controllers se suposa que ja estaran convenientment integrats en la llibreria i no haurien de donar problemes.
Mathengine té una manera de definir "change blocks" dins els quals es poden fer canvis sobre els objectes simulats.
Interactions between Objects do not always need to couple them tightly and/or affect them in the same way.
We may want to constrain a dynamic particle move on a surface attached to a dynamic Rigid Body and let the movement of the rigid body influence the particle but not the other way round. In this case, the Rigid Body movement would not depend on the Particle's, and therefore could be computed independently (even in a different Solver and/or using a different simulation method).
Shortly, the Rigid Body would act as if it was Kinematic from the Particle's point of view.
Should we fit this in the standard ObjectA <- Interaction (Constraint) -> ObjectB framework by specifying if an object acts as Kinematic or Dynamic in the Interaction or we'd better treat this case as ObjectA controlling ObjectB?
We should also consider the difference between intra-system and inter-system interactions. While the first case should be natively solved (contacts and constraints), the second one couples the simulation of 2 or more systems and therefore must be treated in some way:
- Partitioned Dynamics: Systems are simulated independently but taking into account their effects on the other ones... see the paper from Baraff on "Partitioned Dynamics" BARAFF-WITKIN97.
- Temporal System fusion: Some kind of Meta-System merges temporally several Systems and simulates them all as coupled (this can imply model-switching and selecting appropiate solvers) until the intra-system interaction ends.
There should be a mechanism for reporting simulation/animation events to the App. Events that may be interesting for the App include:
- Collision/Contact Started/Broken
- Constraint violated by Controller (and if it could be fixed or not)
- Object frozen/unfrozen (Simulation Culling)
- Broken Joint
- Joint limit reached (max_angle and the like)
An S2API::IEventListenerAPI interface class should be defined to allow the Apps instantiate it and register themselves to S2 for receiving some/all event types.
Events => Discontinuitats:
- Els events serien discontinuitats de l'animació, que probablement obligarien a integrar en 2 parts un cert dt interromput per un event.
- Idealment haurien de poder generar-se en QUALSEVOL instant de temps, no només a principi de frame.
- La seq de càlculs hauria de poder adaptar-se a la recepció d'un event fent només la feina imprescindible per tractar-lo.
- Les colisions, la creació o destrucció d'un objecte o Constraint, etc... es podrien considerar events, i haurien de poder produir-se en qualsevol instant de temps, però es podrien tractar molt més eficientment si es produissin en un instant d'inici de frame (no cal integrar en 2 parts en aquest cas)
- La creació d'objectes i altres canvis en la simulació es podrien escriptar com a events que es produeixen en instants de temps determinats, donant lloc així a un "guió" amb control de temps de les animacions...
- Note:
- De moment PASSO d'això de les discontinuitats
La majoria de mètodes per resoldre contactes són menys fiables quan hi ha fricció que quan no n'hi ha. Perquè??? És per les propietats de les matrius involucrades, crec, però no acabo de veure el motiu físic si és que n'hi ha.
=> En qualsevol cas, pq no provar algun model de fricció que eviti aquest problema???
a) Forces de fricció i forces normals estan acoblades pel model de fricció de Coulomb, però i si les desacobléssim artificialment:
- Calcular Fn sense fricció, NO aplicar-les, calcular Fr corresponents, aplicar-les i finalment tornar a calcular Fn definitives tenint en compte les Fr ja aplicades i aplicar-les.
- Intercalar el càlcul de Fn i Fr en el temps, de manera que les Fr d'un dt s'apliquin al dt següent ABANS de calcular les Fn corresponents i aplicar-les. => Està clar que això és menys realista, però caldria comparar-ho amb els mètodes "realistes" i veure si:
- És més estable?
- Té bon aspecte (dóna el pego?)
- És més eficient?
b) Model de fricció diferent al de Coulomb:
- Viscous drag (basat en velocitats) => Estudiar diversos models de fricció per veure si n'hi ha algun de més adient.
=> JAJAJAJAJA... altre cop: a) és justament el que fa ODE... o algo semblant... ho diu a la documentació.
Instead of detecting contacts every timestep, track them (using the motion between timesteps) i order to predict their next position (ideas from WalkOnSurface could be used here...)
I'm pretty sure people is doing this... at least to smooth the contact handling along time (to achieve better continuity)
Seria interessant admetre instanciació d'objectes pesats:
- Shapes (sobretot malles complexes!)
- Collision Objects
- Animacions
- Algun objecte físic complex? (deformable amb pos repòs, per exemple?...) o topologia d'un tros de roba, o estructura/topologia i posició de repòs d'un model articulat...)
There could be a "bulletproof" simulation mode that checked for all possible sources of numerical errors/unstability and adapted to it (or reported/logged the reason to the user/app).
This would be very useful in prototyping simulations. Reporting the source of error would help to tune the simulation parameters to make it stable in the "relaase mode".
This could be implemented as a compilation time option, but it would be far more interesting to have the option to switch the simulation mode interactively, so, maybe implementing 2 code-paths for all solvers that may encounter numerical errors is better.
Generated on Tue Aug 10 15:58:31 2004 for Saphyre2 by
1.3.5