Skip to content

Conversation

@xezon
Copy link

@xezon xezon commented Jan 29, 2026

This change optimizes the angleBetween() function a bit by removing 2 redundant length function calls, which each contain

  • 1 square root
  • 2 multiplications
  • 1 addition

It is used by the Particle System update.

Not measured, because impact is expected very minor.

@xezon xezon added Minor Severity: Minor < Major < Critical < Blocker Performance Is a performance concern Gen Relates to Generals ZH Relates to Zero Hour labels Jan 29, 2026
@greptile-apps
Copy link

greptile-apps bot commented Jan 29, 2026

Greptile Overview

Greptile Summary

Optimized the angleBetween() function by caching vector length calculations, eliminating 2 redundant calls to Coord2D::length(). Each eliminated call saves 1 sqrt operation, 2 multiplications, and 1 addition.

Key changes:

  • Computed lengthA and lengthB once upfront instead of calling length() 4 times total
  • Removed redundant null pointer checks (the function is file-static and only called with stack-allocated objects)
  • Fixed typo: "dotproduct" → "dot product"
  • Changed return literal from 0.0 to 0.0f for consistency

The optimization is mathematically correct and maintains the same behavior for all valid inputs. The null pointer check removal is safe given the single call site at ParticleSys.cpp:415 passes stack-allocated addresses.

Confidence Score: 5/5

  • This PR is safe to merge with no risk - it's a straightforward performance optimization
  • The change is a simple, mathematically sound optimization that reduces redundant calculations without altering correctness. The removal of null checks is safe given the function's file-local scope and single call site that never passes nulls
  • No files require special attention

Important Files Changed

Filename Overview
Core/GameEngine/Source/GameClient/System/ParticleSys.cpp Optimized angleBetween() by caching length calculations, eliminating 2 redundant sqrt operations per call

Sequence Diagram

sequenceDiagram
    participant Particle as Particle::updateParticle()
    participant angleBetween as angleBetween()
    participant Coord2D as Coord2D::length()
    
    Note over Particle: m_particleUpTowardsEmitter == true
    Particle->>Particle: Create upVec {0, 1}
    Particle->>Particle: Create emitterDir from positions
    Particle->>angleBetween: angleBetween(&upVec, &emitterDir)
    
    Note over angleBetween: Before optimization:<br/>4 calls to length()
    Note over angleBetween: After optimization:<br/>2 calls to length()
    
    angleBetween->>Coord2D: vecA->length()
    Coord2D-->>angleBetween: lengthA
    angleBetween->>Coord2D: vecB->length()
    Coord2D-->>angleBetween: lengthB
    
    Note over angleBetween: Check if both lengths != 0
    
    alt Both lengths are zero
        angleBetween-->>Particle: return 0.0f
    else Valid vectors
        Note over angleBetween: Calculate dot product<br/>Calculate cosTheta<br/>Calculate theta using ACos
        angleBetween-->>Particle: return ±theta
    end
    
    Particle->>Particle: Set m_angleZ = theta + PI
Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker Performance Is a performance concern ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant