2016-03-12 01:20:51 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation
|
|
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
#ifndef SE_INCL_WORLDCOLLISION_H
|
|
|
|
#define SE_INCL_WORLDCOLLISION_H
|
|
|
|
#ifdef PRAGMA_ONCE
|
|
|
|
#pragma once
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <Engine/Base/Lists.h>
|
|
|
|
#include <Engine/Templates/StaticArray.h>
|
|
|
|
#include <Engine/Math/Vector.h>
|
|
|
|
#include <Engine/Math/Matrix.h>
|
|
|
|
#include <Engine/Math/Placement.h>
|
|
|
|
#include <Engine/Entities/EntityCollision.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A class used for clipping a movement.
|
|
|
|
*/
|
|
|
|
class CClipMove {
|
|
|
|
public:
|
|
|
|
BOOL cm_bMovingBrush; // set if moving a brush (some things are reversed then)
|
|
|
|
CMovableEntity *cm_penMoving; // entity that is moving
|
|
|
|
CEntity *cm_penA; // entity A - can be only model
|
|
|
|
CEntity *cm_penB; // entity B - can be either model or brush
|
|
|
|
|
|
|
|
// masks for collision flags of other entities
|
|
|
|
ULONG cm_ulTestMask1;
|
|
|
|
ULONG cm_ulTestMask2;
|
|
|
|
ULONG cm_ulPassMaskA; // pass - send event to A
|
|
|
|
ULONG cm_ulPassMaskB; // pass - send event to B
|
|
|
|
|
|
|
|
// test if should test with some entity
|
|
|
|
inline BOOL MustTest(CEntity *pen) {
|
|
|
|
return
|
|
|
|
(pen->en_ulCollisionFlags&cm_ulTestMask1)&&
|
|
|
|
(pen->en_ulCollisionFlags&cm_ulTestMask2);
|
|
|
|
};
|
|
|
|
// send pass if needed
|
|
|
|
inline BOOL SendPassEvent(CEntity *pen);
|
|
|
|
|
|
|
|
CListHead cm_lhActiveSectors; // brush sectors that are queued for testing
|
|
|
|
|
|
|
|
// placement of entity A
|
|
|
|
FLOAT3D cm_vA0; FLOATmatrix3D cm_mA0; // at the start of movement
|
|
|
|
FLOAT3D cm_vA1; FLOATmatrix3D cm_mA1; // at the end of movement
|
|
|
|
// placement of entity B
|
|
|
|
FLOAT3D cm_vB0; FLOATmatrix3D cm_mB0; // at the start of movement
|
|
|
|
FLOAT3D cm_vB1; FLOATmatrix3D cm_mB1; // at the end of movement
|
|
|
|
|
|
|
|
CStaticArray<CMovingSphere> *cm_pamsA; // bounding spheres used by entity A
|
|
|
|
CStaticArray<CMovingSphere> *cm_pamsB; // bounding spheres used by entity B (if not brush)
|
|
|
|
|
|
|
|
// helper variables
|
|
|
|
FLOATaabbox3D cm_boxMovementPath; // aabbox around entire movement path
|
|
|
|
CEntity *cm_penTested; // entity to be remembered if hit (A or B)
|
|
|
|
CBrushPolygon *cm_pbpoTested; // brush polygon to be remembered if hit
|
|
|
|
class CWorld *cm_pwoWorld; // world that movement is taking place in
|
|
|
|
|
|
|
|
// projections for converting from space of entity A to space of entity B
|
|
|
|
FLOAT3D cm_vAToB0; FLOATmatrix3D cm_mAToB0; // at the start of movement
|
|
|
|
FLOAT3D cm_vAToB1; FLOATmatrix3D cm_mAToB1; // at the end of movement
|
|
|
|
// for converting from space of entity B to absolute space
|
|
|
|
FLOAT3D cm_vBToAbsolute; FLOATmatrix3D cm_mBToAbsolute;
|
|
|
|
|
|
|
|
FLOATaabbox3D cm_boxMovementPathAbsoluteA; // movement box in absolute space for A entity
|
|
|
|
|
|
|
|
// get start and end positions of an entity in this tick
|
|
|
|
inline void GetPositionsOfEntity(
|
|
|
|
CEntity *pen, FLOAT3D &v0, FLOATmatrix3D &m0, FLOAT3D &v1, FLOATmatrix3D &m1);
|
|
|
|
|
|
|
|
/* Project spheres of entity A to space of entity B. */
|
|
|
|
void ProjectASpheresToB(void);
|
|
|
|
/* Find movement box in absolute space for A entity. */
|
|
|
|
void FindAbsoluteMovementBoxForA(void);
|
|
|
|
|
|
|
|
/* Clip a moving point to a sphere, update collision data. */
|
|
|
|
inline void ClipMovingPointToSphere(const FLOAT3D &vStart, const FLOAT3D &vEnd,
|
|
|
|
const FLOAT3D &vSphereCenter, const FLOAT fSphereRadius);
|
|
|
|
/* Clip a moving point to a cylinder, update collision data. */
|
|
|
|
inline void ClipMovingPointToCylinder(const FLOAT3D &vStart, const FLOAT3D &vEnd,
|
|
|
|
const FLOAT3D &vCylinderBottomCenter, const FLOAT3D &vCylinderTopCenter,
|
|
|
|
const FLOAT fCylinderRadius);
|
|
|
|
|
|
|
|
/* Clip a moving sphere to a standing sphere, update collision data. */
|
|
|
|
void ClipMovingSphereToSphere(const CMovingSphere &msMoving,
|
|
|
|
const CMovingSphere &msStanding);
|
|
|
|
/* Clip a moving sphere to a brush polygon, update collision data. */
|
|
|
|
void ClipMovingSphereToBrushPolygon(
|
|
|
|
const CMovingSphere &msMoving, CBrushPolygon *pbpoPolygon);
|
|
|
|
/* Clip a moving sphere to a terrain polygon, update collision data. */
|
|
|
|
void ClipMovingSphereToTerrainPolygon(
|
|
|
|
const CMovingSphere &msMoving, const FLOAT3D &v0, const FLOAT3D &v1, const FLOAT3D &v2);
|
|
|
|
/* Clip movement to a brush polygon. */
|
|
|
|
void ClipMoveToBrushPolygon(CBrushPolygon *pbpoPolygon);
|
|
|
|
/* Clip movement to a terrain polygon. */
|
|
|
|
void ClipMoveToTerrainPolygon(const FLOAT3D &v0, const FLOAT3D &v1, const FLOAT3D &v2);
|
|
|
|
|
|
|
|
/* Prepare projections and spheres for movement clipping. */
|
|
|
|
void PrepareProjectionsAndSpheres(void);
|
|
|
|
/* Clip movement if B is a model. */
|
|
|
|
void ClipModelMoveToModel(void);
|
|
|
|
/* Clip movement if B is a brush. */
|
|
|
|
void ClipBrushMoveToModel(void);
|
|
|
|
|
|
|
|
/* Clip movement to a model entity. */
|
|
|
|
void ClipMoveToModel(CEntity *penModel);
|
|
|
|
|
|
|
|
void ClipToNonZoningSector(CBrushSector *pbsc);
|
|
|
|
void ClipToZoningSector(CBrushSector *pbsc);
|
|
|
|
void ClipToTerrain(CEntity *pen);
|
|
|
|
|
|
|
|
/* Cache near polygons of movable entity. */
|
|
|
|
void CacheNearPolygons(void);
|
|
|
|
/* Clip movement to brush sectors near the entity. */
|
|
|
|
void ClipMoveToBrushes(void);
|
|
|
|
/* Clip movement to models near the entity. */
|
|
|
|
void ClipMoveToModels(void);
|
|
|
|
|
|
|
|
/* Clip movement to the world. */
|
|
|
|
void ClipMoveToWorld(class CWorld *pwoWorld);
|
|
|
|
public:
|
|
|
|
|
|
|
|
// these are filled by clipping algorithm:
|
|
|
|
CEntity *cm_penHit; // entity hit when moving. NULL if nothing was hit
|
|
|
|
CBrushPolygon *cm_pbpoHit; // brush polygon that was hit (NULL if did not hit a brush)
|
|
|
|
FLOAT cm_fMovementFraction; // fraction of movement done before hitting
|
|
|
|
FLOATplane3D cm_plClippedPlane; // the plane that was hit (in absolute space)
|
|
|
|
FLOAT3D cm_vClippedLine; // vector describing part of test line that was clipped
|
|
|
|
|
|
|
|
/* Constructor. */
|
|
|
|
CClipMove(CMovableEntity *penEntity);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* include-once check. */
|
|
|
|
|