1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef PROJECTILE_HANDLER_H
#define PROJECTILE_HANDLER_H
#include <list>
#include <set>
#include <vector>
#include <stack>
#include "lib/gml/ThreadSafeContainers.h"
#include "Sim/Projectiles/ProjectileFunctors.h"
#include "System/float3.h"
#include "System/Platform/Threading.h"
// bypass id and event handling for unsynced projectiles (faster)
#define UNSYNCED_PROJ_NOEVENT 1
class CProjectile;
class CUnit;
class CFeature;
class CGroundFlash;
struct UnitDef;
struct FlyingPiece;
struct S3DOPrimitive;
struct S3DOPiece;
struct SS3OVertex;
typedef std::pair<CProjectile*, int> ProjectileMapValPair;
typedef std::pair<int, ProjectileMapValPair> ProjectileMapKeyPair;
typedef std::map<int, ProjectileMapValPair> ProjectileMap;
typedef ThreadListSim<std::list<CProjectile*>, std::set<CProjectile*>, CProjectile*, ProjectileDetacher> ProjectileContainer;
typedef ThreadListSimRender<std::list<CGroundFlash*>, std::set<CGroundFlash*>, CGroundFlash*> GroundFlashContainer;
typedef ThreadListSimRender<std::set<FlyingPiece*, FlyingPieceComparator>, void, FlyingPiece*> FlyingPieceContainer;
typedef ThreadMapRender<CProjectile*, int, ProjectileMapValPair, ProjectileIndexer> ProjectileRenderMap;
class CProjectileHandler
{
CR_DECLARE_STRUCT(CProjectileHandler)
public:
CProjectileHandler();
~CProjectileHandler();
void Serialize(creg::ISerializer* s);
void PostLoad();
inline const ProjectileMapValPair* GetMapPairBySyncedID(int id) const {
const ProjectileMap& projectileIDs = syncedProjectileIDs;
const ProjectileMap::const_iterator it = projectileIDs.find(id);
if (it == projectileIDs.end())
return NULL;
return &(it->second);
}
inline const ProjectileMapValPair* GetMapPairByUnsyncedID(int id) const {
if (UNSYNCED_PROJ_NOEVENT)
return NULL; // unsynced projectiles have no IDs if UNSYNCED_PROJ_NOEVENT
const ProjectileMap& projectileIDs = unsyncedProjectileIDs;
const ProjectileMap::const_iterator it = projectileIDs.find(id);
if (it == projectileIDs.end())
return NULL;
return &(it->second);
}
ProjectileRenderMap& GetSyncedRenderProjectileIDs() { return syncedRenderProjectileIDs; }
ProjectileRenderMap& GetUnsyncedRenderProjectileIDs() { return unsyncedRenderProjectileIDs; }
void CheckUnitCollisions(CProjectile*, std::vector<CUnit*>&, const float3&, const float3&);
void CheckFeatureCollisions(CProjectile*, std::vector<CFeature*>&, const float3&, const float3&);
void CheckUnitFeatureCollisions(ProjectileContainer&);
void CheckGroundCollisions(ProjectileContainer&);
void CheckCollisions();
void SetMaxParticles(int value) { maxParticles = value; }
void SetMaxNanoParticles(int value) { maxNanoParticles = value; }
void Update();
void UpdateParticleSaturation() {
particleSaturation = (maxParticles > 0)? (currentParticles / float(maxParticles)): 1.0f;
}
void AddProjectile(CProjectile* p);
void AddGroundFlash(CGroundFlash* flash);
void AddFlyingPiece(const float3& pos, const float3& speed, int team, const S3DOPiece* piece, const S3DOPrimitive* chunk);
void AddFlyingPiece(const float3& pos, const float3& speed, int team, int textureType, const SS3OVertex* chunk);
void AddNanoParticle(const float3&, const float3&, const UnitDef*, int team, bool highPriority);
void AddNanoParticle(const float3&, const float3&, const UnitDef*, int team, float radius, bool inverse, bool highPriority);
bool RenderAccess(const CProjectile *p) const;
public:
ProjectileContainer syncedProjectiles; // contains only projectiles that can change simulation state
ProjectileContainer unsyncedProjectiles; // contains only projectiles that cannot change simulation state
FlyingPieceContainer flyingPieces3DO; // unsynced
FlyingPieceContainer flyingPiecesS3O; // unsynced
GroundFlashContainer groundFlashes; // unsynced
int maxParticles; // different effects should start to cut down on unnececary(unsynced) particles when this number is reached
int maxNanoParticles;
int currentParticles; // number of particles weighted by how complex they are
int currentNanoParticles;
float particleSaturation; // currentParticles / maxParticles ratio
private:
void UpdateProjectileContainer(ProjectileContainer&, bool);
ProjectileRenderMap syncedRenderProjectileIDs; // same as syncedProjectileIDs, used by render thread
ProjectileRenderMap unsyncedRenderProjectileIDs; // same as unsyncedProjectileIDs, used by render thread
int maxUsedSyncedID;
int maxUsedUnsyncedID;
std::list<int> freeSyncedIDs; // available synced (weapon, piece) projectile ID's
std::list<int> freeUnsyncedIDs; // available unsynced projectile ID's
ProjectileMap syncedProjectileIDs; // ID ==> <projectile, allyteam> map for living synced projectiles
ProjectileMap unsyncedProjectileIDs; // ID ==> <projectile, allyteam> map for living unsynced projectiles
};
extern CProjectileHandler* projectileHandler;
#endif /* PROJECTILE_HANDLER_H */
|