Skip to content

Commit d587f67

Browse files
committed
Added "RequiresAllTriggers" & Adjusted StealthDetectorUpdate to check Upgrade only when Necessary + Optimized Codes + Adjusted 2DVector length-based calculations to use math.hypot
1 parent c1f149d commit d587f67

File tree

11 files changed

+145
-72
lines changed

11 files changed

+145
-72
lines changed

Core/Libraries/Source/WWVegas/WWMath/vector2.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ WWINLINE Vector2 Normalize(const Vector2 & vec)
356356
*========================================================================*/
357357
WWINLINE float Vector2::Length() const
358358
{
359-
return (float)WWMath::Sqrt(Length2());
359+
return (float)WWMath::Hypot(X, Y);
360+
//return (float)WWMath::Sqrt(Length2());
360361
}
361362

362363
/**************************************************************************

Core/Libraries/Source/WWVegas/WWMath/wwmath.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ static WWINLINE float Acos(float val);
132132
static WWINLINE float Fast_Asin(float val);
133133
static WWINLINE float Asin(float val);
134134

135+
static WWINLINE float Hypot(float x, float y);
136+
static WWINLINE float Hypot(float x, float y, float z);
137+
static WWINLINE float Hypot(float x, float y, float z, float w);
138+
135139

136140
static WWINLINE float Atan(float x) { return static_cast<float>(atan(x)); }
137141
static WWINLINE float Atan2(float y,float x) { return static_cast<float>(atan2(y,x)); }
@@ -540,6 +544,15 @@ WWINLINE float WWMath::Asin(float val)
540544
return (float)asin(val);
541545
}
542546

547+
// ----------------------------------------------------------------------------
548+
// Hypothenus
549+
// ----------------------------------------------------------------------------
550+
551+
WWINLINE float WWMath::Hypot(float x, float y)
552+
{
553+
return (float)hypot(x, y);
554+
}
555+
543556
// ----------------------------------------------------------------------------
544557
// Sqrt
545558
// ----------------------------------------------------------------------------

Core/Tools/WW3D/pluglib/vector2.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,8 @@ inline Vector2 Normalize(const Vector2 & vec)
344344
*========================================================================*/
345345
inline float Vector2::Length() const
346346
{
347-
return (float)WWMath::Sqrt(Length2());
347+
return (float)WWMath::Hypot(X, Y);
348+
//return (float)WWMath::Sqrt(Length2());
348349
}
349350

350351
/**************************************************************************

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StealthDetectorUpdate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class StealthDetectorUpdateModuleData : public UpdateModuleData
5353
KindOfMaskType m_extraDetectKindofNot; ///< units must NOT match any kindof bits set here, in order to be detected
5454
Bool m_canDetectWhileGarrisoned;
5555
Bool m_canDetectWhileTransported;
56+
Bool m_requiresAllTriggers;
5657
ObjectStatusMaskType m_extraRequiredStatus;
5758
ObjectStatusMaskType m_extraForbiddenStatus;
5859
std::vector<AsciiString> m_extraRequiredCustomStatus;
@@ -77,6 +78,7 @@ class StealthDetectorUpdateModuleData : public UpdateModuleData
7778
m_extraForbiddenCustomStatus.clear();
7879
m_canDetectWhileGarrisoned = false;
7980
m_canDetectWhileTransported = false;
81+
m_requiresAllTriggers = false;
8082
}
8183

8284
static void buildFieldParse(MultiIniFieldParse& p);
@@ -97,6 +99,7 @@ class StealthDetectorUpdate : public UpdateModule
9799

98100
Bool isSDEnabled() const { return m_enabled; }
99101
void setSDEnabled( Bool enabled );
102+
void doUpgrade();
100103
virtual UpdateSleepTime update();
101104
virtual DisabledMaskType getDisabledTypesToProcess() const { return MAKE_DISABLED_MASK( DISABLED_HELD ); }
102105

GeneralsMD/Code/GameEngine/Source/Common/System/Trig.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ Real ASin(Real x)
7171
return asinf(x);
7272
}
7373

74+
Real Hypot(Real x, Real y)
75+
{
76+
return hypot(x, y);
77+
}
78+
7479
#ifdef REGENERATE_TRIG_TABLES
7580
void initTrig( void )
7681
{

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#include "GameLogic/Module/SpecialPowerModule.h"
106106
#include "GameLogic/Module/SpecialAbilityUpdate.h"
107107
#include "GameLogic/Module/StatusDamageHelper.h"
108+
#include "GameLogic/Module/StealthDetectorUpdate.h"
108109
#include "GameLogic/Module/StickyBombUpdate.h"
109110
#include "GameLogic/Module/SubdualDamageHelper.h"
110111
#include "GameLogic/Module/ChronoDamageHelper.h"
@@ -6049,6 +6050,7 @@ void Object::removeUpgrade( const UpgradeTemplate *upgradeT )
60496050
}
60506051
}
60516052

6053+
//-------------------------------------------------------------------------------------------------
60526054
void Object::doObjectUpgradeChecks()
60536055
{
60546056
if( testStatus(OBJECT_STATUS_UNDER_CONSTRUCTION) || testStatus( OBJECT_STATUS_DESTROYED ) || getControllingPlayer() == NULL )
@@ -6076,8 +6078,16 @@ void Object::doObjectUpgradeChecks()
60766078
{
60776079
getStealth()->refreshUpdate();
60786080
}
6081+
6082+
static NameKeyType key_StealthDetectorUpdate = NAMEKEY( "StealthDetectorUpdate" );
6083+
StealthDetectorUpdate *SDupdate = (StealthDetectorUpdate*)findUpdateModule( key_StealthDetectorUpdate );
6084+
if( SDupdate )
6085+
{
6086+
SDupdate->doUpgrade();
6087+
}
60796088
}
60806089

6090+
//-------------------------------------------------------------------------------------------------
60816091
void Object::doObjectStatusChecks()
60826092
{
60836093
if( testStatus(OBJECT_STATUS_UNDER_CONSTRUCTION) || testStatus( OBJECT_STATUS_DESTROYED ) )

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ static void rectToFourPoints(
354354
const CollideInfo *a, // z is ignored
355355
Coord2D pts[]
356356
);
357+
357358
static void testRotatedPointsAgainstRect(
358359
const Coord2D *pts, // an array of 4
359360
const CollideInfo *a,
@@ -368,10 +369,16 @@ static void testRotatedPointsAgainstRect(
368369
Int *avgTot,
369370
Real *minDistSqr
370371
);*/
372+
static Real fast_getBoundaryLength(
373+
Real x1,
374+
Real x2,
375+
Real y1,
376+
Real y2
377+
);
371378
static void testSphereAgainstRect(
372379
const Coord2D *pts, // an array of 4
373380
const CollideInfo *a,
374-
Real angle,
381+
//Real angle,
375382
Real &distance
376383
);
377384

@@ -561,11 +568,35 @@ static void testRotatedPointsAgainstRect(
561568
}
562569
}*/
563570

571+
//-----------------------------------------------------------------------------
572+
static Real fast_getBoundaryLength(Real x1, Real x2, Real y1, Real y2)
573+
{
574+
// Fast approximation of Boundary length, generally if one line has the length of only 10% or less of the other line, we take the longest line as the boundary.
575+
// Has an error rate of approx 0.5%.
576+
// Example: A line of dx = 5, and dy = 0.5, would give h = 5.025, we take dx directly
577+
Real dx = fabs(x1 - x2);
578+
Real dy = fabs(y1 - y2);
579+
580+
// Longest line and shortest between x and y
581+
Real dmax = max(dx, dy);
582+
Real dmin = min(dx, dy);
583+
Real maxTolerance = 0.1f * dmax;
584+
Real distTolerance = max(20.0f, 0.5f * maxTolerance);
585+
586+
// Two conditions:
587+
// - the difference must be less than a maximum of 20 units, or 5% of the maximum length (to be not more than 1 whole unit)
588+
// - the min length must be 10% or less than the max length
589+
if(dmin < distTolerance && dmin <= maxTolerance)
590+
return dmax;
591+
else
592+
return sqrtf(dx*dx + dy*dy);
593+
}
594+
564595
//-----------------------------------------------------------------------------
565596
static void testSphereAgainstRect(
566597
const Coord2D *pts, // an array of 4
567598
const CollideInfo *a,
568-
Real angle,
599+
//Real angle,
569600
Real &distance
570601
)
571602
{
@@ -624,43 +655,49 @@ static void testSphereAgainstRect(
624655
dist[i] = sqr(pts->x - a->position.x) + sqr(pts->y - a->position.y);
625656
}
626657

627-
Real minDist = HUGE_DIST_SQR;
628-
Int minIdx, lastMinIdx;
629-
for (Int i = 0; i < 4; i++)
658+
Real minDist;
659+
Int minIdx;
660+
Int lastMinIdx = -1;
661+
while( TRUE )
630662
{
631-
if(minDist > dist[i])
663+
minDist = HUGE_DIST_SQR;
664+
minIdx = 4;
665+
for (Int idx = 0; idx < 4; idx++)
666+
{
667+
if(minDist > dist[idx] && idx != lastMinIdx)
668+
{
669+
minDist = dist[idx];
670+
minIdx = idx;
671+
}
672+
}
673+
if(x1 == 0.0f && y1 == 0.0f)
632674
{
633-
minDist = dist[i];
634-
minIdx = i;
675+
x1 = points[minIdx].x;
676+
y1 = points[minIdx].y;
677+
lastMinIdx = minIdx;
635678
}
636-
}
637-
x1 = points[minIdx].x;
638-
y1 = points[minIdx].y;
639-
640-
lastMinIdx = minIdx;
641-
minIdx = 4;
642-
minDist = HUGE_DIST_SQR;
643-
for (Int i = 0; i < 4; i++)
644-
{
645-
if(minDist > dist[i] && i != lastMinIdx)
679+
else
646680
{
647-
minDist = dist[i];
648-
minIdx = i;
681+
x2 = points[minIdx].x;
682+
y2 = points[minIdx].y;
683+
break;
649684
}
650685
}
651-
x2 = points[minIdx].x;
652-
y2 = points[minIdx].y;
653686

654687
DEBUG_ASSERTCRASH(minIdx <= 3, ("Hmm, this should not be possible."));
655688

656689
// Get the Triangle length of all 3 points
657-
Real boundary_h_Sqr = sqr(x1 - x2) + sqr(y1 - y2);
658-
Real boundary_1_Sqr = sqr(x1 - a->position.x) + sqr(y1 - a->position.y);
659-
Real boundary_2_Sqr = sqr(x2 - a->position.x) + sqr(y2 - a->position.y);
690+
//Real boundary_h = fast_getBoundaryLength(x1, x2, y1, y2);
691+
//Real boundary_1 = fast_getBoundaryLength(x1, a->position.x, y1, a->position.y);
692+
//Real boundary_2 = fast_getBoundaryLength(x2, a->position.x, y2, a->position.y);
693+
694+
//Real boundary_h = sqrtf(sqr(x1 - x2) + sqr(y1 - y2));
695+
//Real boundary_1 = sqrtf(sqr(x1 - a->position.x) + sqr(y1 - a->position.y));
696+
//Real boundary_2 = sqrtf(sqr(x2 - a->position.x) + sqr(y2 - a->position.y));
660697

661-
Real boundary_h = sqrtf(boundary_h_Sqr);
662-
Real boundary_1 = sqrtf(boundary_1_Sqr);
663-
Real boundary_2 = sqrtf(boundary_2_Sqr);
698+
Real boundary_h = Hypot(fabs(x1-x2), fabs(y1-y2));
699+
Real boundary_1 = Hypot(fabs(x1 - a->position.x), fabs(y1 - a->position.y));
700+
Real boundary_2 = Hypot(fabs(x2 - a->position.x), fabs(y2 - a->position.y));
664701

665702
// Heron's formula
666703
Real semiPeri = (boundary_h + boundary_1 + boundary_2) * 0.5;
@@ -758,9 +795,8 @@ static Bool xy_collideTest_Rect_Circle(const CollideInfo *a, const CollideInfo *
758795
Coord2D pts[4];
759796
rectToFourPoints(a, pts);
760797

761-
Real dir = atan2(diff.y, diff.x);
762798
Real distance = 0.0f;
763-
testSphereAgainstRect(pts, b, dir, distance);
799+
testSphereAgainstRect(pts, b, distance);
764800

765801
//DEBUG_LOG(("Radius: %f Distance: %f", b->geom.getMajorRadius(), distance));
766802

@@ -3707,7 +3743,7 @@ Object *PartitionManager::getClosestObjects(
37073743
useNewStructureCheck = TRUE;
37083744
GeometryInfo geometry( GEOMETRY_SPHERE, TRUE, maxDist, maxDist, maxDist );
37093745
if(!geomCollidesWithGeom(objPos, geometry, 0.0f, thisObj->getPosition(), geomInfo, thisObj->getOrientation(), distProc == distCalcProc_BoundaryAndBoundary_2D ? SKIP_HEIGHT_CHECK : BOUNDARY_HEIGHT_CHECK, &thisDistSqr))
3710-
continue;
3746+
continue;
37113747
//DEBUG_LOG(("geomCollidesWithGeom Not Passed. Object: %s Radius: %f, DistSqr: %f", thisObj->getTemplate()->getName().str(), maxDist, thisDistSqr));
37123748

37133749
//DEBUG_LOG(("Passed. Object: %s Radius: %f, DistSqr: %f", thisObj->getTemplate()->getName().str(), maxDist, thisDistSqr));
@@ -6897,9 +6933,8 @@ Bool PartitionFilterAcceptByObjectCustomStatus::allow(Object *objOther)
68976933
{
68986934
for (std::vector<AsciiString>::const_iterator it = m_mustBeClear.begin(); it != m_mustBeClear.end(); ++it)
68996935
{
6900-
allow = objOther->testCustomStatus( *it );
6901-
if(!allow)
6902-
break;
6936+
if(objOther->testCustomStatus( *it ))
6937+
return FALSE;
69036938
}
69046939
}
69056940
return allow;

0 commit comments

Comments
 (0)