From 7a506f21dca2ab612af0198bcbcff8ef192e9bfd Mon Sep 17 00:00:00 2001 From: _Redstone_c_ <2824517378@qq.com> Date: Mon, 4 Jan 2021 20:31:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=8E=20Github=20=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E8=BF=87=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 15 ++ FixedPointMath.uplugin | 24 ++ LICENSE | 21 ++ Resources/Icon128.png | Bin 0 -> 12699 bytes Source/FixedPointMath/FixedPointMath.Build.cs | 53 ++++ .../FixedPointMath/Private/BlueprintFixed.cpp | 35 +++ Source/FixedPointMath/Private/Fixed.cpp | 167 ++++++++++++ Source/FixedPointMath/Private/FixedPlane.cpp | 4 + .../FixedPointMath/Private/FixedPointMath.cpp | 22 ++ .../FixedPointMath/Private/FixedRotator.cpp | 6 + Source/FixedPointMath/Private/FixedVector.cpp | 13 + Source/FixedPointMath/Public/BlueprintFixed.h | 254 ++++++++++++++++++ Source/FixedPointMath/Public/Fixed.h | 158 +++++++++++ Source/FixedPointMath/Public/FixedPlane.h | 73 +++++ Source/FixedPointMath/Public/FixedPointMath.h | 17 ++ Source/FixedPointMath/Public/FixedRotator.h | 71 +++++ Source/FixedPointMath/Public/FixedVector.h | 106 ++++++++ 17 files changed, 1039 insertions(+) create mode 100644 .gitignore create mode 100644 FixedPointMath.uplugin create mode 100644 LICENSE create mode 100644 Resources/Icon128.png create mode 100644 Source/FixedPointMath/FixedPointMath.Build.cs create mode 100644 Source/FixedPointMath/Private/BlueprintFixed.cpp create mode 100644 Source/FixedPointMath/Private/Fixed.cpp create mode 100644 Source/FixedPointMath/Private/FixedPlane.cpp create mode 100644 Source/FixedPointMath/Private/FixedPointMath.cpp create mode 100644 Source/FixedPointMath/Private/FixedRotator.cpp create mode 100644 Source/FixedPointMath/Private/FixedVector.cpp create mode 100644 Source/FixedPointMath/Public/BlueprintFixed.h create mode 100644 Source/FixedPointMath/Public/Fixed.h create mode 100644 Source/FixedPointMath/Public/FixedPlane.h create mode 100644 Source/FixedPointMath/Public/FixedPointMath.h create mode 100644 Source/FixedPointMath/Public/FixedRotator.h create mode 100644 Source/FixedPointMath/Public/FixedVector.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93e6106 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +Binaries +DerivedDataCache +Intermediate +Saved +Build +.vscode +.vs +*.VC.db +*.opensdf +*.opendb +*.sdf +*.sln +*.suo +*.xcodeproj +*.xcworkspace diff --git a/FixedPointMath.uplugin b/FixedPointMath.uplugin new file mode 100644 index 0000000..46dbbd1 --- /dev/null +++ b/FixedPointMath.uplugin @@ -0,0 +1,24 @@ +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "1.0", + "FriendlyName": "Fixed Point Math", + "Description": "", + "Category": "Math", + "CreatedBy": "_Redstone_c_", + "CreatedByURL": "", + "DocsURL": "", + "MarketplaceURL": "", + "SupportURL": "", + "CanContainContent": false, + "IsBetaVersion": true, + "IsExperimentalVersion": false, + "Installed": false, + "Modules": [ + { + "Name": "FixedPointMath", + "Type": "Runtime", + "LoadingPhase": "Default" + } + ] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2295698 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 _Redstone_c_ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Resources/Icon128.png b/Resources/Icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..1231d4aad4d0d462fb7b178eb5b30aa61a10df0b GIT binary patch literal 12699 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 a;7#~yJh_ha>A&A^fRdb=Y>l)<=>Gxy=2LS3 literal 0 HcmV?d00001 diff --git a/Source/FixedPointMath/FixedPointMath.Build.cs b/Source/FixedPointMath/FixedPointMath.Build.cs new file mode 100644 index 0000000..4a9a945 --- /dev/null +++ b/Source/FixedPointMath/FixedPointMath.Build.cs @@ -0,0 +1,53 @@ +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; + +public class FixedPointMath : ModuleRules +{ + public FixedPointMath(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicIncludePaths.AddRange( + new string[] { + // ... add public include paths required here ... + } + ); + + + PrivateIncludePaths.AddRange( + new string[] { + // ... add other private include paths required here ... + } + ); + + + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + // ... add other public dependencies that you statically link with here ... + } + ); + + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + // ... add private dependencies that you statically link with here ... + } + ); + + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } +} diff --git a/Source/FixedPointMath/Private/BlueprintFixed.cpp b/Source/FixedPointMath/Private/BlueprintFixed.cpp new file mode 100644 index 0000000..be414fd --- /dev/null +++ b/Source/FixedPointMath/Private/BlueprintFixed.cpp @@ -0,0 +1,35 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "BlueprintFixed.h" + +FFixed UBlueprintFixedMath::Divide_FixedFixed(FFixed A, FFixed B) +{ + if (B == 0) + { + FFrame::KismetExecutionMessage(TEXT("Divide by zero: Divide_FixedFixed"), ELogVerbosity::Warning, FName("DivideByZeroWarning")); + return 0; + } + + return A / B; +} + +FFixed UBlueprintFixedMath::Sqrt_Fixed(FFixed A) +{ + if (A >= 0) + return FFixedMath::Sqrt(A); + + FFrame::KismetExecutionMessage(TEXT("Attempt to take Sqrt_Fixed() of negative number - returning 0."), ELogVerbosity::Warning, FName("NegativeSqrtWarning")); + return 0; +} + +FFixedVector UBlueprintFixedMath::Divide_FixedVectorFixedVector(FFixedVector A, FFixedVector B) +{ + if (B == FFixedVector(0)) + { + FFrame::KismetExecutionMessage(TEXT("Divide by zero: Divide_FixedFixed"), ELogVerbosity::Warning, FName("DivideByZeroWarning")); + return FFixedVector(0); + } + + return A / B; +} diff --git a/Source/FixedPointMath/Private/Fixed.cpp b/Source/FixedPointMath/Private/Fixed.cpp new file mode 100644 index 0000000..3e10909 --- /dev/null +++ b/Source/FixedPointMath/Private/Fixed.cpp @@ -0,0 +1,167 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Fixed.h" + +const FFixed FFixed::Unit = FFixed::FromBit(1); +const FFixed FFixed::Pi = FFixed::FromBit(12868); + +namespace +{ + constexpr int64 TanTable[] = + { + 0, 6, 13, 19, 25, 31, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 101, 107, 113, 119, 126, 132, 138, 145, 151, + 157, 163, 170, 176, 182, 189, 195, 201, 208, 214, 220, 226, 233, 239, 245, 252, 258, 264, 271, 277, 283, 290, + 296, 302, 308, 315, 321, 327, 334, 340, 346, 353, 359, 365, 372, 378, 384, 391, 397, 403, 410, 416, 422, 429, + 435, 442, 448, 454, 461, 467, 473, 480, 486, 492, 499, 505, 512, 518, 524, 531, 537, 544, 550, 556, 563, 569, + 576, 582, 588, 595, 601, 608, 614, 620, 627, 633, 640, 646, 653, 659, 665, 672, 678, 685, 691, 698, 704, 711, + 717, 724, 730, 737, 743, 750, 756, 763, 769, 776, 782, 789, 795, 802, 808, 815, 821, 828, 834, 841, 847, 854, + 861, 867, 874, 880, 887, 893, 900, 907, 913, 920, 926, 933, 940, 946, 953, 959, 966, 973, 979, 986, 993, 999, + 1006, 1013, 1019, 1026, 1033, 1039, 1046, 1053, 1059, 1066, 1073, 1080, 1086, 1093, 1100, 1107, 1113, 1120, 1127, + 1134, 1140, 1147, 1154, 1161, 1167, 1174, 1181, 1188, 1195, 1201, 1208, 1215, 1222, 1229, 1236, 1243, 1249, 1256, + 1263, 1270, 1277, 1284, 1291, 1298, 1305, 1311, 1318, 1325, 1332, 1339, 1346, 1353, 1360, 1367, 1374, 1381, 1388, + 1395, 1402, 1409, 1416, 1423, 1430, 1437, 1444, 1451, 1458, 1466, 1473, 1480, 1487, 1494, 1501, 1508, 1515, 1523, + 1530, 1537, 1544, 1551, 1558, 1566, 1573, 1580, 1587, 1594, 1602, 1609, 1616, 1623, 1631, 1638, 1645, 1653, 1660, + 1667, 1675, 1682, 1689, 1697, 1704, 1711, 1719, 1726, 1734, 1741, 1748, 1756, 1763, 1771, 1778, 1786, 1793, 1801, + 1808, 1816, 1823, 1831, 1838, 1846, 1853, 1861, 1869, 1876, 1884, 1891, 1899, 1907, 1914, 1922, 1930, 1937, 1945, + 1953, 1960, 1968, 1976, 1984, 1991, 1999, 2007, 2015, 2023, 2030, 2038, 2046, 2054, 2062, 2070, 2078, 2085, 2093, + 2101, 2109, 2117, 2125, 2133, 2141, 2149, 2157, 2165, 2173, 2181, 2189, 2197, 2206, 2214, 2222, 2230, 2238, 2246, + 2254, 2263, 2271, 2279, 2287, 2296, 2304, 2312, 2320, 2329, 2337, 2345, 2354, 2362, 2370, 2379, 2387, 2396, 2404, + 2413, 2421, 2429, 2438, 2447, 2455, 2464, 2472, 2481, 2489, 2498, 2507, 2515, 2524, 2533, 2541, 2550, 2559, 2567, + 2576, 2585, 2594, 2603, 2611, 2620, 2629, 2638, 2647, 2656, 2665, 2674, 2683, 2692, 2701, 2710, 2719, 2728, 2737, + 2746, 2755, 2764, 2773, 2783, 2792, 2801, 2810, 2819, 2829, 2838, 2847, 2857, 2866, 2875, 2885, 2894, 2904, 2913, + 2922, 2932, 2941, 2951, 2961, 2970, 2980, 2989, 2999, 3009, 3018, 3028, 3038, 3048, 3057, 3067, 3077, 3087, 3097, + 3107, 3116, 3126, 3136, 3146, 3156, 3166, 3176, 3186, 3197, 3207, 3217, 3227, 3237, 3247, 3258, 3268, 3278, 3289, + 3299, 3309, 3320, 3330, 3341, 3351, 3362, 3372, 3383, 3393, 3404, 3414, 3425, 3436, 3446, 3457, 3468, 3479, 3490, + 3500, 3511, 3522, 3533, 3544, 3555, 3566, 3577, 3588, 3600, 3611, 3622, 3633, 3644, 3656, 3667, 3678, 3690, 3701, + 3712, 3724, 3735, 3747, 3758, 3770, 3782, 3793, 3805, 3817, 3828, 3840, 3852, 3864, 3876, 3888, 3900, 3912, 3924, + 3936, 3948, 3960, 3972, 3984, 3997, 4009, 4021, 4034, 4046, 4058, 4071, 4083, 4096, 4109, 4121, 4134, 4147, 4159, + 4172, 4185, 4198, 4211, 4224, 4237, 4250, 4263, 4276, 4289, 4302, 4315, 4329, 4342, 4355, 4369, 4382, 4396, 4409, + 4423, 4436, 4450, 4464, 4478, 4491, 4505, 4519, 4533, 4547, 4561, 4575, 4589, 4604, 4618, 4632, 4647, 4661, 4675, + 4690, 4704, 4719, 4734, 4748, 4763, 4778, 4793, 4808, 4823, 4838, 4853, 4868, 4883, 4898, 4914, 4929, 4944, 4960, + 4975, 4991, 5007, 5022, 5038, 5054, 5070, 5086, 5102, 5118, 5134, 5150, 5166, 5183, 5199, 5215, 5232, 5249, 5265, + 5282, 5299, 5315, 5332, 5349, 5366, 5383, 5401, 5418, 5435, 5453, 5470, 5488, 5505, 5523, 5541, 5558, 5576, 5594, + 5612, 5630, 5649, 5667, 5685, 5704, 5722, 5741, 5759, 5778, 5797, 5816, 5835, 5854, 5873, 5892, 5912, 5931, 5951, + 5970, 5990, 6010, 6029, 6049, 6069, 6090, 6110, 6130, 6151, 6171, 6192, 6212, 6233, 6254, 6275, 6296, 6317, 6338, + 6360, 6381, 6403, 6425, 6446, 6468, 6490, 6512, 6535, 6557, 6579, 6602, 6625, 6647, 6670, 6693, 6716, 6740, 6763, + 6786, 6810, 6834, 6858, 6882, 6906, 6930, 6954, 6979, 7003, 7028, 7053, 7078, 7103, 7128, 7153, 7179, 7205, 7230, + 7256, 7282, 7309, 7335, 7362, 7388, 7415, 7442, 7469, 7496, 7524, 7551, 7579, 7607, 7635, 7663, 7691, 7720, 7749, + 7777, 7807, 7836, 7865, 7895, 7924, 7954, 7984, 8015, 8045, 8076, 8106, 8137, 8169, 8200, 8231, 8263, 8295, 8327, + 8360, 8392, 8425, 8458, 8491, 8525, 8558, 8592, 8626, 8660, 8695, 8729, 8764, 8800, 8835, 8871, 8906, 8943, 8979, + 9016, 9052, 9089, 9127, 9164, 9202, 9240, 9279, 9317, 9356, 9396, 9435, 9475, 9515, 9555, 9596, 9637, 9678, 9720, + 9761, 9803, 9846, 9889, 9932, 9975, 10019, 10063, 10107, 10152, 10197, 10242, 10288, 10334, 10381, 10427, 10475, + 10522, 10570, 10618, 10667, 10716, 10766, 10816, 10866, 10917, 10968, 11019, 11071, 11124, 11177, 11230, 11284, + 11338, 11392, 11448, 11503, 11559, 11616, 11673, 11730, 11788, 11847, 11906, 11966, 12026, 12087, 12148, 12210, + 12272, 12335, 12399, 12463, 12528, 12593, 12659, 12726, 12793, 12861, 12929, 12999, 13068, 13139, 13210, 13282, + 13355, 13429, 13503, 13578, 13653, 13730, 13807, 13885, 13964, 14044, 14124, 14206, 14288, 14371, 14455, 14540, + 14626, 14713, 14801, 14890, 14980, 15071, 15162, 15255, 15349, 15444, 15540, 15638, 15736, 15836, 15937, 16039, + 16142, 16246, 16352, 16459, 16568, 16677, 16789, 16901, 17015, 17131, 17247, 17366, 17486, 17607, 17731, 17856, + 17982, 18110, 18240, 18372, 18506, 18641, 18779, 18918, 19059, 19203, 19348, 19496, 19645, 19797, 19951, 20108, + 20267, 20428, 20592, 20758, 20927, 21099, 21273, 21451, 21631, 21814, 22000, 22189, 22381, 22576, 22775, 22978, + 23183, 23393, 23606, 23823, 24044, 24268, 24497, 24730, 24968, 25210, 25457, 25708, 25964, 26226, 26492, 26764, + 27041, 27324, 27613, 27908, 28209, 28517, 28831, 29152, 29480, 29815, 30158, 30509, 30868, 31236, 31612, 31997, + 32391, 32795, 33209, 33634, 34070, 34516, 34975, 35445, 35928, 36425, 36935, 37459, 37999, 38554, 39125, 39713, + 40319, 40943, 41587, 42252, 42937, 43646, 44377, 45134, 45916, 46726, 47564, 48433, 49335, 50270, 51241, 52250, + 53299, 54391, 55528, 56714, 57951, 59243, 60594, 62007, 63488, 65040, 66671, 68384, 70188, 72089, 74096, 76217, + 78463, 80845, 83376, 86070, 88943, 92014, 95305, 98839, 102645, 106755, 111207, 116046, 121326, 127107, 133467, + 140496, 148305, 157034, 166853, 177980, 190698, 205371, 222490, 242720, 266997, 296667, 333755, 381439, 445017, + 534025, 667536, 890053, 1335084, 2670175, + }; + + constexpr int64 CosTable[] = + { + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4094, + 4094, 4094, 4094, 4094, 4093, 4093, 4093, 4093, 4092, 4092, 4092, 4092, 4091, 4091, 4091, 4090, 4090, 4090, 4089, + 4089, 4089, 4088, 4088, 4088, 4087, 4087, 4086, 4086, 4085, 4085, 4084, 4084, 4083, 4083, 4082, 4082, 4081, 4081, + 4080, 4080, 4079, 4079, 4078, 4077, 4077, 4076, 4076, 4075, 4074, 4074, 4073, 4072, 4072, 4071, 4070, 4070, 4069, + 4068, 4067, 4067, 4066, 4065, 4064, 4064, 4063, 4062, 4061, 4060, 4060, 4059, 4058, 4057, 4056, 4055, 4054, 4053, + 4053, 4052, 4051, 4050, 4049, 4048, 4047, 4046, 4045, 4044, 4043, 4042, 4041, 4040, 4039, 4038, 4037, 4036, 4035, + 4034, 4032, 4031, 4030, 4029, 4028, 4027, 4026, 4024, 4023, 4022, 4021, 4020, 4019, 4017, 4016, 4015, 4014, 4012, + 4011, 4010, 4008, 4007, 4006, 4005, 4003, 4002, 4001, 3999, 3998, 3996, 3995, 3994, 3992, 3991, 3989, 3988, 3987, + 3985, 3984, 3982, 3981, 3979, 3978, 3976, 3975, 3973, 3972, 3970, 3969, 3967, 3965, 3964, 3962, 3961, 3959, 3958, + 3956, 3954, 3953, 3951, 3949, 3948, 3946, 3944, 3943, 3941, 3939, 3937, 3936, 3934, 3932, 3930, 3929, 3927, 3925, + 3923, 3921, 3920, 3918, 3916, 3914, 3912, 3910, 3909, 3907, 3905, 3903, 3901, 3899, 3897, 3895, 3893, 3891, 3889, + 3887, 3885, 3883, 3881, 3879, 3877, 3875, 3873, 3871, 3869, 3867, 3865, 3863, 3861, 3859, 3857, 3854, 3852, 3850, + 3848, 3846, 3844, 3842, 3839, 3837, 3835, 3833, 3831, 3828, 3826, 3824, 3822, 3819, 3817, 3815, 3812, 3810, 3808, + 3805, 3803, 3801, 3798, 3796, 3794, 3791, 3789, 3787, 3784, 3782, 3779, 3777, 3775, 3772, 3770, 3767, 3765, 3762, + 3760, 3757, 3755, 3752, 3750, 3747, 3745, 3742, 3739, 3737, 3734, 3732, 3729, 3727, 3724, 3721, 3719, 3716, 3713, + 3711, 3708, 3705, 3703, 3700, 3697, 3695, 3692, 3689, 3686, 3684, 3681, 3678, 3675, 3673, 3670, 3667, 3664, 3661, + 3659, 3656, 3653, 3650, 3647, 3644, 3642, 3639, 3636, 3633, 3630, 3627, 3624, 3621, 3618, 3615, 3612, 3609, 3606, + 3603, 3600, 3597, 3594, 3591, 3588, 3585, 3582, 3579, 3576, 3573, 3570, 3567, 3564, 3561, 3558, 3555, 3551, 3548, + 3545, 3542, 3539, 3536, 3532, 3529, 3526, 3523, 3520, 3516, 3513, 3510, 3507, 3504, 3500, 3497, 3494, 3490, 3487, + 3484, 3481, 3477, 3474, 3471, 3467, 3464, 3461, 3457, 3454, 3450, 3447, 3444, 3440, 3437, 3433, 3430, 3426, 3423, + 3420, 3416, 3413, 3409, 3406, 3402, 3399, 3395, 3392, 3388, 3385, 3381, 3378, 3374, 3370, 3367, 3363, 3360, 3356, + 3352, 3349, 3345, 3342, 3338, 3334, 3331, 3327, 3323, 3320, 3316, 3312, 3309, 3305, 3301, 3297, 3294, 3290, 3286, + 3282, 3279, 3275, 3271, 3267, 3264, 3260, 3256, 3252, 3248, 3244, 3241, 3237, 3233, 3229, 3225, 3221, 3217, 3214, + 3210, 3206, 3202, 3198, 3194, 3190, 3186, 3182, 3178, 3174, 3170, 3166, 3162, 3158, 3154, 3150, 3146, 3142, 3138, + 3134, 3130, 3126, 3122, 3118, 3114, 3110, 3106, 3102, 3097, 3093, 3089, 3085, 3081, 3077, 3073, 3068, 3064, 3060, + 3056, 3052, 3048, 3043, 3039, 3035, 3031, 3026, 3022, 3018, 3014, 3009, 3005, 3001, 2997, 2992, 2988, 2984, 2979, + 2975, 2971, 2967, 2962, 2958, 2953, 2949, 2945, 2940, 2936, 2932, 2927, 2923, 2918, 2914, 2910, 2905, 2901, 2896, + 2892, 2887, 2883, 2878, 2874, 2870, 2865, 2861, 2856, 2852, 2847, 2843, 2838, 2833, 2829, 2824, 2820, 2815, 2811, + 2806, 2802, 2797, 2792, 2788, 2783, 2779, 2774, 2769, 2765, 2760, 2755, 2751, 2746, 2741, 2737, 2732, 2727, 2723, + 2718, 2713, 2709, 2704, 2699, 2694, 2690, 2685, 2680, 2675, 2671, 2666, 2661, 2656, 2652, 2647, 2642, 2637, 2632, + 2628, 2623, 2618, 2613, 2608, 2603, 2598, 2594, 2589, 2584, 2579, 2574, 2569, 2564, 2559, 2555, 2550, 2545, 2540, + 2535, 2530, 2525, 2520, 2515, 2510, 2505, 2500, 2495, 2490, 2485, 2480, 2475, 2470, 2465, 2460, 2455, 2450, 2445, + 2440, 2435, 2430, 2425, 2420, 2415, 2410, 2405, 2399, 2394, 2389, 2384, 2379, 2374, 2369, 2364, 2359, 2353, 2348, + 2343, 2338, 2333, 2328, 2322, 2317, 2312, 2307, 2302, 2296, 2291, 2286, 2281, 2276, 2270, 2265, 2260, 2255, 2249, + 2244, 2239, 2234, 2228, 2223, 2218, 2213, 2207, 2202, 2197, 2191, 2186, 2181, 2175, 2170, 2165, 2159, 2154, 2149, + 2143, 2138, 2133, 2127, 2122, 2117, 2111, 2106, 2100, 2095, 2090, 2084, 2079, 2073, 2068, 2062, 2057, 2052, 2046, + 2041, 2035, 2030, 2024, 2019, 2013, 2008, 2002, 1997, 1992, 1986, 1981, 1975, 1970, 1964, 1958, 1953, 1947, 1942, + 1936, 1931, 1925, 1920, 1914, 1909, 1903, 1898, 1892, 1886, 1881, 1875, 1870, 1864, 1858, 1853, 1847, 1842, 1836, + 1830, 1825, 1819, 1813, 1808, 1802, 1797, 1791, 1785, 1780, 1774, 1768, 1763, 1757, 1751, 1746, 1740, 1734, 1729, + 1723, 1717, 1711, 1706, 1700, 1694, 1689, 1683, 1677, 1671, 1666, 1660, 1654, 1648, 1643, 1637, 1631, 1625, 1620, + 1614, 1608, 1602, 1596, 1591, 1585, 1579, 1573, 1567, 1562, 1556, 1550, 1544, 1538, 1533, 1527, 1521, 1515, 1509, + 1503, 1498, 1492, 1486, 1480, 1474, 1468, 1462, 1457, 1451, 1445, 1439, 1433, 1427, 1421, 1415, 1409, 1404, 1398, + 1392, 1386, 1380, 1374, 1368, 1362, 1356, 1350, 1344, 1338, 1332, 1327, 1321, 1315, 1309, 1303, 1297, 1291, 1285, + 1279, 1273, 1267, 1261, 1255, 1249, 1243, 1237, 1231, 1225, 1219, 1213, 1207, 1201, 1195, 1189, 1183, 1177, 1171, + 1165, 1159, 1153, 1147, 1141, 1135, 1129, 1123, 1117, 1111, 1105, 1099, 1092, 1086, 1080, 1074, 1068, 1062, 1056, + 1050, 1044, 1038, 1032, 1026, 1020, 1014, 1007, 1001, 995, 989, 983, 977, 971, 965, 959, 953, 946, 940, 934, 928, + 922, 916, 910, 904, 897, 891, 885, 879, 873, 867, 861, 854, 848, 842, 836, 830, 824, 818, 811, 805, 799, 793, 787, + 781, 774, 768, 762, 756, 750, 744, 737, 731, 725, 719, 713, 706, 700, 694, 688, 682, 675, 669, 663, 657, 651, 644, + 638, 632, 626, 620, 613, 607, 601, 595, 589, 582, 576, 570, 564, 557, 551, 545, 539, 533, 526, 520, 514, 508, 501, + 495, 489, 483, 476, 470, 464, 458, 451, 445, 439, 433, 426, 420, 414, 408, 401, 395, 389, 383, 376, 370, 364, 358, + 351, 345, 339, 333, 326, 320, 314, 308, 301, 295, 289, 283, 276, 270, 264, 257, 251, 245, 239, 232, 226, 220, 214, + 207, 201, 195, 188, 182, 176, 170, 163, 157, 151, 144, 138, 132, 126, 119, 113, 107, 101, 94, 88, 82, 75, 69, 63, + 57, 50, 44, 38, 31, 25, 19, 13, 6, + }; +} + +FFixed FFixedMath::TanUnit(FFixed A) +{ + FFixed Result; + bool Signed = A.Data < 0; + A.Data = FMath::Abs(A.Data); + int64 Temp = A.Data % 2048; + if (Temp == 1024) Result.Data = INT64_MAX; + else if (Temp < 1024) + Result.Data = TanTable[Temp]; + else + Result.Data = -TanTable[2048 - Temp]; + Result.Data *= Signed ? -1 : 1; + return Result; +} + +FFixed FFixedMath::SinUnit(FFixed A) +{ + FFixed Quarter; + Quarter.Data = 1024; + return CosUnit(A - Quarter); +} + +FFixed FFixedMath::CosUnit(FFixed A) +{ + FFixed Result; + A.Data = FMath::Abs(A.Data); + int64 Temp = A.Data % 2048; + bool Signed = A.Data % 4096 < 2048; + if (Temp == 1024) Result.Data = 0; + else if (Signed && Temp < 1024) + Result.Data = CosTable[Temp]; + else if (Signed && Temp >= 1024) + Result.Data = -CosTable[2048 - Temp]; + else if (Temp < 1024) + Result.Data = -CosTable[Temp]; + else + Result.Data = CosTable[2048 - Temp]; + return Result; +} diff --git a/Source/FixedPointMath/Private/FixedPlane.cpp b/Source/FixedPointMath/Private/FixedPlane.cpp new file mode 100644 index 0000000..4323651 --- /dev/null +++ b/Source/FixedPointMath/Private/FixedPlane.cpp @@ -0,0 +1,4 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "FixedPlane.h" diff --git a/Source/FixedPointMath/Private/FixedPointMath.cpp b/Source/FixedPointMath/Private/FixedPointMath.cpp new file mode 100644 index 0000000..730242f --- /dev/null +++ b/Source/FixedPointMath/Private/FixedPointMath.cpp @@ -0,0 +1,22 @@ +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. + +#include "FixedPointMath.h" + +DEFINE_LOG_CATEGORY(LogFixedPointMath); + +#define LOCTEXT_NAMESPACE "FFixedPointMathModule" + +void FFixedPointMathModule::StartupModule() +{ + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module +} + +void FFixedPointMathModule::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FFixedPointMathModule, FixedPointMath) \ No newline at end of file diff --git a/Source/FixedPointMath/Private/FixedRotator.cpp b/Source/FixedPointMath/Private/FixedRotator.cpp new file mode 100644 index 0000000..74abe03 --- /dev/null +++ b/Source/FixedPointMath/Private/FixedRotator.cpp @@ -0,0 +1,6 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "FixedRotator.h" + +const FFixedRotator FFixedRotator::ZeroRotator = FFixedRotator(0); diff --git a/Source/FixedPointMath/Private/FixedVector.cpp b/Source/FixedPointMath/Private/FixedVector.cpp new file mode 100644 index 0000000..49d2535 --- /dev/null +++ b/Source/FixedPointMath/Private/FixedVector.cpp @@ -0,0 +1,13 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "FixedVector.h" + +const FFixedVector FFixedVector::ZeroVector = FFixedVector(0); +const FFixedVector FFixedVector::OneVector = FFixedVector(1); +const FFixedVector FFixedVector::UpVector = FFixedVector(0, 0, 1); +const FFixedVector FFixedVector::DownVector = FFixedVector(0, 0, -1); +const FFixedVector FFixedVector::ForwardVector = FFixedVector(1, 0, 0); +const FFixedVector FFixedVector::BackwardVector = FFixedVector(-1, 0, 0); +const FFixedVector FFixedVector::RightVector = FFixedVector(0, 1, 0); +const FFixedVector FFixedVector::LeftVector = FFixedVector(0, -1, 0); diff --git a/Source/FixedPointMath/Public/BlueprintFixed.h b/Source/FixedPointMath/Public/BlueprintFixed.h new file mode 100644 index 0000000..1358508 --- /dev/null +++ b/Source/FixedPointMath/Public/BlueprintFixed.h @@ -0,0 +1,254 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Fixed.h" +#include "FixedPlane.h" +#include "FixedVector.h" +#include "FixedRotator.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "BlueprintFixed.generated.h" + +UCLASS(meta = (BlueprintThreadSafe, ScriptName = "FixedMathLibrary")) +class FIXEDPOINTMATH_API UBlueprintFixedMath : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + // 一般: + // 类型转换 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixed (byte)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixed Conv_ByteToFixed(uint8 InByte) { return static_cast(InByte); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixed (integer)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixed Conv_IntToFixed(int32 InInt) { return static_cast(InInt); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixed (float)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixed Conv_FloatToFixed(float InFloat) { return static_cast(InFloat); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToByte (fixed)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE uint8 Conv_FixedToByte(FFixed InFixed) { return static_cast(InFixed); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToInt (fixed)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE int32 Conv_FixedToInt(FFixed InFixed) { return static_cast(InFixed); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFloat (fixed)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE float Conv_FixedToFloat(FFixed InFixed) { return static_cast(InFixed); } + + // 四则运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed * fixed", CompactNodeTitle = "*", Keywords = "* multiply", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|Fixed") + static FORCEINLINE FFixed Multiply_FixedFixed(FFixed A, FFixed B) { return A * B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed / fixed", CompactNodeTitle = "/", Keywords = "/ divide division"), Category = "Math|Fixed") + static FFixed Divide_FixedFixed(FFixed A, FFixed B); + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed + fixed", CompactNodeTitle = "+", Keywords = "+ add plus", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|Fixed") + static FORCEINLINE FFixed Add_FixedFixed(FFixed A, FFixed B) { return A + B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed - fixed", CompactNodeTitle = "-", Keywords = "- subtract minus"), Category = "Math|Fixed") + static FORCEINLINE FFixed Subtract_FixedFixed(FFixed A, FFixed B) { return A - B; } + + // 布尔运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed < fixed", CompactNodeTitle = "<", Keywords = "< less"), Category = "Math|Fixed") + static FORCEINLINE bool Less_FixedFixed(FFixed A, FFixed B) { return A < B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed > fixed", CompactNodeTitle = ">", Keywords = "> greater"), Category = "Math|Fixed") + static FORCEINLINE bool Greater_FixedFixed(FFixed A, FFixed B) { return A > B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed <= fixed", CompactNodeTitle = "<=", Keywords = "<= less"), Category = "Math|Fixed") + static FORCEINLINE bool LessEqual_FixedFixed(FFixed A, FFixed B) { return A <= B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "fixed >= fixed", CompactNodeTitle = ">=", Keywords = ">= greater"), Category = "Math|Fixed") + static FORCEINLINE bool GreaterEqual_FixedFixed(FFixed A, FFixed B) { return A >= B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal (fixed)", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Math|Fixed") + static FORCEINLINE bool EqualEqual_FixedFixed(FFixed A, FFixed B) { return A == B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "NotEqual (fixed)", CompactNodeTitle = "!=", Keywords = "!= not equal"), Category = "Math|Fixed") + static FORCEINLINE bool NotEqual_FixedFixed(FFixed A, FFixed B) { return A != A; } + + // 常用数学 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Absolute (fixed)", CompactNodeTitle = "ABS"), Category = "Math|Fixed") + static FORCEINLINE FFixed Abs_Fixed(FFixed A) { return FFixedMath::Abs(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Min (fixed)", CompactNodeTitle = "MIN", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|Fixed") + static FORCEINLINE FFixed Min_FixedFixed(FFixed A, FFixed B) { return FFixedMath::Min(A, B); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Max (fixed)", CompactNodeTitle = "MAX", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|Fixed") + static FORCEINLINE FFixed Max_FixedFixed(FFixed A, FFixed B) { return FFixedMath::Max(A, B); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Clamp (fixed)"), Category = "Math|Fixed") + static FORCEINLINE FFixed Clamp_Fixed(FFixed Value, FFixed Min, FFixed Max) { return FFixedMath::Clamp(Value, Min, Max); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "InRange (fixed)", Min = "0", Max = "10"), Category = "Math|Fixed") + static FORCEINLINE bool InRange_Fixed(FFixed Value, FFixed Min, FFixed Max, bool InclusiveMin = true, bool InclusiveMax = true) + { return ((InclusiveMin ? (Value >= Min) : (Value > Min)) && (InclusiveMax ? (Value <= Max) : (Value < Max))); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Sqrt (fixed)", Keywords = "square root", CompactNodeTitle = "SQRT"), Category = "Math|Fixed") + static FFixed Sqrt_Fixed(FFixed A); + + // 三角函数 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Get PI (fixed)", CompactNodeTitle = "PI"), Category = "Math|Trig") + static FORCEINLINE FFixed GetPI_Fixed() { return FFixed::Pi; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Tan (Radians)", CompactNodeTitle = "TAN"), Category = "Math|Trig") + static FORCEINLINE FFixed Tan_Fixed(FFixed A) { return FFixedMath::Tan(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Sin (Radians)", CompactNodeTitle = "SIN"), Category = "Math|Trig") + static FORCEINLINE FFixed Sin_Fixed(FFixed A) { return FFixedMath::Sin(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Cos (Radians)", CompactNodeTitle = "COS"), Category = "Math|Trig") + static FORCEINLINE FFixed Cos_Fixed(FFixed A) { return FFixedMath::Cos(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Tan (Degrees)", CompactNodeTitle = "TANd"), Category = "Math|Trig") + static FORCEINLINE FFixed TanDeg_Fixed(FFixed A) { return FFixedMath::TanDeg(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Sin (Degrees)", CompactNodeTitle = "SINd"), Category = "Math|Trig") + static FORCEINLINE FFixed SinDeg_Fixed(FFixed A) { return FFixedMath::SinDeg(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Cos (Degrees)", CompactNodeTitle = "COSd"), Category = "Math|Trig") + static FORCEINLINE FFixed CosDeg_Fixed(FFixed A) { return FFixedMath::CosDeg(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Tan (Unit)", CompactNodeTitle = "TANu"), Category = "Math|Trig") + static FORCEINLINE FFixed TanUnit_Fixed(FFixed A) { return FFixedMath::TanUnit(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Sin (Unit)", CompactNodeTitle = "SINu"), Category = "Math|Trig") + static FORCEINLINE FFixed SinUnit_Fixed(FFixed A) { return FFixedMath::SinUnit(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Cos (Unit)", CompactNodeTitle = "COSu"), Category = "Math|Trig") + static FORCEINLINE FFixed CosUnit_Fixed(FFixed A) { return FFixedMath::CosUnit(A); } + + // 向量: + // 类型转换 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixedVector (fixed)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixedVector Conv_FixedToFixedVector(FFixed InFixed) { return static_cast(InFixed); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixedVector (Vector)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixedVector Conv_VectorToFixedVector(FVector InVector) { return static_cast(InVector); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixedVector (IntVector)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixedVector Conv_IntVectorToFixedVector(FIntVector InVector) { return static_cast(InVector); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToVector (FixedVector)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FVector Conv_FixedVectorToVector(FFixedVector InVector) { return FVector(InVector); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToIntVector (FixedVector)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FIntVector Conv_FixedVectorToIntVector(FFixedVector InVector) { return FIntVector(InVector); } + + // 四则运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "FixedVector * FixedVector", CompactNodeTitle = "*", Keywords = "* multiply", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Multiply_FixedVectorFixedVector(FFixedVector A, FFixedVector B) { return A * B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "FixedVector / FixedVector", CompactNodeTitle = "/", Keywords = "/ divide division"), Category = "Math|FixedVector") + static FFixedVector Divide_FixedVectorFixedVector(FFixedVector A, FFixedVector B); + + UFUNCTION(BlueprintPure, meta = (DisplayName = "FixedVector + FixedVector", CompactNodeTitle = "+", Keywords = "+ add plus", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Add_FixedVectorFixedVector(FFixedVector A, FFixedVector B) { return A + B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "FixedVector - FixedVector", CompactNodeTitle = "-", Keywords = "- subtract minus"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Subtract_FixedVectorFixedVector(FFixedVector A, FFixedVector B) { return A - B; } + + // 布尔运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal (FixedVector)", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Math|FixedVector") + static FORCEINLINE bool EqualEqual_FixedVectorFixedVector(FFixedVector A, FFixedVector B) { return A == B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "NotEqual (FixedVector)", CompactNodeTitle = "!=", Keywords = "!= not equal"), Category = "Math|FixedVector") + static FORCEINLINE bool NotEqual_FixedVectorFixedVector(FFixedVector A, FFixedVector B) { return A != A; } + + // 常用数学 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Absolute (FixedVector)", CompactNodeTitle = "ABS"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Abs_FixedVector(FFixedVector A) { return FFixedMath::ComponentAbs(A); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Min (FixedVector)", CompactNodeTitle = "MIN", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Min_FixedVector(FFixedVector A, FFixedVector B) { return FFixedMath::ComponentMin(A, B); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Max (FixedVector)", CompactNodeTitle = "MAX", CommutativeAssociativeBinaryOperator = "true"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Max_FixedVector(FFixedVector A, FFixedVector B) { return FFixedMath::ComponentMax(A, B); } + + UFUNCTION(BlueprintPure, meta = (ScriptMethod = "Negated", ScriptOperator = "neg"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector NegateFixedVector(FFixedVector A) { return -A; } + + // 向量运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Cross Product", CompactNodeTitle = "cross", ScriptMethod = "Cross", ScriptOperator = "^"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Cross_FixedVectorFixedVector(const FFixedVector& A, const FFixedVector& B) { return FFixedMath::CrossProduct(A, B); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Dot Product", CompactNodeTitle = "dot", ScriptMethod = "Dot", ScriptOperator = "|"), Category = "Math|FixedVector") + static FORCEINLINE FFixed Dot_FixedVectorFixedVector(const FFixedVector& A, const FFixedVector& B) { return FFixedMath::DotProduct(A, B); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "VectorLength", ScriptMethod = "Length", Keywords = "magnitude"), Category = "Math|FixedVector") + static FORCEINLINE FFixed Length_FixedVector(const FFixedVector& A) { return A.Size(); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "VectorLengthSquared", ScriptMethod = "LengthSquared", Keywords = "magnitude"), Category = "Math|FixedVector") + static FORCEINLINE FFixed LengthSquared_FixedVector(const FFixedVector& A) { return A.SizeSquared(); } + + UFUNCTION(BlueprintPure, meta = (ScriptMethod = "IsZero"), Category = "Math|FixedVector") + static FORCEINLINE bool IsZero_FixedVector(const FFixedVector& A) { return A.IsZero(); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Normalize (FixedVector)", ScriptMethod = "Normalize", Keywords = "Unit Vector"), Category = "Math|FixedVector") + static FORCEINLINE FFixedVector Normalize_FixedVector(const FFixedVector& A) { return FFixedMath::Normalize(A); } + + // 旋转: + // Make/Break + + UFUNCTION(BlueprintPure, Category = "Math|FixedRotator", meta = (Keywords = "construct build rotation rotate rotator makerotator", NativeMakeFunc)) + static FFixedRotator MakeFixedRotator(UPARAM(DisplayName = "X (Roll)") FFixed Roll, UPARAM(DisplayName = "Y (Pitch)") FFixed Pitch, UPARAM(DisplayName = "Z (Yaw)") FFixed Yaw) { return FFixedRotator(Pitch, Yaw, Roll); } + + UFUNCTION(BlueprintPure, Category = "Math|FixedRotator", meta = (Keywords = "rotation rotate rotator breakrotator", NativeBreakFunc)) + static void BreakFixedRotator(UPARAM(DisplayName = "Rotation") const FFixedRotator& InRot, UPARAM(DisplayName = "X (Roll)") FFixed& Roll, UPARAM(DisplayName = "Y (Pitch)") FFixed& Pitch, UPARAM(DisplayName = "Z (Yaw)") FFixed& Yaw) { Roll = InRot.Roll; Pitch = InRot.Pitch; Yaw = InRot.Yaw; } + + // 类型转换 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixedRotator (Rotator)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixedRotator Conv_RotatorToFixedRotator(const FRotator& InRotator) { return static_cast(InRotator); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToRotator (FixedRotator)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FRotator Conv_FixedRotatorToRotator(const FFixedRotator& InRotator) { return FRotator(InRotator); } + + // 布尔运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal (FixedRotator)", CompactNodeTitle = "==", ScriptMethod = "IsNearEqual", ScriptOperator = "==", Keywords = "== equal"), Category = "Math|FixedRotator") + static FORCEINLINE bool EqualEqual_FixedRotatorFixedRotator(const FFixedRotator& A, const FFixedRotator& B) { return A == B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Not Equal (FixedRotator)", CompactNodeTitle = "!=", ScriptMethod = "IsNotNearEqual", ScriptOperator = "!=", Keywords = "!= not equal"), Category = "Math|FixedRotator") + static FORCEINLINE bool NotEqual_FixedRotatorFixedRotator(const FFixedRotator& A, const FFixedRotator& B) { return A != B; } + + // 旋转运算 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Normalize (FixedRotator)", ScriptMethod = "Normalize", Keywords = "Unit Rotator"), Category = "Math|FixedRotator") + static FORCEINLINE FFixedRotator Normalize_FixedRotator(const FFixedRotator& A) { return FFixedMath::NormalizeRotator(A); } + +// UFUNCTION(BlueprintPure, meta = (DisplayName = "CombineFixedRotators", ScriptMethod = "Combine", Keywords = "rotate rotation add"), Category = "Math|FixedRotator") +// static FORCEINLINE FFixedRotator CombineFixedRotators(const FFixedRotator& A, const FFixedRotator& B); + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Delta (FixedRotator)", ScriptMethod = "Delta"), Category = "Math|FixedRotator") + static FORCEINLINE FFixedRotator NormalizedDeltaFixedRotator(const FFixedRotator& A, const FFixedRotator& B) { return FFixedMath::NormalizeRotator(A - B); } + +// UFUNCTION(BlueprintPure, meta = (DisplayName = "InvertFixedRotator", ScriptMethod = "Inversed", ScriptOperator = "neg", Keywords = "rotate rotation"), Category = "Math|FixedRotator") +// static FORCEINLINE FFixedRotator NegateFixedRotator(const FFixedRotator& A); + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ScaleFixedRotator", CompactNodeTitle = "*", ScriptMethod = "Scale", Keywords = "* multiply rotate rotation"), Category = "Math|FixedRotator") + static FORCEINLINE FFixedRotator Multiply_FixedRotatorFixed(const FFixedRotator& A, FFixed B) { return A * B; } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "Lerp (FixedRotator)", ScriptMethod = "Lerp"), Category = "Math|FixedRotator") + static FORCEINLINE FFixedRotator Lerp_FixedRotator(const FFixedRotator& A, const FFixedRotator& B, FFixed Alpha) { return FFixedMath::LerpRotator(A, B, Alpha); } + + // 平面: + // 类型转换 + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToFixedPlane (Plane)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FFixedPlane Conv_PlaneToFixedPlane(const FPlane& InPlane) { return static_cast(InPlane); } + + UFUNCTION(BlueprintPure, meta = (DisplayName = "ToPlane (FixedPlane)", CompactNodeTitle = "->", Keywords = "cast convert", BlueprintAutocast), Category = "Math|Conversions") + static FORCEINLINE FPlane Conv_FixedPlaneToPlane(const FFixedPlane& InPlane) { return FPlane(InPlane); } +}; diff --git a/Source/FixedPointMath/Public/Fixed.h b/Source/FixedPointMath/Public/Fixed.h new file mode 100644 index 0000000..9f16516 --- /dev/null +++ b/Source/FixedPointMath/Public/Fixed.h @@ -0,0 +1,158 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "FixedPointMath.h" +#include "Fixed.generated.h" + +USTRUCT(BlueprintType) +struct FIXEDPOINTMATH_API FFixed +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed", SaveGame) + int64 Data; + + static const FFixed Unit; + static const FFixed Pi; + + static constexpr unsigned int DecimalBit = 12; + + FORCEINLINE FFixed() { }; + FORCEINLINE FFixed(int64 A) { Data = A << DecimalBit; } + explicit FORCEINLINE operator int64() const { return Data >> DecimalBit; } + + FORCEINLINE FFixed(int32 A) : FFixed(static_cast(A)) { } + explicit FORCEINLINE operator int32() const { return static_cast(Data >> DecimalBit); } + +#define BASIC_INT_TYPE_CAST(T) explicit FORCEINLINE FFixed(T A) : FFixed(static_cast(A)) { } \ + explicit FORCEINLINE operator T() const { return static_cast(Data >> DecimalBit); } + + BASIC_INT_TYPE_CAST(int8) + BASIC_INT_TYPE_CAST(int16) + + BASIC_INT_TYPE_CAST(uint8) + BASIC_INT_TYPE_CAST(uint16) + BASIC_INT_TYPE_CAST(uint32) + BASIC_INT_TYPE_CAST(uint64) + +#undef BASIC_INT_TYPE_CAST + + explicit FFixed(float A) { Data = A * (1 << DecimalBit) + 0.5; } + explicit FORCEINLINE operator float() const { return static_cast(Data) / (1 << DecimalBit); } + + explicit FFixed(double A) { Data = A * (1 << DecimalBit) + 0.5; } + explicit FORCEINLINE operator double() const { return static_cast(Data) / (1 << DecimalBit); } + + explicit FFixed(long double A) { Data = A * (1 << DecimalBit) + 0.5; } + explicit FORCEINLINE operator long double() const { return static_cast(Data) / (1 << DecimalBit); } + + static FFixed FromBit(int64 A) { FFixed Temp; Temp.Data = A; return Temp; } + +#define FIXED_CMP_OP(O) friend FORCEINLINE bool operator O(const FFixed A, const FFixed B) { return A.Data O B.Data; } + + FIXED_CMP_OP(==) + FIXED_CMP_OP(!=) + FIXED_CMP_OP(<) + FIXED_CMP_OP(>) + FIXED_CMP_OP(>=) + FIXED_CMP_OP(<=) + +#undef FIXED_CMP_OP + + FORCEINLINE bool operator !() const { return !Data; } + FORCEINLINE FFixed operator ~() const { return FFixed(~Data); } + FORCEINLINE FFixed& operator ++() { Data += (1 << DecimalBit); return *this; } + FORCEINLINE FFixed& operator --() { Data += (1 << DecimalBit); return *this; } + FORCEINLINE FFixed operator -() const { FFixed Temp; Temp.Data = -Data; return Temp; } + +#define FIXED_NAS_OP(O) friend FORCEINLINE FFixed operator O(FFixed A, FFixed B) { A O##= B; return A; } +#define FIXED_DIR_OP(O) FORCEINLINE FFixed& operator O ##=(const FFixed F) { Data O##= F.Data; return *this; } FIXED_NAS_OP(O) + + FIXED_DIR_OP(+) + FIXED_DIR_OP(-) + FIXED_DIR_OP(&) + FIXED_DIR_OP(|) + FIXED_DIR_OP(^) + +#undef FIXED_DIR_OP + + FORCEINLINE FFixed& operator *=(const FFixed& F) { + Data *= F.Data; + Data >>= DecimalBit; + return *this; + } + + FORCEINLINE FFixed& operator /=(const FFixed& F) { + Data <<= DecimalBit; + Data /= F.Data; + return *this; + } + + FORCEINLINE FFixed& operator %=(const FFixed& F) { + Data %= F.Data; + return *this; + } + + FIXED_NAS_OP(*) + FIXED_NAS_OP(/) + FIXED_NAS_OP(%) + +#undef FIXED_NAS_OP + + FORCEINLINE FFixed& operator >>=(uint64 F) { Data >>= F; return *this; } + FORCEINLINE FFixed operator >>(uint64 F) const { FFixed Temp(*this); Temp >>= F; return Temp; } + FORCEINLINE FFixed& operator <<=(uint64 F) { Data <<= F; return *this; } + FORCEINLINE FFixed operator <<(uint64 F) const { FFixed Temp(*this); Temp <<= F; return Temp; } +}; + +namespace FFixedMath +{ + // 常用数学 + + FORCEINLINE FFixed Abs(FFixed A) { return FMath::Abs(A); } + FORCEINLINE FFixed Min(FFixed A, FFixed B) { return FMath::Min(A, B); } + FORCEINLINE FFixed Max(FFixed A, FFixed B) { return FMath::Max(A, B); } + FORCEINLINE FFixed Lerp(FFixed A, FFixed B, FFixed Alpha) { return FMath::Lerp(A, B, Alpha); } + FORCEINLINE FFixed Clamp(FFixed Value, FFixed Min, FFixed Max) { return FMath::Clamp(Value, Min, Max); } + FORCEINLINE FFixed Sqrt(FFixed A); + + // 三角函数 + + FIXEDPOINTMATH_API FFixed TanUnit(FFixed A); + FIXEDPOINTMATH_API FFixed SinUnit(FFixed A); + FIXEDPOINTMATH_API FFixed CosUnit(FFixed A); + FORCEINLINE FFixed TanDeg(FFixed A) { return TanUnit(A / FFixed(360)); } + FORCEINLINE FFixed SinDeg(FFixed A) { return SinUnit(A / FFixed(360)); } + FORCEINLINE FFixed CosDeg(FFixed A) { return CosUnit(A / FFixed(360)); } + FORCEINLINE FFixed Tan(FFixed A) { return TanUnit(A / (FFixed(2) * FFixed::Pi)); } + FORCEINLINE FFixed Sin(FFixed A) { return SinUnit(A / (FFixed(2) * FFixed::Pi)); } + FORCEINLINE FFixed Cos(FFixed A) { return CosUnit(A / (FFixed(2) * FFixed::Pi)); } +} + +FORCEINLINE FFixed FFixedMath::Sqrt(FFixed A) +{ + if (A < 0) + { + UE_LOG(LogFixedPointMath, Warning, TEXT("The square root cannot be negative. (An overflow may have occurred!)")); + return 0; + } + + // TODO: 将此处的二分求解换成更快的算法 + + static const FFixed DefaultL = 0; + static const FFixed DefaultR = (int64)UINT32_MAX >> FFixed::DecimalBit; + + FFixed Temp = 0; + FFixed L = DefaultL; + FFixed R = DefaultR; + FFixed M = L + ((R - L) >> 1); + while (L < R) { + if (M * M <= A) L = M + FFixed::Unit, Temp = M; + else R = M - FFixed::Unit; + M = L + ((R - L) >> 1); + } + + return Temp; +} diff --git a/Source/FixedPointMath/Public/FixedPlane.h b/Source/FixedPointMath/Public/FixedPlane.h new file mode 100644 index 0000000..f4e544e --- /dev/null +++ b/Source/FixedPointMath/Public/FixedPlane.h @@ -0,0 +1,73 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +#include "Fixed.h" +#include "FixedVector.h" +#include "FixedPointMath.h" +#include "FixedPlane.generated.h" + +USTRUCT(BlueprintType) +struct FIXEDPOINTMATH_API FFixedPlane + : public FFixedVector +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Plane", SaveGame) + FFixed W; + + FORCEINLINE FFixedPlane() { } + FORCEINLINE FFixedPlane(FFixed InX, FFixed InY, FFixed InZ, FFixed InW) : FFixedVector(InX, InY, InZ), W(InW) { } + FORCEINLINE FFixedPlane(const FFixedVector& InNormal, FFixed InW) : FFixedVector(InNormal), W(InW) { } + FORCEINLINE FFixedPlane(const FFixedVector& InBase, const FFixedVector &InNormal) : FFixedVector(InNormal), W(InBase | InNormal) { } + FORCEINLINE FFixedPlane(FFixedVector A, FFixedVector B, FFixedVector C) : FFixedVector(FFixedMath::Normalize((B - A) ^ (C - A))), W(A | (FFixedVector)(*this)) { } + + explicit FORCEINLINE FFixedPlane(const FPlane& InPlane) : FFixedVector(InPlane), W(InPlane.W) { } + explicit FORCEINLINE operator FPlane() const { return FPlane(static_cast(*this), static_cast(W)); } + + FORCEINLINE FFixed PlaneDot(const FFixedVector &P) const { return X * P.X + Y * P.Y + Z * P.Z - W; } + FORCEINLINE bool Normalize(); + + FORCEINLINE FFixedPlane operator -() const { return FFixedPlane(-X, -Y, -Z, -W); } + FORCEINLINE bool operator ==(const FFixedPlane& V) const { return (X == V.X) && (Y == V.Y) && (Z == V.Z) && (W == V.W); } + FORCEINLINE bool operator !=(const FFixedPlane& V) const { return (X != V.X) || (Y != V.Y) || (Z != V.Z) || (W != V.W); } + FORCEINLINE FFixed operator |(const FFixedPlane& V) const { return X * V.X + Y * V.Y + Z * V.Z + W * V.W; } + friend FORCEINLINE FFixedPlane operator +(const FFixedPlane& A, const FFixedPlane& B) { return FFixedPlane(A.X + B.X, A.Y + B.Y, A.Z + B.Z, A.W + B.W); } + friend FORCEINLINE FFixedPlane operator -(const FFixedPlane& A, const FFixedPlane& B) { return FFixedPlane(A.X - B.X, A.Y - B.Y, A.Z - B.Z, A.W - B.W); } + friend FORCEINLINE FFixedPlane operator *(const FFixedPlane& A, const FFixedPlane& B) { return FFixedPlane(A.X * B.X, A.Y * B.Y, A.Z * B.Z, A.W * B.W); } + friend FORCEINLINE FFixedPlane operator /(const FFixedPlane& A, const FFixedPlane& B) { return FFixedPlane(A.X / B.X, A.Y / B.Y, A.Z / B.Z, A.W / B.W); } + FORCEINLINE FFixedPlane operator /(FFixed Scale) const { return FFixedPlane(X / Scale, Y / Scale, Z / Scale, W / Scale); } + FORCEINLINE FFixedPlane operator *(FFixed Scale) const { return FFixedPlane(X * Scale, Y * Scale, Z * Scale, W * Scale); } + FORCEINLINE FFixedPlane& operator +=(const FFixedPlane& V) { X += V.X; Y += V.Y; Z += V.Z; W += V.W; return *this; } + FORCEINLINE FFixedPlane& operator -=(const FFixedPlane& V) { X -= V.X; Y -= V.Y; Z -= V.Z; W -= V.W; return *this; } + FORCEINLINE FFixedPlane& operator *=(const FFixedPlane& V) { X *= V.X; Y *= V.Y; Z *= V.Z; W *= V.W; return *this; } + FORCEINLINE FFixedPlane& operator /=(const FFixedPlane& V) { X /= V.X; Y /= V.Y; Z /= V.Z; W /= V.W; return *this; } + FORCEINLINE FFixedPlane& operator *=(FFixed Scale) { X *= Scale; Y *= Scale; Z *= Scale; W *= Scale; return *this; } + FORCEINLINE FFixedPlane& operator /=(FFixed Scale) { X /= Scale; Y /= Scale; Z /= Scale; W /= Scale; return *this; } + + FORCEINLINE FFixed& operator [](int32 Index) { check(Index >= 0 && Index < 4); return (&X)[Index]; } + FORCEINLINE FFixed operator [](int32 Index) const { check(Index >= 0 && Index < 4); return (&X)[Index]; } +}; + +FORCEINLINE bool FFixedPlane::Normalize() +{ + FFixed SquareSum = SizeSquared(); + + if (SquareSum < 0) + { + UE_LOG(LogFixedPointMath, Warning, TEXT("Vector length is too long. (An overflow may have occurred!)")); + return false; + } + + FFixed Length = FFixedMath::Sqrt(SquareSum); + + if (Length > 0) + { + *this /= Length; + return true; + } + + return false; +} diff --git a/Source/FixedPointMath/Public/FixedPointMath.h b/Source/FixedPointMath/Public/FixedPointMath.h new file mode 100644 index 0000000..8fbffa5 --- /dev/null +++ b/Source/FixedPointMath/Public/FixedPointMath.h @@ -0,0 +1,17 @@ +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogFixedPointMath, Log, All); + +class FFixedPointMathModule : public IModuleInterface +{ +public: + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; diff --git a/Source/FixedPointMath/Public/FixedRotator.h b/Source/FixedPointMath/Public/FixedRotator.h new file mode 100644 index 0000000..e0c27e3 --- /dev/null +++ b/Source/FixedPointMath/Public/FixedRotator.h @@ -0,0 +1,71 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +#include "Fixed.h" +#include "FixedVector.h" +#include "FixedPointMath.h" +#include "FixedRotator.generated.h" + +USTRUCT(BlueprintType, meta = (HasNativeMake = "FixedPointMath.BlueprintFixedMath.MakeFixedRotator", HasNativeBreak = "FixedPointMath.BlueprintFixedMath.BreakFixedRotator")) +struct FIXEDPOINTMATH_API FFixedRotator +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Rotator", SaveGame, meta = (DisplayName = "Y")) + FFixed Pitch; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Rotator", SaveGame, meta = (DisplayName = "Z")) + FFixed Yaw; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Rotator", SaveGame, meta = (DisplayName = "X")) + FFixed Roll; + + static const FFixedRotator ZeroRotator; + + FORCEINLINE FFixedRotator() { } + explicit FORCEINLINE FFixedRotator(FFixed InF) : Pitch(InF), Yaw(InF), Roll(InF) { } + FORCEINLINE FFixedRotator(FFixed InPitch, FFixed InYaw, FFixed InRoll) : Pitch(InPitch), Yaw(InYaw), Roll(InRoll) { } + explicit FORCEINLINE FFixedRotator(const FRotator& InRotator) : Pitch(InRotator.Pitch), Yaw(InRotator.Yaw), Roll(InRotator.Roll) { } + explicit FORCEINLINE operator FRotator() const { return FRotator(static_cast(Pitch), static_cast(Yaw), static_cast(Roll)); } + + FORCEINLINE FFixedRotator operator -() const { return FFixedRotator(-Pitch, -Yaw, -Roll); } + FORCEINLINE bool operator ==(const FFixedRotator& R) const { return (Pitch == R.Pitch) && (Yaw == R.Yaw) && (Roll == R.Roll); } + FORCEINLINE bool operator !=(const FFixedRotator& R) const { return (Pitch != R.Pitch) || (Yaw != R.Yaw) || (Roll != R.Roll); } + friend FORCEINLINE FFixedRotator operator +(const FFixedRotator& A, const FFixedRotator& B) { return FFixedRotator(A.Pitch + B.Pitch, A.Yaw + B.Yaw, A.Roll + B.Roll); } + friend FORCEINLINE FFixedRotator operator -(const FFixedRotator& A, const FFixedRotator& B) { return FFixedRotator(A.Pitch - B.Pitch, A.Yaw - B.Yaw, A.Roll - B.Roll); } + FORCEINLINE FFixedRotator operator *(const FFixed Scale) const { return FFixedRotator(Pitch * Scale, Yaw * Scale, Roll * Scale); } + FORCEINLINE FFixedRotator operator /(const FFixed Scale) const { return FFixedRotator(Pitch / Scale, Yaw / Scale, Roll / Scale); } + FORCEINLINE FFixedRotator& operator +=(const FFixedRotator& R) { Pitch += R.Pitch; Yaw += R.Yaw; Roll += R.Roll; return *this; } + FORCEINLINE FFixedRotator& operator -=(const FFixedRotator& R) { Pitch -= R.Pitch; Yaw -= R.Yaw; Roll -= R.Roll; return *this; } + FORCEINLINE FFixedRotator& operator *=(const FFixed Scale) { Pitch *= Scale; Yaw *= Scale; Roll *= Scale; return *this; } + FORCEINLINE FFixedRotator& operator /=(const FFixed Scale) { Pitch /= Scale; Yaw /= Scale; Roll /= Scale; return *this; } + + FORCEINLINE bool IsZero() const { return Pitch == 0 && Yaw == 0 && Roll == 0; } +}; + +namespace FFixedMath +{ + FORCEINLINE FFixed ClampAxis(FFixed Angle); + FORCEINLINE FFixed NormalizeAxis(FFixed Angle); + FORCEINLINE FFixedRotator ClampRotator(FFixedRotator R) { return FFixedRotator(ClampAxis(R.Pitch), ClampAxis(R.Yaw), ClampAxis(R.Roll)); } + FORCEINLINE FFixedRotator NormalizeRotator(FFixedRotator R) { return FFixedRotator(NormalizeAxis(R.Pitch), NormalizeAxis(R.Yaw), NormalizeAxis(R.Roll)); } + FORCEINLINE FFixedRotator LerpRotator(FFixedRotator A, FFixedRotator B, FFixed Alpha) { return A + (B - A) * Alpha; } +} + +FORCEINLINE FFixed FFixedMath::ClampAxis(FFixed Angle) +{ + Angle = Angle % 360; + if (Angle < 0) Angle += 360; + return Angle; +} + +FFixed FFixedMath::NormalizeAxis(FFixed Angle) +{ + Angle = ClampAxis(Angle); + if (Angle > 180) + Angle -= 360; + return Angle; +} diff --git a/Source/FixedPointMath/Public/FixedVector.h b/Source/FixedPointMath/Public/FixedVector.h new file mode 100644 index 0000000..6fc73c6 --- /dev/null +++ b/Source/FixedPointMath/Public/FixedVector.h @@ -0,0 +1,106 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +#include "Fixed.h" +#include "FixedPointMath.h" +#include "FixedVector.generated.h" + +USTRUCT(BlueprintType) +struct FIXEDPOINTMATH_API FFixedVector +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Vector", SaveGame) + FFixed X; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Vector", SaveGame) + FFixed Y; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Fixed Vector", SaveGame) + FFixed Z; + + static const FFixedVector ZeroVector; + static const FFixedVector OneVector; + static const FFixedVector UpVector; + static const FFixedVector DownVector; + static const FFixedVector ForwardVector; + static const FFixedVector BackwardVector; + static const FFixedVector RightVector; + static const FFixedVector LeftVector; + + FORCEINLINE FFixedVector() { } + FORCEINLINE FFixedVector(FFixed InF) : X(InF), Y(InF), Z(InF) { } + FORCEINLINE FFixedVector(FFixed InX, FFixed InY, FFixed InZ) : X(InX), Y(InY), Z(InZ) { } + explicit FORCEINLINE FFixedVector(const FVector& InVector) : X(InVector.X), Y(InVector.Y), Z(InVector.Z) { } + explicit FORCEINLINE operator FVector() const { return FVector(static_cast(X), static_cast(Y), static_cast(Z)); } + explicit FORCEINLINE FFixedVector(const FIntVector& InVector) : X(InVector.X), Y(InVector.Y), Z(InVector.Z) { } + explicit FORCEINLINE operator FIntVector() const { return FIntVector(static_cast(X), static_cast(Y), static_cast(Z)); } + + FORCEINLINE bool IsZero() const { return X == 0 && Y == 0 && Z == 0; } + FORCEINLINE FFixed Size() const { return FFixedMath::Sqrt(SizeSquared()); } + FORCEINLINE FFixed SizeSquared() const { return X * X + Y * Y + Z * Z; } + FORCEINLINE bool Normalize(); + + FORCEINLINE FFixedVector& operator ^=(const FFixedVector& V) { *this = *this ^ V; return *this; } + FORCEINLINE FFixedVector operator ^(const FFixedVector& V) const { return FFixedVector(Y * V.Z - Z * V.Y, Z * V.X - X * V.Z, X * V.Y - Y * V.X); } + FORCEINLINE FFixed operator |(const FFixedVector& V) const { return X * V.X + Y * V.Y + Z * V.Z; } + + FORCEINLINE FFixedVector operator -() const { return FFixedVector(-X, -Y, -Z); } + FORCEINLINE bool operator ==(const FFixedVector& V) const { return (X == V.X) && (Y == V.Y) && (Z == V.Z); } + FORCEINLINE bool operator !=(const FFixedVector& V) const { return (X != V.X) || (Y != V.Y) || (Z != V.Z); } + friend FORCEINLINE FFixedVector operator +(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(A.X + B.X, A.Y + B.Y, A.Z + B.Z); } + friend FORCEINLINE FFixedVector operator -(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(A.X - B.X, A.Y - B.Y, A.Z - B.Z); } + friend FORCEINLINE FFixedVector operator *(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(A.X * B.X, A.Y * B.Y, A.Z * B.Z); } + friend FORCEINLINE FFixedVector operator /(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(A.X / B.X, A.Y / B.Y, A.Z / B.Z); } + FORCEINLINE FFixedVector operator /(FFixed Scale) const { return FFixedVector(X / Scale, Y / Scale, Z / Scale); } + FORCEINLINE FFixedVector operator *(FFixed Scale) const { return FFixedVector(X * Scale, Y * Scale, Z * Scale); } + FORCEINLINE FFixedVector& operator +=(const FFixedVector& V) { X += V.X; Y += V.Y; Z += V.Z; return *this; } + FORCEINLINE FFixedVector& operator -=(const FFixedVector& V) { X -= V.X; Y -= V.Y; Z -= V.Z; return *this; } + FORCEINLINE FFixedVector& operator *=(const FFixedVector& V) { X *= V.X; Y *= V.Y; Z *= V.Z; return *this; } + FORCEINLINE FFixedVector& operator /=(const FFixedVector& V) { X /= V.X; Y /= V.Y; Z /= V.Z; return *this; } + FORCEINLINE FFixedVector& operator *=(FFixed Scale) { X *= Scale; Y *= Scale; Z *= Scale; return *this; } + FORCEINLINE FFixedVector& operator /=(FFixed Scale) { X /= Scale; Y /= Scale; Z /= Scale; return *this; } + + FORCEINLINE FFixed& operator [](int32 Index) { check(Index >= 0 && Index < 3); return (&X)[Index]; } + FORCEINLINE FFixed operator [](int32 Index) const { check(Index >= 0 && Index < 3); return (&X)[Index]; } +}; + +namespace FFixedMath +{ + // 常用数学 + + FORCEINLINE FFixedVector LerpVector(FFixedVector A, FFixedVector B, FFixed Alpha) { return FMath::Lerp(A, B, Alpha); } + FORCEINLINE FFixedVector ComponentAbs(const FFixedVector& A) { return FFixedVector(FFixedMath::Abs(A.X), FFixedMath::Abs(A.Y), FFixedMath::Abs(A.Z)); } + FORCEINLINE FFixedVector ComponentMin(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(FFixedMath::Min(A.X, B.X), FFixedMath::Min(A.Y, B.Y), FFixedMath::Min(A.Z, B.Z)); } + FORCEINLINE FFixedVector ComponentMax(const FFixedVector& A, const FFixedVector& B) { return FFixedVector(FFixedMath::Max(A.X, B.X), FFixedMath::Max(A.Y, B.Y), FFixedMath::Max(A.Z, B.Z)); } + + // 向量运算 + + FORCEINLINE FFixedVector CrossProduct(const FFixedVector& A, const FFixedVector& B) { return A ^ B; } + FORCEINLINE FFixed DotProduct(const FFixedVector& A, const FFixedVector& B) { return A | B; } + FORCEINLINE FFixedVector Normalize(const FFixedVector& A) { FFixedVector Result = A; Result.Normalize(); return Result; } +} + +FORCEINLINE bool FFixedVector::Normalize() +{ + FFixed SquareSum = SizeSquared(); + + if (SquareSum < 0) + { + UE_LOG(LogFixedPointMath, Warning, TEXT("Vector length is too long. (An overflow may have occurred!)")); + return false; + } + + FFixed Length = FFixedMath::Sqrt(SquareSum); + + if (Length > 0) + { + *this /= Length; + return true; + } + + return false; +} \ No newline at end of file