00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #pragma once
00017
00018
00019
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
00056
00057
00058
00067 virtual int SuppportedCollisions() = 0;
00068
00069
00070
00078 virtual void PreFrame(TimeValue t, TimeValue dt) = 0;
00079
00080
00088 virtual void PostFrame(TimeValue t, TimeValue dt) = 0;
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
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
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
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
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
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
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
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
00395 enum { collisionplane_params, };
00396
00397
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
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
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
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
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
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
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
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
00703 void DeleteThis();
00707 Class_ID ClassID() {return PLANAR_COLLISION_ID;}
00711 SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
00712
00713
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
00772 enum { collisionsphere_params, };
00773
00774
00775 enum Collision_Params { collisionsphere_radius,
00776 collisionsphere_node,
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
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
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
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
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
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
01028 void DeleteThis();
01032 Class_ID ClassID() {return SPHERICAL_COLLISION_ID;}
01036 SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
01037
01038
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
01149 enum { collisionmesh_params, };
01150
01151
01152 enum {
01153 collisionmesh_hit_face_index,
01154 collisionmesh_hit_bary,
01155 collisionmesh_node
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
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
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
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
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
01381 void SetNode(TimeValue t, INode *n) {
01382
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
01397
01398
01399
01400
01404 void DeleteThis();
01408 Class_ID ClassID() {return MESH_COLLISION_ID;}
01412 SClass_ID SuperClassID() {return REF_MAKER_CLASS_ID;}
01413
01414
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
01473
01474 return( REF_STOP);
01475 }
01476 };
01477
01478 #pragma warning(pop)