diff --git a/.gitignore b/.gitignore index c997b98..3236ef3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .gemini/ *.DS_Store build*/ +_diagnostics/ # conductor/ gha-creds-*.json xcuserdata/ diff --git a/Makefile b/Makefile index 336a7fe..ab592ac 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ DOCS_VERSION_PATH ?= main HOSTING_BASE_PATH ?= $(REPO_NAME)/$(DOCS_VERSION_PATH) # Targets -.PHONY: setup lint lint-fix test test-coverage clean pre-commit docs docs-preview docs-generate docs-coverage +.PHONY: setup lint lint-fix test test-coverage clean pre-commit docs docs-preview docs-generate docs-coverage profile-stats benchmark-commits setup: @echo "Detected Package Swift Version: $(PACKAGE_SWIFT_VERSION)" @@ -75,3 +75,12 @@ clean: swift package clean rm -rf .build rm -rf .swiftpm + +profile-stats: + chmod +x Scripts/profile-compiler-stats.sh + ./Scripts/profile-compiler-stats.sh + +benchmark-commits: + chmod +x Scripts/profile-compiler-stats.sh + chmod +x Scripts/benchmark-commits.py + python3 Scripts/benchmark-commits.py diff --git a/Scripts/benchmark-commits.py b/Scripts/benchmark-commits.py new file mode 100755 index 0000000..e8f37cc --- /dev/null +++ b/Scripts/benchmark-commits.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +import subprocess +import json +import glob +import os +import sys +import argparse + +def main(): + parser = argparse.ArgumentParser(description="Benchmark compiler stats across git commits.") + parser.add_argument("--base", default="origin/master", help="Base commit or branch to start benchmark from") + parser.add_argument("--runs", type=int, default=2, help="Number of benchmark runs per commit") + parser.add_argument("--output", default="_diagnostics/commit_stats_multi.json", help="Path to output JSON result file") + args = parser.parse_args() + + # Determine root directory of git repository + repo_root = subprocess.check_output(["git", "rev-parse", "--show-toplevel"], text=True).strip() + os.chdir(repo_root) + + profile_script = os.path.join(repo_root, "Scripts", "profile-compiler-stats.sh") + if not os.path.exists(profile_script): + print(f"Error: Profile script not found at {profile_script}") + sys.exit(1) + + # Get current branch + current_branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], text=True).strip() + + # Get commits from base to HEAD + try: + log_output = subprocess.check_output( + ["git", "log", f"{args.base}..HEAD", "--oneline", "--reverse"], + text=True + ).strip() + except subprocess.CalledProcessError as e: + print(f"Error fetching git commit log: {e}") + sys.exit(1) + + commits = [(args.base, f"Baseline ({args.base})")] + if log_output: + for line in log_output.splitlines(): + parts = line.split(" ", 1) + sha = parts[0] + msg = parts[1] if len(parts) > 1 else "" + commits.append((sha, msg)) + + results = [] + + try: + for commit_sha, commit_msg in commits: + print(f"\n==================================================") + print(f"Checking out {commit_sha}: {commit_msg}") + print(f"==================================================") + + subprocess.run(["git", "checkout", "-f", commit_sha], check=True) + + runs = [] + for run_idx in range(1, args.runs + 1): + print(f"--- Run {run_idx}/{args.runs} for {commit_sha} ---") + + res = subprocess.run([profile_script], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + + stats_dir = "_diagnostics/stats" + json_files = glob.glob(os.path.join(stats_dir, "stats-*.json")) + + total_instructions = 0 + total_source_lines = 0 + total_typechecking_wall = 0.0 + total_silgen_wall = 0.0 + total_frontend_wall = 0.0 + + frontend_stats = [] + + for filepath in json_files: + try: + with open(filepath, 'r') as f: + data = json.load(f) + + instructions = data.get("Frontend.NumInstructionsExecuted", 0) + lines = data.get("AST.NumSourceLines", 0) + + tc_wall = data.get("time.swift.perform-whole-module-type-checking.wall", 0.0) + if tc_wall == 0.0: + tc_wall = data.get("time.swift.perform-sema.wall", 0.0) + if tc_wall == 0.0: + tc_wall = data.get("time.swift.Type checking and Semantic analysis.wall", 0.0) + + sil_wall = data.get("time.swift.SILGen.wall", 0.0) + + fe_wall = 0.0 + for k, v in data.items(): + if k.startswith("time.swift-frontend.") and k.endswith(".wall"): + fe_wall = v + break + + total_instructions += instructions + total_source_lines += lines + total_typechecking_wall += tc_wall + total_silgen_wall += sil_wall + total_frontend_wall += fe_wall + + filename = os.path.basename(filepath) + parts = filename.split("swift-frontend-FirebladeMath-") + swift_file = parts[1].split("-arm64")[0] if len(parts) > 1 else filename + + if instructions > 0: + frontend_stats.append({ + "file": swift_file, + "instructions": instructions, + "lines": lines, + "tc_wall": tc_wall, + "fe_wall": fe_wall + }) + except Exception as e: + print(f"Error parsing {filepath}: {e}") + + frontend_stats.sort(key=lambda x: x["instructions"], reverse=True) + + runs.append({ + "run_index": run_idx, + "total_instructions": total_instructions, + "total_source_lines": total_source_lines, + "typechecking_wall": total_typechecking_wall, + "frontend_wall": total_frontend_wall, + "silgen_wall": total_silgen_wall, + "top_hotspots": frontend_stats[:5] + }) + + avg_instructions = sum(r["total_instructions"] for r in runs) / len(runs) if runs else 0 + avg_frontend_wall = sum(r["frontend_wall"] for r in runs) / len(runs) if runs else 0 + + results.append({ + "commit_sha": commit_sha, + "commit_msg": commit_msg, + "runs": runs, + "avg_instructions": avg_instructions, + "avg_frontend_wall": avg_frontend_wall + }) + + finally: + # Always restore original branch + subprocess.run(["git", "checkout", "-f", current_branch], check=True) + + os.makedirs(os.path.dirname(os.path.abspath(args.output)), exist_ok=True) + with open(args.output, 'w') as f: + json.dump(results, f, indent=2) + + print(f"\nBenchmarking complete. Saved results to {args.output}") + +if __name__ == "__main__": + main() diff --git a/Scripts/profile-compiler-stats.sh b/Scripts/profile-compiler-stats.sh new file mode 100755 index 0000000..4d6d52f --- /dev/null +++ b/Scripts/profile-compiler-stats.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +set -euo pipefail + +STATS_DIR="_diagnostics/stats" + +echo "=== Cleaning build directory and previous diagnostics ===" +rm -rf "${STATS_DIR}" .build +mkdir -p "${STATS_DIR}" + +echo "=== Building project with compiler statistics enabled ===" +swift build --disable-sandbox -Xswiftc -stats-output-dir -Xswiftc "${STATS_DIR}" + +echo "=== Analyzing compiler stats ===" +python3 - "${STATS_DIR}" << 'EOF' +import json +import glob +import os +import sys + +stats_dir = sys.argv[1] +json_files = glob.glob(os.path.join(stats_dir, "stats-*.json")) + +if not json_files: + print(f"No stat JSON files found in {stats_dir}") + sys.exit(1) + +total_instructions = 0 +total_source_lines = 0 +total_typechecking_wall = 0.0 +total_silgen_wall = 0.0 +total_frontend_wall = 0.0 + +frontend_stats = [] + +for filepath in json_files: + try: + with open(filepath, 'r') as f: + data = json.load(f) + + instructions = data.get("Frontend.NumInstructionsExecuted", 0) + lines = data.get("AST.NumSourceLines", 0) + + # Sema / Type checking time + tc_wall = data.get("time.swift.perform-whole-module-type-checking.wall", 0.0) + if tc_wall == 0.0: + tc_wall = data.get("time.swift.perform-sema.wall", 0.0) + if tc_wall == 0.0: + tc_wall = data.get("time.swift.Type checking and Semantic analysis.wall", 0.0) + + sil_wall = data.get("time.swift.SILGen.wall", 0.0) + + # Find frontend wall key + fe_wall = 0.0 + for k, v in data.items(): + if k.startswith("time.swift-frontend.") and k.endswith(".wall"): + fe_wall = v + break + + total_instructions += instructions + total_source_lines += lines + total_typechecking_wall += tc_wall + total_silgen_wall += sil_wall + total_frontend_wall += fe_wall + + filename = os.path.basename(filepath) + # Find swift file name from JSON filename if present + parts = filename.split("swift-frontend-FirebladeMath-") + swift_file = parts[1].split("-arm64")[0] if len(parts) > 1 else filename + + if instructions > 0: + frontend_stats.append({ + "file": swift_file, + "instructions": instructions, + "lines": lines, + "tc_wall": tc_wall, + "fe_wall": fe_wall + }) + except Exception as e: + print(f"Error reading {filepath}: {e}") + +# Sort by instructions descending +frontend_stats.sort(key=lambda x: x["instructions"], reverse=True) + +print("\n--------------------------------------------------------------------------------") +print(f"{'Swift File':<40} | {'Instructions':<15} | {'Lines':<8} | {'Sema Wall (s)':<12}") +print("--------------------------------------------------------------------------------") +for item in frontend_stats[:10]: + print(f"{item['file']:<40} | {item['instructions']:>15,} | {item['lines']:>8,} | {item['tc_wall']:>12.3f}") + +print("--------------------------------------------------------------------------------") +print("Compiler Statistics Summary:") +print("--------------------------------------------------") +print(f"Total Instructions Executed : {total_instructions:,}") +print(f"Total AST Source Lines : {total_source_lines:,}") +if total_source_lines > 0: + print(f"Instructions / Source Line : {total_instructions / total_source_lines:,.1f}") +print(f"Type-Checking Wall Time : {total_typechecking_wall:.3f} s") +print(f"Total Frontend Wall Time : {total_frontend_wall:.3f} s") +print(f"SILGen Wall Time : {total_silgen_wall:.3f} s") +print("--------------------------------------------------\n") +EOF diff --git a/Sources/FirebladeMath/Constants.swift b/Sources/FirebladeMath/Constants.swift index 59e15af..1c7b303 100644 --- a/Sources/FirebladeMath/Constants.swift +++ b/Sources/FirebladeMath/Constants.swift @@ -1,21 +1,21 @@ /// Factor to convert degrees to radians (Double). -public let kDegreeToRadians64 = Double.pi / 180.0 +@inlinable public var kDegreeToRadians64: Double { Double.pi / 180.0 } /// Factor to convert degrees to radians (Float). -public let kDegreeToRadians32 = Float(kDegreeToRadians64) +@inlinable public var kDegreeToRadians32: Float { Float(Double.pi / 180.0) } /// Factor to convert radians to degrees (Double). -public let kRadiansToDegree64: Double = 180.0 / Double.pi +@inlinable public var kRadiansToDegree64: Double { 180.0 / Double.pi } /// Factor to convert radians to degrees (Float). -public let kRadiansToDegree32 = Float(kRadiansToDegree64) +@inlinable public var kRadiansToDegree32: Float { Float(180.0 / Double.pi) } /// Extension to add constants to Float. extension Float { /// Half of Pi (π/2). - public static let halfPi = Float(Double.halfPi) + @inlinable public static var halfPi: Float { Float.pi * 0.5 } } /// Extension to add constants to Double. extension Double { /// Half of Pi (π/2). - public static let halfPi: Double = .pi * 0.5 + @inlinable public static var halfPi: Double { Double.pi * 0.5 } } diff --git a/Sources/FirebladeMath/Functions/abs.swift b/Sources/FirebladeMath/Functions/abs.swift index 1d3015f..00796cd 100644 --- a/Sources/FirebladeMath/Functions/abs.swift +++ b/Sources/FirebladeMath/Functions/abs.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the absolute value of a floating point value x. @@ -11,7 +11,13 @@ import Glibc /// - Parameter x: floating point value /// - Returns: If successful, returns the absolute value of x (|x|). The value returned is exact and does not depend on any rounding modes. public func abs(_ x: Float) -> Float { - fabsf(x) + #if canImport(Darwin) + return Darwin.fabsf(x) + #elseif canImport(Glibc) + return Glibc.fabsf(x) + #else + return Foundation.fabsf(x) + #endif } /// Computes the absolute value of a floating point value x. diff --git a/Sources/FirebladeMath/Functions/acos.swift b/Sources/FirebladeMath/Functions/acos.swift index f495dc0..356de8b 100644 --- a/Sources/FirebladeMath/Functions/acos.swift +++ b/Sources/FirebladeMath/Functions/acos.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the principal value of the arc cosine of x. diff --git a/Sources/FirebladeMath/Functions/acosh.swift b/Sources/FirebladeMath/Functions/acosh.swift index 51bd137..f902fbe 100644 --- a/Sources/FirebladeMath/Functions/acosh.swift +++ b/Sources/FirebladeMath/Functions/acosh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the inverse hyperbolic cosine of x. diff --git a/Sources/FirebladeMath/Functions/asin.swift b/Sources/FirebladeMath/Functions/asin.swift index 2037b26..55f5cf0 100644 --- a/Sources/FirebladeMath/Functions/asin.swift +++ b/Sources/FirebladeMath/Functions/asin.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the principal values of the arc sine of x. diff --git a/Sources/FirebladeMath/Functions/asinh.swift b/Sources/FirebladeMath/Functions/asinh.swift index df98850..8489be7 100644 --- a/Sources/FirebladeMath/Functions/asinh.swift +++ b/Sources/FirebladeMath/Functions/asinh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the inverse hyperbolic sine of x. diff --git a/Sources/FirebladeMath/Functions/atan.swift b/Sources/FirebladeMath/Functions/atan.swift index d1761ce..8595385 100644 --- a/Sources/FirebladeMath/Functions/atan.swift +++ b/Sources/FirebladeMath/Functions/atan.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the principal value of the arc tangent of x. @@ -11,6 +11,7 @@ import Glibc /// - Parameter x: floating point value /// - Returns: If no errors occur, the arc tangent of x (arctan(x)) in the range [-π/2;+π/2] radians, is returned. /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func atan(_ x: Double) -> Double { #if canImport(Darwin) return Darwin.atan(x) @@ -26,6 +27,7 @@ public func atan(_ x: Double) -> Double { /// - Parameter x: floating point value /// - Returns: If no errors occur, the arc tangent of x (arctan(x)) in the range [-π/2;+π/2] radians, is returned. /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func atan(_ x: Float) -> Float { #if canImport(Darwin) return Darwin.atanf(x) diff --git a/Sources/FirebladeMath/Functions/atan2.swift b/Sources/FirebladeMath/Functions/atan2.swift index 4c21474..1df0d09 100644 --- a/Sources/FirebladeMath/Functions/atan2.swift +++ b/Sources/FirebladeMath/Functions/atan2.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// The atan2() function computes the principal value of the arc tangent of y/x, diff --git a/Sources/FirebladeMath/Functions/atanh.swift b/Sources/FirebladeMath/Functions/atanh.swift index c3443cd..082b9e3 100644 --- a/Sources/FirebladeMath/Functions/atanh.swift +++ b/Sources/FirebladeMath/Functions/atanh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the inverse hyperbolic tangent of x. diff --git a/Sources/FirebladeMath/Functions/axis.swift b/Sources/FirebladeMath/Functions/axis.swift index 5b05930..97c5954 100644 --- a/Sources/FirebladeMath/Functions/axis.swift +++ b/Sources/FirebladeMath/Functions/axis.swift @@ -14,9 +14,10 @@ import func simd.simd_axis @inlinable public func axis(_ quat: Quat4f) -> SIMD3 { #if FRB_MATH_USE_SIMD - return simd.simd_axis(quat.storage) + return simd_axis(quat.storage) #else - return normalize(Vec3f(quat.x, quat.y, quat.z)) + let vec = Vec3f(quat.x, quat.y, quat.z) + return normalize(vec) #endif } @@ -26,8 +27,9 @@ public func axis(_ quat: Quat4f) -> SIMD3 { @inlinable public func axis(_ quat: Quat4d) -> SIMD3 { #if FRB_MATH_USE_SIMD - return simd.simd_axis(quat.storage) + return simd_axis(quat.storage) #else - return normalize(Vec3d(quat.x, quat.y, quat.z)) + let vec = Vec3d(quat.x, quat.y, quat.z) + return normalize(vec) #endif } diff --git a/Sources/FirebladeMath/Functions/ceil.swift b/Sources/FirebladeMath/Functions/ceil.swift index fce9549..2056e50 100644 --- a/Sources/FirebladeMath/Functions/ceil.swift +++ b/Sources/FirebladeMath/Functions/ceil.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the smallest integer value not less than x. diff --git a/Sources/FirebladeMath/Functions/clamp.swift b/Sources/FirebladeMath/Functions/clamp.swift index 09fd551..efd06df 100644 --- a/Sources/FirebladeMath/Functions/clamp.swift +++ b/Sources/FirebladeMath/Functions/clamp.swift @@ -9,8 +9,9 @@ import func simd.simd_clamp /// - minVal: min range bound /// - maxVal: max range bound /// - Returns: x clamped to the range [min, max] +@inlinable public func clamp(_ x: Value, min minVal: Value, max maxVal: Value) -> Value { - min(max(x, minVal), maxVal) + Swift.min(Swift.max(x, minVal), maxVal) } /// x clamped to the range [min, max], such that min ≤ x ≤ max. @@ -20,11 +21,12 @@ public func clamp(_ x: Value, min minVal: Value, max maxVal: /// - minVal: min range bound /// - maxVal: max range bound /// - Returns: x clamped to the range [min, max] +@inlinable public func clamp(_ x: Double, _ minVal: Double, _ maxVal: Double) -> Double { #if FRB_MATH_USE_SIMD return simd_clamp(x, minVal, maxVal) #else - return min(max(x, minVal), maxVal) + return FirebladeMath.min(FirebladeMath.max(x, minVal), maxVal) #endif } @@ -35,11 +37,12 @@ public func clamp(_ x: Double, _ minVal: Double, _ maxVal: Double) -> Double { /// - minVal: min range bound /// - maxVal: max range bound /// - Returns: x clamped to the range [min, max] +@inlinable public func clamp(_ x: Float, _ minVal: Float, _ maxVal: Float) -> Float { #if FRB_MATH_USE_SIMD return simd_clamp(x, minVal, maxVal) #else - return min(max(x, minVal), maxVal) + return FirebladeMath.min(FirebladeMath.max(x, minVal), maxVal) #endif } diff --git a/Sources/FirebladeMath/Functions/copysign.swift b/Sources/FirebladeMath/Functions/copysign.swift index 756826d..b79d849 100644 --- a/Sources/FirebladeMath/Functions/copysign.swift +++ b/Sources/FirebladeMath/Functions/copysign.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Composes a floating point value with the magnitude of x and the sign of y. diff --git a/Sources/FirebladeMath/Functions/cos.swift b/Sources/FirebladeMath/Functions/cos.swift index 152c9cf..d8b48e6 100644 --- a/Sources/FirebladeMath/Functions/cos.swift +++ b/Sources/FirebladeMath/Functions/cos.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the cosine of arg (measured in radians). @@ -12,6 +12,7 @@ import Glibc /// - Returns: If no errors occur, the cosine of arg (cos(arg)) in the range [-1 ; +1], is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func cos(_ angleRad: Float) -> Float { #if canImport(Darwin) return Darwin.cosf(angleRad) @@ -24,10 +25,11 @@ public func cos(_ angleRad: Float) -> Float { /// Computes the cosine of arg (measured in radians). /// -/// - Parameter angleRad: floating point value representing angle in radians +/// - Parameter angleRad: floating point value representing angle in radians /// - Returns: If no errors occur, the cosine of arg (cos(arg)) in the range [-1 ; +1], is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func cos(_ angleRad: Double) -> Double { #if canImport(Darwin) return Darwin.cos(angleRad) diff --git a/Sources/FirebladeMath/Functions/cosh.swift b/Sources/FirebladeMath/Functions/cosh.swift index b15cf4a..4dd905e 100644 --- a/Sources/FirebladeMath/Functions/cosh.swift +++ b/Sources/FirebladeMath/Functions/cosh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the hyperbolic cosine of x. diff --git a/Sources/FirebladeMath/Functions/cross.swift b/Sources/FirebladeMath/Functions/cross.swift index f0ef435..8140e45 100644 --- a/Sources/FirebladeMath/Functions/cross.swift +++ b/Sources/FirebladeMath/Functions/cross.swift @@ -13,7 +13,7 @@ public func cross(_ x: SIMD2, _ y: SIMD2) -> SIMD3 { #if FRB_MATH_USE_SIMD return simd.simd_cross(x, y) #else - return SIMD3(0, 0, (x.x * y.y) - (x.y * y.x)) + return SIMD3(0.0, 0.0, (x.x * y.y) - (x.y * y.x)) #endif } @@ -28,7 +28,7 @@ public func cross(_ x: SIMD2, _ y: SIMD2) -> SIMD3 { #if FRB_MATH_USE_SIMD return simd.simd_cross(x, y) #else - return SIMD3(0, 0, (x.x * y.y) - (x.y * y.x)) + return SIMD3(0.0, 0.0, (x.x * y.y) - (x.y * y.x)) #endif } diff --git a/Sources/FirebladeMath/Functions/distance.swift b/Sources/FirebladeMath/Functions/distance.swift index f93efa2..f4d8004 100644 --- a/Sources/FirebladeMath/Functions/distance.swift +++ b/Sources/FirebladeMath/Functions/distance.swift @@ -1,11 +1,27 @@ +#if canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#else +import Foundation +#endif + /// Computes the distance between the arguments. /// /// - Parameters: /// - x: a float argument. /// - y: a float argument. /// - Returns: the distance between the arguments. +@inlinable public func distance(_ x: Float, _ y: Float) -> Float { - abs(x - y) + let diff: Float = x - y + #if canImport(Darwin) + return Darwin.fabsf(diff) + #elseif canImport(Glibc) + return Glibc.fabsf(diff) + #else + return Foundation.fabsf(diff) + #endif } /// Computes the distance between the arguments. @@ -14,6 +30,14 @@ public func distance(_ x: Float, _ y: Float) -> Float { /// - x: a double argument. /// - y: a double argument. /// - Returns: the distance between the arguments. +@inlinable public func distance(_ x: Double, _ y: Double) -> Double { - abs(x - y) + let diff: Double = x - y + #if canImport(Darwin) + return Darwin.fabs(diff) + #elseif canImport(Glibc) + return Glibc.fabs(diff) + #else + return Foundation.fabs(diff) + #endif } diff --git a/Sources/FirebladeMath/Functions/exp.swift b/Sources/FirebladeMath/Functions/exp.swift index b3139cc..007da26 100644 --- a/Sources/FirebladeMath/Functions/exp.swift +++ b/Sources/FirebladeMath/Functions/exp.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the e (Euler's number, 2.7182818) raised to the given power arg. diff --git a/Sources/FirebladeMath/Functions/exp2.swift b/Sources/FirebladeMath/Functions/exp2.swift index 0eaf6fd..f8e1cf3 100644 --- a/Sources/FirebladeMath/Functions/exp2.swift +++ b/Sources/FirebladeMath/Functions/exp2.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes 2 raised to the given power n. diff --git a/Sources/FirebladeMath/Functions/floor.swift b/Sources/FirebladeMath/Functions/floor.swift index b6bff20..802d1a7 100644 --- a/Sources/FirebladeMath/Functions/floor.swift +++ b/Sources/FirebladeMath/Functions/floor.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the largest integer value not greater than x. diff --git a/Sources/FirebladeMath/Functions/hypot.swift b/Sources/FirebladeMath/Functions/hypot.swift index 0358e72..30ace55 100644 --- a/Sources/FirebladeMath/Functions/hypot.swift +++ b/Sources/FirebladeMath/Functions/hypot.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Returns the hypotenuse of a right-angled triangle whose legs are x and y. diff --git a/Sources/FirebladeMath/Functions/isInfinite.swift b/Sources/FirebladeMath/Functions/isInfinite.swift index cab8a8d..1edc720 100644 --- a/Sources/FirebladeMath/Functions/isInfinite.swift +++ b/Sources/FirebladeMath/Functions/isInfinite.swift @@ -2,14 +2,16 @@ /// /// - Parameter x: floating point value /// - Returns: true if Float.infinity == x, false otherwise +@inlinable public func isInfinite(_ x: Float) -> Bool { - Float.infinity == x + x.isInfinite } /// Returns true if Double.infinity == x. /// /// - Parameter x: floating point value /// - Returns: true if Double.infinity == x, false otherwise +@inlinable public func isInfinite(_ x: Double) -> Bool { - Double.infinity == x + x.isInfinite } diff --git a/Sources/FirebladeMath/Functions/isNegativeInfinity.swift b/Sources/FirebladeMath/Functions/isNegativeInfinity.swift index d4179c7..9e5ed58 100644 --- a/Sources/FirebladeMath/Functions/isNegativeInfinity.swift +++ b/Sources/FirebladeMath/Functions/isNegativeInfinity.swift @@ -1,13 +1,15 @@ /// Returns true if the value is negative infinity. /// - Parameter x: floating point value /// - Returns: true if the value is negative infinity, false otherwise. +@inlinable public func isNegativeInfinity(_ x: Float) -> Bool { - x.floatingPointClass == .negativeInfinity + x.isInfinite && x.sign == FloatingPointSign.minus } /// Returns true if the value is negative infinity. /// - Parameter x: floating point value /// - Returns: true if the value is negative infinity, false otherwise. +@inlinable public func isNegativeInfinity(_ x: Double) -> Bool { - x.floatingPointClass == .negativeInfinity + x.isInfinite && x.sign == FloatingPointSign.minus } diff --git a/Sources/FirebladeMath/Functions/isNegativeZero.swift b/Sources/FirebladeMath/Functions/isNegativeZero.swift index 8ccb5db..c99f3cc 100644 --- a/Sources/FirebladeMath/Functions/isNegativeZero.swift +++ b/Sources/FirebladeMath/Functions/isNegativeZero.swift @@ -1,13 +1,15 @@ /// Returns true if the value is negative zero. /// - Parameter x: floating point value /// - Returns: true if the value is negative zero, false otherwise. +@inlinable public func isNegativeZero(_ x: Float) -> Bool { - x.floatingPointClass == .negativeZero + x.isZero && x.sign == FloatingPointSign.minus } /// Returns true if the value is negative zero. /// - Parameter x: floating point value /// - Returns: true if the value is negative zero, false otherwise. +@inlinable public func isNegativeZero(_ x: Double) -> Bool { - x.floatingPointClass == .negativeZero + x.isZero && x.sign == FloatingPointSign.minus } diff --git a/Sources/FirebladeMath/Functions/isPositiveInfinity.swift b/Sources/FirebladeMath/Functions/isPositiveInfinity.swift index 4d606a9..b948658 100644 --- a/Sources/FirebladeMath/Functions/isPositiveInfinity.swift +++ b/Sources/FirebladeMath/Functions/isPositiveInfinity.swift @@ -1,13 +1,15 @@ /// Returns true if the value is positive infinity. /// - Parameter x: floating point value /// - Returns: true if the value is positive infinity, false otherwise. +@inlinable public func isPositiveInfinity(_ x: Float) -> Bool { - x.floatingPointClass == .positiveInfinity + x.isInfinite && x.sign == FloatingPointSign.plus } /// Returns true if the value is positive infinity. /// - Parameter x: floating point value /// - Returns: true if the value is positive infinity, false otherwise. +@inlinable public func isPositiveInfinity(_ x: Double) -> Bool { - x.floatingPointClass == .positiveInfinity + x.isInfinite && x.sign == FloatingPointSign.plus } diff --git a/Sources/FirebladeMath/Functions/isPositiveZero.swift b/Sources/FirebladeMath/Functions/isPositiveZero.swift index ea8bb2f..3d76340 100644 --- a/Sources/FirebladeMath/Functions/isPositiveZero.swift +++ b/Sources/FirebladeMath/Functions/isPositiveZero.swift @@ -1,13 +1,15 @@ /// Returns true if the value is positive zero. /// - Parameter x: floating point value /// - Returns: true if the value is positive zero, false otherwise. +@inlinable public func isPositiveZero(_ x: Float) -> Bool { - x.floatingPointClass == .positiveZero + x.isZero && x.sign == FloatingPointSign.plus } /// Returns true if the value is positive zero. /// - Parameter x: floating point value /// - Returns: true if the value is positive zero, false otherwise. +@inlinable public func isPositiveZero(_ x: Double) -> Bool { - x.floatingPointClass == .positiveZero + x.isZero && x.sign == FloatingPointSign.plus } diff --git a/Sources/FirebladeMath/Functions/log.swift b/Sources/FirebladeMath/Functions/log.swift index 9ba1239..cb7faf6 100644 --- a/Sources/FirebladeMath/Functions/log.swift +++ b/Sources/FirebladeMath/Functions/log.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the natural (base e) logarithm of x. diff --git a/Sources/FirebladeMath/Functions/log10.swift b/Sources/FirebladeMath/Functions/log10.swift index 1732de4..a8eeb83 100644 --- a/Sources/FirebladeMath/Functions/log10.swift +++ b/Sources/FirebladeMath/Functions/log10.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the common (base-10) logarithm of x. diff --git a/Sources/FirebladeMath/Functions/log2.swift b/Sources/FirebladeMath/Functions/log2.swift index 8fa5e79..3de74b5 100644 --- a/Sources/FirebladeMath/Functions/log2.swift +++ b/Sources/FirebladeMath/Functions/log2.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the base 2 logarithm of x. diff --git a/Sources/FirebladeMath/Functions/max.swift b/Sources/FirebladeMath/Functions/max.swift index e90b61c..5a9a286 100644 --- a/Sources/FirebladeMath/Functions/max.swift +++ b/Sources/FirebladeMath/Functions/max.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Returns the larger of two floating point arguments, treating NaNs as missing data (between a NaN and a numeric value, the numeric value is chosen). @@ -12,6 +12,7 @@ import Glibc /// - x: floating point value /// - y: floating point value /// - Returns: If successful, returns the larger of two floating point values. The value returned is exact and does not depend on any rounding modes. +@inlinable public func max(_ x: Float, _ y: Float) -> Float { #if canImport(Darwin) return Darwin.fmaxf(x, y) @@ -28,6 +29,7 @@ public func max(_ x: Float, _ y: Float) -> Float { /// - x: floating point value /// - y: floating point value /// - Returns: If successful, returns the larger of two floating point values. The value returned is exact and does not depend on any rounding modes. +@inlinable public func max(_ x: Double, _ y: Double) -> Double { #if canImport(Darwin) return Darwin.fmax(x, y) diff --git a/Sources/FirebladeMath/Functions/min.swift b/Sources/FirebladeMath/Functions/min.swift index 361d7fd..cff31b9 100644 --- a/Sources/FirebladeMath/Functions/min.swift +++ b/Sources/FirebladeMath/Functions/min.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Returns the smaller of two floating point arguments, treating NaNs as missing data (between a NaN and a numeric value, the numeric value is chosen). @@ -12,6 +12,7 @@ import Glibc /// - x: floating point value /// - y: floating point value /// - Returns: If successful, returns the smaller of two floating point values. The value returned is exact and does not depend on any rounding modes. +@inlinable public func min(_ x: Float, _ y: Float) -> Float { #if canImport(Darwin) return Darwin.fminf(x, y) @@ -28,6 +29,7 @@ public func min(_ x: Float, _ y: Float) -> Float { /// - x: floating point value /// - y: floating point value /// - Returns: If successful, returns the smaller of two floating point values. The value returned is exact and does not depend on any rounding modes. +@inlinable public func min(_ x: Double, _ y: Double) -> Double { #if canImport(Darwin) return Darwin.fmin(x, y) diff --git a/Sources/FirebladeMath/Functions/mod.swift b/Sources/FirebladeMath/Functions/mod.swift index 86353a7..e265853 100644 --- a/Sources/FirebladeMath/Functions/mod.swift +++ b/Sources/FirebladeMath/Functions/mod.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the floating-point remainder of the division operation x/y. diff --git a/Sources/FirebladeMath/Functions/pow.swift b/Sources/FirebladeMath/Functions/pow.swift index c8656bb..7c779b1 100644 --- a/Sources/FirebladeMath/Functions/pow.swift +++ b/Sources/FirebladeMath/Functions/pow.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the value of base raised to the power exponent. diff --git a/Sources/FirebladeMath/Functions/pow2.swift b/Sources/FirebladeMath/Functions/pow2.swift index eda7b3a..f3b8780 100644 --- a/Sources/FirebladeMath/Functions/pow2.swift +++ b/Sources/FirebladeMath/Functions/pow2.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the value of base 2 raised to the power exponent. /// - Parameter exponent: The exponent. diff --git a/Sources/FirebladeMath/Functions/remap.swift b/Sources/FirebladeMath/Functions/remap.swift index 63be498..90d1caf 100644 --- a/Sources/FirebladeMath/Functions/remap.swift +++ b/Sources/FirebladeMath/Functions/remap.swift @@ -1,15 +1,12 @@ -/// Extension to add remapping functionality to FloatingPoint types. -extension FloatingPoint { +extension Float { /// Remaps this value from one range to another, clamping the input to the input range. /// - Parameters: /// - rangeClamp: The input range to clamp to. /// - rangeOut: The output range to map to. /// - Returns: The remapped value. @inlinable - public func remaped(clampingIn rangeClamp: ClosedRange, - to rangeOut: ClosedRange) -> Self - { - var v = clamped(to: rangeClamp) + public func remaped(clampingIn rangeClamp: ClosedRange, to rangeOut: ClosedRange) -> Float { + var v: Float = clamped(to: rangeClamp) v = v.lerped(from: rangeClamp, to: rangeOut) return v } @@ -19,9 +16,31 @@ extension FloatingPoint { /// - rangeClamp: The input range to clamp to. /// - rangeOut: The output range to map to. @inlinable - public mutating func remap(clampingIn rangeClamp: ClosedRange, - to rangeOut: ClosedRange) - { + public mutating func remap(clampingIn rangeClamp: ClosedRange, to rangeOut: ClosedRange) { + clamp(to: rangeClamp) + lerp(from: rangeClamp, to: rangeOut) + } +} + +extension Double { + /// Remaps this value from one range to another, clamping the input to the input range. + /// - Parameters: + /// - rangeClamp: The input range to clamp to. + /// - rangeOut: The output range to map to. + /// - Returns: The remapped value. + @inlinable + public func remaped(clampingIn rangeClamp: ClosedRange, to rangeOut: ClosedRange) -> Double { + var v: Double = clamped(to: rangeClamp) + v = v.lerped(from: rangeClamp, to: rangeOut) + return v + } + + /// Remaps this value from one range to another in place, clamping the input to the input range. + /// - Parameters: + /// - rangeClamp: The input range to clamp to. + /// - rangeOut: The output range to map to. + @inlinable + public mutating func remap(clampingIn rangeClamp: ClosedRange, to rangeOut: ClosedRange) { clamp(to: rangeClamp) lerp(from: rangeClamp, to: rangeOut) } diff --git a/Sources/FirebladeMath/Functions/sin.swift b/Sources/FirebladeMath/Functions/sin.swift index bf12853..93436da 100644 --- a/Sources/FirebladeMath/Functions/sin.swift +++ b/Sources/FirebladeMath/Functions/sin.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the sine of arg (measured in radians). @@ -12,6 +12,7 @@ import Glibc /// - Returns: If no errors occur, the sine of arg (sin(arg)) in the range [-1 ; +1], is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func sin(_ angleRad: Float) -> Float { #if canImport(Darwin) return Darwin.sinf(angleRad) @@ -28,6 +29,7 @@ public func sin(_ angleRad: Float) -> Float { /// - Returns: If no errors occur, the sine of arg (sin(arg)) in the range [-1 ; +1], is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func sin(_ angleRad: Double) -> Double { #if canImport(Darwin) return Darwin.sin(angleRad) diff --git a/Sources/FirebladeMath/Functions/sinh.swift b/Sources/FirebladeMath/Functions/sinh.swift index 38fcfed..a49fbec 100644 --- a/Sources/FirebladeMath/Functions/sinh.swift +++ b/Sources/FirebladeMath/Functions/sinh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes hyperbolic sine of x. diff --git a/Sources/FirebladeMath/Functions/sqrt.swift b/Sources/FirebladeMath/Functions/sqrt.swift index 1491908..bf8274b 100644 --- a/Sources/FirebladeMath/Functions/sqrt.swift +++ b/Sources/FirebladeMath/Functions/sqrt.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes square root of x. diff --git a/Sources/FirebladeMath/Functions/tan.swift b/Sources/FirebladeMath/Functions/tan.swift index 7b28c24..495422d 100644 --- a/Sources/FirebladeMath/Functions/tan.swift +++ b/Sources/FirebladeMath/Functions/tan.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the tangent of arg (measured in radians). @@ -12,6 +12,7 @@ import Glibc /// - Returns: If no errors occur, the tangent of arg (tan(arg)) is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func tan(_ angleRad: Float) -> Float { #if canImport(Darwin) return Darwin.tanf(angleRad) @@ -28,6 +29,7 @@ public func tan(_ angleRad: Float) -> Float { /// - Returns: If no errors occur, the tangent of arg (tan(arg)) is returned. /// If a domain error occurs, an implementation-defined value is returned (NaN where supported). /// If a range error occurs due to underflow, the correct result (after rounding) is returned. +@inlinable public func tan(_ angleRad: Double) -> Double { #if canImport(Darwin) return Darwin.tan(angleRad) diff --git a/Sources/FirebladeMath/Functions/tanh.swift b/Sources/FirebladeMath/Functions/tanh.swift index 7e66076..12c4b63 100644 --- a/Sources/FirebladeMath/Functions/tanh.swift +++ b/Sources/FirebladeMath/Functions/tanh.swift @@ -1,9 +1,9 @@ -import Foundation - #if canImport(Darwin) import Darwin #elseif canImport(Glibc) import Glibc +#else +import Foundation #endif /// Computes the hyperbolic tangent of x. diff --git a/Sources/FirebladeMath/Matrix/Matrix+Identity.swift b/Sources/FirebladeMath/Matrix/Matrix+Identity.swift index a695aea..770aa86 100644 --- a/Sources/FirebladeMath/Matrix/Matrix+Identity.swift +++ b/Sources/FirebladeMath/Matrix/Matrix+Identity.swift @@ -1,41 +1,41 @@ extension Mat2x2f { /// The 2x2 identity matrix. public static var identity: Mat2x2f { - Mat2x2f(diagonal: Vector(1, 1)) + Mat2x2f(diagonal: Vector(1.0, 1.0)) } } extension Mat2x2d { /// The 2x2 identity matrix. public static var identity: Mat2x2d { - Mat2x2d(diagonal: Vector(1, 1)) + Mat2x2d(diagonal: Vector(1.0, 1.0)) } } extension Mat3x3f { /// The 3x3 identity matrix. public static var identity: Mat3x3f { - Mat3x3f(diagonal: Vector(1, 1, 1)) + Mat3x3f(diagonal: Vector(1.0, 1.0, 1.0)) } } extension Mat3x3d { /// The 3x3 identity matrix. public static var identity: Mat3x3d { - Mat3x3d(diagonal: Vector(1, 1, 1)) + Mat3x3d(diagonal: Vector(1.0, 1.0, 1.0)) } } extension Mat4x4f { /// The 4x4 identity matrix. public static var identity: Mat4x4f { - Mat4x4f(diagonal: Vector(1, 1, 1, 1)) + Mat4x4f(diagonal: Vector(1.0, 1.0, 1.0, 1.0)) } } extension Mat4x4d { /// The 4x4 identity matrix. public static var identity: Mat4x4d { - Mat4x4d(diagonal: Vector(1, 1, 1, 1)) + Mat4x4d(diagonal: Vector(1.0, 1.0, 1.0, 1.0)) } } diff --git a/Sources/FirebladeMath/Matrix/Matrix+Multiplication.swift b/Sources/FirebladeMath/Matrix/Matrix+Multiplication.swift index 761d48e..e2ceb01 100644 --- a/Sources/FirebladeMath/Matrix/Matrix+Multiplication.swift +++ b/Sources/FirebladeMath/Matrix/Matrix+Multiplication.swift @@ -14,31 +14,31 @@ public func multiply(_ lhs: Mat4x4d, _ rhs: Mat4x4d) -> Mat4x4d { #if FRB_MATH_USE_SIMD return Mat4x4d(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Double = lhs[0] * rhs[0] + lhs[4] * rhs[1] + lhs[8] * rhs[2] + lhs[12] * rhs[3] + let c01: Double = lhs[1] * rhs[0] + lhs[5] * rhs[1] + lhs[9] * rhs[2] + lhs[13] * rhs[3] + let c02: Double = lhs[2] * rhs[0] + lhs[6] * rhs[1] + lhs[10] * rhs[2] + lhs[14] * rhs[3] + let c03: Double = lhs[3] * rhs[0] + lhs[7] * rhs[1] + lhs[11] * rhs[2] + lhs[15] * rhs[3] + + let c10: Double = lhs[0] * rhs[4] + lhs[4] * rhs[5] + lhs[8] * rhs[6] + lhs[12] * rhs[7] + let c11: Double = lhs[1] * rhs[4] + lhs[5] * rhs[5] + lhs[9] * rhs[6] + lhs[13] * rhs[7] + let c12: Double = lhs[2] * rhs[4] + lhs[6] * rhs[5] + lhs[10] * rhs[6] + lhs[14] * rhs[7] + let c13: Double = lhs[3] * rhs[4] + lhs[7] * rhs[5] + lhs[11] * rhs[6] + lhs[15] * rhs[7] + + let c20: Double = lhs[0] * rhs[8] + lhs[4] * rhs[9] + lhs[8] * rhs[10] + lhs[12] * rhs[11] + let c21: Double = lhs[1] * rhs[8] + lhs[5] * rhs[9] + lhs[9] * rhs[10] + lhs[13] * rhs[11] + let c22: Double = lhs[2] * rhs[8] + lhs[6] * rhs[9] + lhs[10] * rhs[10] + lhs[14] * rhs[11] + let c23: Double = lhs[3] * rhs[8] + lhs[7] * rhs[9] + lhs[11] * rhs[10] + lhs[15] * rhs[11] + + let c30: Double = lhs[0] * rhs[12] + lhs[4] * rhs[13] + lhs[8] * rhs[14] + lhs[12] * rhs[15] + let c31: Double = lhs[1] * rhs[12] + lhs[5] * rhs[13] + lhs[9] * rhs[14] + lhs[13] * rhs[15] + let c32: Double = lhs[2] * rhs[12] + lhs[6] * rhs[13] + lhs[10] * rhs[14] + lhs[14] * rhs[15] + let c33: Double = lhs[3] * rhs[12] + lhs[7] * rhs[13] + lhs[11] * rhs[14] + lhs[15] * rhs[15] + return Mat4x4d( - Vec4d( - lhs[0] * rhs[0] + lhs[4] * rhs[1] + lhs[8] * rhs[2] + lhs[12] * rhs[3], - lhs[1] * rhs[0] + lhs[5] * rhs[1] + lhs[9] * rhs[2] + lhs[13] * rhs[3], - lhs[2] * rhs[0] + lhs[6] * rhs[1] + lhs[10] * rhs[2] + lhs[14] * rhs[3], - lhs[3] * rhs[0] + lhs[7] * rhs[1] + lhs[11] * rhs[2] + lhs[15] * rhs[3] - ), - Vec4d( - lhs[0] * rhs[4] + lhs[4] * rhs[5] + lhs[8] * rhs[6] + lhs[12] * rhs[7], - lhs[1] * rhs[4] + lhs[5] * rhs[5] + lhs[9] * rhs[6] + lhs[13] * rhs[7], - lhs[2] * rhs[4] + lhs[6] * rhs[5] + lhs[10] * rhs[6] + lhs[14] * rhs[7], - lhs[3] * rhs[4] + lhs[7] * rhs[5] + lhs[11] * rhs[6] + lhs[15] * rhs[7] - ), - Vec4d( - lhs[0] * rhs[8] + lhs[4] * rhs[9] + lhs[8] * rhs[10] + lhs[12] * rhs[11], - lhs[1] * rhs[8] + lhs[5] * rhs[9] + lhs[9] * rhs[10] + lhs[13] * rhs[11], - lhs[2] * rhs[8] + lhs[6] * rhs[9] + lhs[10] * rhs[10] + lhs[14] * rhs[11], - lhs[3] * rhs[8] + lhs[7] * rhs[9] + lhs[11] * rhs[10] + lhs[15] * rhs[11] - ), - Vec4d( - lhs[0] * rhs[12] + lhs[4] * rhs[13] + lhs[8] * rhs[14] + lhs[12] * rhs[15], - lhs[1] * rhs[12] + lhs[5] * rhs[13] + lhs[9] * rhs[14] + lhs[13] * rhs[15], - lhs[2] * rhs[12] + lhs[6] * rhs[13] + lhs[10] * rhs[14] + lhs[14] * rhs[15], - lhs[3] * rhs[12] + lhs[7] * rhs[13] + lhs[11] * rhs[14] + lhs[15] * rhs[15] - ) + Vec4d(c00, c01, c02, c03), + Vec4d(c10, c11, c12, c13), + Vec4d(c20, c21, c22, c23), + Vec4d(c30, c31, c32, c33) ) #endif } @@ -109,31 +109,31 @@ public func multiply(_ lhs: Mat4x4f, _ rhs: Mat4x4f) -> Mat4x4f { #if FRB_MATH_USE_SIMD return Mat4x4f(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Float = lhs[0] * rhs[0] + lhs[4] * rhs[1] + lhs[8] * rhs[2] + lhs[12] * rhs[3] + let c01: Float = lhs[1] * rhs[0] + lhs[5] * rhs[1] + lhs[9] * rhs[2] + lhs[13] * rhs[3] + let c02: Float = lhs[2] * rhs[0] + lhs[6] * rhs[1] + lhs[10] * rhs[2] + lhs[14] * rhs[3] + let c03: Float = lhs[3] * rhs[0] + lhs[7] * rhs[1] + lhs[11] * rhs[2] + lhs[15] * rhs[3] + + let c10: Float = lhs[0] * rhs[4] + lhs[4] * rhs[5] + lhs[8] * rhs[6] + lhs[12] * rhs[7] + let c11: Float = lhs[1] * rhs[4] + lhs[5] * rhs[5] + lhs[9] * rhs[6] + lhs[13] * rhs[7] + let c12: Float = lhs[2] * rhs[4] + lhs[6] * rhs[5] + lhs[10] * rhs[6] + lhs[14] * rhs[7] + let c13: Float = lhs[3] * rhs[4] + lhs[7] * rhs[5] + lhs[11] * rhs[6] + lhs[15] * rhs[7] + + let c20: Float = lhs[0] * rhs[8] + lhs[4] * rhs[9] + lhs[8] * rhs[10] + lhs[12] * rhs[11] + let c21: Float = lhs[1] * rhs[8] + lhs[5] * rhs[9] + lhs[9] * rhs[10] + lhs[13] * rhs[11] + let c22: Float = lhs[2] * rhs[8] + lhs[6] * rhs[9] + lhs[10] * rhs[10] + lhs[14] * rhs[11] + let c23: Float = lhs[3] * rhs[8] + lhs[7] * rhs[9] + lhs[11] * rhs[10] + lhs[15] * rhs[11] + + let c30: Float = lhs[0] * rhs[12] + lhs[4] * rhs[13] + lhs[8] * rhs[14] + lhs[12] * rhs[15] + let c31: Float = lhs[1] * rhs[12] + lhs[5] * rhs[13] + lhs[9] * rhs[14] + lhs[13] * rhs[15] + let c32: Float = lhs[2] * rhs[12] + lhs[6] * rhs[13] + lhs[10] * rhs[14] + lhs[14] * rhs[15] + let c33: Float = lhs[3] * rhs[12] + lhs[7] * rhs[13] + lhs[11] * rhs[14] + lhs[15] * rhs[15] + return Mat4x4f( - Vec4f( - lhs[0] * rhs[0] + lhs[4] * rhs[1] + lhs[8] * rhs[2] + lhs[12] * rhs[3], - lhs[1] * rhs[0] + lhs[5] * rhs[1] + lhs[9] * rhs[2] + lhs[13] * rhs[3], - lhs[2] * rhs[0] + lhs[6] * rhs[1] + lhs[10] * rhs[2] + lhs[14] * rhs[3], - lhs[3] * rhs[0] + lhs[7] * rhs[1] + lhs[11] * rhs[2] + lhs[15] * rhs[3] - ), - Vec4f( - lhs[0] * rhs[4] + lhs[4] * rhs[5] + lhs[8] * rhs[6] + lhs[12] * rhs[7], - lhs[1] * rhs[4] + lhs[5] * rhs[5] + lhs[9] * rhs[6] + lhs[13] * rhs[7], - lhs[2] * rhs[4] + lhs[6] * rhs[5] + lhs[10] * rhs[6] + lhs[14] * rhs[7], - lhs[3] * rhs[4] + lhs[7] * rhs[5] + lhs[11] * rhs[6] + lhs[15] * rhs[7] - ), - Vec4f( - lhs[0] * rhs[8] + lhs[4] * rhs[9] + lhs[8] * rhs[10] + lhs[12] * rhs[11], - lhs[1] * rhs[8] + lhs[5] * rhs[9] + lhs[9] * rhs[10] + lhs[13] * rhs[11], - lhs[2] * rhs[8] + lhs[6] * rhs[9] + lhs[10] * rhs[10] + lhs[14] * rhs[11], - lhs[3] * rhs[8] + lhs[7] * rhs[9] + lhs[11] * rhs[10] + lhs[15] * rhs[11] - ), - Vec4f( - lhs[0] * rhs[12] + lhs[4] * rhs[13] + lhs[8] * rhs[14] + lhs[12] * rhs[15], - lhs[1] * rhs[12] + lhs[5] * rhs[13] + lhs[9] * rhs[14] + lhs[13] * rhs[15], - lhs[2] * rhs[12] + lhs[6] * rhs[13] + lhs[10] * rhs[14] + lhs[14] * rhs[15], - lhs[3] * rhs[12] + lhs[7] * rhs[13] + lhs[11] * rhs[14] + lhs[15] * rhs[15] - ) + Vec4f(c00, c01, c02, c03), + Vec4f(c10, c11, c12, c13), + Vec4f(c20, c21, c22, c23), + Vec4f(c30, c31, c32, c33) ) #endif } @@ -204,22 +204,22 @@ public func multiply(_ lhs: Mat3x3d, _ rhs: Mat3x3d) -> Mat3x3d { #if FRB_MATH_USE_SIMD return Mat3x3d(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Double = lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + lhs[2, 0] * rhs[0, 2] + let c01: Double = lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + lhs[2, 1] * rhs[0, 2] + let c02: Double = lhs[0, 2] * rhs[0, 0] + lhs[1, 2] * rhs[0, 1] + lhs[2, 2] * rhs[0, 2] + + let c10: Double = lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + lhs[2, 0] * rhs[1, 2] + let c11: Double = lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + lhs[2, 1] * rhs[1, 2] + let c12: Double = lhs[0, 2] * rhs[1, 0] + lhs[1, 2] * rhs[1, 1] + lhs[2, 2] * rhs[1, 2] + + let c20: Double = lhs[0, 0] * rhs[2, 0] + lhs[1, 0] * rhs[2, 1] + lhs[2, 0] * rhs[2, 2] + let c21: Double = lhs[0, 1] * rhs[2, 0] + lhs[1, 1] * rhs[2, 1] + lhs[2, 1] * rhs[2, 2] + let c22: Double = lhs[0, 2] * rhs[2, 0] + lhs[1, 2] * rhs[2, 1] + lhs[2, 2] * rhs[2, 2] + return Mat3x3d( - Vec3d( - lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + lhs[2, 0] * rhs[0, 2], - lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + lhs[2, 1] * rhs[0, 2], - lhs[0, 2] * rhs[0, 0] + lhs[1, 2] * rhs[0, 1] + lhs[2, 2] * rhs[0, 2] - ), - Vec3d( - lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + lhs[2, 0] * rhs[1, 2], - lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + lhs[2, 1] * rhs[1, 2], - lhs[0, 2] * rhs[1, 0] + lhs[1, 2] * rhs[1, 1] + lhs[2, 2] * rhs[1, 2] - ), - Vec3d( - lhs[0, 0] * rhs[2, 0] + lhs[1, 0] * rhs[2, 1] + lhs[2, 0] * rhs[2, 2], - lhs[0, 1] * rhs[2, 0] + lhs[1, 1] * rhs[2, 1] + lhs[2, 1] * rhs[2, 2], - lhs[0, 2] * rhs[2, 0] + lhs[1, 2] * rhs[2, 1] + lhs[2, 2] * rhs[2, 2] - ) + Vec3d(c00, c01, c02), + Vec3d(c10, c11, c12), + Vec3d(c20, c21, c22) ) #endif } @@ -287,22 +287,22 @@ public func multiply(_ lhs: Mat3x3f, _ rhs: Mat3x3f) -> Mat3x3f { #if FRB_MATH_USE_SIMD return Mat3x3f(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Float = lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + lhs[2, 0] * rhs[0, 2] + let c01: Float = lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + lhs[2, 1] * rhs[0, 2] + let c02: Float = lhs[0, 2] * rhs[0, 0] + lhs[1, 2] * rhs[0, 1] + lhs[2, 2] * rhs[0, 2] + + let c10: Float = lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + lhs[2, 0] * rhs[1, 2] + let c11: Float = lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + lhs[2, 1] * rhs[1, 2] + let c12: Float = lhs[0, 2] * rhs[1, 0] + lhs[1, 2] * rhs[1, 1] + lhs[2, 2] * rhs[1, 2] + + let c20: Float = lhs[0, 0] * rhs[2, 0] + lhs[1, 0] * rhs[2, 1] + lhs[2, 0] * rhs[2, 2] + let c21: Float = lhs[0, 1] * rhs[2, 0] + lhs[1, 1] * rhs[2, 1] + lhs[2, 1] * rhs[2, 2] + let c22: Float = lhs[0, 2] * rhs[2, 0] + lhs[1, 2] * rhs[2, 1] + lhs[2, 2] * rhs[2, 2] + return Mat3x3f( - Vec3f( - lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + lhs[2, 0] * rhs[0, 2], - lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + lhs[2, 1] * rhs[0, 2], - lhs[0, 2] * rhs[0, 0] + lhs[1, 2] * rhs[0, 1] + lhs[2, 2] * rhs[0, 2] - ), - Vec3f( - lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + lhs[2, 0] * rhs[1, 2], - lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + lhs[2, 1] * rhs[1, 2], - lhs[0, 2] * rhs[1, 0] + lhs[1, 2] * rhs[1, 1] + lhs[2, 2] * rhs[1, 2] - ), - Vec3f( - lhs[0, 0] * rhs[2, 0] + lhs[1, 0] * rhs[2, 1] + lhs[2, 0] * rhs[2, 2], - lhs[0, 1] * rhs[2, 0] + lhs[1, 1] * rhs[2, 1] + lhs[2, 1] * rhs[2, 2], - lhs[0, 2] * rhs[2, 0] + lhs[1, 2] * rhs[2, 1] + lhs[2, 2] * rhs[2, 2] - ) + Vec3f(c00, c01, c02), + Vec3f(c10, c11, c12), + Vec3f(c20, c21, c22) ) #endif } @@ -370,15 +370,15 @@ public func multiply(_ lhs: Mat2x2d, _ rhs: Mat2x2d) -> Mat2x2d { #if FRB_MATH_USE_SIMD return Mat2x2d(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Double = lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + let c01: Double = lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + + let c10: Double = lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + let c11: Double = lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + return Mat2x2d( - Vec2d( - lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1], - lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] - ), - Vec2d( - lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1], - lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] - ) + Vec2d(c00, c01), + Vec2d(c10, c11) ) #endif } @@ -443,15 +443,15 @@ public func multiply(_ lhs: Mat2x2f, _ rhs: Mat2x2f) -> Mat2x2f { #if FRB_MATH_USE_SIMD return Mat2x2f(storage: simd_mul(lhs.storage, rhs.storage)) #else + let c00: Float = lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1] + let c01: Float = lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] + + let c10: Float = lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1] + let c11: Float = lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] + return Mat2x2f( - Vec2f( - lhs[0, 0] * rhs[0, 0] + lhs[1, 0] * rhs[0, 1], - lhs[0, 1] * rhs[0, 0] + lhs[1, 1] * rhs[0, 1] - ), - Vec2f( - lhs[0, 0] * rhs[1, 0] + lhs[1, 0] * rhs[1, 1], - lhs[0, 1] * rhs[1, 0] + lhs[1, 1] * rhs[1, 1] - ) + Vec2f(c00, c01), + Vec2f(c10, c11) ) #endif } diff --git a/Sources/FirebladeMath/Matrix/Matrix+Operators.swift b/Sources/FirebladeMath/Matrix/Matrix+Operators.swift index 329a073..d32d959 100644 --- a/Sources/FirebladeMath/Matrix/Matrix+Operators.swift +++ b/Sources/FirebladeMath/Matrix/Matrix+Operators.swift @@ -5,8 +5,9 @@ /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat4x4f, rhs: Mat4x4f) -> Mat4x4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4x4 float matrix by a scalar. @@ -14,8 +15,9 @@ public func * (lhs: Mat4x4f, rhs: Mat4x4f) -> Mat4x4f { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Float, rhs: Mat4x4f) -> Mat4x4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4D float vector by a 4x4 float matrix. @@ -23,8 +25,9 @@ public func * (lhs: Float, rhs: Mat4x4f) -> Mat4x4f { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec4f, rhs: Mat4x4f) -> Vec4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4x4 float matrix by a 4D float vector. @@ -32,16 +35,18 @@ public func * (lhs: Vec4f, rhs: Mat4x4f) -> Vec4f { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat4x4f, rhs: Vec4f) -> Vec4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 4x4 float matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat4x4f, rhs: Mat4x4f) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } // MARK: 4x4d @@ -51,8 +56,9 @@ public func *= (lhs: inout Mat4x4f, rhs: Mat4x4f) { /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat4x4d, rhs: Mat4x4d) -> Mat4x4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4x4 double matrix by a scalar. @@ -60,8 +66,9 @@ public func * (lhs: Mat4x4d, rhs: Mat4x4d) -> Mat4x4d { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Double, rhs: Mat4x4d) -> Mat4x4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4D double vector by a 4x4 double matrix. @@ -69,8 +76,9 @@ public func * (lhs: Double, rhs: Mat4x4d) -> Mat4x4d { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec4d, rhs: Mat4x4d) -> Vec4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 4x4 double matrix by a 4D double vector. @@ -78,16 +86,18 @@ public func * (lhs: Vec4d, rhs: Mat4x4d) -> Vec4d { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat4x4d, rhs: Vec4d) -> Vec4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 4x4 double matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat4x4d, rhs: Mat4x4d) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } // MARK: 3x3f @@ -97,8 +107,9 @@ public func *= (lhs: inout Mat4x4d, rhs: Mat4x4d) { /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat3x3f, rhs: Mat3x3f) -> Mat3x3f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3x3 float matrix by a scalar. @@ -106,8 +117,9 @@ public func * (lhs: Mat3x3f, rhs: Mat3x3f) -> Mat3x3f { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Float, rhs: Mat3x3f) -> Mat3x3f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3D float vector by a 3x3 float matrix. @@ -115,8 +127,9 @@ public func * (lhs: Float, rhs: Mat3x3f) -> Mat3x3f { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec3f, rhs: Mat3x3f) -> Vec3f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3x3 float matrix by a 3D float vector. @@ -124,16 +137,18 @@ public func * (lhs: Vec3f, rhs: Mat3x3f) -> Vec3f { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat3x3f, rhs: Vec3f) -> Vec3f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 3x3 float matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat3x3f, rhs: Mat3x3f) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } // MARK: 3x3d @@ -143,8 +158,9 @@ public func *= (lhs: inout Mat3x3f, rhs: Mat3x3f) { /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat3x3d, rhs: Mat3x3d) -> Mat3x3d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3x3 double matrix by a scalar. @@ -152,8 +168,9 @@ public func * (lhs: Mat3x3d, rhs: Mat3x3d) -> Mat3x3d { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Double, rhs: Mat3x3d) -> Mat3x3d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3D double vector by a 3x3 double matrix. @@ -161,8 +178,9 @@ public func * (lhs: Double, rhs: Mat3x3d) -> Mat3x3d { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec3d, rhs: Mat3x3d) -> Vec3d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 3x3 double matrix by a 3D double vector. @@ -170,16 +188,18 @@ public func * (lhs: Vec3d, rhs: Mat3x3d) -> Vec3d { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat3x3d, rhs: Vec3d) -> Vec3d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 3x3 double matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat3x3d, rhs: Mat3x3d) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } // MARK: 2x2f @@ -189,8 +209,9 @@ public func *= (lhs: inout Mat3x3d, rhs: Mat3x3d) { /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat2x2f, rhs: Mat2x2f) -> Mat2x2f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2x2 float matrix by a scalar. @@ -198,8 +219,9 @@ public func * (lhs: Mat2x2f, rhs: Mat2x2f) -> Mat2x2f { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Float, rhs: Mat2x2f) -> Mat2x2f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2D float vector by a 2x2 float matrix. @@ -207,8 +229,9 @@ public func * (lhs: Float, rhs: Mat2x2f) -> Mat2x2f { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec2f, rhs: Mat2x2f) -> Vec2f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2x2 float matrix by a 2D float vector. @@ -216,16 +239,18 @@ public func * (lhs: Vec2f, rhs: Mat2x2f) -> Vec2f { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat2x2f, rhs: Vec2f) -> Vec2f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 2x2 float matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat2x2f, rhs: Mat2x2f) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } // MARK: 2x2d @@ -235,8 +260,9 @@ public func *= (lhs: inout Mat2x2f, rhs: Mat2x2f) { /// - lhs: The left-hand side matrix. /// - rhs: The right-hand side matrix. /// - Returns: The product of the two matrices. +@inlinable public func * (lhs: Mat2x2d, rhs: Mat2x2d) -> Mat2x2d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2x2 double matrix by a scalar. @@ -244,8 +270,9 @@ public func * (lhs: Mat2x2d, rhs: Mat2x2d) -> Mat2x2d { /// - lhs: The scalar value. /// - rhs: The matrix. /// - Returns: The resulting matrix. +@inlinable public func * (lhs: Double, rhs: Mat2x2d) -> Mat2x2d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2D double vector by a 2x2 double matrix. @@ -253,8 +280,9 @@ public func * (lhs: Double, rhs: Mat2x2d) -> Mat2x2d { /// - lhs: The vector. /// - rhs: The matrix. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Vec2d, rhs: Mat2x2d) -> Vec2d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a 2x2 double matrix by a 2D double vector. @@ -262,14 +290,16 @@ public func * (lhs: Vec2d, rhs: Mat2x2d) -> Vec2d { /// - lhs: The matrix. /// - rhs: The vector. /// - Returns: The resulting vector. +@inlinable public func * (lhs: Mat2x2d, rhs: Vec2d) -> Vec2d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies two 2x2 double matrices and assigns the result to the first matrix. /// - Parameters: /// - lhs: The left-hand side matrix to be updated. /// - rhs: The right-hand side matrix. +@inlinable public func *= (lhs: inout Mat2x2d, rhs: Mat2x2d) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } diff --git a/Sources/FirebladeMath/Matrix/Matrix4x4+Projections.swift b/Sources/FirebladeMath/Matrix/Matrix4x4+Projections.swift index 5367658..a590c3e 100644 --- a/Sources/FirebladeMath/Matrix/Matrix4x4+Projections.swift +++ b/Sources/FirebladeMath/Matrix/Matrix4x4+Projections.swift @@ -13,7 +13,7 @@ extension Mat4x4f { /// - zFar: The distance to the far clipping plane. /// - Returns: The perspective projection matrix. public static func perspectiveRH(fovy fovyRad: Float, aspect: Float, zNear: Float, zFar: Float) -> Self { - let yScale: Float = 1.0 / tan(fovyRad / 2.0) + let yScale: Float = 1.0 / FirebladeMath.tan(fovyRad * 0.5) let xScale: Float = yScale / aspect let m00: Float = xScale @@ -39,7 +39,7 @@ extension Mat4x4f { /// - zFar: The distance to the far clipping plane. /// - Returns: The perspective projection matrix. public static func perspectiveLH(fovy fovyRad: Float, aspect: Float, zNear: Float, zFar: Float) -> Self { - let yScale: Float = 1.0 / tan(fovyRad / 2.0) + let yScale: Float = 1.0 / FirebladeMath.tan(fovyRad * 0.5) let xScale: Float = yScale / aspect let m00: Float = xScale @@ -98,7 +98,7 @@ extension Mat4x4f { let m11: Float = 2.0 / (top - bottom) let m13: Float = (top + bottom) / (bottom - top) let m22: Float = 1.0 / (zFar - zNear) - let m23: Float = zNear / (zNear - zFar) + let m23: Float = -zNear / (zFar - zNear) let m33: Float = 1.0 let P = Vector(m00, 0.0, 0.0, 0.0) @@ -121,7 +121,7 @@ extension Mat4x4d { /// - zFar: The distance to the far clipping plane. /// - Returns: The perspective projection matrix. public static func perspectiveRH(fovy fovyRad: Double, aspect: Double, zNear: Double, zFar: Double) -> Self { - let yScale = 1.0 / tan(fovyRad / 2.0) + let yScale: Double = 1.0 / FirebladeMath.tan(fovyRad * 0.5) let xScale: Double = yScale / aspect let m00: Double = xScale @@ -129,7 +129,7 @@ extension Mat4x4d { let m22: Double = zFar / (zNear - zFar) let m23: Double = -1.0 let m32: Double = (zNear * zFar) / (zNear - zFar) - let m33 = 0.0 + let m33: Double = 0.0 let P = Vector(m00, 0.0, 0.0, 0.0) let Q = Vector(0.0, m11, 0.0, 0.0) @@ -147,15 +147,15 @@ extension Mat4x4d { /// - zFar: The distance to the far clipping plane. /// - Returns: The perspective projection matrix. public static func perspectiveLH(fovy fovyRad: Double, aspect: Double, zNear: Double, zFar: Double) -> Self { - let yScale = 1.0 / tan(fovyRad / 2.0) + let yScale: Double = 1.0 / FirebladeMath.tan(fovyRad * 0.5) let xScale: Double = yScale / aspect let m00: Double = xScale let m11: Double = yScale let m22: Double = zFar / (zFar - zNear) - let m23 = 1.0 + let m23: Double = 1.0 let m32: Double = -(zNear * zFar) / (zFar - zNear) - let m33 = 0.0 + let m33: Double = 0.0 let P = Vector(m00, 0.0, 0.0, 0.0) let Q = Vector(0.0, m11, 0.0, 0.0) @@ -175,13 +175,13 @@ extension Mat4x4d { /// - zFar: The distance to the far clipping plane. /// - Returns: The orthographic projection matrix. public static func orthographicRH(left: Double, right: Double, top: Double, bottom: Double, zNear: Double, zFar: Double) -> Self { - let m00 = 2.0 / (right - left) + let m00: Double = 2.0 / (right - left) let m03: Double = (left + right) / (left - right) - let m11 = 2.0 / (top - bottom) + let m11: Double = 2.0 / (top - bottom) let m13: Double = (top + bottom) / (bottom - top) - let m22 = 1.0 / (zNear - zFar) + let m22: Double = 1.0 / (zNear - zFar) let m23: Double = zNear / (zNear - zFar) - let m33 = 1.0 + let m33: Double = 1.0 let P = Vector(m00, 0.0, 0.0, 0.0) let Q = Vector(0.0, m11, 0.0, 0.0) @@ -201,13 +201,13 @@ extension Mat4x4d { /// - zFar: The distance to the far clipping plane. /// - Returns: The orthographic projection matrix. public static func orthographicLH(left: Double, right: Double, top: Double, bottom: Double, zNear: Double, zFar: Double) -> Self { - let m00 = 2.0 / (right - left) + let m00: Double = 2.0 / (right - left) let m03: Double = (left + right) / (left - right) - let m11 = 2.0 / (top - bottom) + let m11: Double = 2.0 / (top - bottom) let m13: Double = (top + bottom) / (bottom - top) - let m22 = 1.0 / (zFar - zNear) - let m23: Double = zNear / (zNear - zFar) - let m33 = 1.0 + let m22: Double = 1.0 / (zFar - zNear) + let m23: Double = -zNear / (zFar - zNear) + let m33: Double = 1.0 let P = Vector(m00, 0.0, 0.0, 0.0) let Q = Vector(0.0, m11, 0.0, 0.0) diff --git a/Sources/FirebladeMath/Quat/Quat.swift b/Sources/FirebladeMath/Quat/Quat.swift index 96b8e1b..c297140 100644 --- a/Sources/FirebladeMath/Quat/Quat.swift +++ b/Sources/FirebladeMath/Quat/Quat.swift @@ -22,6 +22,7 @@ extension Quaternion { /// Note that the imaginary (vector) part of the quaternion comes /// from lanes 0, 1, and 2 of the vector, and the real (scalar) part comes from /// lane 3. + @inlinable public init(_ vector: SIMD4) { self.init(storage: Storage(vector)) } @@ -32,6 +33,7 @@ extension Quaternion { /// - y: The y component of the imaginary part. /// - z: The z component of the imaginary part. /// - w: The real component. + @inlinable public init(_ x: Value, _ y: Value, _ z: Value, _ w: Value) { self.init(storage: Storage(x, y, z, w)) } @@ -71,6 +73,7 @@ extension Quaternion { extension Quaternion: Sequence { /// Creates an iterator over the components of the quaternion. + @inlinable public func makeIterator() -> Storage.Iterator { storage.makeIterator() } @@ -83,6 +86,7 @@ extension Quaternion: Sequence { extension Quaternion: ExpressibleByArrayLiteral { /// Creates a quaternion from an array literal. + @inlinable public init(arrayLiteral elements: Value...) { precondition(elements.count == 4, "Quaternion needs to be initialized with exactly 4 elements") self.init(storage: Storage(elements[0], elements[1], elements[2], elements[3])) @@ -91,6 +95,7 @@ extension Quaternion: ExpressibleByArrayLiteral { extension Quaternion: Equatable where Value: Equatable { /// Returns a Boolean value indicating whether two quaternions are equal. + @inlinable public static func == (lhs: Quaternion, rhs: Quaternion) -> Bool { lhs.storage == rhs.storage } diff --git a/Sources/FirebladeMath/Quat/Quat4f+Euler.swift b/Sources/FirebladeMath/Quat/Quat4f+Euler.swift index 8432276..65e60c1 100644 --- a/Sources/FirebladeMath/Quat/Quat4f+Euler.swift +++ b/Sources/FirebladeMath/Quat/Quat4f+Euler.swift @@ -13,12 +13,12 @@ extension Quat4f { // } public static func fromEulerAngles_123(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 - s1 * s2 * s3 let q3 = s1 * c2 * c3 + c1 * s2 * s3 @@ -42,12 +42,12 @@ extension Quat4f { // } public static func fromEulerAngles_132(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 + s1 * s2 * s3 let q3 = s1 * c2 * c3 - c1 * s2 * s3 @@ -71,12 +71,12 @@ extension Quat4f { // } public static func fromEulerAngles_213(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 + s1 * s2 * s3 let q3 = c1 * s2 * c3 + s1 * c2 * s3 @@ -87,12 +87,12 @@ extension Quat4f { } public static func fromEulerAngles_231(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 - s1 * s2 * s3 let q3 = c1 * c2 * s3 + s1 * s2 * c3 @@ -116,12 +116,12 @@ extension Quat4f { // } public static func fromEulerAngles_312(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 - s1 * s2 * s3 let q3 = c1 * s2 * c3 - s1 * c2 * s3 @@ -145,12 +145,12 @@ extension Quat4f { // } public static func fromEulerAngles_321(_ e: Vec3f) -> Quat4f { - let c1 = cos(e.x / 2) - let s1 = sin(e.x / 2) - let c2 = cos(e.y / 2) - let s2 = sin(e.y / 2) - let c3 = cos(e.z / 2) - let s3 = sin(e.z / 2) + let c1 = cos(e.x / 2.0) + let s1 = sin(e.x / 2.0) + let c2 = cos(e.y / 2.0) + let s2 = sin(e.y / 2.0) + let c3 = cos(e.z / 2.0) + let s3 = sin(e.z / 2.0) let q4 = c1 * c2 * c3 + s1 * s2 * s3 let q3 = c1 * c2 * s3 - s1 * s2 * c3 @@ -218,9 +218,9 @@ public func quaternionToEulerAngles_123(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(-2 * (q2 * q3 - q0 * q1), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) - let e2 = asin(2 * (q1 * q3 + q0 * q2)) - let e3 = atan2(-2 * (q1 * q2 - q0 * q3), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) + let e1 = atan2(-2.0 * (q2 * q3 - q0 * q1), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) + let e2 = asin(2.0 * (q1 * q3 + q0 * q2)) + let e3 = atan2(-2.0 * (q1 * q2 - q0 * q3), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) return Vec3f(e1, e2, e3) } @@ -241,9 +241,9 @@ public func quaternionToEulerAngles_132(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(2 * (q2 * q3 + q0 * q1), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) - let e2 = asin(-2 * (q1 * q2 - q0 * q3)) - let e3 = atan2(2 * (q1 * q3 + q0 * q2), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) + let e1 = atan2(2.0 * (q2 * q3 + q0 * q1), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) + let e2 = asin(-2.0 * (q1 * q2 - q0 * q3)) + let e3 = atan2(2.0 * (q1 * q3 + q0 * q2), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) return Vec3f(e1, e2, e3) } @@ -265,9 +265,9 @@ public func quaternionToEulerAngles_213(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(2 * (q1 * q3 + q0 * q2), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) - let e2 = asin(-2 * (q2 * q3 - q0 * q1)) - let e3 = atan2(2 * (q1 * q2 + q0 * q3), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) + let e1 = atan2(2.0 * (q1 * q3 + q0 * q2), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) + let e2 = asin(-2.0 * (q2 * q3 - q0 * q1)) + let e3 = atan2(2.0 * (q1 * q2 + q0 * q3), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) return Vec3f(e1, e2, e3) } @@ -278,9 +278,9 @@ public func quaternionToEulerAngles_231(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(-2 * (q1 * q3 - q0 * q2), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) - let e2 = asin(2 * (q1 * q2 + q0 * q3)) - let e3 = atan2(-2 * (q2 * q3 - q0 * q1), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) + let e1 = atan2(-2.0 * (q1 * q3 - q0 * q2), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) + let e2 = asin(2.0 * (q1 * q2 + q0 * q3)) + let e3 = atan2(-2.0 * (q2 * q3 - q0 * q1), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) return Vec3f(e1, e2, e3) } @@ -302,9 +302,9 @@ public func quaternionToEulerAngles_312(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(-2 * (q1 * q2 - q0 * q3), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) - let e2 = asin(2 * (q2 * q3 + q0 * q1)) - let e3 = atan2(-2 * (q1 * q3 - q0 * q2), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) + let e1 = atan2(-2.0 * (q1 * q2 - q0 * q3), q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3) + let e2 = asin(2.0 * (q2 * q3 + q0 * q1)) + let e3 = atan2(-2.0 * (q1 * q3 - q0 * q2), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) return Vec3f(e1, e2, e3) } @@ -326,9 +326,9 @@ public func quaternionToEulerAngles_321(_ q: Quat4f) -> Vec3f { let q2 = q.y let q3 = q.x - let e1 = atan2(2 * (q1 * q2 + q0 * q3), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) - let e2 = asin(-2 * (q1 * q3 - q0 * q2)) - let e3 = atan2(2 * (q2 * q3 + q0 * q1), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) + let e1 = atan2(2.0 * (q1 * q2 + q0 * q3), q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3) + let e2 = asin(-2.0 * (q1 * q3 - q0 * q2)) + let e3 = atan2(2.0 * (q2 * q3 + q0 * q1), q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3) return Vec3f(e1, e2, e3) } diff --git a/Sources/FirebladeMath/Quat/Quaternion+Identity.swift b/Sources/FirebladeMath/Quat/Quaternion+Identity.swift index fb594f0..7493851 100644 --- a/Sources/FirebladeMath/Quat/Quaternion+Identity.swift +++ b/Sources/FirebladeMath/Quat/Quaternion+Identity.swift @@ -1,11 +1,11 @@ extension Quat4d { public static var identity: Quat4d { - Quat4d(0, 0, 0, 1) + Quat4d(0.0, 0.0, 0.0, 1.0) } } extension Quat4f { public static var identity: Quat4f { - Quat4f(0, 0, 0, 1) + Quat4f(0.0, 0.0, 0.0, 1.0) } } diff --git a/Sources/FirebladeMath/Quat/Quaternion+Operators.swift b/Sources/FirebladeMath/Quat/Quaternion+Operators.swift index e297c1b..fa79e63 100644 --- a/Sources/FirebladeMath/Quat/Quaternion+Operators.swift +++ b/Sources/FirebladeMath/Quat/Quaternion+Operators.swift @@ -3,8 +3,9 @@ /// - lhs: The scalar value. /// - rhs: The quaternion. /// - Returns: The scaled quaternion. +@inlinable public func * (lhs: Float, rhs: Quat4f) -> Quat4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a quaternion by a scalar. @@ -12,8 +13,9 @@ public func * (lhs: Float, rhs: Quat4f) -> Quat4f { /// - lhs: The quaternion. /// - rhs: The scalar value. /// - Returns: The scaled quaternion. +@inlinable public func * (lhs: Quat4f, rhs: Float) -> Quat4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Returns the product of two quaternions. @@ -21,8 +23,9 @@ public func * (lhs: Quat4f, rhs: Float) -> Quat4f { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The product of the two quaternions. +@inlinable public func * (lhs: Quat4f, rhs: Quat4f) -> Quat4f { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Returns a vector rotated by a quaternion. @@ -30,16 +33,18 @@ public func * (lhs: Quat4f, rhs: Quat4f) -> Quat4f { /// - lhs: The quaternion. /// - rhs: The vector to rotate. /// - Returns: The rotated vector. +@inlinable public func * (lhs: Quat4f, rhs: Vec3f) -> Vec3f { - act(lhs, rhs) + FirebladeMath.act(lhs, rhs) } /// Multiplies two quaternions and assigns the result to the left-hand side. /// - Parameters: /// - lhs: The left-hand side quaternion to be modified. /// - rhs: The right-hand side quaternion. +@inlinable public func *= (lhs: inout Quat4f, rhs: Quat4f) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } /// Adds two quaternions component-wise. @@ -47,8 +52,9 @@ public func *= (lhs: inout Quat4f, rhs: Quat4f) { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The sum of the two quaternions. +@inlinable public func + (lhs: Quat4f, rhs: Quat4f) -> Quat4f { - add(lhs, rhs) + FirebladeMath.add(lhs, rhs) } /// Subtracts the right-hand side quaternion from the left-hand side quaternion component-wise. @@ -56,8 +62,9 @@ public func + (lhs: Quat4f, rhs: Quat4f) -> Quat4f { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The difference of the two quaternions. +@inlinable public func - (lhs: Quat4f, rhs: Quat4f) -> Quat4f { - subtract(lhs, rhs) + FirebladeMath.subtract(lhs, rhs) } /// Multiplies a scalar by a quaternion. @@ -65,8 +72,9 @@ public func - (lhs: Quat4f, rhs: Quat4f) -> Quat4f { /// - lhs: The scalar value. /// - rhs: The quaternion. /// - Returns: The scaled quaternion. +@inlinable public func * (lhs: Double, rhs: Quat4d) -> Quat4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Multiplies a quaternion by a scalar. @@ -74,8 +82,9 @@ public func * (lhs: Double, rhs: Quat4d) -> Quat4d { /// - lhs: The quaternion. /// - rhs: The scalar value. /// - Returns: The scaled quaternion. +@inlinable public func * (lhs: Quat4d, rhs: Double) -> Quat4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Returns the product of two quaternions. @@ -83,8 +92,9 @@ public func * (lhs: Quat4d, rhs: Double) -> Quat4d { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The product of the two quaternions. +@inlinable public func * (lhs: Quat4d, rhs: Quat4d) -> Quat4d { - multiply(lhs, rhs) + FirebladeMath.multiply(lhs, rhs) } /// Returns a vector rotated by a quaternion. @@ -92,16 +102,18 @@ public func * (lhs: Quat4d, rhs: Quat4d) -> Quat4d { /// - lhs: The quaternion. /// - rhs: The vector to rotate. /// - Returns: The rotated vector. +@inlinable public func * (lhs: Quat4d, rhs: Vec3d) -> Vec3d { - act(lhs, rhs) + FirebladeMath.act(lhs, rhs) } /// Multiplies two quaternions and assigns the result to the left-hand side. /// - Parameters: /// - lhs: The left-hand side quaternion to be modified. /// - rhs: The right-hand side quaternion. +@inlinable public func *= (lhs: inout Quat4d, rhs: Quat4d) { - lhs = multiply(lhs, rhs) + lhs = FirebladeMath.multiply(lhs, rhs) } /// Adds two quaternions component-wise. @@ -109,8 +121,9 @@ public func *= (lhs: inout Quat4d, rhs: Quat4d) { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The sum of the two quaternions. +@inlinable public func + (lhs: Quat4d, rhs: Quat4d) -> Quat4d { - add(lhs, rhs) + FirebladeMath.add(lhs, rhs) } /// Subtracts the right-hand side quaternion from the left-hand side quaternion component-wise. @@ -118,6 +131,7 @@ public func + (lhs: Quat4d, rhs: Quat4d) -> Quat4d { /// - lhs: The left-hand side quaternion. /// - rhs: The right-hand side quaternion. /// - Returns: The difference of the two quaternions. +@inlinable public func - (lhs: Quat4d, rhs: Quat4d) -> Quat4d { - subtract(lhs, rhs) + FirebladeMath.subtract(lhs, rhs) }