1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __PUSH_H__
30 #define __PUSH_H__
31 
32 #include "cm/CollisionModel.h"
33 
34 #include "physics/Clip.h"
35 #include "GameBase.h"
36 
37 class idEntity;
38 
39 /*
40 ===============================================================================
41 
42   Allows physics objects to be pushed geometrically.
43 
44 ===============================================================================
45 */
46 
47 #define PUSHFL_ONLYMOVEABLE			1		// only push moveable entities
48 #define PUSHFL_NOGROUNDENTITIES		2		// don't push entities the clip model rests upon
49 #define PUSHFL_CLIP					4		// also clip against all non-moveable entities
50 #define PUSHFL_CRUSH				8		// kill blocking entities
51 #define PUSHFL_APPLYIMPULSE			16		// apply impulse to pushed entities
52 
53 //#define NEW_PUSH
54 
55 class idPush {
56 public:
57 					// Try to push other entities by moving the given entity.
58 					// If results.fraction < 1.0 the move was blocked by results.c.entityNum
59 					// Returns total mass of all pushed entities.
60 	float			ClipTranslationalPush( trace_t &results, idEntity *pusher, const int flags,
61 											const idVec3 &newOrigin, const idVec3 &move );
62 
63 	float			ClipRotationalPush( trace_t &results, idEntity *pusher, const int flags,
64 											const idMat3 &newAxis, const idRotation &rotation );
65 
66 	float			ClipPush( trace_t &results, idEntity *pusher, const int flags,
67 											const idVec3 &oldOrigin, const idMat3 &oldAxis,
68 												idVec3 &newOrigin, idMat3 &newAxis );
69 
70 					// initialize saving the positions of entities being pushed
71 	void			InitSavingPushedEntityPositions( void );
72 					// move all pushed entities back to their previous position
73 	void			RestorePushedEntityPositions( void );
74 					// returns the number of pushed entities
GetNumPushedEntities(void)75 	int				GetNumPushedEntities( void ) const { return numPushed; }
76 					// get the ith pushed entity
GetPushedEntity(int i)77 	idEntity *		GetPushedEntity( int i ) const { assert( i >= 0 && i < numPushed ); return pushed[i].ent; }
78 
79 private:
80 	struct pushed_s {
81 		idEntity *	ent;					// pushed entity
82 		idAngles	deltaViewAngles;		// actor delta view angles
83 	}				pushed[MAX_GENTITIES];	// pushed entities
84 	int				numPushed;				// number of pushed entities
85 
86 	struct pushedGroup_s {
87 		idEntity *	ent;
88 		float		fraction;
89 		bool		groundContact;
90 		bool		test;
91 	}				pushedGroup[MAX_GENTITIES];
92 	int				pushedGroupSize;
93 
94 private:
95 	void			SaveEntityPosition( idEntity *ent );
96 	bool			RotateEntityToAxial( idEntity *ent, idVec3 rotationPoint );
97 #ifdef NEW_PUSH
98 	bool			CanPushEntity( idEntity *ent, idEntity *pusher, idEntity *initialPusher, const int flags );
99 	void			AddEntityToPushedGroup( idEntity *ent, float fraction, bool groundContact );
100 	bool			IsFullyPushed( idEntity *ent );
101 	bool			ClipTranslationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idVec3 &translation );
102 	int				GetPushableEntitiesForTranslation( idEntity *pusher, idEntity *initialPusher, const int flags,
103 											const idVec3 &translation, idEntity *entityList[], int maxEntities );
104 	bool			ClipRotationAgainstPusher( trace_t &results, idEntity *ent, idEntity *pusher, const idRotation &rotation );
105 	int				GetPushableEntitiesForRotation( idEntity *pusher, idEntity *initialPusher, const int flags,
106 											const idRotation &rotation, idEntity *entityList[], int maxEntities );
107 #else
108 	void			ClipEntityRotation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel,
109 										idClipModel *skip, const idRotation &rotation );
110 	void			ClipEntityTranslation( trace_t &trace, const idEntity *ent, const idClipModel *clipModel,
111 										idClipModel *skip, const idVec3 &translation );
112 	int				TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
113 												const idVec3 &newOrigin, const idVec3 &move );
114 	int				TryRotatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
115 												const idMat3 &newAxis, const idRotation &rotation );
116 	int				DiscardEntities( idEntity *entityList[], int numEntities, int flags, idEntity *pusher );
117 #endif
118 };
119 
120 #endif /* !__PUSH_H__ */
121