HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SIM_Solver.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __SIM_Solver_h__
9 #define __SIM_Solver_h__
10 
11 #include "SIM_API.h"
12 #include "SIM_DataUtils.h"
13 #include "SIM_PhysicalParms.h"
14 
15 class SIM_Solver;
16 class SIM_Engine;
18 
21 
22 /// This is the base class for all Solvers. Solvers are the classes that
23 /// perform the actual simulation for objects. The solver is passed a
24 /// set of objects with mutual affector relationships.
25 class SIM_API SIM_Solver : public SIM_Data
26 {
27 public:
28  /// The possible return codes from a solve operation. These are kept in
29  /// order of priority to make multi-solvers easier to write. Any result
30  /// value from a subsolver that is greater than the previous highest
31  /// subsolver result becmoes the new overall return value.
32  typedef enum {
36  SIM_SOLVER_FAIL
37  } SIM_Result;
38 
39  /// Solve for the given objects. This function is called for each timestep
40  /// after the one where the objects are first created. This function calls
41  /// solveObjectSubclass to perform the real work.
42  SIM_Result solveObjects(SIM_Engine &engine,
43  SIM_ObjectArray &objects,
44  SIM_ObjectArray &newobjects,
45  SIM_ObjectArray &feedbacktoobjects,
46  const SIM_Time &timestep);
47 
48  SIM_Result postSolveObjects(SIM_Engine &engine,
49  SIM_ObjectArray &objects,
50  SIM_ObjectArray &newobjects,
51  SIM_ObjectArray &feedbacktoobjects,
52  const SIM_Time &timestep);
53 
54  /// Solves for a relationship. Invoked if "Solver" is a subdata
55  /// of a SIM_Relationship data.
56  SIM_Result solveRelationship(SIM_Engine &engine,
57  SIM_Relationship &relationship,
58  const SIM_Time &timestep);
59 
60  /// Get the number of cached time steps we want to solve for these objects.
61  /// This function calls getRequestedCacheSubclass to get the real value.
62  int getRequestedCache() const;
63  /// Gets the impulse mass matrix of an object for an impulse at the
64  /// provided world space position. This function simply calls
65  /// getImpulseMassMatrixSubclass().
66  void getImpulseMassMatrix(const SIM_Object &object,
67  const UT_Vector3 &impulseworldpos,
68  UT_DMatrix3 &immatrix) const;
69  /// Gets the impulse mass matrix of an object for an impulse at the
70  /// provided point on the geometry of the object. This function simply
71  /// calls getPointImpulseMassMatrixSubclass().
72  void getPointImpulseMassMatrix(const SIM_Object &object,
73  GA_Index ptnum, UT_DMatrix3 &immatrix) const;
74  /// Builds a resolver to efficiently compute mass matrices.
75  SIM_PointImpulseMassMatrixResolver *getPointImpulseMassMatrixResolver(
76  const SIM_Object &object) const;
77  /// Gets the value of some physical property for the supplied object
78  /// at a given position in world space. This function simply calls
79  /// getPropertyAtPositionSubclass().
80  fpreal getPropertyAtPosition(const SIM_Object &object,
81  const UT_Vector3 &worldpos,
82  const SIM_Property &property) const;
83  /// Gets the value of some physical property for the supplied object
84  /// at a given point on the object's geometry. This function simply
85  /// calls getPropertyAtPointSubclass().
86  fpreal getPropertyAtPoint(const SIM_Object &object,
87  GA_Index ptnum,
88  const SIM_Property &property) const;
89 
90  /// Builds a resolver to efficiently compute property values
91  SIM_PropertyResolver *getPropertyResolver(const SIM_Object &object,
92  const SIM_Property &property) const;
93  /// Gets the default collider label for an object using this solver.
94  void getDefaultColliderLabel(const SIM_Object &object,
95  UT_String &label) const;
96  /// Gets the default collider type for use on an object with a
97  /// particular collider label. This information is used by
98  /// SIM_Object::getCollider() to create a SIM_Collider to use
99  /// for collision detection betweena pair of objects. The
100  /// collidertype value returns the name of the SIM_Collider
101  /// subclass to use, and the collidereverseobjectroles parameter
102  /// returns whether the reverse object roles flag should be turned
103  /// on for the new collider. See the ReverseObjectRoles flag in
104  /// SIM_Collider for an explanation of this parameter.
105  void getDefaultCollider(const SIM_Object &object,
106  const UT_String &colliderlabel,
107  UT_String &collidertype,
108  bool &colliderreverseobjectroles) const;
109 
110  /// Returns the standard attribute name that corresponds to a given
111  /// SIM_Property value.
112  static const char *getPropertyAttribName(const SIM_Property &property);
113  /// Static method that implements a good standard approach to getting
114  /// a property at a given position.
115  static fpreal getPropertyAtPositionStatic(const SIM_Object &object,
116  const UT_Vector3 &worldpos,
117  const SIM_Property &property);
118  /// Static method that implements a good standard approach to getting
119  /// a property at a given point number.
120  static fpreal getPropertyAtPointStatic(const SIM_Object &object,
121  GA_Index ptnum, const SIM_Property &property);
122  /// Static resolver for getting property values.
123  static SIM_PropertyResolver *getPropertyResolverStatic(
124  const SIM_Object &object,
125  const SIM_Property &property);
126 
127  // Sets a temporary start time which may be used by this solver in
128  // place of the global simulation time. This is useful when
129  // handling substeps or multi-phase integration schemes. It is up
130  // to each solver to use this start time.
131  void setStartTime(const SIM_Time &starttime);
132 
133  // Returns true if this solver is a trivial solver, ie, does no
134  // updates itself. Is allowed to vary depending on which object
135  // is being solved.
136  bool isStatic(const SIM_Object *obj) const { return isStaticSubclass(obj); }
137 
138 protected:
139  /// Basic SIM_Solver constructor.
140  explicit SIM_Solver(const SIM_DataFactory *factory);
141  /// Basic SIM_Solver destructor.
142  virtual ~SIM_Solver();
143 
144  // Gets the currently stored start time. Returns false if the start time
145  // is invalid and leaves time unchanged.
146  bool getStartTime(SIM_Time &time);
147  void clearStartTime();
148 
149  /// Gets an array of SIM_Solver subdata attached to this data.
150  /// Useful for solvers which switch between or run other solvers.
151  void getSolverSubdata(SIM_SolverArray &subsolvers,
152  UT_StringArray *subsolvernames);
153  /// Gets an array of const SIM_Solver subdata attached to this data.
154  /// Useful for solvers which switch between or run other solvers.
155  void getConstSolverSubdata(SIM_ConstSolverArray &subsolvers,
156  UT_StringArray *subsolvernames) const;
157 
158  /// Determines if this solver does nothing on the object
159  virtual bool isStaticSubclass(const SIM_Object *obj) const
160  { return false; }
161 
162  /// This method solves for some objects. It performs whatever processing
163  /// is necessary to take objects from their state at one time to another.
164  /// The default implementation does nothing. The objects parameter holds
165  /// all the objects that should be solved for this timestep. The
166  /// newobjects parameter is a set of objects that were just created in
167  /// this timestep, and so should in most cases not be solved on this
168  /// timestep so that they maintain correct initial conditions.
169  virtual SIM_Result solveObjectsSubclass(SIM_Engine &engine,
170  SIM_ObjectArray &objects,
171  SIM_ObjectArray &newobjects,
172  SIM_ObjectArray &feedbacktoobjects,
173  const SIM_Time &timestep) = 0;
174 
175  // return success?
177  SIM_ObjectArray &objects,
178  SIM_ObjectArray &newobjects,
179  SIM_ObjectArray &feedbacktoobjects,
180  const SIM_Time &timestep){ return SIM_SOLVER_SUCCESS; };
181 
183  SIM_Relationship &relationship,
184  const SIM_Time &timestep)
185  { return SIM_SOLVER_SUCCESS; }
186 
187  /// Returns the amount of history required by this solver. Override
188  /// this function if your solver requires past data to calculate the
189  /// next time step. The default implementation returns 0.
190  virtual int getRequestedCacheSubclass() const;
191  /// Gets the impulse mass matrix of an object for an impulse at the
192  /// provided world space position. The default implementation gets the
193  /// closest point in the geometry and calls getPointImpulseMassMatrix().
194  virtual void getImpulseMassMatrixSubclass(
195  const SIM_Object &object,
196  const UT_Vector3 &impulseworldpos,
197  UT_DMatrix3 &immatrix) const;
198  /// Gets the impulse mass matrix of an object for an impulse at the
199  /// provided point on the geometry of the object. The default
200  /// implementation finds the world space position of the point and
201  /// calls getImpulseMassMatrix().
202  virtual void getPointImpulseMassMatrixSubclass(
203  const SIM_Object &object,
204  int ptnum, UT_DMatrix3 &immatrix) const;
205  /// Builds a resolver for evaluating mass matrices swiftly
206  virtual SIM_PointImpulseMassMatrixResolver *getPointImpulseMassMatrixResolverSubclass(
207  const SIM_Object &object) const;
208  /// Gets the value of some physical property for the supplied object
209  /// at a given position in world space.
210  virtual fpreal getPropertyAtPositionSubclass(const SIM_Object &object,
211  const UT_Vector3 &worldpos,
212  const SIM_Property &property) const;
213  /// Gets the value of some physical property for the supplied object
214  /// at a given point on the object's geometry.
215  virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object,
216  int ptnum,
217  const SIM_Property &property) const;
218  /// Builds a resolver for evaluating properties swiftly
219  virtual SIM_PropertyResolver *getPropertyResolverSubclass(
220  const SIM_Object &object,
221  const SIM_Property &property) const;
222  /// Gets the default collider label for an object using this solver.
223  virtual void getDefaultColliderLabelSubclass(
224  const SIM_Object &object,
225  UT_String &label) const;
226  /// Gets the default collider type for use on an object with a
227  /// particular collider label.
228  virtual void getDefaultColliderSubclass(
229  const SIM_Object &object,
230  const UT_String &colliderlabel,
231  UT_String &collidertype,
232  bool &colliderreverseobjectroles) const;
233 
234 private:
237 
238  // Holds the current time - ie. the time at the beginning
239  // of the timestep currently being processed. This can be
240  // used (by using calls to setStartTime and getStartTime)
241  // to inform solvers of when they should use a time other
242  // than the global simulation time when processing a timestep
243  SIM_Time myCurrentStartTime;
244  bool myCurrentStartTimeValid;
245 
246 };
247 
248 #endif
249 
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:45
#define DECLARE_CLASSNAME(DataClass, SuperClass)
Definition: SIM_DataUtils.h:20
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2544
UT_ValArray< const SIM_Solver * > SIM_ConstSolverArray
Definition: SIM_Solver.h:20
3D Vector class.
UT_ValArray< SIM_Solver * > SIM_SolverArray
Definition: SIM_Solver.h:17
Holds pointers to a number of SIM_Object objects.
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
bool isStatic(const SIM_Object *obj) const
Definition: SIM_Solver.h:136
double fpreal
Definition: SYS_Types.h:269
virtual SIM_Result postSolveObjectsSubclass(SIM_Engine &engine, SIM_ObjectArray &objects, SIM_ObjectArray &newobjects, SIM_ObjectArray &feedbacktoobjects, const SIM_Time &timestep)
Definition: SIM_Solver.h:176
#define SIM_API
Definition: SIM_API.h:10
virtual SIM_Result solveRelationshipSubclass(SIM_Engine &engine, SIM_Relationship &relationship, const SIM_Time &timestep)
Definition: SIM_Solver.h:182
virtual bool isStaticSubclass(const SIM_Object *obj) const
Determines if this solver does nothing on the object.
Definition: SIM_Solver.h:159
SIM_Property