Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion Core/GameEngine/Include/Common/BezierSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,34 @@

#define USUAL_TOLERANCE 1.0f

#ifndef SAGE_USE_GLM
#ifdef SAGE_USE_GLM
// GeneralsX @bugfix Copilot 15/08/2026 Match D3DX operation ordering for deterministic Bezier trajectories.
class BezierMath
{
public:
static glm::vec4 GLMVec4Transform(const glm::vec4& v, const glm::mat4& m)
{
#if USE_DETERMINISTIC_MATH
return glm::vec4(
((v.x * m[0][0] + v.y * m[1][0]) + v.z * m[2][0]) + v.w * m[3][0],
((v.x * m[0][1] + v.y * m[1][1]) + v.z * m[2][1]) + v.w * m[3][1],
((v.x * m[0][2] + v.y * m[1][2]) + v.z * m[2][2]) + v.w * m[3][2],
((v.x * m[0][3] + v.y * m[1][3]) + v.z * m[2][3]) + v.w * m[3][3]);
#else
return m * v;
#endif
}

static float GLMVec4Dot(const glm::vec4& a, const glm::vec4& b)
{
#if USE_DETERMINISTIC_MATH
return ((a.x * b.x + a.y * b.y) + a.z * b.z) + a.w * b.w;
#else
return glm::dot(a, b);
#endif
}
};
#else
class BezierMath
{
public:
Expand Down
7 changes: 3 additions & 4 deletions Core/GameEngine/Source/Common/Bezier/BezFwdIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ void BezFwdIterator::start()
glm::vec4 pz(mBezSeg.m_controlPoints[0].z, mBezSeg.m_controlPoints[1].z, mBezSeg.m_controlPoints[2].z, mBezSeg.m_controlPoints[3].z);

glm::vec4 cVec[3];
cVec[0] = BezierSegment::s_bezBasisMatrix * px;
cVec[1] = BezierSegment::s_bezBasisMatrix * py;
cVec[2] = BezierSegment::s_bezBasisMatrix * pz;
cVec[0] = BezierMath::GLMVec4Transform(px, BezierSegment::s_bezBasisMatrix);
cVec[1] = BezierMath::GLMVec4Transform(py, BezierSegment::s_bezBasisMatrix);
cVec[2] = BezierMath::GLMVec4Transform(pz, BezierSegment::s_bezBasisMatrix);
#endif

mCurrPoint = mBezSeg.m_controlPoints[0];
Expand Down Expand Up @@ -129,4 +129,3 @@ void BezFwdIterator::next()

++mStep;
}

8 changes: 4 additions & 4 deletions Core/GameEngine/Source/Common/Bezier/BezierSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ void BezierSegment::evaluateBezSegmentAtT(Real tValue, Coord3D *outResult) const
glm::vec4 yCoords(m_controlPoints[0].y, m_controlPoints[1].y, m_controlPoints[2].y, m_controlPoints[3].y);
glm::vec4 zCoords(m_controlPoints[0].z, m_controlPoints[1].z, m_controlPoints[2].z, m_controlPoints[3].z);

glm::vec4 tResult = BezierSegment::s_bezBasisMatrix * tVec;
glm::vec4 tResult = BezierMath::GLMVec4Transform(tVec, BezierSegment::s_bezBasisMatrix);

outResult->x = glm::dot(xCoords, tResult);
outResult->y = glm::dot(yCoords, tResult);
outResult->z = glm::dot(zCoords, tResult);
outResult->x = BezierMath::GLMVec4Dot(xCoords, tResult);
outResult->y = BezierMath::GLMVec4Dot(yCoords, tResult);
outResult->z = BezierMath::GLMVec4Dot(zCoords, tResult);
#endif
}

Expand Down
5 changes: 5 additions & 0 deletions docs/WORKLOG/2026-08-DIARY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# August 2026

## 15/08/2026
### Match Cross-Platform Bezier Trajectories
- Fixed deterministic projectile paths using GLM's platform-dependent matrix and dot-product evaluation order while Windows used explicitly ordered D3DX-compatible scalar operations.
- Applied the same operation order to GLM transforms and dot products so projectile positions remain bit-identical across macOS and Windows.

## 14/08/2026
### Restore Windows LAN Map Compatibility
- Kept spaces literal when serializing map names so TheSuperHackers Windows builds can resolve official maps such as Twilight Flame.
Expand Down
Loading