INTERFACE ConstraintManager; IMPORT Constraint, Integrator, SparseSymetricMatrix; CONST NoEvent = Constraint.NoEvent; TYPE T <: Public; Public = OBJECT METHODS init(n, h: CARDINAL); (* Alocates data structures for (initially) up to h constraints. *) addConstraint(constraint: Constraint.T); (* Adds a constraint to the manager's collection. *) removeConstraint(constraint: Constraint.T); (* Removes the given constraint from the manager's collection. *) start(t: LONGREAL; pos, vel: Constraint.Vector); (* Informs all constraints that the simulation is starting at time "t" in state "(pos, vel)". Must be called once before any other method below. *) numEquations(): CARDINAL; (* Total number of equations (and also of Lagrange multipliers) for the constraints, in the current regime. Updated by "start" and "treatEvent". *) computeForces( M: SparseSymetricMatrix.T; pos, vel, f: Constraint.Vector; t: LONGREAL; ); (* Computes the total reaction force for all constraints. *) detectEvent( t0: LONGREAL; pos0, vel0: Vector; t1: LONGREAL; pos1, vel1: Vector; ): LONGREAL; (* Returns the time of the earliest constraint-related event in the interval (t0 _ t1], or NoEvent if there is none. *) treatEvent(t: LONGREAL; pos, vel: Constraint.Vector); (* Treats all the constraint-related event(s) that were scheduled for time "t" by the preceding "detectEvent". *) END; END ConstraintManager.