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_Collider_h__ 00015 #define __SIM_Collider_h__ 00016 00017 #include "SIM_API.h" 00018 #include "SIM_DataUtils.h" 00019 #include "SIM_OptionsUser.h" 00020 00021 class SIM_Impacts; 00022 class SIM_Object; 00023 class SIM_ObjectArray; 00024 00025 /// This simple holder stores cache data associated with the collider. 00026 class SIM_API SIM_ColliderCacheData 00027 { 00028 public: 00029 SIM_ColliderCacheData() {} 00030 00031 virtual ~SIM_ColliderCacheData() {} 00032 }; 00033 00034 /// This is an abstract base class for all colliders. 00035 /// A collider is any class that takes a pair of objects and generated 00036 /// information about how those two objects intersect. See the 00037 /// SIM_Object::getCollider() function for a description of how a 00038 /// solver should determine the right SIM_Collider class to use for 00039 /// a given pair of objects. 00040 class SIM_API SIM_Collider : public SIM_Data, 00041 public SIM_OptionsUser 00042 { 00043 public: 00044 /// Specifies whether the object and affector need to be reversed to 00045 /// perform collision detection. This flag is useful for colliders that 00046 /// make assumptions about the makeup of the object and affector are 00047 /// in the call to collideObjectsSubclass(). For example, the 00048 /// point collider (SIM_ColliderPoint) always treats the object as 00049 /// a particle system, using ray casting to follow the trajectory of 00050 /// each particle. But suppose an RBD Solver has a particle system 00051 /// as an affector object. The RBD Solver would find that the best 00052 /// collider to use is a point collider. Rather than requiring that 00053 /// the RBD Solver then somehow discover that the particle object must 00054 /// always be sent as the "object" parameter, the collider can have 00055 /// the reverse object roles flag turned on. Then when the RBD Solver 00056 /// calls the collider with the RBD object first and the particle object 00057 /// second, the collider itself will reverse the objects before passing 00058 /// them on to collideObjectSubclass(). 00059 GETSET_DATA_FUNCS_B(SIM_NAME_REVERSEOBJECTROLES, ReverseObjectRoles); 00060 00061 /// Defines the possible affector types when doing collision detection. 00062 typedef enum { 00063 SIM_IMPACTAPPLY_NONE, /// Don't do any collision detection. 00064 SIM_IMPACTAPPLY_ONEWAY, /// Object A gets Impacts from object B. 00065 SIM_IMPACTAPPLY_MUTUAL, /// Object A and B both get Impacts. 00066 SIM_IMPACTAPPLY_FEEDBACK /// Object A gets Impacts, B gets Feedback. 00067 } SIM_ImpactApplyType; 00068 00069 /// Perform the collision detection for a pair of objects. 00070 /// This function calls the collideObjectsSubclass() function. 00071 /// This also attempts to do collision response. 00072 /// 00073 /// Preconditions: 00074 /// collideObjects expects that 00075 /// getEngine.getObjectAtTime(object, starttime, true) results in the 00076 /// object that holds the correct geometry and transform for starttime. 00077 /// Similarly, passing in endtime must give an object that holds the 00078 /// correct geometry and transformation for endtime. 00079 /// The same principle applies to the affector. 00080 /// Please note that starttime and endtime may be substep times. 00081 /// 00082 /// The solver that calls collideObjects may have to create substep objects 00083 /// at t_start and t_end to ensure that these preconditions are met. 00084 /// This is is not always needed for the affector, the affector may 00085 /// belong to a solver that isn't substepping. 00086 /// In that case collideObjects will use the 00087 /// linear interpolations for the affector's geometry and transform. 00088 /// 00089 bool collideObjects(SIM_Engine &engine, 00090 SIM_Object &object, 00091 SIM_Object &affector, 00092 const SIM_Time &starttime, 00093 const SIM_Time &endtime, 00094 SIM_ImpactApplyType impactapplytype, 00095 int impactflags) const; 00096 00097 /// This variant of the collider lets you specify a list of 00098 /// cache data. The collider subclasses will search for a cache 00099 /// data they like and use it. If none exists, they will build one 00100 /// and add it to the list. 00101 /// The caller is expected to delete any allocated cachedata. 00102 bool collideObjects(SIM_Engine &engine, 00103 SIM_Object &object, 00104 SIM_Object &affector, 00105 const SIM_Time &starttime, 00106 const SIM_Time &endtime, 00107 SIM_ImpactApplyType impactapplytype, 00108 int impactflags, 00109 UT_PtrArray<SIM_ColliderCacheData *> &objcachedata, 00110 UT_PtrArray<SIM_ColliderCacheData *> &affectorcachedata) const; 00111 00112 protected: 00113 /// The SIM_Collider constructor. 00114 explicit SIM_Collider(const SIM_DataFactory *factory); 00115 /// The SIM_Collider destructor. 00116 virtual ~SIM_Collider(); 00117 00118 /// Finds or creates the impact data on the affector that is appropriate 00119 /// for the given affector type. It also takes into account the value 00120 /// of the ReverseObjectRoles flag. 00121 SIM_Impacts *getObjectImpactData(SIM_Object &object, 00122 SIM_ImpactApplyType impactapplytype) const; 00123 00124 /// Finds or creates the impact data on the affector that is appropriate 00125 /// for the given affector type. It also takes into account the value 00126 /// of the ReverseObjectRoles flag. 00127 SIM_Impacts *getAffectorImpactData(SIM_Object &affector, 00128 SIM_ImpactApplyType impactapplytype) const; 00129 00130 /// Returns true if the collideObjects function should always be 00131 /// called with the affector object interpolated to the endtime. 00132 /// This function just calls getAffectorInterpolatedToEndTimeSubclass(). 00133 bool getAffectorInterpolatedToEndTime() const; 00134 00135 /// Override this method to implement your custom collision detection. 00136 /// This function can access any data on the main object or affector 00137 /// object. It can also add any extra data structures it needs to the 00138 /// object for efficiency (rather than recalculating the extra data 00139 /// each time this function is called). 00140 virtual bool collideObjectsSubclass(SIM_Engine &engine, 00141 SIM_Object &object, 00142 SIM_Object &affector, 00143 const SIM_Time &starttime, 00144 const SIM_Time &endtime, 00145 SIM_ImpactApplyType impactapplytype, 00146 int impactflags) const; 00147 00148 /// This version will default to invoking the non-cached version 00149 /// of the collider. 00150 /// If this is overridden, you do not need to override 00151 /// collideObjectSubclass. 00152 virtual bool collideObjectsCachedSubclass(SIM_Engine &engine, 00153 SIM_Object &object, 00154 SIM_Object &affector, 00155 const SIM_Time &starttime, 00156 const SIM_Time &endtime, 00157 SIM_ImpactApplyType impactapplytype, 00158 int impactflags, 00159 UT_PtrArray<SIM_ColliderCacheData *> &objcachedata, 00160 UT_PtrArray<SIM_ColliderCacheData *> &affectorcachedata) const; 00161 00162 /// Returns true if the collideObjects function should always be 00163 /// called with the affector object interpolated to the endtime. 00164 /// The default implementation returns true. 00165 virtual bool getAffectorInterpolatedToEndTimeSubclass() const; 00166 00167 private: 00168 DECLARE_STANDARD_GETCASTTOTYPE(); 00169 DECLARE_CLASSNAME(SIM_Collider, SIM_Data); 00170 }; 00171 00172 #endif 00173
1.5.9