diff --git a/rts/Game/SelectedUnitsAI.cpp b/rts/Game/SelectedUnitsAI.cpp index 76c3cd37b39..4df80f8ee70 100644 --- a/rts/Game/SelectedUnitsAI.cpp +++ b/rts/Game/SelectedUnitsAI.cpp @@ -8,7 +8,7 @@ #include "Game/Players/Player.h" #include "Game/Players/PlayerHandler.h" #include "Map/Ground.h" -#include "Sim/Misc/GlobalSynced.h" +#include "Sim/Misc/GlobalConstants.h" #include "Sim/Misc/QuadField.h" #include "Sim/Misc/TeamHandler.h" #include "Sim/MoveTypes/MoveType.h" diff --git a/rts/Game/UI/UnitTracker.cpp b/rts/Game/UI/UnitTracker.cpp index 39be0c3be3a..15285f884e2 100644 --- a/rts/Game/UI/UnitTracker.cpp +++ b/rts/Game/UI/UnitTracker.cpp @@ -8,6 +8,7 @@ #include "Game/SelectedUnitsHandler.h" #include "Map/Ground.h" #include "Rendering/GlobalRendering.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Units/Unit.h" #include "Sim/Units/UnitHandler.h" #include "System/Config/ConfigHandler.h" diff --git a/rts/Map/Ground.cpp b/rts/Map/Ground.cpp index 0db0a976948..72b7c8cdf2a 100644 --- a/rts/Map/Ground.cpp +++ b/rts/Map/Ground.cpp @@ -3,6 +3,8 @@ #include "Ground.h" #include "ReadMap.h" +#include "Sim/Misc/GlobalConstants.h" +#include "Sim/Misc/GlobalSynced.h" #include "System/myMath.h" #include @@ -400,25 +402,25 @@ float CGround::LinePlaneCol(const float3 pos, const float3 dir, float len, float float CGround::LineGroundWaterCol(const float3 pos, const float3 dir, float len, bool testWater, bool synced) { - const float dist = LineGroundCol(pos, dir, len, synced); + const float terraDist = LineGroundCol(pos, dir, len, synced); if (!testWater) - return dist; + return terraDist; const float waterDist = LinePlaneCol(pos, dir, len, 0.0f); if (waterDist < 0.0f) - return dist; + return terraDist; - float3 end = pos + dir * waterDist; - if (end.x > float3::maxxpos || end.x < 0.0f) - return dist; + const float3 end = pos + dir * waterDist; - if (end.z > float3::maxzpos || end.z < 0.0f) - return dist; + if (end.x < 0.0f || end.x > float3::maxxpos) + return terraDist; + if (end.z < 0.0f || end.z > float3::maxzpos) + return terraDist; - if (dist < 0.0f) + if (terraDist < 0.0f) return waterDist; - return std::min(dist, waterDist); + return std::min(terraDist, waterDist); } @@ -519,37 +521,80 @@ float3 CGround::GetSmoothNormal(float x, float z, bool synced) const float3& n1 = normalMap[sz * mapDims.mapx + sx ] * ifx * ifz; const float3& n2 = normalMap[sz * mapDims.mapx + sx2] * fx * ifz; - const float3& n3 = normalMap[sz2 * mapDims.mapx + sx ] * ifx * fz; - const float3& n4 = normalMap[sz2 * mapDims.mapx + sx2] * fx * fz; + const float3& n3 = normalMap[sz2 * mapDims.mapx + sx ] * ifx * fz; + const float3& n4 = normalMap[sz2 * mapDims.mapx + sx2] * fx * fz; return ((n1 + n2 + n3 + n4).Normalize()); } -float CGround::TrajectoryGroundCol(float3 from, const float3& flatdir, float length, float linear, float quadratic) + + +float CGround::SimTrajectoryGroundColDist(const float3& trajStartPos, const float3& trajStartDir, const float3& acc, const float2& args) +{ + // args.x := speed, args.y := length + const float2 ips = GetMapBoundaryIntersectionPoints(trajStartPos, trajStartDir * XZVector * args.y); + + // outside map + if (ips.y < 0.0f) + return -1.0; + + const float minDist = args.y * std::max(0.0f, ips.x); + const float maxDist = args.y * std::min(1.0f, ips.y); + + float3 pos = trajStartPos; + float3 vel = trajStartDir * args.x; + + // sample heights along the trajectory of a virtual projectile launched + // from with velocity ; is assumed to + // start inside map + while (pos.SqDistance2D(trajStartPos) < Square(minDist)) { + pos += vel; + vel += acc; + } + while (pos.y >= GetHeightReal(pos)) { + pos += vel; + vel += acc; + } + + if (pos.SqDistance2D(trajStartPos) >= Square(maxDist)) + return -1.0f; + + return (math::sqrt(pos.SqDistance2D(trajStartPos))); +} + +float CGround::TrajectoryGroundCol(const float3& trajStartPos, const float3& trajTargetDir, float length, float linCoeff, float qdrCoeff) { - float3 dir(flatdir.x, linear, flatdir.z); + // trajTargetDir should be the normalized xz-vector from to the target + const float3 dir = {trajTargetDir.x, linCoeff, trajTargetDir.z}; + const float3 alt = UpVector * qdrCoeff; - // limit the checking to the `in map part` of the line - std::pair near_far = GetMapBoundaryIntersectionPoints(from, dir * length); + // limit checking to the in-map part of the line + const float2 ips = GetMapBoundaryIntersectionPoints(trajStartPos, dir * length); - // outside of map - if (near_far.second < 0.0f) + // outside map + if (ips.y < 0.0f) return -1.0; - const float near = length * std::max(0.0f, near_far.first); - const float far = length * std::min(1.0f, near_far.second); + const float minDist = length * std::max(0.0f, ips.x); + const float maxDist = length * std::min(1.0f, ips.y); - for (float l = near; l < far; l += SQUARE_SIZE) { - const float3 pos = (from + dir * l) + (UpVector * quadratic * l * l); + for (float dist = minDist; dist < maxDist; dist += SQUARE_SIZE) { + const float3 pos = (trajStartPos + dir * dist) + (alt * dist * dist); - if (GetApproximateHeight(pos.x, pos.z) > pos.y) { - return l; - } + #if 1 + if (GetApproximateHeight(pos) > pos.y) + return dist; + #else + if (GetHeightReal(pos) > pos.y) + return dist; + #endif } return -1.0f; } + + int CGround::GetSquare(const float3& pos) { const int x = Clamp((int(pos.x) / SQUARE_SIZE), 0, mapDims.mapxm1); const int z = Clamp((int(pos.z) / SQUARE_SIZE), 0, mapDims.mapym1); diff --git a/rts/Map/Ground.h b/rts/Map/Ground.h index 920f18a8cd1..ce2795c2295 100644 --- a/rts/Map/Ground.h +++ b/rts/Map/Ground.h @@ -4,8 +4,8 @@ #define GROUND_H #include "System/float3.h" -#include "Sim/Misc/GlobalConstants.h" -#include "Sim/Misc/GlobalSynced.h" +#include "System/type2.h" + class CGround { @@ -39,7 +39,9 @@ class CGround static float LineGroundCol(const float3 pos, const float3 dir, float len, bool synced = true); static float LinePlaneCol(const float3 pos, const float3 dir, float len, float hgt); static float LineGroundWaterCol(const float3 pos, const float3 dir, float len, bool testWater, bool synced = true); - static float TrajectoryGroundCol(float3 from, const float3& flatdir, float length, float linear, float quadratic); + + static float TrajectoryGroundCol(const float3& trajStartPos, const float3& trajTargetDir, float length, float linCoeff, float qdrCoeff); + static float SimTrajectoryGroundColDist(const float3& startPos, const float3& trajStartDir, const float3& acc, const float2& args); static int GetSquare(const float3& pos); }; diff --git a/rts/Rendering/Env/Particles/Classes/SmokeTrailProjectile.cpp b/rts/Rendering/Env/Particles/Classes/SmokeTrailProjectile.cpp index af671a30ae4..e783cda222e 100644 --- a/rts/Rendering/Env/Particles/Classes/SmokeTrailProjectile.cpp +++ b/rts/Rendering/Env/Particles/Classes/SmokeTrailProjectile.cpp @@ -9,6 +9,7 @@ #include "Rendering/Env/Particles/ProjectileDrawer.h" #include "Rendering/GL/RenderDataBuffer.hpp" #include "Rendering/Textures/TextureAtlas.h" +#include "Sim/Misc/GlobalSynced.h" #include "System/myMath.h" CR_BIND_DERIVED(CSmokeTrailProjectile, CProjectile, ) diff --git a/rts/Rendering/Env/Particles/Classes/WreckProjectile.cpp b/rts/Rendering/Env/Particles/Classes/WreckProjectile.cpp index ede197f53f6..21d4a8068ea 100644 --- a/rts/Rendering/Env/Particles/Classes/WreckProjectile.cpp +++ b/rts/Rendering/Env/Particles/Classes/WreckProjectile.cpp @@ -10,6 +10,7 @@ #include "Rendering/GL/RenderDataBuffer.hpp" #include "Rendering/GL/VertexArray.h" #include "Rendering/Textures/TextureAtlas.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/ProjectileMemPool.h" diff --git a/rts/Rendering/Env/Particles/ProjectileDrawer.cpp b/rts/Rendering/Env/Particles/ProjectileDrawer.cpp index 13269669c8e..9c4f71ffd6d 100644 --- a/rts/Rendering/Env/Particles/ProjectileDrawer.cpp +++ b/rts/Rendering/Env/Particles/ProjectileDrawer.cpp @@ -22,6 +22,7 @@ #include "Rendering/Textures/S3OTextureHandler.h" #include "Rendering/Textures/TextureAtlas.h" #include "Rendering/Models/ModelRenderContainer.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/LosHandler.h" #include "Sim/Misc/TeamHandler.h" #include "Sim/Projectiles/ExplosionGenerator.h" diff --git a/rts/Sim/Features/Feature.cpp b/rts/Sim/Features/Feature.cpp index dd1d8f29959..74c3f2b8452 100644 --- a/rts/Sim/Features/Feature.cpp +++ b/rts/Sim/Features/Feature.cpp @@ -12,6 +12,7 @@ #include "Rendering/Env/Particles/Classes/GeoThermSmokeProjectile.h" #include "Rendering/Env/Particles/Classes/SmokeProjectile.h" #include "Sim/Misc/DamageArray.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/QuadField.h" #include "Sim/Misc/CollisionVolume.h" #include "Sim/Misc/LosHandler.h" diff --git a/rts/Sim/Misc/InterceptHandler.cpp b/rts/Sim/Misc/InterceptHandler.cpp index e6fb87a3b5f..ae6cc14fb06 100644 --- a/rts/Sim/Misc/InterceptHandler.cpp +++ b/rts/Sim/Misc/InterceptHandler.cpp @@ -6,11 +6,12 @@ #include "InterceptHandler.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" +#include "Sim/Misc/TeamHandler.h" #include "Sim/Weapons/Weapon.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectile.h" #include "Sim/Units/Unit.h" #include "Sim/Weapons/WeaponDef.h" -#include "Sim/Misc/TeamHandler.h" #include "System/EventHandler.h" #include "System/float3.h" #include "System/myMath.h" diff --git a/rts/Sim/MoveTypes/HoverAirMoveType.cpp b/rts/Sim/MoveTypes/HoverAirMoveType.cpp index 0bd56e20136..a88ed0e788b 100644 --- a/rts/Sim/MoveTypes/HoverAirMoveType.cpp +++ b/rts/Sim/MoveTypes/HoverAirMoveType.cpp @@ -7,6 +7,7 @@ #include "Map/Ground.h" #include "Rendering/Env/Particles/Classes/SmokeProjectile.h" #include "Sim/Misc/GeometricObjects.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/GroundBlockingObjectMap.h" #include "Sim/Misc/QuadField.h" #include "Sim/Misc/ModInfo.h" diff --git a/rts/Sim/Projectiles/PieceProjectile.cpp b/rts/Sim/Projectiles/PieceProjectile.cpp index 68e1f2f1851..b33d87a7a25 100644 --- a/rts/Sim/Projectiles/PieceProjectile.cpp +++ b/rts/Sim/Projectiles/PieceProjectile.cpp @@ -11,11 +11,12 @@ #include "Rendering/Textures/TextureAtlas.h" #include "Rendering/Colors.h" #include "Rendering/Env/Particles/ProjectileDrawer.h" +#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Rendering/Models/3DModel.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/ProjectileMemPool.h" -#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Sim/Units/Unit.h" #include "Sim/Units/UnitDef.h" #include "System/Matrix44f.h" diff --git a/rts/Sim/Projectiles/Projectile.cpp b/rts/Sim/Projectiles/Projectile.cpp index 46c97106405..8a38aa0442b 100644 --- a/rts/Sim/Projectiles/Projectile.cpp +++ b/rts/Sim/Projectiles/Projectile.cpp @@ -134,7 +134,7 @@ CProjectile::~CProjectile() void CProjectile::Init(const CUnit* owner, const float3& offset) { - if (owner != NULL) { + if (owner != nullptr) { // must be set before the AddProjectile call ownerID = owner->id; teamID = owner->team; diff --git a/rts/Sim/Projectiles/ProjectileHandler.cpp b/rts/Sim/Projectiles/ProjectileHandler.cpp index 1744e4f80c4..98240134fc8 100644 --- a/rts/Sim/Projectiles/ProjectileHandler.cpp +++ b/rts/Sim/Projectiles/ProjectileHandler.cpp @@ -14,6 +14,7 @@ #include "Sim/Features/FeatureDef.h" #include "Sim/Misc/CollisionHandler.h" #include "Sim/Misc/CollisionVolume.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/QuadField.h" #include "Sim/Misc/TeamHandler.h" #include "Rendering/Env/Particles/Classes/FlyingPiece.h" diff --git a/rts/Sim/Projectiles/WeaponProjectiles/LaserProjectile.cpp b/rts/Sim/Projectiles/WeaponProjectiles/LaserProjectile.cpp index 5cbb15746ba..644511a6a99 100644 --- a/rts/Sim/Projectiles/WeaponProjectiles/LaserProjectile.cpp +++ b/rts/Sim/Projectiles/WeaponProjectiles/LaserProjectile.cpp @@ -4,10 +4,11 @@ #include "Game/Camera.h" #include "LaserProjectile.h" #include "Map/Ground.h" +#include "Rendering/Env/Particles/Classes/SimpleParticleSystem.h" #include "Rendering/GL/RenderDataBuffer.hpp" +#include "Sim/Misc/GlobalConstants.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Projectiles/ProjectileHandler.h" -#include "Rendering/Env/Particles/Classes/SimpleParticleSystem.h" #include "Sim/Weapons/WeaponDef.h" #ifdef TRACE_SYNC diff --git a/rts/Sim/Projectiles/WeaponProjectiles/MissileProjectile.cpp b/rts/Sim/Projectiles/WeaponProjectiles/MissileProjectile.cpp index d45315fb194..fe2295eab90 100644 --- a/rts/Sim/Projectiles/WeaponProjectiles/MissileProjectile.cpp +++ b/rts/Sim/Projectiles/WeaponProjectiles/MissileProjectile.cpp @@ -6,13 +6,14 @@ #include "Map/Ground.h" #include "MissileProjectile.h" #include "Rendering/GlobalRendering.h" +#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Rendering/GL/RenderDataBuffer.hpp" #include "Rendering/Textures/TextureAtlas.h" #include "Sim/Misc/GeometricObjects.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/ProjectileMemPool.h" -#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Sim/Units/Unit.h" #include "Sim/Weapons/WeaponDefHandler.h" #include "System/Matrix44f.h" diff --git a/rts/Sim/Projectiles/WeaponProjectiles/TorpedoProjectile.cpp b/rts/Sim/Projectiles/WeaponProjectiles/TorpedoProjectile.cpp index 93f6bd71df6..a45a4197335 100644 --- a/rts/Sim/Projectiles/WeaponProjectiles/TorpedoProjectile.cpp +++ b/rts/Sim/Projectiles/WeaponProjectiles/TorpedoProjectile.cpp @@ -7,13 +7,14 @@ #include "Game/GlobalUnsynced.h" #include "Map/Ground.h" #include "Rendering/Env/Particles/ProjectileDrawer.h" +#include "Rendering/Env/Particles/Classes/BubbleProjectile.h" +#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Rendering/GL/RenderDataBuffer.hpp" #include "Rendering/Textures/TextureAtlas.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/ProjectileMemPool.h" -#include "Rendering/Env/Particles/Classes/BubbleProjectile.h" -#include "Rendering/Env/Particles/Classes/SmokeTrailProjectile.h" #include "Sim/Units/Unit.h" #include "Sim/Weapons/WeaponDef.h" #include "System/myMath.h" diff --git a/rts/Sim/Projectiles/WeaponProjectiles/WeaponProjectile.cpp b/rts/Sim/Projectiles/WeaponProjectiles/WeaponProjectile.cpp index f9340a8a2b5..9032fe1feff 100644 --- a/rts/Sim/Projectiles/WeaponProjectiles/WeaponProjectile.cpp +++ b/rts/Sim/Projectiles/WeaponProjectiles/WeaponProjectile.cpp @@ -1,22 +1,23 @@ /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ #include "Game/GameHelper.h" +#include "Map/Ground.h" #include "Rendering/Colors.h" #include "Rendering/GL/VertexArray.h" +#include "Sim/Features/Feature.h" +#include "Sim/Misc/DamageArray.h" +#include "Sim/Misc/GlobalSynced.h" +#include "Sim/Misc/InterceptHandler.h" +#include "Sim/Misc/QuadField.h" +#include "Sim/Misc/TeamHandler.h" #include "Sim/Projectiles/ExplosionGenerator.h" #include "Sim/Projectiles/ProjectileHandler.h" #include "Sim/Projectiles/ProjectileParams.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectile.h" -#include "Sim/Weapons/Weapon.h" -#include "Sim/Weapons/WeaponDefHandler.h" -#include "Sim/Features/Feature.h" -#include "Sim/Misc/TeamHandler.h" #include "Sim/Units/Unit.h" #include "Sim/Units/UnitHandler.h" -#include "Sim/Misc/DamageArray.h" -#include "Sim/Misc/InterceptHandler.h" -#include "Sim/Misc/QuadField.h" -#include "Map/Ground.h" +#include "Sim/Weapons/Weapon.h" +#include "Sim/Weapons/WeaponDefHandler.h" #include "System/Matrix44f.h" #include "System/myMath.h" #include "System/creg/DefTypes.h" diff --git a/rts/Sim/Units/CommandAI/BuilderCAI.cpp b/rts/Sim/Units/CommandAI/BuilderCAI.cpp index 8d2511015e7..ad1cfa8c98b 100644 --- a/rts/Sim/Units/CommandAI/BuilderCAI.cpp +++ b/rts/Sim/Units/CommandAI/BuilderCAI.cpp @@ -12,6 +12,7 @@ #include "Sim/Features/Feature.h" #include "Sim/Features/FeatureDef.h" #include "Sim/Features/FeatureHandler.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/GroundBlockingObjectMap.h" #include "Sim/Misc/QuadField.h" #include "Sim/Misc/Team.h" diff --git a/rts/Sim/Units/CommandAI/CommandAI.cpp b/rts/Sim/Units/CommandAI/CommandAI.cpp index 8ab61736bb7..87e044628c5 100644 --- a/rts/Sim/Units/CommandAI/CommandAI.cpp +++ b/rts/Sim/Units/CommandAI/CommandAI.cpp @@ -15,6 +15,7 @@ #include "Sim/Features/Feature.h" #include "Sim/Features/FeatureDef.h" #include "Sim/Features/FeatureHandler.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/ModInfo.h" #include "Sim/Misc/TeamHandler.h" #include "Sim/MoveTypes/MoveType.h" diff --git a/rts/Sim/Units/CommandAI/MobileCAI.cpp b/rts/Sim/Units/CommandAI/MobileCAI.cpp index 8aca166ac49..5b7f174cecc 100644 --- a/rts/Sim/Units/CommandAI/MobileCAI.cpp +++ b/rts/Sim/Units/CommandAI/MobileCAI.cpp @@ -7,6 +7,7 @@ #include "Game/GlobalUnsynced.h" #include "Game/SelectedUnitsHandler.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/LosHandler.h" #include "Sim/Misc/ModInfo.h" #include "Sim/Misc/QuadField.h" diff --git a/rts/Sim/Units/Scripts/UnitScript.cpp b/rts/Sim/Units/Scripts/UnitScript.cpp index 83ada55eb43..61277a33f69 100644 --- a/rts/Sim/Units/Scripts/UnitScript.cpp +++ b/rts/Sim/Units/Scripts/UnitScript.cpp @@ -13,6 +13,7 @@ #include "Game/GameHelper.h" #include "Game/GlobalUnsynced.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/GroundBlockingObjectMap.h" #include "Sim/Misc/LosHandler.h" #include "Sim/Misc/TeamHandler.h" diff --git a/rts/Sim/Weapons/Cannon.cpp b/rts/Sim/Weapons/Cannon.cpp index 2157bb8b259..8baec9180b0 100644 --- a/rts/Sim/Weapons/Cannon.cpp +++ b/rts/Sim/Weapons/Cannon.cpp @@ -7,6 +7,7 @@ #include "Map/MapInfo.h" #include "Rendering/Env/Particles/Classes/HeatCloudProjectile.h" #include "Rendering/Env/Particles/Classes/SmokeProjectile.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" #include "System/Sync/SyncTracer.h" @@ -18,27 +19,18 @@ CR_BIND_DERIVED(CCannon, CWeapon, ) CR_REG_METADATA(CCannon,( CR_MEMBER(highTrajectory), CR_MEMBER(rangeFactor), - CR_MEMBER(lastDiff), - CR_MEMBER(lastDir), - CR_MEMBER(gravity) + CR_MEMBER(gravity), + CR_MEMBER(lastTargetVec), + CR_MEMBER(lastLaunchDir) )) ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CCannon::CCannon(CUnit* owner, const WeaponDef* def) - : CWeapon(owner, def) - , rangeFactor(1.0f) - , lastDir(-UpVector) - , highTrajectory(false) - , gravity(0.0f) -{ -} - void CCannon::Init() { - gravity = (weaponDef->myGravity == 0)? mapInfo->map.gravity : -(weaponDef->myGravity); + gravity = mix(mapInfo->map.gravity, -weaponDef->myGravity, weaponDef->myGravity != 0.0f); highTrajectory = (weaponDef->highTrajectory == 1); CWeapon::Init(); @@ -64,8 +56,7 @@ void CCannon::UpdateRange(const float val) void CCannon::UpdateWantedDir() { - const float3 targetVec = currentTargetPos - aimFromPos; - wantedDir = GetWantedDir(targetVec); + wantedDir = GetWantedDir(currentTargetPos - aimFromPos); } @@ -78,50 +69,51 @@ bool CCannon::HaveFreeLineOfFire(const float3 srcPos, const float3 tgtPos, const if (projectileSpeed == 0.0f) return true; - float3 dif(tgtPos - srcPos); - float3 dir(GetWantedDir2(dif)); - float3 flatDir(dif.x, 0.0f, dif.z); + float3 launchDir = CalcWantedDir(tgtPos - srcPos); + float3 targetVec = (tgtPos - srcPos) * XZVector; - if (dir.SqLength() == 0.0f) + if (launchDir.SqLength() == 0.0f) return false; - const float flatLength = flatDir.LengthNormalize(); + const float xzTargetDist = targetVec.LengthNormalize(); + const float xzCoeffRatio = targetVec.x / launchDir.x; - if (flatLength == 0.0f) + if (xzTargetDist == 0.0f) return true; - const float linear = dir.y; - const float quadratic = gravity / (projectileSpeed * projectileSpeed) * 0.5f; + // targetVec is normalized in the xz-plane while launchDir is xyz + // therefore the linear parabolic coefficient has to be scaled by + // their ratio or tested heights will fall short of those reached + // by projectiles + const float linCoeff = launchDir.y * xzCoeffRatio; + const float qdrCoeff = (gravity * 0.5f) / (projectileSpeed * projectileSpeed); + + // CGround::SimTrajectoryGroundColDist(weaponMuzzlePos, launchDir, UpVector * gravity, {projectileSpeed, xzTargetDist - 10.0f}) const float groundDist = ((avoidFlags & Collision::NOGROUND) == 0)? - CGround::TrajectoryGroundCol(weaponMuzzlePos, flatDir, flatLength - 10, linear, quadratic): + CGround::TrajectoryGroundCol(weaponMuzzlePos, targetVec, xzTargetDist - 10.0f, linCoeff, qdrCoeff): -1.0f; - const float spread = (AccuracyExperience() + SprayAngleExperience()) * 0.6f * 0.9f; + const float angleSpread = (AccuracyExperience() + SprayAngleExperience()) * 0.6f * 0.9f; if (groundDist > 0.0f) return false; - //FIXME add a forcedUserTarget (a forced fire mode enabled with meta key or something) and skip the test below then - if (TraceRay::TestTrajectoryCone(srcPos, flatDir, flatLength, - dir.y, quadratic, spread, owner->allyteam, avoidFlags, owner)) { - return false; - } - - return true; + // TODO: add a forcedUserTarget mode (enabled with meta key e.g.) and skip this test accordingly + return (!TraceRay::TestTrajectoryCone(srcPos, targetVec, xzTargetDist, linCoeff, qdrCoeff, angleSpread, owner->allyteam, avoidFlags, owner)); } void CCannon::FireImpl(const bool scriptCall) { - float3 diff = currentTargetPos - weaponMuzzlePos; - float3 dir = (diff.SqLength() > 4.0f) ? GetWantedDir(diff) : diff; // prevent vertical aim when emit-sfx firing the weapon + float3 targetVec = currentTargetPos - weaponMuzzlePos; + float3 launchDir = (targetVec.SqLength() > 4.0f) ? GetWantedDir(targetVec) : targetVec; // prevent vertical aim when emit-sfx firing the weapon - dir += (gsRNG.NextVector() * SprayAngleExperience() + SalvoErrorExperience()); - dir.SafeNormalize(); + launchDir += (gsRNG.NextVector() * SprayAngleExperience() + SalvoErrorExperience()); + launchDir.SafeNormalize(); int ttl = 0; - const float sqSpeed2D = dir.SqLength2D() * projectileSpeed * projectileSpeed; + const float sqSpeed2D = launchDir.SqLength2D() * projectileSpeed * projectileSpeed; const int predict = math::ceil((sqSpeed2D == 0.0f) ? - (-2.0f * projectileSpeed * dir.y / gravity): - math::sqrt(diff.SqLength2D() / sqSpeed2D)); + (-2.0f * projectileSpeed * launchDir.y / gravity): + math::sqrt(targetVec.SqLength2D() / sqSpeed2D)); if (weaponDef->flighttime > 0) { ttl = weaponDef->flighttime; @@ -136,7 +128,7 @@ void CCannon::FireImpl(const bool scriptCall) ProjectileParams params = GetProjectileParams(); params.pos = weaponMuzzlePos; params.end = currentTargetPos; - params.speed = dir * projectileSpeed; + params.speed = launchDir * projectileSpeed; params.ttl = ttl; params.gravity = gravity; @@ -152,31 +144,35 @@ void CCannon::SlowUpdate() } -float3 CCannon::GetWantedDir(const float3& diff) +float3 CCannon::GetWantedDir(const float3& targetVec) { + const float3 tgtDif = targetVec - lastTargetVec; + // try to cache results, sacrifice some (not much too much even for a pewee) accuracy - // it saves a dozen or two expensive calculations per second when 5 guardians - // are shooting at several slow- and fast-moving targets - if (math::fabs(diff.x - lastDiff.x) < (SQUARE_SIZE / 4.0f) && - math::fabs(diff.y - lastDiff.y) < (SQUARE_SIZE / 4.0f) && - math::fabs(diff.z - lastDiff.z) < (SQUARE_SIZE / 4.0f)) { - return lastDir; + // saves a dozen or two expensive calculations per second when 5 cannons are shooting + // at several slow- and fast-moving targets + if (math::fabs(tgtDif.x) < (SQUARE_SIZE / 4.0f) && + math::fabs(tgtDif.y) < (SQUARE_SIZE / 4.0f) && + math::fabs(tgtDif.z) < (SQUARE_SIZE / 4.0f)) { + return lastLaunchDir; } - const float3 dir = GetWantedDir2(diff); - lastDiff = diff; - lastDir = dir; - return dir; + const float3 launchDir = CalcWantedDir(targetVec); + + lastTargetVec = targetVec; + lastLaunchDir = launchDir; + return launchDir; } -float3 CCannon::GetWantedDir2(const float3& diff) const +float3 CCannon::CalcWantedDir(const float3& targetVec) const { - const float Dsq = diff.SqLength(); - const float DFsq = diff.SqLength2D(); + const float Dsq = targetVec.SqLength(); + const float DFsq = targetVec.SqLength2D(); const float g = gravity; const float v = projectileSpeed; - const float dy = diff.y; + const float dy = targetVec.y; const float dxz = math::sqrt(DFsq); + float Vxz = 0.0f; float Vy = 0.0f; @@ -203,9 +199,10 @@ float3 CCannon::GetWantedDir2(const float3& diff) const float3 dir = ZeroVector; if (Vxz != 0.0f || Vy != 0.0f) { - dir.x = diff.x; - dir.z = diff.z; + dir.x = targetVec.x; + dir.z = targetVec.z; dir.SafeNormalize(); + dir *= Vxz; dir.y = Vy; dir.SafeNormalize(); @@ -231,9 +228,8 @@ float CCannon::GetRange2D(float yDiff, float rFact) const const float root1 = speed2dSq + 2.0f * gravity * yDiff; - if (root1 < 0.0f) { + if (root1 < 0.0f) return 0.0f; - } return (rFact * (speed2dSq + speed2d * math::sqrt(root1)) / (-gravity)); } diff --git a/rts/Sim/Weapons/Cannon.h b/rts/Sim/Weapons/Cannon.h index e74b4447837..dfda34d6129 100644 --- a/rts/Sim/Weapons/Cannon.h +++ b/rts/Sim/Weapons/Cannon.h @@ -10,15 +10,22 @@ class CCannon: public CWeapon CR_DECLARE_DERIVED(CCannon) protected: - /// this is used to keep range true to range tag - float rangeFactor; /// cached input for GetWantedDir - float3 lastDiff; + float3 lastTargetVec; /// cached result for GetWantedDir - float3 lastDir; + float3 lastLaunchDir = -UpVector; + + /// this is used to keep range true to range tag + float rangeFactor = 1.0f; + + /// projectile gravity + float gravity = 0.0f; + + /// indicates high trajectory on/off state + bool highTrajectory = false; public: - CCannon(CUnit* owner = nullptr, const WeaponDef* def = nullptr); + CCannon(CUnit* owner = nullptr, const WeaponDef* def = nullptr): CWeapon(owner, def) {} void Init() override final; void UpdateRange(const float val) override final; @@ -28,16 +35,10 @@ class CCannon: public CWeapon float GetRange2D(float yDiff, float rFact) const; float GetRange2D(const float yDiff) const override final; - - /// indicates high trajectory on/off state - bool highTrajectory; - /// projectile gravity - float gravity; - private: /// tells where to point the gun to hit the point at pos+diff float3 GetWantedDir(const float3& diff); - float3 GetWantedDir2(const float3& diff) const; + float3 CalcWantedDir(const float3& diff) const; const float3& GetAimFromPos(bool useMuzzle = false) const override { return weaponMuzzlePos; } diff --git a/rts/Sim/Weapons/EmgCannon.cpp b/rts/Sim/Weapons/EmgCannon.cpp index 7696ab94c89..ea85f920685 100644 --- a/rts/Sim/Weapons/EmgCannon.cpp +++ b/rts/Sim/Weapons/EmgCannon.cpp @@ -4,6 +4,7 @@ #include "WeaponDef.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/Team.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" diff --git a/rts/Sim/Weapons/FlameThrower.cpp b/rts/Sim/Weapons/FlameThrower.cpp index a25f027dd7c..b868c3c5303 100644 --- a/rts/Sim/Weapons/FlameThrower.cpp +++ b/rts/Sim/Weapons/FlameThrower.cpp @@ -4,6 +4,7 @@ #include "WeaponDef.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" #include "System/myMath.h" diff --git a/rts/Sim/Weapons/LaserCannon.cpp b/rts/Sim/Weapons/LaserCannon.cpp index e19aabee2f3..b75285d3779 100644 --- a/rts/Sim/Weapons/LaserCannon.cpp +++ b/rts/Sim/Weapons/LaserCannon.cpp @@ -3,6 +3,7 @@ #include "LaserCannon.h" #include "WeaponDef.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" #include "Sim/Units/UnitDef.h" diff --git a/rts/Sim/Weapons/MissileLauncher.cpp b/rts/Sim/Weapons/MissileLauncher.cpp index 33e6e629b43..3d615eacfda 100644 --- a/rts/Sim/Weapons/MissileLauncher.cpp +++ b/rts/Sim/Weapons/MissileLauncher.cpp @@ -5,6 +5,7 @@ #include "WeaponDef.h" #include "Game/TraceRay.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" #include "Sim/Units/UnitDef.h" @@ -26,22 +27,21 @@ void CMissileLauncher::UpdateWantedDir() void CMissileLauncher::FireImpl(const bool scriptCall) { - float3 dir = currentTargetPos - weaponMuzzlePos; - const float dist = dir.LengthNormalize(); + float3 targetVec = currentTargetPos - weaponMuzzlePos; + const float targetDist = targetVec.LengthNormalize(); if (onlyForward) { - dir = owner->frontdir; + targetVec = owner->frontdir; } else if (weaponDef->fixedLauncher) { - dir = weaponDir; + targetVec = weaponDir; } else if (weaponDef->trajectoryHeight > 0.0f) { - dir.y += weaponDef->trajectoryHeight; - dir.Normalize(); + targetVec = (targetVec + UpVector * weaponDef->trajectoryHeight).Normalize(); } - dir += (gsRNG.NextVector() * SprayAngleExperience() + SalvoErrorExperience()); - dir.Normalize(); + targetVec += (gsRNG.NextVector() * SprayAngleExperience() + SalvoErrorExperience()); + targetVec.Normalize(); - float3 startSpeed = dir * weaponDef->startvelocity; + float3 startSpeed = targetVec * weaponDef->startvelocity; // NOTE: why only for SAMT units? if (onlyForward && owner->unitDef->IsStrafingAirUnit()) @@ -51,39 +51,34 @@ void CMissileLauncher::FireImpl(const bool scriptCall) params.pos = weaponMuzzlePos; params.end = currentTargetPos; params.speed = startSpeed; - params.ttl = weaponDef->flighttime == 0? math::ceil(std::max(dist, range) / projectileSpeed + 25 * weaponDef->selfExplode): weaponDef->flighttime; + params.ttl = weaponDef->flighttime == 0? math::ceil(std::max(targetDist, range) / projectileSpeed + 25 * weaponDef->selfExplode): weaponDef->flighttime; WeaponProjectileFactory::LoadProjectile(params); } bool CMissileLauncher::HaveFreeLineOfFire(const float3 srcPos, const float3 tgtPos, const SWeaponTarget& trg) const { - // do a different test depending on if the missile has high - // trajectory (parabolic vs. linear ground intersection) + // high-trajectory missiles use parabolic rather than linear ground intersection if (weaponDef->trajectoryHeight <= 0.0f) return (CWeapon::HaveFreeLineOfFire(srcPos, tgtPos, trg)); - float3 dir(tgtPos - srcPos); - float3 flatDir(dir.x, 0, dir.z); - dir.SafeNormalize(); - const float flatLength = flatDir.LengthNormalize(); + float3 targetVec = (tgtPos - srcPos) * XZVector; + float3 launchDir = (tgtPos - srcPos).SafeNormalize(); - if (flatLength == 0.0f) + const float xzTargetDist = targetVec.LengthNormalize(); + + if (xzTargetDist == 0.0f) return true; - const float linear = dir.y + weaponDef->trajectoryHeight; - const float quadratic = -weaponDef->trajectoryHeight / flatLength; + const float linCoeff = launchDir.y + weaponDef->trajectoryHeight; + const float qdrCoeff = -weaponDef->trajectoryHeight / xzTargetDist; const float groundDist = ((avoidFlags & Collision::NOGROUND) == 0)? - CGround::TrajectoryGroundCol(srcPos, flatDir, flatLength, linear, quadratic): + CGround::TrajectoryGroundCol(srcPos, targetVec, xzTargetDist, linCoeff, qdrCoeff): -1.0f; if (groundDist > 0.0f) return false; - if (TraceRay::TestTrajectoryCone(srcPos, flatDir, flatLength, - linear, quadratic, 0.0f, owner->allyteam, avoidFlags, owner)) { - return false; - } - - return true; + return (!TraceRay::TestTrajectoryCone(srcPos, targetVec, xzTargetDist, linCoeff, qdrCoeff, 0.0f, owner->allyteam, avoidFlags, owner)); } + diff --git a/rts/Sim/Weapons/Rifle.cpp b/rts/Sim/Weapons/Rifle.cpp index d2f9784c63a..21ab64543cc 100644 --- a/rts/Sim/Weapons/Rifle.cpp +++ b/rts/Sim/Weapons/Rifle.cpp @@ -8,6 +8,7 @@ #include "Rendering/Env/Particles/Classes/HeatCloudProjectile.h" #include "Rendering/Env/Particles/Classes/SmokeProjectile.h" #include "Rendering/Env/Particles/Classes/TracerProjectile.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Units/Unit.h" #include "Sim/Features/Feature.h" #include "Sim/Projectiles/ProjectileMemPool.h" diff --git a/rts/Sim/Weapons/StarburstLauncher.cpp b/rts/Sim/Weapons/StarburstLauncher.cpp index 862d699a047..5d960af6760 100644 --- a/rts/Sim/Weapons/StarburstLauncher.cpp +++ b/rts/Sim/Weapons/StarburstLauncher.cpp @@ -4,6 +4,8 @@ #include "WeaponDef.h" #include "Game/TraceRay.h" #include "Map/Ground.h" +#include "Sim/Misc/GlobalConstants.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Projectiles/WeaponProjectiles/WeaponProjectileFactory.h" #include "Sim/Units/Unit.h" diff --git a/rts/Sim/Weapons/Weapon.cpp b/rts/Sim/Weapons/Weapon.cpp index c9a72ad2d86..abdb3ff5cca 100644 --- a/rts/Sim/Weapons/Weapon.cpp +++ b/rts/Sim/Weapons/Weapon.cpp @@ -10,6 +10,7 @@ #include "Map/Ground.h" #include "Sim/Misc/CollisionHandler.h" #include "Sim/Misc/CollisionVolume.h" +#include "Sim/Misc/GlobalSynced.h" #include "Sim/Misc/InterceptHandler.h" #include "Sim/Misc/ModInfo.h" #include "Sim/Misc/TeamHandler.h" diff --git a/rts/System/myMath.cpp b/rts/System/myMath.cpp index e6ebb12bfbb..48fd7d00715 100644 --- a/rts/System/myMath.cpp +++ b/rts/System/myMath.cpp @@ -104,21 +104,21 @@ float3 ClosestPointOnLine(const float3 l1, const float3 l2, const float3 p) * credits: * http://ompf.org/ray/ray_box.html */ -std::pair GetMapBoundaryIntersectionPoints(const float3 start, const float3 dir) +float2 GetMapBoundaryIntersectionPoints(const float3 start, const float3 dir) { const float rcpdirx = (dir.x != 0.0f)? (1.0f / dir.x): 10000.0f; const float rcpdirz = (dir.z != 0.0f)? (1.0f / dir.z): 10000.0f; - const float& mapwidth = float3::maxxpos + 1; - const float& mapheight = float3::maxzpos + 1; + const float mapwidth = float3::maxxpos + 1.0f; + const float mapheight = float3::maxzpos + 1.0f; - // x component + // x-component float xl1 = ( 0.0f - start.x) * rcpdirx; float xl2 = (mapwidth - start.x) * rcpdirx; float xnear = std::min(xl1, xl2); float xfar = std::max(xl1, xl2); - // z component + // z-component float zl1 = ( 0.0f - start.z) * rcpdirz; float zl2 = (mapheight - start.z) * rcpdirz; float znear = std::min(zl1, zl2); @@ -133,16 +133,18 @@ std::pair GetMapBoundaryIntersectionPoints(const float3 start, con near = -1.0f; far = -1.0f; } - return std::pair(near, far); + + return {near, far}; } bool ClampLineInMap(float3& start, float3& end) { const float3 dir = end - start; - const std::pair& interp = GetMapBoundaryIntersectionPoints(start, dir); - const float& near = interp.first; - const float& far = interp.second; + const float2 ips = GetMapBoundaryIntersectionPoints(start, dir); + + const float near = ips.x; + const float far = ips.y; if (far < 0.0f) { //! outside of map! @@ -160,6 +162,7 @@ bool ClampLineInMap(float3& start, float3& end) start.ClampInMap(); return true; } + return false; } @@ -167,9 +170,10 @@ bool ClampLineInMap(float3& start, float3& end) bool ClampRayInMap(const float3 start, float3& end) { const float3 dir = end - start; - std::pair interp = GetMapBoundaryIntersectionPoints(start, dir); - const float& near = interp.first; - const float& far = interp.second; + const float2 ips = GetMapBoundaryIntersectionPoints(start, dir); + + const float near = ips.x; + const float far = ips.y; if (far < 0.0f) { //! outside of map! @@ -184,6 +188,7 @@ bool ClampRayInMap(const float3 start, float3& end) end.ClampInMap(); return true; } + return false; } diff --git a/rts/System/myMath.h b/rts/System/myMath.h index eaceb694eb3..c8066978e93 100644 --- a/rts/System/myMath.h +++ b/rts/System/myMath.h @@ -66,7 +66,7 @@ float3 ClosestPointOnLine(const float3 l1, const float3 l2, const float3 p) _pur * @param dir float3 direction of the ray * @return std::pair distance to the intersection points in mulitples of `dir` */ -std::pair GetMapBoundaryIntersectionPoints(const float3 start, const float3 dir) _pure _warn_unused_result; +float2 GetMapBoundaryIntersectionPoints(const float3 start, const float3 dir) _pure _warn_unused_result; /** * @brief clamps a line (start & end points) to the map boundaries