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_Object_h__ 00015 #define __SIM_Object_h__ 00016 00017 #include "SIM_API.h" 00018 #include "SIM_RootData.h" 00019 #include "SIM_PhysicalParms.h" 00020 #include "SIM_RelationshipArray.h" 00021 #include "SIM_ColliderInfo.h" 00022 00023 class UT_IStream; 00024 class UT_TokenString; 00025 class SIM_Collider; 00026 class SIM_ColliderLabel; 00027 class SIM_Geometry; 00028 class SIM_Position; 00029 class SIM_ObjectSolveInfo; 00030 class SIM_Solver; 00031 class SIM_MetaObject; 00032 class SIM_ObjectArray; 00033 class SIM_ConstObjectArray; 00034 class SIM_SimulationState; 00035 00036 /// This class is a simple container for all the data that is used to 00037 /// represent an object in a simulation. Each piece of data has a name 00038 /// and can be of any type that is subclassed from SIM_Data. 00039 class SIM_API SIM_Object : public SIM_RootData 00040 { 00041 public: 00042 /// Returns the unique identifier for the object. This identifier is 00043 /// unique for the duration of a simulation and will not be reused even 00044 /// if the object is deleted. 00045 int getObjectId() const; 00046 /// Sets the name ofthe object to a new value. This value does not need 00047 /// to be unique. If the value is not a valid object name (e.g. it 00048 /// contains spaces or other invalid characters), this function modifies 00049 /// the name to make it valid. 00050 void setName(const char *name); 00051 /// Returns true if the object's baked flag is set. This flag indicates 00052 /// that the object was loaded from a file or merged from another 00053 /// simulation. 00054 bool getIsBaked() const; 00055 /// Returns true if the object was created with the solve first frame 00056 /// flag turned on. 00057 bool getSolveFirstFrame() const; 00058 /// Returns the affector information for this object. The returned 00059 /// array contains a list of all objects that affect this object. 00060 void getAffectors(SIM_ObjectArray &affobjs, 00061 const char *relationshiptype); 00062 /// Returns the affector information for this object. The returned 00063 /// array contains a const list of all objects that affect this object. 00064 void getConstAffectors(SIM_ConstObjectArray &affobjs, 00065 const char *relationshiptype) const; 00066 /// Returns true if the supplied object is an affector of this object. 00067 /// Checking this way is faster than building a full affector list and 00068 /// comparing against that. 00069 bool getIsAffector(const SIM_Object *affector, 00070 const char *relationshiptype) const; 00071 /// Gets an array of objects we will collide with, what collider to 00072 /// use, and how to apply impact data to those objects. 00073 void getColliderInfo(SIM_ColliderInfoArray &colliderinfo); 00074 /// Fills a UT_TokenString with enough information to uniquely determine 00075 /// what the SIM_ColliderInfoArray for this object will contain. This lets 00076 /// use very quickly determine if two objects will have the same array 00077 /// of collider infos. 00078 void getColliderInfoTokenString(UT_TokenString &ts); 00079 00080 /// This enumeration defines the possible solve states for an object. 00081 typedef enum { 00082 SIM_UNSOLVED, 00083 SIM_SOLVING, 00084 SIM_FEEDBACK, 00085 SIM_SOLVED 00086 } SIM_SolveState; 00087 /// Returns the current solved state of this object. 00088 const SIM_SolveState &getSolveState() const; 00089 00090 /// Returns our cached SIM_Solver pointer. This function is equivalent to 00091 /// but much faster than using the SIM_DATA_GETCONST() macro. 00092 const SIM_Solver *getSolver() const; 00093 /// Returns our cached SIM_Position pointer. This function is equivalent to 00094 /// but much faster than using the SIM_DATA_GETCONST() macro. 00095 const SIM_Position *getPosition() const; 00096 /// Returns our cached SIM_Geometry pointer. This function is equivalent to 00097 /// but much faster than using the SIM_DATA_GETCONST() macro. 00098 const SIM_Geometry *getGeometry() const; 00099 /// Returns our cached SIM_PhysicalParms pointer. This function is 00100 /// equivalent to but much faster than using the SIM_DATA_GETCONST() macro. 00101 const SIM_PhysicalParms *getPhysicalParms() const; 00102 /// Returns our cached SIM_ColliderLabel pointer. This function is 00103 /// equivalent to but much faster than using the SIM_DATA_GETCONST() macro. 00104 const SIM_ColliderLabel *getColliderLabel() const; 00105 /// Gets the actual collider label string from our collider label subdata. 00106 /// If we have no collider label subdata, our solver is queried to get 00107 /// the default collider label for an object handled by that solver. 00108 void getColliderLabel(UT_String &label) const; 00109 00110 /// Get a const reference to our array of relationships. Note that even 00111 /// though the returned array is const, it's members are non-const, and 00112 /// so the SIM_Relationship data can be modified. Thus this must be a 00113 /// non-const function on SIM_Object. 00114 const SIM_RelationshipArray &getRelationships(bool ingroup); 00115 /// Returns the number of relationships to which this object belongs. 00116 int getNumRelationships(bool ingroup) const; 00117 /// This function allows looping through the relationships for an object. 00118 /// This is a const function, so it returns a const SIM_Relationship. 00119 const SIM_Relationship *getRelationship(bool ingroup, int index) const; 00120 /// Get the relationship for this object with a particular name. Because 00121 /// This is a const function, so it returns a const SIM_Relationship. 00122 const SIM_Relationship *getRelationship(bool ingroup, 00123 const char *name) const; 00124 /// Gets all the relationships of a particular type. The type of a 00125 /// relationship is defined by the one subdata on the SIM_Relationship. 00126 void filterConstRelationships(bool ingroup, 00127 const SIM_DataFilter &filter, 00128 SIM_ConstDataArray &rels) const; 00129 00130 /// Returns whether or not this object is a substep object. This is 00131 /// true for both temporary interpolated objects created with 00132 /// SIM_Engine::getObjectAtTime() and substep objects explicitly 00133 /// created with SIM_Engine::createSubStepObject(). 00134 bool getIsSubStepObject() const; 00135 /// Returns false if the object is either a baked object (because it 00136 /// was loaded from a file) or it is passive. 00137 bool getIsStatic() const; 00138 00139 /// Gets the meta-object pointer for this object. The meta-object is 00140 /// a value that is used only by the SIM_Engine. 00141 SIM_MetaObject *getMetaObject() const; 00142 00143 /// Returns a pointer to a SIM_Collider that should be used to do 00144 /// collision detection between this object and the supplied affector 00145 /// object. This function should be called only if the SIM_ColliderInfo 00146 /// for this affector object did not specify a SIM_Collider to use. 00147 /// The return value from this function can be null, in which case no 00148 /// collision detection should be done between the objects. 00149 /// 00150 /// The method for determining the SIM_Collider to use is as follows: 00151 /// First, we look at the collider label for the affector, and look 00152 /// for SIM_Collider subdata on the SIM_ColliderLabel of this object 00153 /// with a name that matches the affector's collider label. If a 00154 /// SIM_Collider is found with that subdata name, we return that 00155 /// collider. Otherwise, we go to the solver attached to this object. 00156 /// The SIM_Solver::getDefaultCollider() function is called, passing 00157 /// in this object, the affector object's collider label. This function 00158 /// returns the name of the SIM_Collider subclass we should use based 00159 /// on the needs of the solver. We then create subdata on the solver 00160 /// itself, and attach a SIM_Collider of the requested type. Then 00161 /// we return a pointer to this new collider. 00162 /// 00163 /// For the special case of self-collision, the collider label of 00164 /// the affector is replaced with SIM_COLLIDERLABEL_SELF, which allows 00165 /// the solver and the collider label data to treat self-collision as 00166 /// a special case. In some cases this means using a spcial SIM_Collider, 00167 /// and in other cases it means returning null and skipping collision 00168 /// detection altogether (e.g. the RBD Solver doesn't do self-collision 00169 /// detection). 00170 const SIM_Collider *getCollider(const SIM_Object &affector) const; 00171 /// Stores impacts information from the temporary locations to the 00172 /// permanent locations. Copies impact information from the 00173 /// SIM_NEWIMPACTS_DATANAME data into SIM_IMPACTS_DATANAME, and 00174 /// from SIM_NEWFEEDBACK_DATANAME to SIM_FEEDBACK_DATANAME. Then 00175 /// the NEW impact data is removed. This should be called after 00176 /// a set of new impacts have been processed successfully. 00177 void preserveImpacts(SIM_Engine &engine); 00178 /// Eliminates any temporary impact data. Temporary impacts data is 00179 /// stored in SIM_Impacts data named SIM_NEWIMPACTS_DATANAME and 00180 /// SIM_NEWFEEDBACK_DATANAME. Unlike preserveImpacts(), which copies 00181 /// the data into SIM_IMPACTS_DATANAME and SIM_FEEDBACK_DATANAME, 00182 /// this function simply deletes the data. This funciton should be 00183 /// called when rolling back a substep. 00184 void rollbackImpacts(SIM_Engine &engine); 00185 00186 /// Gets the velocity of a point in the space local to an object. The 00187 /// returned velocity is also in local space. There are two methods 00188 /// that can be used to calculate the velocity. The first method uses 00189 /// the SDF representing the geometry at the previous time step 00190 /// compared to the current time step. The second method uses the 00191 /// velocity point attribute attached to the geometry. If no velocity 00192 /// attribute is found, the geometry at this time step is compared to 00193 /// the geometry at the previous time step to calculate the velocity 00194 /// for each point. 00195 UT_Vector3 getLocalVelocityAtPosition( 00196 const UT_Vector3 &localspacepos, 00197 bool usesdfhistory, 00198 bool usegeohistory) const; 00199 00200 /// Gets the velocity of a point on the object specified in world space. 00201 /// The returned velocity is also in world space. The two boolean values 00202 /// specify what method should be used to determine the local space 00203 /// portion of the velocity. If both these values are false, no local 00204 /// velocity component is calculated and it is assumed that the geometry 00205 /// attached to the object is static. 00206 UT_Vector3 getVelocityAtPosition( 00207 const UT_Vector3 &worldspacepos, 00208 bool usesdfhistory, 00209 bool usegeohistory, 00210 fpreal integrateovertime = 0.0) const; 00211 00212 /// Returns a resolver for efficiently computing velocity values 00213 /// The caller must delete the returned object. 00214 SIM_PropertyResolver *getVelocityAtPositionResolver( 00215 bool usesdfhistory, 00216 bool usegeohistory, 00217 fpreal integrateovertime = 0.0) const; 00218 00219 /// Gets the value of some physical property for the supplied object 00220 /// at a given position in world space. This function calls 00221 /// SIM_Solver::getPropertyAtPosition(). 00222 fpreal getPropertyAtPosition(const UT_Vector3 &wpos, 00223 const SIM_Property &property) const; 00224 /// Gets the value of some physical property for the supplied object 00225 /// at a given point on the object's geometry. This function calls 00226 /// SIM_Solver::getPropertyAtPoint(). 00227 fpreal getPropertyAtPoint(int ptnum, 00228 const SIM_Property &property) const; 00229 00230 /// Returns a resolver for efficiently computing property values 00231 /// The caller must delete the returned object. 00232 SIM_PropertyResolver *getPropertyResolver(const SIM_Property &property) const; 00233 00234 /// Gets the velocity of a point on the object specified by a point 00235 /// number. The returned velocity is in world space. If a velocity 00236 /// point attribute exists, that value is used as the local velocity. 00237 UT_Vector3 getVelocityAtPoint(int ptnum, 00238 const SIM_Geometry *geo = 0) const; 00239 /// Gets the simulation space position of a point on our geometry. 00240 UT_Vector3 getPositionOfPoint(int ptnum, 00241 const SIM_Geometry *geo = 0) const; 00242 /// Returns the point number closest to a world space position. 00243 int getNearestPoint(const UT_Vector3 &wspos) const; 00244 00245 /// Returns a resolver to lookup the closest point and extract 00246 /// the given attribute. If attribute not found, 1.0 is returned. 00247 SIM_PropertyResolver *getNearestPointAttribResolver(const char *attribname) const; 00248 00249 /// Fetches the value of the supplied point attribute from our geometry. 00250 /// Returns true if the attribute was found, otherwise it returns false. 00251 /// The attribute must be a simple float attribute. 00252 bool getPointAttribute(int ptnum, 00253 const char *attrib, 00254 fpreal &value) const; 00255 00256 /// Fetches the SIM_Position data associated with the geometry data 00257 /// at the supplied location. This just strips off the last subdata name, 00258 /// and appends the word Position. 00259 const SIM_Position *getPositionForGeometry(const char *geo) const; 00260 00261 /// Returns the object-specific solve info for this object. 00262 SIM_ObjectSolveInfo *getSolveInfo() const; 00263 00264 protected: 00265 /// The constructor for a new simulation object. 00266 explicit SIM_Object(const SIM_SimulationState *factory); 00267 /// The object destructor. 00268 virtual ~SIM_Object(); 00269 00270 /// Clears all attached data. 00271 virtual void initializeSubclass(); 00272 /// Makes two objects equal, but not their names or object ids. 00273 virtual void makeEqualSubclass(const SIM_Data *source); 00274 /// Saves an object to a stream. 00275 virtual void saveSubclass(ostream &os) const; 00276 /// Loads an object from a stream. 00277 virtual bool loadSubclass(UT_IStream &is); 00278 /// Caches the solver, collider, and position data for quick access. 00279 virtual void setNamedSubDataSubclass(const char *dataname, 00280 const SIM_Data *data); 00281 /// Clears the solver, collider, and position cached pointers. 00282 virtual void removeNamedSubDataSubclass(const char *dataname); 00283 /// Creates a query object for getting SIM_Object-specific information. 00284 virtual SIM_Query *createQueryObjectSubclass() const; 00285 /// Overrides interpolateSubclass() to set our interpolated flag. 00286 virtual void interpolateSubclass(const SIM_Data *source1, 00287 const SIM_Data *source2, 00288 fpreal interp); 00289 /// Get the amount of memory used by this object. 00290 virtual int64 getMemorySizeSubclass() const; 00291 00292 /// Override the SIM_RootData function for getting our identifier. 00293 virtual void getRootDataIdSubclass(SIM_RootDataId &id) const; 00294 /// Override the SIM_RootData function for matching us to a string. 00295 virtual bool getMatchesStringSubclass(const char *pattern) const; 00296 00297 private: 00298 void getAffectorsUnsafe(SIM_ObjectArray &affectors, 00299 const char *relationshiptype) const; 00300 void setMetaObject(SIM_MetaObject *metaobject); 00301 void setSubStepCopyFromObject(SIM_Object *fromobject); 00302 void setObjectId(int id); 00303 void setIsBaked(bool baked); 00304 void setSolveFirstFrame(bool solvefirstframe); 00305 void setSolveState(const SIM_SolveState &solvestate); 00306 void copyObjectIdentifiers(const SIM_Object &source); 00307 UT_Vector3 getSDFVelocity(const UT_Vector3 &localpos) const; 00308 UT_Vector3 getPointVelocity(const UT_Vector3 &localpos) const; 00309 00310 /// Get a const reference to our array of relationships. 00311 const SIM_RelationshipArray &getRelationshipArray(bool ingroup) const; 00312 /// Get a non-const reference to our array of relationships. 00313 SIM_RelationshipArray &getRelationshipArray(bool ingroup); 00314 00315 const SIM_SimulationState *mySimulationState; 00316 00317 SIM_MetaObject *myMetaObject; 00318 SIM_Object *mySubStepCopyFromObject; 00319 SIM_SolveState mySolveState; 00320 SIM_RelationshipArray myGroupRelationships; 00321 SIM_RelationshipArray myAffectorRelationships; 00322 00323 const SIM_Solver *myCachedSolver; 00324 const SIM_Geometry *myCachedGeometry; 00325 const SIM_ColliderLabel *myCachedColliderLabel; 00326 const SIM_PhysicalParms *myCachedPhysicalParms; 00327 mutable SIM_ObjectSolveInfo *mySolveInfo; 00328 00329 int myObjectId; 00330 bool myIsBaked; 00331 bool mySolveFirstFrame; 00332 00333 friend class SIM_SimulationState; 00334 friend class SIM_Relationship; 00335 friend class SIM_ObjectSolveInfo; 00336 00337 DECLARE_STANDARD_GETCASTTOTYPE(); 00338 DECLARE_CLASSNAME(SIM_Object, SIM_RootData); 00339 }; 00340 00341 #endif 00342
1.5.9