icollision.h

Go to the documentation of this file.
00001 //**************************************************************************/
00002 // Copyright (c) 1998-2006 Autodesk, Inc.
00003 // All rights reserved.
00004 //
00005 // These coded instructions, statements, and computer programs contain
00006 // unpublished proprietary information written by Autodesk, Inc., and are
00007 // protected by Federal copyright law. They may not be disclosed to third
00008 // parties or copied or duplicated in any form, in whole or in part, without
00009 // the prior written consent of Autodesk, Inc.
00010 //**************************************************************************/
00011 // FILE:        ICollision.h
00012 // DESCRIPTION: An interface class to our collisions
00013 // AUTHOR:      Peter Watje
00014 // HISTORY:     3-15-00
00015 //**************************************************************************/
00016 #pragma once
00017 
00018 //
00019 // \TODO Consider these classes for a move to maxsdk/samples/objects/particles/colliders/...
00020 //
00021 
00022 #include "maxheap.h"
00023 #include "iparamm2.h"
00024 #include "iFnPub.h"
00025 
00026 #define PLANAR_COLLISION_ID Class_ID(0x14585111, 0x444a7dcf)
00027 #define SPHERICAL_COLLISION_ID Class_ID(0x14585222, 0x555a7dcf)
00028 #define MESH_COLLISION_ID Class_ID(0x14585333, 0x666a7dcf)
00029 
00030 
00031 #define COLLISION_FO_INTERFACE Class_ID(0x14585444, 0x777a7dcf)
00032 
00033 #define GetCollisionOpsInterface(cd) \
00034             (CollisionOps *)(cd)->GetInterface(COLLISION_FO_INTERFACE)
00035 
00036 
00037 
00038 #define POINT_COLLISION     1
00039 #define SPHERE_COLLISION    2
00040 #define BOX_COLLISION       4
00041 #define EDGE_COLLISION      8
00042 
00053 class ICollision : public ReferenceTarget {
00054 public:
00055 //return what is supported for collision engine
00056 //right now all we support is point to surface collision
00057 //but in the future the others maybe support by us or 3rd party
00058 //it returns the or'd flags above
00067     virtual int SuppportedCollisions() = 0; 
00068 
00069 //This method is called once before the checkcollision is called for each frame
00070 //which allows you to do some data initializations
00078     virtual void PreFrame(TimeValue t, TimeValue dt) = 0;
00079 //This method is called at the end f each frame solve to allow 
00080 //you to destroy any data you don't need want
00088     virtual void PostFrame(TimeValue t, TimeValue dt) = 0;
00089 
00090 //point to surface collision
00091 //computes the time at which the particle hit the surface 
00092 //t is the end time of the particle 
00093 //dt is the delta of time that particle travels
00094 //   t-dt = start of time of the particle
00095 //pos the position of the particle in world space
00096 //vel the velocity of the particle in world space
00097 //at is the point in time that the collision occurs with respect to dt
00098 //norm is bounce vector component of the final velocity
00099 //friction is the friction vector component of the final velocity
00100 //inheritVel is the amount of velocity inherited from the motion of the delfector
00101 //      this is a rough apporximate
00127     virtual BOOL CheckCollision (TimeValue t,Point3 pos, Point3 vel, float dt, 
00128                                  float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel) = 0;
00129 
00130 //sphere to surface collision
00158     virtual BOOL CheckCollision (TimeValue t,Point3 pos, float radius, Point3 vel, float dt, 
00159                                  float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel) = 0;
00160 //box to surface collision
00186     virtual BOOL CheckCollision (TimeValue t, Box3 box, Point3 vel, float dt,  
00187                                  float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel) = 0;
00188 //edge to surface collision
00216     virtual BOOL CheckCollision (TimeValue t,Point3 edgeA,Point3 edgeB ,Point3 vel, float dt,  
00217                                  float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel) = 0;
00218 };
00219 
00220 
00221 enum { collision_supportedcollisions, collision_preframe,collision_postframe,
00222        collision_point_to_surface,collision_sphere_to_surface ,collision_box_to_surface,
00223        collision_edge_to_surface   };
00224 
00225 
00235 class CollisionOps : public FPInterface
00236 {
00237 public:
00250     virtual int SuppportedCollisions(ReferenceTarget *r) = 0; 
00260     virtual void PreFrame(ReferenceTarget *r, TimeValue &t, TimeValue &dt) = 0;
00270     virtual void PostFrame(ReferenceTarget *r, TimeValue &t, TimeValue &dt) = 0;
00296     virtual BOOL CheckCollision (ReferenceTarget *r, TimeValue &t,Point3 *pos, Point3 *vel, float &dt, 
00297                                  float &at, Point3 *hitPoint, Point3 *norm, Point3 *friction, Point3 *inheritedVel) = 0;
00298 
00299 //sphere to surface collision
00327     virtual BOOL CheckCollision (ReferenceTarget *r, TimeValue &t,Point3 *pos, float &radius, Point3 *vel, float &dt, 
00328                                  float &at, Point3 *hitPoint, Point3 *norm, Point3 *friction, Point3 *inheritedVel) = 0;
00329 //box to surface collision FIX ME can't publish box3
00355     virtual BOOL CheckCollision (ReferenceTarget *r, TimeValue &t, 
00356                                  Point3 *boxCenter,float &w, float &h, float &d, Point3 *vel, float &dt,  
00357                                  float &at, Point3 *hitPoint, Point3 *norm, Point3 *friction, Point3 *inheritedVel) = 0;
00358 
00359 //edge to surface collision
00387     virtual BOOL CheckCollision (ReferenceTarget *r, TimeValue &t,Point3 *edgeA,Point3 *edgeB ,Point3 *vel, float &dt,  
00388                                  float &at, Point3 *hitPoint, Point3 *norm, Point3 *friction, Point3 *inheritedVel) = 0;
00389 
00390 
00391 };
00392 
00393 
00394 // block IDs
00395 enum { collisionplane_params, };
00396 
00397 // geo_param param IDs
00398 enum { collisionplane_width,
00399        collisionplane_height, 
00400        collisionplane_quality,
00401        collisionplane_node,    
00402     };
00403 
00404 #pragma warning(push)
00405 #pragma warning(disable:4239 4100)
00406 
00440 class CollisionPlane : public ICollision
00441 {
00442 private:
00443     INode *node;
00444 public:
00445     IParamBlock2 *pblock;
00446     Interval validity;
00447 
00449     CollisionPlane();
00451     ~CollisionPlane();
00452 //determines what type of collisions are supported
00463     int SuppportedCollisions() 
00464         { 
00465         return POINT_COLLISION; 
00466         } 
00467 
00475     void PreFrame(TimeValue t, TimeValue dt) ;
00485     void PostFrame(TimeValue t, TimeValue dt) {}
00486 
00512     BOOL CheckCollision (TimeValue t,Point3 pos, Point3 vel, float dt, 
00513                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel);
00514 //sphere to surface collision
00542     BOOL CheckCollision (TimeValue t,Point3 pos, float radius, Point3 vel, float dt, 
00543                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00544         {
00545         return FALSE;
00546         }
00547 
00548 //box to surface collision
00574     BOOL CheckCollision (TimeValue t, Box3 box, Point3 vel, float dt,  
00575                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00576         {
00577         return FALSE;
00578         }
00579 //edge to surface collision
00607     BOOL CheckCollision (TimeValue t,Point3 edgeA,Point3 edgeB ,Point3 vel,  float dt,  
00608                         float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00609         {
00610         return FALSE;
00611         }
00612 
00613 //access functions to the pblock
00622     void SetWidth(TimeValue t, float w)  { if (!pblock->GetControllerByID(collisionplane_width)) pblock->SetValue(collisionplane_width,t,w); }
00631     void SetHeight(TimeValue t, float h) { if (!pblock->GetControllerByID(collisionplane_height)) pblock->SetValue(collisionplane_height,t,h); }
00643     void SetQuality(TimeValue t, int q)  { if (!pblock->GetControllerByID(collisionplane_quality)) pblock->SetValue(collisionplane_quality,t,q); }
00644 //  void SetTM(TimeValue t, Matrix3 tm)  { pblock->SetValue(collisionplane_tm,t,&tm); }
00654     void SetNode(TimeValue t, INode *n)  
00655     { 
00656         {
00657             HoldSuspend hs;
00658             pblock->SetValue(collisionplane_node,t,n);
00659         }
00660         node = n; 
00661 }
00662 
00669     void SetWidth(Control *c) { pblock->SetControllerByID(collisionplane_width,0,c,FALSE); }
00676     void SetHeight(Control *c) { pblock->SetControllerByID(collisionplane_height,0,c,FALSE); }
00686     void SetQuality(Control *c) { pblock->SetControllerByID(collisionplane_quality,0,c,FALSE); }
00687 //  void SetTM(Control *c);
00688 
00689     Matrix3 tm, invtm;
00690     Matrix3 prevInvTm;
00691 
00692     int initialTime;
00693     Tab<Matrix3> invTmList;
00694     float  width, height;
00695     int quality;
00696 
00697 
00698 
00699     // Methods from Animatable
00703     void DeleteThis();
00707     Class_ID ClassID() {return PLANAR_COLLISION_ID;}
00711     SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
00712 
00713     // Methods from ReferenceTarget :
00717     int NumRefs() { return 1; }
00721     RefTargetHandle GetReference(int i) { return pblock; }
00730 protected:
00731     virtual void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock2*)rtarg;}
00732 public:
00742     RefTargetHandle Clone(RemapDir &remap);      
00743 
00763     RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message);
00764 
00765 };
00766 
00767 
00768 
00769 
00770 
00771 // block IDs
00772 enum { collisionsphere_params, };
00773 
00774 // geo_param param IDs
00775 enum Collision_Params { collisionsphere_radius,
00776        collisionsphere_node,    //using a node right now this really needs to be a TM but it does not look like tms are hooked up yet in pb2
00777        collisionsphere_scaleFactor
00778     };
00779 
00780 
00805 class CollisionSphere : public ICollision
00806 {
00807 private:
00808     INode *node;
00809 public:
00810     IParamBlock2 *pblock;
00811     Interval validity;
00812 
00814     CollisionSphere();
00816     ~CollisionSphere();
00817 //determines what type of collisions are supported
00828     int SuppportedCollisions() 
00829         { 
00830         return POINT_COLLISION; 
00831         } 
00832 
00840     void PreFrame(TimeValue t, TimeValue dt) ;
00850     void PostFrame(TimeValue t, TimeValue dt) {}
00851 
00877     BOOL CheckCollision (TimeValue t,Point3 pos, Point3 vel, float dt, 
00878                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel);
00879 //sphere to surface collision
00907     BOOL CheckCollision (TimeValue t,Point3 pos, float radius, Point3 vel, float dt, 
00908                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00909         {
00910         return FALSE;
00911         }
00912 
00913 //box to surface collision
00939     BOOL CheckCollision (TimeValue t, Box3 box, Point3 vel, float dt,  
00940                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00941         {
00942         return FALSE;
00943         }
00944 //edge to surface collision
00972     BOOL CheckCollision (TimeValue t,Point3 edgeA,Point3 edgeB ,Point3 vel,  float dt,  
00973                         float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
00974         {
00975         return FALSE;
00976         }
00977 
00978 //access functions to the pblock
00987     void SetRadius(TimeValue t, float r)  { if (!pblock->GetControllerByID(collisionsphere_radius)) pblock->SetValue(collisionsphere_radius,t,r); }
00997     void SetNode(TimeValue t, INode *n)  
00998     { 
00999         {
01000             HoldSuspend hs;
01001             pblock->SetValue(collisionsphere_node,t,n);
01002         }
01003         node = n; 
01004 }
01005 
01012     void SetRadius(Control *c) { pblock->SetControllerByID(collisionsphere_radius,0,c,FALSE); }
01013 
01014     Matrix3 tm, invtm;
01015     Matrix3 prevInvTm;
01016     Point3 Vc;
01017 
01018 
01019 
01020     float  radius;
01021 
01022 
01023 
01024     // Methods from Animatable
01028     void DeleteThis();
01032     Class_ID ClassID() {return SPHERICAL_COLLISION_ID;}
01036     SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
01037 
01038     // Methods from ReferenceTarget :
01042     int NumRefs() { return 1; }
01046     RefTargetHandle GetReference(int i) { return pblock; }
01055 protected:
01056     virtual void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock2*)rtarg;}
01057 public:
01067     RefTargetHandle Clone(RemapDir &remap);      
01068 
01089     RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message);
01090 };
01091 
01092 
01093 
01107 class CollisionVNormal: public MaxHeapOperators {
01108     public:
01109         Point3 norm;
01110         DWORD smooth;
01111         CollisionVNormal *next;
01112         BOOL init;
01113 
01117         CollisionVNormal() {smooth=0;next=NULL;init=FALSE;norm=Point3(0,0,0);}
01126         CollisionVNormal(Point3 &n,DWORD s) {next=NULL;init=TRUE;norm=n;smooth=s;}
01130         ~CollisionVNormal();
01137         void AddNormal(Point3 &n,DWORD s);
01142         Point3 &GetNormal(DWORD s);
01144         void Normalize();
01145     };
01146 
01147 
01148 // block IDs
01149 enum { collisionmesh_params, };
01150 
01151 // geo_param param IDs
01152 enum { 
01153         collisionmesh_hit_face_index,
01154         collisionmesh_hit_bary,
01155         collisionmesh_node    //using a node right now this really needs to be a TM but it does not look like tms are hooked up yet in pb2
01156     };
01157 
01158 
01195 class CollisionMesh : public ICollision
01196 {
01197 private:
01198     INode *node;
01199 public:
01200     IParamBlock2 *pblock;
01201     Interval validity;
01202     DWORD outFi;
01203     Point3 outBary;
01204 
01206     CollisionMesh();
01208     ~CollisionMesh();
01209 //determines what type of collisions are supported
01220     int SuppportedCollisions() 
01221         { 
01222         return POINT_COLLISION; 
01223         } 
01224 
01232     void PreFrame(TimeValue t, TimeValue dt) ;
01242     void PostFrame(TimeValue t, TimeValue dt) {}
01243 
01269     BOOL CheckCollision (TimeValue t,Point3 pos, Point3 vel, float dt, 
01270                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel);
01271 
01272 //sphere to surface collision
01300     BOOL CheckCollision (TimeValue t,Point3 pos, float radius, Point3 vel, float dt, 
01301                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
01302         {
01303         return FALSE;
01304         }
01305 
01306 //box to surface collision
01332     BOOL CheckCollision (TimeValue t, Box3 box, Point3 vel, float dt,  
01333                          float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
01334         {
01335         return FALSE;
01336         }
01337 //edge to surface collision
01365     BOOL CheckCollision (TimeValue t,Point3 edgeA,Point3 edgeB ,Point3 vel,  float dt,  
01366                         float &at, Point3 &hitPoint, Point3 &norm, Point3 &friction, Point3 &inheritedVel)
01367         {
01368         return FALSE;
01369         }
01370 
01371 //access functions to the pblock
01381     void SetNode(TimeValue t, INode *n)  { 
01382 //check for circle loop here
01383 
01384                                            pblock->SetValue(collisionmesh_node,t,n);
01385                                            node = n; }
01386 
01387 
01388     Matrix3 tm, invtm;
01389     Matrix3 tmPrev,invtmPrev;
01390 
01391     Mesh *dmesh;
01392     int nv,nf;
01393     CollisionVNormal *vnorms;
01394     Point3 *fnorms;
01395 
01396 //  Mesh *dmeshPrev;
01397 //  VNormal *vnormsPrev;
01398 //  Point3 *fnormsPrev;
01399 
01400     // Methods from Animatable
01404     void DeleteThis();
01408     Class_ID ClassID() {return MESH_COLLISION_ID;}
01412     SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
01413 
01414     // Methods from ReferenceTarget :
01418     int NumRefs() { return 1; }
01422     RefTargetHandle GetReference(int i) { return pblock; }
01431 protected:
01432     virtual void SetReference(int i, RefTargetHandle rtarg) {pblock = (IParamBlock2*)rtarg;}
01433 public:
01443     RefTargetHandle Clone(RemapDir &remap);      
01444 
01464     RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message)
01465         {
01466         switch (message) {
01467             case REFMSG_CHANGE:
01468                 if (hTarget == pblock)
01469                     validity.SetEmpty();
01470                 break;
01471             }
01472 //note this is ref_stop because we don't want the engine updating it references
01473 //may need a flag to turn this off or on
01474         return( REF_STOP);
01475         }
01476 };
01477 
01478 #pragma warning(pop)