00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Side Effects Software Inc. 00008 * 477 Richmond Street West, Suite 1001 00009 * Toronto, Ontario 00010 * Canada M5V 3E7 00011 * 416-504-9876 00012 */ 00013 00014 #ifndef __SIM_Solver_h__ 00015 #define __SIM_Solver_h__ 00016 00017 #include "SIM_API.h" 00018 #include "SIM_DataUtils.h" 00019 #include "SIM_PhysicalParms.h" 00020 00021 class SIM_Solver; 00022 class SIM_Engine; 00023 class SIM_ObjectArray; 00024 00025 typedef UT_PtrArray<SIM_Solver *> SIM_SolverArray; 00026 typedef UT_PtrArray<const SIM_Solver *> SIM_ConstSolverArray; 00027 00028 /// This is the base class for all Solvers. Solvers are the classes that 00029 /// perform the actual simulation for objects. The solver is passed a 00030 /// set of objects with mutual affector relationships. 00031 class SIM_API SIM_Solver : public SIM_Data 00032 { 00033 public: 00034 /// The possible return codes from a solve operation. These are kept in 00035 /// order of priority to make multi-solvers easier to write. Any result 00036 /// value from a subsolver that is greater than the previous highest 00037 /// subsolver result becmoes the new overall return value. 00038 typedef enum { 00039 SIM_SOLVER_SUCCESS, 00040 SIM_SOLVER_REPEAT, 00041 SIM_SOLVER_SUBSTEP, 00042 SIM_SOLVER_FAIL 00043 } SIM_Result; 00044 00045 /// Solve for the given objects. This function is called for each timestep 00046 /// after the one where the objects are first created. This function calls 00047 /// solveObjectSubclass to perform the real work. 00048 SIM_Result solveObjects(SIM_Engine &engine, 00049 SIM_ObjectArray &objects, 00050 SIM_ObjectArray &newobjects, 00051 SIM_ObjectArray &feedbacktoobjects, 00052 const SIM_Time ×tep); 00053 00054 SIM_Result postSolveObjects(SIM_Engine &engine, 00055 SIM_ObjectArray &objects, 00056 SIM_ObjectArray &newobjects, 00057 SIM_ObjectArray &feedbacktoobjects, 00058 const SIM_Time ×tep); 00059 00060 /// Get the number of cached time steps we want to solve for these objects. 00061 /// This function calls getRequestedCacheSubclass to get the real value. 00062 int getRequestedCache(); 00063 /// Gets the impulse mass matrix of an object for an impulse at the 00064 /// provided world space position. This function simply calls 00065 /// getImpulseMassMatrixSubclass(). 00066 void getImpulseMassMatrix(const SIM_Object &object, 00067 const UT_Vector3 &impulseworldpos, 00068 UT_DMatrix3 &immatrix) const; 00069 /// Gets the impulse mass matrix of an object for an impulse at the 00070 /// provided point on the geometry of the object. This function simply 00071 /// calls getPointImpulseMassMatrixSubclass(). 00072 void getPointImpulseMassMatrix(const SIM_Object &object, 00073 int ptnum, UT_DMatrix3 &immatrix) const; 00074 /// Gets the value of some physical property for the supplied object 00075 /// at a given position in world space. This function simply calls 00076 /// getPropertyAtPositionSubclass(). 00077 fpreal getPropertyAtPosition(const SIM_Object &object, 00078 const UT_Vector3 &worldpos, 00079 const SIM_Property &property) const; 00080 /// Gets the value of some physical property for the supplied object 00081 /// at a given point on the object's geometry. This function simply 00082 /// calls getPropertyAtPointSubclass(). 00083 fpreal getPropertyAtPoint(const SIM_Object &object, 00084 int ptnum, const SIM_Property &property) const; 00085 00086 /// Builds a resolver to efficiently compute property values 00087 SIM_PropertyResolver *getPropertyResolver(const SIM_Object &object, 00088 const SIM_Property &property) const; 00089 /// Gets the default collider label for an object using this solver. 00090 void getDefaultColliderLabel(const SIM_Object &object, 00091 UT_String &label) const; 00092 /// Gets the default collider type for use on an object with a 00093 /// particular collider label. This information is used by 00094 /// SIM_Object::getCollider() to create a SIM_Collider to use 00095 /// for collision detection betweena pair of objects. The 00096 /// collidertype value returns the name of the SIM_Collider 00097 /// subclass to use, and the collidereverseobjectroles parameter 00098 /// returns whether the reverse object roles flag should be turned 00099 /// on for the new collider. See the ReverseObjectRoles flag in 00100 /// SIM_Collider for an explanation of this parameter. 00101 void getDefaultCollider(const SIM_Object &object, 00102 const UT_String &colliderlabel, 00103 UT_String &collidertype, 00104 bool &colliderreverseobjectroles) const; 00105 00106 /// Returns the standard attribute name that corresponds to a given 00107 /// SIM_Property value. 00108 static const char *getPropertyAttribName(const SIM_Property &property); 00109 /// Static method that implements a good standard approach to getting 00110 /// a property at a given position. 00111 static fpreal getPropertyAtPositionStatic(const SIM_Object &object, 00112 const UT_Vector3 &worldpos, 00113 const SIM_Property &property); 00114 /// Static method that implements a good standard approach to getting 00115 /// a property at a given point number. 00116 static fpreal getPropertyAtPointStatic(const SIM_Object &object, 00117 int ptnum, const SIM_Property &property); 00118 /// Static resolver for getting property values. 00119 static SIM_PropertyResolver *getPropertyResolverStatic( 00120 const SIM_Object &object, 00121 const SIM_Property &property); 00122 00123 // Sets a temporary start time which may be used by this solver in 00124 // place of the global simulation time. This is useful when 00125 // handling substeps or multi-phase integration schemes. It is up 00126 // to each solver to use this start time. 00127 void setStartTime(const SIM_Time &starttime); 00128 00129 protected: 00130 /// Basic SIM_Solver constructor. 00131 explicit SIM_Solver(const SIM_DataFactory *factory); 00132 /// Basic SIM_Solver destructor. 00133 virtual ~SIM_Solver(); 00134 00135 // Gets the currently stored start time. Returns false if the start time 00136 // is invalid. 00137 bool getStartTime(SIM_Time &time, bool invalidate = false); 00138 00139 /// Gets an array of SIM_Solver subdata attached to this data. 00140 /// Useful for solvers which switch between or run other solvers. 00141 void getSolverSubdata(SIM_SolverArray &subsolvers, 00142 UT_StringArray *subsolvernames); 00143 /// Gets an array of const SIM_Solver subdata attached to this data. 00144 /// Useful for solvers which switch between or run other solvers. 00145 void getConstSolverSubdata(SIM_ConstSolverArray &subsolvers, 00146 UT_StringArray *subsolvernames) const; 00147 00148 /// This method solves for some objects. It performs whatever processing 00149 /// is necessary to take objects from their state at one time to another. 00150 /// The default implementation does nothing. The objects parameter holds 00151 /// all the objects that should be solved for this timestep. The 00152 /// newobjects parameter is a set of objects that were just created in 00153 /// this timestep, and so should in most cases not be solved on this 00154 /// timestep so that they maintain correct initial conditions. 00155 virtual SIM_Result solveObjectsSubclass(SIM_Engine &engine, 00156 SIM_ObjectArray &objects, 00157 SIM_ObjectArray &newobjects, 00158 SIM_ObjectArray &feedbacktoobjects, 00159 const SIM_Time ×tep) = 0; 00160 00161 // return success? 00162 virtual SIM_Result postSolveObjectsSubclass(SIM_Engine &engine, 00163 SIM_ObjectArray &objects, 00164 SIM_ObjectArray &newobjects, 00165 SIM_ObjectArray &feedbacktoobjects, 00166 const SIM_Time ×tep){ return SIM_SOLVER_SUCCESS; }; 00167 00168 /// Returns the amount of history required by this solver. Override 00169 /// this function if your solver requires past data to calculate the 00170 /// next time step. The default implementation returns 0. 00171 virtual int getRequestedCacheSubclass(); 00172 /// Gets the impulse mass matrix of an object for an impulse at the 00173 /// provided world space position. The default implementation gets the 00174 /// closest point in the geometry and calls getPointImpulseMassMatrix(). 00175 virtual void getImpulseMassMatrixSubclass( 00176 const SIM_Object &object, 00177 const UT_Vector3 &impulseworldpos, 00178 UT_DMatrix3 &immatrix) const; 00179 /// Gets the impulse mass matrix of an object for an impulse at the 00180 /// provided point on the geometry of the object. The default 00181 /// implementation finds the world space position of the point and 00182 /// calls getImpulseMassMatrix(). 00183 virtual void getPointImpulseMassMatrixSubclass( 00184 const SIM_Object &object, 00185 int ptnum, UT_DMatrix3 &immatrix) const; 00186 /// Gets the value of some physical property for the supplied object 00187 /// at a given position in world space. 00188 virtual fpreal getPropertyAtPositionSubclass(const SIM_Object &object, 00189 const UT_Vector3 &worldpos, 00190 const SIM_Property &property) const; 00191 /// Gets the value of some physical property for the supplied object 00192 /// at a given point on the object's geometry. 00193 virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object, 00194 int ptnum, const SIM_Property &property) const; 00195 /// Builds a resolver for evaulating properties swiftly 00196 virtual SIM_PropertyResolver *getPropertyResolverSubclass( 00197 const SIM_Object &object, 00198 const SIM_Property &property) const; 00199 /// Gets the default collider label for an object using this solver. 00200 virtual void getDefaultColliderLabelSubclass( 00201 const SIM_Object &object, 00202 UT_String &label) const; 00203 /// Gets the default collider type for use on an object with a 00204 /// particular collider label. 00205 virtual void getDefaultColliderSubclass( 00206 const SIM_Object &object, 00207 const UT_String &colliderlabel, 00208 UT_String &collidertype, 00209 bool &colliderreverseobjectroles) const; 00210 00211 private: 00212 DECLARE_STANDARD_GETCASTTOTYPE(); 00213 DECLARE_CLASSNAME(SIM_Solver, SIM_Data); 00214 00215 // Holds the current time - ie. the time at the beginning 00216 // of the timestep currently being processed. This can be 00217 // used (by using calls to setStartTime and getStartTime) 00218 // to inform solvers of when they should use a time other 00219 // than the global simulation time when processing a timestep 00220 SIM_Time myCurrentStartTime; 00221 bool myCurrentStartTimeValid; 00222 00223 }; 00224 00225 #endif 00226
1.5.9