Skip to content

Commit

Permalink
Update vector processing (#6438)
Browse files Browse the repository at this point in the history
Add metamethods and utility functions for Vectors and Quaternions to simplify and clean up the code involving operations with them.

Co-authored-by: G C <[email protected]>
  • Loading branch information
lL1l1 and Hdt80bro authored Oct 23, 2024
1 parent d1e6a39 commit c490f7c
Show file tree
Hide file tree
Showing 21 changed files with 1,047 additions and 722 deletions.
1 change: 1 addition & 0 deletions changelog/snippets/fix.6438.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- (#6438) Fix `TerrainUtils.GetTerrainSlopeAngles` returning roll on the -Z axis instead of the +Z axis. Previously, this required the roll to be negated when used to orient objects such as units with the terrain. Now roll no longer needs to be negated.
14 changes: 14 additions & 0 deletions changelog/snippets/other.6438.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- (#5061, #6438) Add metamethods and utility functions for Vectors and Quaternions to simplify and clean up the code involving operations with them.
- This **removes** the file `/lua/shared/quaternions.lua`, which was added in #4768 (Mar 4, 2023), so mods that use that file will have to be updated.
- The metamethods (defined globally in `/lua/system/utils.lua`) include:
- Vector/Vector2 addition/subtraction/negation
- Vector/Vector2 * Scalar multiplication
- Quaternion/Vector * Vector/Quaternion multiplication
- Vector * Vector multiplication (cross product)
- Since these are metamethods, they work on all instances of Vector/Vector2/Quaternion, without having to import anything.
- The utility functions (have to be imported from `/lua/utilities.lua`) include:
- Faster Lua versions of VDist2, VDist2Sq, VDot
- `QuatFromRotation`: Creates a quaternion from an orientation axis and rotation angle.
- `QuatFromXZDirection`: Returns the orientation quaternion given an XZ direction
- `TranslateInXZDirection`: Translates the XZ coordinates of a position by a length in a given quaternion orientation.
- `RotateVectorByQuat`: Rotates a vector representing a 3D point by a quaternion rotation.
73 changes: 49 additions & 24 deletions engine/Core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,33 @@
---@class FileName: string, stringlib
---@operator concat(FileName | string): FileName

---@class Quaternion
---@field [1] number # y
---@field [2] number # z
---@field [3] number # x
---@field [4] number # w

---@class Vector
---@class VectorBase
---@field [1] number # x
---@field [2] number # y (up)
---@field [2] number # y
---@field x number
---@field y number

---@class Quaternion : VectorBase
---@operator mul(Quaternion): Quaternion
---@operator mul(Vector): Quaternion
---@operator mul(number): Quaternion
---@field [3] number # z
---@field [4] number # w
---@field z number

---@class Vector : VectorBase
---@operator add(Vector): Vector
---@operator mul(Quaternion): Quaternion
---@operator mul(Vector): Vector
---@operator mul(number): Vector
---@operator unm: Vector
---@field [3] number # z
---@field x number # east/west
---@field y number # up/down
---@field z number # north/south
---@field z number

---@class Vector2
---@field [1] number # x
---@field [2] number # y
---@class Vector2 : VectorBase
---@operator add(Vector2): Vector2
---@operator mul(number): Vector2
---@operator unm: Vector2

--- A point-to-point based rectangle, where the first point is usually in the top left corner
---@class Rectangle
Expand Down Expand Up @@ -142,6 +152,12 @@ end
---@return Quaternion
function EulerToQuaternion(roll, pitch, yaw)
end
-- {
-- sin(roll/2) * cos(pitch/2) * cos(yaw/2) - cos(roll/2) * sin(pitch/2) * sin(yaw/2), -- x
-- cos(roll/2) * sin(pitch/2) * cos(yaw/2) + sin(roll/2) * cos(pitch/2) * sin(yaw/2), -- y
-- cos(roll/2) * cos(pitch/2) * sin(yaw/2) - sin(roll/2) * sin(pitch/2) * cos(yaw/2), -- z
-- cos(roll/2) * cos(pitch/2) * cos(yaw/2) + sin(roll/2) * sin(pitch/2) * sin(yaw/2) -- w
-- }

--- collapses all relative `/./` or `/../` directory names from a path
---@param fullPath FileName
Expand Down Expand Up @@ -434,20 +450,23 @@ function Trace(enable)
end

--- Adds vector `b` to vector `a`
---@deprecated It is faster to compute it in Lua with `Vector`
---@param a Vector
---@param b Vector
---@return Vector
function VAdd(a, b)
end

--- Subtracts vector `b` from vector `a`
---@deprecated It is faster to compute it in Lua with `Vector`
---@param a Vector
---@param b Vector
---@return Vector
function VDiff(a, b)
end

--- Computes the distance between two points
--- Computes the distance between two points.
---@deprecated It is faster to compute it in Lua.
---@param x1 number
---@param y1 number
---@param x2 number
Expand All @@ -456,7 +475,8 @@ end
function VDist2(x1, y1, x2, y2)
end

--- Computes the squared distance between two points
--- Computes the squared distance between two points.
---@deprecated It is faster to compute it in Lua.
---@param x1 number
---@param y1 number
---@param x2 number
Expand All @@ -465,51 +485,56 @@ end
function VDist2Sq(x1, y1, x2, y2)
end

--- Computes the distance between the vectors `a` and `b`
--- Computes the distance between vectors `a` and `b`
---@param a Vector
---@param b Vector
---@return number
function VDist3(a, b)
end

--- Computes the squared distance between the vectors `a` and `b`
--- Computes the squared distance between vectors `a` and `b`
---@deprecated It is faster to compute it in Lua
---@param a Vector
---@param b Vector
---@return number
function VDist3Sq(a, b)
end

--- Computes the dot product between the vectors `a` and `b`
--- Computes the dot product between vectors `a` and `b`,
--- or `a[1]*b[1] + a[2]*b[2] + a[3]*b[3]`
---@deprecated It is faster to compute it in Lua
---@param a Vector
---@param b Vector
---@return number
function VDot(a, b)
end

--- Scales the vector `v` with the scalar `s`
--- Scales the vector `v` by the scalar `s`
---@deprecated It is faster to compute it in Lua with `Vector`
---@param v Vector
---@param s number
---@return Vector
function VMult(v, s)
end

--- Computes the vector perpendicular to the plane described by the vectors `a` and `b`
--- Computes the component perpendicular to the XZ plane in the cross product of `a` across `b`,
--- or `a[3] * b[1] - a[1] * b[3]`
---@deprecated It is faster to compute it in Lua
---@param a Vector
---@param b Vector
---@return Vector
---@return number
function VPerpDot(a, b)
end

--- Populates a new table with the corresponding meta table
--- Creates a new 3-vector with the corresponding metatable
---@param x number
---@param y number
---@param z number
---@return Vector
function Vector(x, y, z)
end

--- Populates a new table with the corresponding meta table
--- Creates a new 2-vector with the corresponding metatable
---@param x number
---@param y number
---@return Vector2
Expand Down
3 changes: 2 additions & 1 deletion engine/Sim.lua
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ end
---@see CreateUnitHPR() # heading-pitch-roll version
---@param blueprintId string
---@param army Army
---@param layer? number
---@param layer Layer
---@param x number
---@param z number
---@param heading number
Expand Down Expand Up @@ -670,6 +670,7 @@ end
function GetUnitBlueprintByName(bpName)
end

---@overload fun(x1: number, z1: number, x2: number, z2: number): Unit[] | nil
--- retrieves all units in a rectangle
---@param rectangle Rectangle
---@return Unit[] | nil
Expand Down
86 changes: 86 additions & 0 deletions lua/benchmarking/benchmarks/VDist2.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
-- UpvaluedEngineVDist2OnLocals: 0.043102264404297
-- UpvaluedEngineVDist2SqOnLocals: 0.040153503417969
-- UpvaluedLuaVDist2OnLocals: 0.029483795166016
-- UpvaluedLuaVDist2SqOnLocals: 0.014518737792969

-- Conclusion: Lua is much faster, especially when skipping the square root (useful in distance comparisons).

local outerLoop = 1000000

function UpvaluedEngineVDist2OnLocals()
local p1 = Random()*1000
local p2 = Random()*1000
local p3 = Random()*1000
local p4 = Random()*1000

-- upvalue
local VDist2 = VDist2

local start = GetSystemTimeSecondsOnlyForProfileUse()

for i=1, outerLoop do
local dist = VDist2(p1, p2, p3, p4)
end

local final = GetSystemTimeSecondsOnlyForProfileUse()

return final - start
end
function UpvaluedEngineVDist2SqOnLocals()
local p1 = Random()*1000
local p2 = Random()*1000
local p3 = Random()*1000
local p4 = Random()*1000

-- upvalue
local VDist2Sq = VDist2Sq

local start = GetSystemTimeSecondsOnlyForProfileUse()

for i=1, outerLoop do
local dist = VDist2Sq(p1, p2, p3, p4)
end

local final = GetSystemTimeSecondsOnlyForProfileUse()

return final - start
end
function UpvaluedLuaVDist2OnLocals()
local p1 = Random()*1000
local p2 = Random()*1000
local p3 = Random()*1000
local p4 = Random()*1000

-- upvalue
local MathSqrt = math.sqrt

local start = GetSystemTimeSecondsOnlyForProfileUse()

for i=1, outerLoop do
local d1 = p3 - p1
local d2 = p4 - p2
local dist = MathSqrt(d1 * d1 + d2 * d2)
end

local final = GetSystemTimeSecondsOnlyForProfileUse()

return final - start
end
function UpvaluedLuaVDist2SqOnLocals()
local p1 = Random()*1000
local p2 = Random()*1000
local p3 = Random()*1000
local p4 = Random()*1000

local start = GetSystemTimeSecondsOnlyForProfileUse()

for i=1, outerLoop do
local d1 = p3 - p1
local d2 = p4 - p2
local dist = d1 * d1 + d2 * d2
end

local final = GetSystemTimeSecondsOnlyForProfileUse()

return final - start
end
Loading

0 comments on commit c490f7c

Please sign in to comment.