1496 lines
48 KiB
C++
1496 lines
48 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "HeadlessChaosTestSweep.h"
|
|
|
|
#include "HeadlessChaos.h"
|
|
#include "Chaos/Capsule.h"
|
|
#include "Chaos/Convex.h"
|
|
#include "Chaos/TriangleMeshImplicitObject.h"
|
|
#include "Chaos/ImplicitObjectScaled.h"
|
|
#include "Chaos/GeometryQueries.h"
|
|
|
|
namespace ChaosTest
|
|
{
|
|
using namespace Chaos;
|
|
|
|
void CapsuleSweepAgainstTriMeshReal()
|
|
{
|
|
// Trimesh is from SM_Cattus_POI_Rib, this was a real world failure that is now fixed.
|
|
|
|
using namespace Chaos;
|
|
FTriangleMeshImplicitObject::ParticlesType TrimeshParticles(
|
|
{
|
|
{29.0593967, -5.21321106, -10.2669592},
|
|
{34.5006638, -3.16600156, -14.5092020},
|
|
{28.8770218, -5.00888205, -10.4567394},
|
|
{38.9350929, -1.47836626, -17.6896191},
|
|
{39.1246262, -1.58615386, -17.4255066},
|
|
{42.4614334, -0.114946000, -19.8563728},
|
|
{38.7996712, -1.91535223, -16.3864536},
|
|
{29.4634132, -5.15883255, -9.64184284},
|
|
{29.6582336, -5.05185938, -9.37638092},
|
|
{45.0206337, 0.641714215, -21.0300026},
|
|
{46.2034111, 1.19252074, -22.0121441},
|
|
{44.3153610, 0.398101240, -19.9310055},
|
|
{38.2805557, -1.87191427, -15.7972298},
|
|
{48.8065224, 1.82796133, -22.7662964},
|
|
{49.7862473, 2.21876359, -23.4238491},
|
|
{49.1621628, 1.89441979, -22.1913338},
|
|
{52.2055054, 2.59018326, -23.6808910},
|
|
{55.6262436, 3.71029496, -24.4840908},
|
|
{52.2546806, 2.55433965, -22.8908424},
|
|
{47.6990814, 1.76376379, -21.3171616},
|
|
{55.9418335, 3.34045410, -24.2242432},
|
|
{56.7527275, 4.26803923, -24.7314072},
|
|
{56.6030273, 3.37918210, -23.5389385},
|
|
{57.1201477, 3.92609882, -24.5670509},
|
|
{57.5926590, 5.32376480, -24.8299332},
|
|
{57.3900146, 3.86687994, -24.3628445},
|
|
{58.3100967, 5.59623432, -24.5884380},
|
|
{57.9720459, 6.88918400, -24.9411621},
|
|
{58.3736610, 5.22753286, -23.6481304},
|
|
{58.3795776, 9.20724392, -24.4941502},
|
|
{57.6161652, 7.89536858, -25.0186253},
|
|
{57.7064209, 8.63112640, -24.8542480},
|
|
{57.4299011, 9.53679848, -24.7764454},
|
|
{58.6315613, 9.11761856, -24.1844330},
|
|
{58.5211067, 7.24213171, -23.5957718},
|
|
{57.5271606, 9.99959183, -24.4184647},
|
|
{58.2185135, 9.55542183, -23.2548218},
|
|
{57.3097725, 10.2978697, -23.5637169},
|
|
{56.3722000, 9.18606091, -24.9406128},
|
|
{58.2657166, 8.36739063, -23.1939850},
|
|
{56.3347893, 9.67211342, -24.4351349},
|
|
{57.3641586, 9.99938393, -23.0135994},
|
|
{58.1764908, 5.82101727, -23.1902943},
|
|
{57.3481255, 8.60126781, -22.9416485},
|
|
{56.1609459, 9.56552029, -23.1539116},
|
|
{56.2483864, 9.85045052, -23.4782410},
|
|
{55.7174797, 8.29436588, -23.0638103},
|
|
{54.7229729, 8.73790932, -23.3331184},
|
|
{54.0776367, 8.77919769, -23.7519341},
|
|
{53.9943695, 8.17912292, -24.5668526},
|
|
{51.3485641, 7.47948122, -23.0380058},
|
|
{51.2222366, 7.41138554, -23.6724663},
|
|
{53.9260139, 7.74872541, -24.6529694},
|
|
{52.2321625, 7.36892176, -22.8332882},
|
|
{50.7700424, 6.47493553, -23.9456253},
|
|
{56.6027756, 8.31463623, -25.0338459},
|
|
{57.2853279, 6.51692963, -25.0099850},
|
|
{50.7739677, 5.00270128, -24.0342751},
|
|
{47.1190453, 4.83312464, -22.8379707},
|
|
{49.7170258, 2.62024260, -23.6686172},
|
|
{43.0110207, 0.426635355, -20.4862480},
|
|
{42.7733459, 3.24669766, -20.7472992},
|
|
{34.1604767, -2.98149395, -14.5161381},
|
|
{28.7377853, -4.72821426, -10.5358887},
|
|
{28.2660236, -3.50151801, -10.7232647},
|
|
{34.4872894, 0.0475072451, -15.1762705},
|
|
{27.9901352, -2.42618680, -10.5657129},
|
|
{27.6759071, 0.205285028, -10.2063637},
|
|
{36.6210670, 2.21063828, -16.3613548},
|
|
{27.6877193, 0.690624714, -10.0054235},
|
|
{42.8507233, 3.80447602, -20.6911526},
|
|
{39.7815170, 3.57913852, -17.9840279},
|
|
{42.7781487, 4.36921978, -19.9032001},
|
|
{27.8298340, 0.836181641, -9.67990112},
|
|
{28.1982155, 0.777253330, -9.15566635},
|
|
{46.0600357, 5.31439161, -22.0218697},
|
|
{36.9135399, 2.88628912, -15.1429548},
|
|
{47.6548805, 5.92783451, -22.1377392},
|
|
{44.6417084, 4.89560652, -20.4432411},
|
|
{47.3978271, 5.70256472, -21.4681816},
|
|
{42.0819168, 3.81306863, -18.2309093},
|
|
{34.6343575, 1.72932339, -12.9041548},
|
|
{28.5061035, 0.184601068, -8.87326050},
|
|
{28.7382660, -0.523662448, -8.71943665},
|
|
{47.9805756, 5.56415987, -21.3477497},
|
|
{35.0854912, 1.10745859, -13.0555801},
|
|
{29.5277596, -4.36109161, -9.26433849},
|
|
{44.2550583, 3.73801875, -19.3567085},
|
|
{48.6162643, 5.16706753, -21.4052410},
|
|
{33.8666039, -3.11327124, -12.2873840},
|
|
{29.5907612, -4.66688442, -9.28112030},
|
|
{37.8056297, -1.60099864, -15.0567427},
|
|
{43.0328369, 1.30700612, -18.5348587},
|
|
{45.9731026, 1.34582365, -20.3940430},
|
|
{48.3442001, 2.43499756, -21.2875118},
|
|
{53.0610924, 3.33885503, -22.4557037},
|
|
{54.3709755, 5.39051533, -22.8000984},
|
|
{55.9649162, 3.45125723, -23.1164742},
|
|
{56.6591415, 4.77854252, -22.8085098},
|
|
{57.1962891, 4.12890625, -23.1115723},
|
|
{25.7303848, -5.68249369, -8.51585770},
|
|
{26.5309143, -4.24291611, -9.48308945},
|
|
{24.8292999, -5.12226152, -8.47907925},
|
|
{20.3731937, -6.52481079, -5.81806421},
|
|
{26.4056702, -3.28238487, -9.07682896},
|
|
{23.9174252, -5.14487743, -7.70250511},
|
|
{21.3869915, -5.92491102, -6.74390554},
|
|
{18.1200867, -6.53198242, -4.76391602},
|
|
{21.6681881, -5.50328684, -6.94691038},
|
|
{18.0004005, -5.80428123, -5.25099564},
|
|
{15.9813662, -6.10711002, -4.21955252},
|
|
{18.8343563, -5.61828232, -5.61174917},
|
|
{20.2135773, -4.88624334, -5.77969599},
|
|
{15.4357758, -5.21927977, -4.48837900},
|
|
{11.1496544, -2.60679626, -4.38681793},
|
|
{10.0865431, -3.16139269, -3.85664177},
|
|
{8.63047791, -2.38198924, -3.79941773},
|
|
{14.6292696, -4.35020351, -4.44057178},
|
|
{7.90794277, -1.09154844, -4.05677366},
|
|
{6.95699024, -1.20261848, -3.97343445},
|
|
{8.23572540, -0.744559944, -4.00086451},
|
|
{3.10794330, 0.166724160, -4.27361870},
|
|
{3.13311577, -0.346626908, -4.11541176},
|
|
{1.48072076, -0.108915798, -4.42642593},
|
|
{0.311369270, -0.0673256740, -4.49766636},
|
|
{-1.59366548, 0.725093842, -4.37339926},
|
|
{-3.45725179, -0.749191761, -4.34381390},
|
|
{-6.95951319, 0.0120848129, -3.59336853},
|
|
{-6.83396530, -1.23874116, -3.47961354},
|
|
{-7.89957952, -1.66941118, -2.82847047},
|
|
{0.703817546, 0.936612248, -4.19160843},
|
|
{-5.88422966, 0.830549538, -3.74061680},
|
|
{-8.81333447, -0.651533544, -2.60129619},
|
|
{3.10681534, 0.612948775, -3.77665353},
|
|
{-4.67421389, 1.29445243, -3.36058092},
|
|
{-0.481138408, 1.18588996, -3.53271747},
|
|
{7.11869955, -0.267135799, -3.69777322},
|
|
{-7.27621984, 0.737751126, -2.76471734},
|
|
{2.97556901, 1.46023333, -1.62857735},
|
|
{-8.61850739, -0.257534623, -2.48780465},
|
|
{-7.48897791, 0.836947024, -2.17553926},
|
|
{-6.28466797, 1.53784180, -1.55349731},
|
|
{-9.28733826, -2.43306065, -1.33127916},
|
|
{-5.33093262, 1.85986328, -1.26861572},
|
|
{-8.90132236, -2.71124601, -1.38725543},
|
|
{-9.17060471, -2.78321695, -0.819307029},
|
|
{-7.84990644, -2.40683627, -2.12729597},
|
|
{-7.91611624, -3.38985372, -0.952804804},
|
|
{-7.87829638, -3.03356981, -1.37831473},
|
|
{-2.43495178, 1.76181090, -1.93872476},
|
|
{-5.54367924, 1.81969070, -0.745879471},
|
|
{-1.47680271, 1.64132023, -1.37136936},
|
|
{-7.19018078, 0.901845515, -0.857508898},
|
|
{-2.50409842, 1.67723644, -1.04755175},
|
|
{-5.39768934, 1.59197235, -0.603915393},
|
|
{-8.16507626, 0.222914696, -1.11252105},
|
|
{-8.16396332, -0.777114809, -0.289943308},
|
|
{-9.22219181, -2.11877251, -0.794639707},
|
|
{-8.59923363, -0.829777956, -0.520817995},
|
|
{-8.82921314, -1.96039867, -0.298297912},
|
|
{-7.40556860, -1.55998039, -0.250481576},
|
|
{-8.14031315, -2.90432310, -0.262226462},
|
|
{-6.85163212, -3.75249863, -0.688983977},
|
|
{-7.04014444, -3.11551261, -0.126083776},
|
|
{-6.32870483, -3.58578491, -0.493814230},
|
|
{-6.28338480, -3.61894345, -0.929058373},
|
|
{-2.62741208, -3.09605527, -1.33044124},
|
|
{-1.79794896, -2.99078751, -1.21258605},
|
|
{-2.96854925, -2.36802864, -0.369529188},
|
|
{-4.30677605, -1.66542077, -0.303167671},
|
|
{-4.98426914, 0.696137369, -0.565792441},
|
|
{-2.85455132, -0.0173058268, -0.637033641},
|
|
{-2.70905447, 1.40332532, -0.955382884},
|
|
{-2.02012229, 1.18688262, -0.943184257},
|
|
{-2.42252111, 0.0620364472, -0.474374950},
|
|
{-1.56289959, 1.40382648, -0.681109011},
|
|
{-2.39032364, -1.25889599, 0.0907319933},
|
|
{-2.19775391, 0.174560547, 0.274658203},
|
|
{-0.306748420, 1.84567726, -1.35950983},
|
|
{0.250524580, 2.27636194, -0.823237658},
|
|
{-1.23819447, 1.49723995, 0.237386853},
|
|
{-2.13792968, -0.616698205, 0.937073231},
|
|
{-0.347599745, 1.71002686, 0.470531255},
|
|
{-1.66023159, -2.55999684, -0.452154934},
|
|
{-1.58301616, -2.24312091, 0.468077749},
|
|
{-1.67812920, 0.0274793506, 0.998333335},
|
|
{-1.36489558, -1.84878838, 0.930600643},
|
|
{0.255698651, -2.16175246, 0.109909050},
|
|
{-0.787146091, -1.07865918, 0.862207949},
|
|
{-0.293874621, -2.31530595, 0.560731053},
|
|
{0.162645504, 1.18506360, 0.511415780},
|
|
{0.535789251, -1.17199028, 0.772845566},
|
|
{1.08959603, -1.89062190, 0.519282222},
|
|
{-0.329488188, -2.73174953, -0.953910708},
|
|
{3.05201745, -1.60201991, -0.293554634},
|
|
{1.98701501, -1.01330709, 0.433782279},
|
|
{4.13116980, -1.43739676, -0.0357451625},
|
|
{2.42845988, 0.716189802, 0.176060840},
|
|
{5.01461887, -0.924357474, -0.0785766020},
|
|
{2.14807916, 1.47517538, 0.204042286},
|
|
{8.51385689, -0.236161187, -0.669285059},
|
|
{1.14428675, 2.08710790, -0.255287379},
|
|
{6.16604090, 0.561538637, -0.544156194},
|
|
{6.23778296, 0.760041595, -0.706411839},
|
|
{4.30203772, 1.36588299, -1.17367637},
|
|
{8.15555477, 0.428962231, -1.73520589},
|
|
{12.0248108, -0.490237832, -1.43530607},
|
|
{11.9705954, -0.198881984, -1.88936043},
|
|
{10.0048714, -0.699601173, -3.28313756},
|
|
{11.2095804, -0.147232190, -2.45466590},
|
|
{16.6165028, -0.696181834, -3.11862493},
|
|
{11.7848577, -1.81683028, -3.73632550},
|
|
{11.8666601, -1.22696412, -3.14981008},
|
|
{15.7040558, -0.663861752, -3.65228081},
|
|
{14.0951519, -1.07241631, -3.61164665},
|
|
{13.9181585, -2.03203130, -3.63557220},
|
|
{14.9848728, -1.53837466, -3.98249745},
|
|
{15.0845509, -3.46569848, -3.95276761},
|
|
{16.0242348, -2.97810125, -4.17965460},
|
|
{17.6243019, -4.46606350, -4.79625034},
|
|
{17.4456787, -3.35461426, -5.32739258},
|
|
{18.7262955, -3.89710188, -5.70676517},
|
|
{16.9230785, -2.57194042, -5.40591431},
|
|
{22.7467842, -3.61460471, -6.97978115},
|
|
{18.4024391, -1.30696046, -6.12640095},
|
|
{24.8947697, -0.243050858, -8.32624245},
|
|
{20.7879944, -1.08460391, -6.77528811},
|
|
{21.7145271, -0.556654394, -6.90972757},
|
|
{17.4861660, -1.25891256, -5.46996546},
|
|
{24.8378277, 0.196830407, -7.98421001},
|
|
{18.6861229, -0.568430483, -5.20232296},
|
|
{23.9673500, -0.0726047829, -6.57525635},
|
|
{20.4216003, -0.520928204, -4.92496729},
|
|
{23.2731094, -0.885929525, -5.62632990},
|
|
{17.6102352, -1.26811695, -3.06619239},
|
|
{18.1110725, -2.89222097, -2.71354604},
|
|
{15.2493439, -1.51500702, -1.99904561},
|
|
{23.4795017, -5.85999155, -5.31351185},
|
|
{23.3095360, -6.35326576, -5.25977182},
|
|
{17.5398540, -4.66228580, -2.38013840},
|
|
{23.1760674, -6.62616539, -5.57958126},
|
|
{19.5313797, -6.43315840, -3.60291767},
|
|
{15.4807367, -3.66881418, -1.85560131},
|
|
{14.3018312, -4.70082331, -1.46323049},
|
|
{12.8267784, -4.37319517, -1.09716678},
|
|
{15.7109251, -6.05440664, -2.37732816},
|
|
{12.3741608, -1.41286337, -1.26915634},
|
|
{13.8603306, -5.49541807, -1.90867615},
|
|
{17.6683712, -6.81585407, -3.37876749},
|
|
{12.2477732, -4.72466660, -1.29786050},
|
|
{11.1379576, -3.74680114, -0.753773510},
|
|
{9.36099339, -2.47074175, -0.534102321},
|
|
{10.0452557, -3.30079317, -0.685146451},
|
|
{6.68738413, -2.30865097, -0.461158574},
|
|
{7.36793947, -3.03040981, -1.47094512},
|
|
{11.8176231, -4.84084797, -1.82727480},
|
|
{4.59196663, -2.28209496, -1.41259789},
|
|
{7.10861683, -2.85069633, -2.06923938},
|
|
{3.39536858, -2.24798036, -1.65714610},
|
|
{0.172218561, -2.71166372, -1.40673709},
|
|
{2.89844537, -1.88502884, -2.27524662},
|
|
{-2.25631189, -2.96263766, -1.67407131},
|
|
{4.27257490, -1.76102304, -2.35111189},
|
|
{-1.88132656, -2.04832077, -2.39434218},
|
|
{-6.50054932, -3.11684728, -1.45549214},
|
|
{-6.90812969, -1.50060546, -3.38022733},
|
|
{-2.73349977, -0.821462870, -4.29114628},
|
|
{1.80500829, -1.06030691, -3.12149286},
|
|
{4.53264713, -1.14842916, -3.26621342},
|
|
{7.26582527, -2.38612676, -2.95009947},
|
|
{11.0593281, -3.88886213, -3.55232120},
|
|
{13.7664843, -5.74423409, -2.92658687},
|
|
{17.2798290, -6.74407482, -4.16304970},
|
|
{22.1492062, -6.65115118, -6.29792738},
|
|
{ 26.2703266, -5.87738276, -8.47085190 }
|
|
});
|
|
|
|
TArray<TVec3<int32>> Indices(
|
|
{
|
|
{1, 0, 2},
|
|
{3, 0, 1},
|
|
{0, 3, 4},
|
|
{5, 4, 3},
|
|
{4, 6, 0},
|
|
{7, 0, 6},
|
|
{7, 6, 8},
|
|
{4, 5, 9},
|
|
{5, 10, 9},
|
|
{4, 11, 6},
|
|
{4, 9, 11},
|
|
{12, 8, 6},
|
|
{6, 11, 12},
|
|
{9, 10, 13},
|
|
{10, 14, 13},
|
|
{9, 15, 11},
|
|
{9, 13, 15},
|
|
{13, 14, 16},
|
|
{17, 16, 14},
|
|
{13, 18, 15},
|
|
{18, 13, 16},
|
|
{19, 11, 15},
|
|
{19, 15, 18},
|
|
{11, 19, 12},
|
|
{16, 17, 20},
|
|
{21, 20, 17},
|
|
{16, 22, 18},
|
|
{22, 16, 20},
|
|
{23, 20, 21},
|
|
{24, 23, 21},
|
|
{23, 25, 20},
|
|
{20, 25, 22},
|
|
{26, 23, 24},
|
|
{26, 25, 23},
|
|
{27, 26, 24},
|
|
{25, 28, 22},
|
|
{28, 25, 26},
|
|
{26, 27, 29},
|
|
{29, 27, 30},
|
|
{31, 29, 30},
|
|
{31, 32, 29},
|
|
{33, 26, 29},
|
|
{28, 26, 34},
|
|
{33, 34, 26},
|
|
{35, 33, 29},
|
|
{35, 29, 32},
|
|
{34, 33, 36},
|
|
{37, 33, 35},
|
|
{33, 37, 36},
|
|
{38, 35, 32},
|
|
{34, 36, 39},
|
|
{35, 38, 40},
|
|
{40, 37, 35},
|
|
{36, 41, 39},
|
|
{37, 41, 36},
|
|
{42, 34, 39},
|
|
{34, 42, 28},
|
|
{43, 39, 41},
|
|
{43, 42, 39},
|
|
{44, 41, 37},
|
|
{44, 43, 41},
|
|
{37, 45, 44},
|
|
{37, 40, 45},
|
|
{44, 46, 43},
|
|
{42, 43, 46},
|
|
{45, 47, 44},
|
|
{46, 44, 47},
|
|
{48, 45, 40},
|
|
{47, 45, 48},
|
|
{48, 40, 49},
|
|
{38, 49, 40},
|
|
{48, 50, 47},
|
|
{51, 48, 49},
|
|
{50, 48, 51},
|
|
{49, 38, 52},
|
|
{50, 53, 47},
|
|
{53, 46, 47},
|
|
{52, 54, 49},
|
|
{49, 54, 51},
|
|
{38, 55, 52},
|
|
{32, 55, 38},
|
|
{55, 32, 31},
|
|
{55, 31, 30},
|
|
{30, 56, 55},
|
|
{52, 55, 56},
|
|
{30, 27, 56},
|
|
{24, 56, 27},
|
|
{56, 24, 21},
|
|
{56, 57, 52},
|
|
{52, 57, 54},
|
|
{14, 21, 17},
|
|
{57, 58, 54},
|
|
{51, 54, 58},
|
|
{21, 14, 59},
|
|
{59, 56, 21},
|
|
{59, 57, 56},
|
|
{59, 58, 57},
|
|
{10, 59, 14},
|
|
{59, 10, 60},
|
|
{5, 60, 10},
|
|
{3, 60, 5},
|
|
{59, 61, 58},
|
|
{60, 61, 59},
|
|
{60, 3, 62},
|
|
{1, 62, 3},
|
|
{2, 62, 1},
|
|
{62, 2, 63},
|
|
{62, 63, 64},
|
|
{60, 62, 65},
|
|
{62, 64, 65},
|
|
{60, 65, 61},
|
|
{66, 65, 64},
|
|
{66, 67, 65},
|
|
{67, 68, 65},
|
|
{61, 65, 68},
|
|
{68, 67, 69},
|
|
{61, 68, 70},
|
|
{58, 61, 70},
|
|
{69, 71, 68},
|
|
{70, 68, 71},
|
|
{69, 72, 71},
|
|
{70, 71, 72},
|
|
{72, 69, 73},
|
|
{74, 72, 73},
|
|
{58, 70, 75},
|
|
{70, 72, 75},
|
|
{58, 75, 51},
|
|
{74, 76, 72},
|
|
{75, 77, 51},
|
|
{50, 51, 77},
|
|
{72, 78, 75},
|
|
{78, 77, 75},
|
|
{78, 72, 76},
|
|
{79, 50, 77},
|
|
{79, 77, 78},
|
|
{79, 53, 50},
|
|
{80, 78, 76},
|
|
{80, 79, 78},
|
|
{76, 74, 81},
|
|
{81, 80, 76},
|
|
{82, 81, 74},
|
|
{82, 83, 81},
|
|
{80, 84, 79},
|
|
{84, 53, 79},
|
|
{83, 85, 81},
|
|
{85, 80, 81},
|
|
{83, 86, 85},
|
|
{87, 84, 80},
|
|
{80, 85, 87},
|
|
{88, 53, 84},
|
|
{87, 88, 84},
|
|
{89, 85, 86},
|
|
{89, 86, 90},
|
|
{90, 8, 89},
|
|
{12, 89, 8},
|
|
{91, 85, 89},
|
|
{89, 12, 91},
|
|
{85, 92, 87},
|
|
{92, 85, 91},
|
|
{91, 12, 93},
|
|
{93, 92, 91},
|
|
{12, 19, 93},
|
|
{87, 92, 94},
|
|
{92, 93, 94},
|
|
{93, 19, 94},
|
|
{87, 94, 88},
|
|
{94, 19, 95},
|
|
{19, 18, 95},
|
|
{88, 94, 96},
|
|
{96, 94, 95},
|
|
{53, 88, 96},
|
|
{18, 97, 95},
|
|
{97, 18, 22},
|
|
{95, 98, 96},
|
|
{98, 53, 96},
|
|
{95, 97, 98},
|
|
{53, 98, 46},
|
|
{46, 98, 42},
|
|
{97, 22, 99},
|
|
{98, 97, 99},
|
|
{98, 99, 42},
|
|
{28, 99, 22},
|
|
{99, 28, 42},
|
|
{100, 63, 2},
|
|
{100, 64, 63},
|
|
{64, 100, 101},
|
|
{102, 101, 100},
|
|
{103, 102, 100},
|
|
{104, 64, 101},
|
|
{64, 104, 66},
|
|
{101, 102, 105},
|
|
{105, 104, 101},
|
|
{102, 103, 106},
|
|
{107, 106, 103},
|
|
{102, 108, 105},
|
|
{108, 102, 106},
|
|
{109, 106, 107},
|
|
{110, 109, 107},
|
|
{111, 108, 106},
|
|
{109, 111, 106},
|
|
{112, 105, 108},
|
|
{111, 112, 108},
|
|
{113, 109, 110},
|
|
{113, 111, 109},
|
|
{114, 113, 110},
|
|
{115, 114, 110},
|
|
{115, 116, 114},
|
|
{117, 111, 113},
|
|
{114, 117, 113},
|
|
{116, 118, 114},
|
|
{119, 118, 116},
|
|
{114, 118, 120},
|
|
{117, 114, 120},
|
|
{121, 118, 119},
|
|
{118, 121, 120},
|
|
{119, 122, 121},
|
|
{123, 121, 122},
|
|
{124, 121, 123},
|
|
{121, 124, 125},
|
|
{126, 125, 124},
|
|
{127, 125, 126},
|
|
{128, 127, 126},
|
|
{128, 129, 127},
|
|
{130, 121, 125},
|
|
{125, 127, 131},
|
|
{130, 125, 131},
|
|
{132, 127, 129},
|
|
{127, 132, 131},
|
|
{121, 130, 133},
|
|
{120, 121, 133},
|
|
{130, 131, 134},
|
|
{130, 135, 133},
|
|
{134, 135, 130},
|
|
{133, 136, 120},
|
|
{134, 131, 137},
|
|
{132, 137, 131},
|
|
{133, 138, 136},
|
|
{135, 138, 133},
|
|
{139, 137, 132},
|
|
{139, 140, 137},
|
|
{137, 140, 141},
|
|
{137, 141, 134},
|
|
{132, 142, 139},
|
|
{141, 143, 134},
|
|
{142, 132, 144},
|
|
{132, 129, 144},
|
|
{142, 144, 145},
|
|
{129, 146, 144},
|
|
{144, 147, 145},
|
|
{148, 144, 146},
|
|
{147, 144, 148},
|
|
{149, 134, 143},
|
|
{149, 135, 134},
|
|
{143, 150, 149},
|
|
{143, 141, 150},
|
|
{135, 149, 151},
|
|
{141, 152, 150},
|
|
{149, 150, 153},
|
|
{151, 149, 153},
|
|
{150, 152, 154},
|
|
{153, 150, 154},
|
|
{152, 141, 155},
|
|
{155, 141, 140},
|
|
{139, 155, 140},
|
|
{156, 152, 155},
|
|
{154, 152, 156},
|
|
{157, 155, 139},
|
|
{157, 139, 142},
|
|
{157, 142, 145},
|
|
{157, 158, 155},
|
|
{158, 156, 155},
|
|
{158, 157, 159},
|
|
{158, 159, 156},
|
|
{157, 145, 159},
|
|
{159, 160, 156},
|
|
{156, 160, 154},
|
|
{161, 159, 145},
|
|
{147, 161, 145},
|
|
{162, 161, 147},
|
|
{163, 159, 161},
|
|
{163, 161, 162},
|
|
{159, 163, 160},
|
|
{163, 162, 164},
|
|
{165, 164, 162},
|
|
{166, 164, 165},
|
|
{164, 166, 167},
|
|
{163, 164, 168},
|
|
{168, 164, 167},
|
|
{160, 163, 169},
|
|
{163, 168, 169},
|
|
{160, 169, 170},
|
|
{154, 160, 170},
|
|
{168, 171, 169},
|
|
{169, 171, 170},
|
|
{154, 170, 172},
|
|
{170, 171, 172},
|
|
{154, 172, 153},
|
|
{173, 153, 172},
|
|
{172, 171, 173},
|
|
{173, 151, 153},
|
|
{173, 171, 174},
|
|
{151, 173, 175},
|
|
{174, 175, 173},
|
|
{171, 176, 174},
|
|
{171, 168, 176},
|
|
{175, 174, 177},
|
|
{177, 174, 176},
|
|
{178, 151, 175},
|
|
{135, 151, 178},
|
|
{138, 135, 178},
|
|
{175, 179, 178},
|
|
{179, 138, 178},
|
|
{175, 177, 180},
|
|
{180, 179, 175},
|
|
{177, 181, 180},
|
|
{177, 176, 181},
|
|
{182, 179, 180},
|
|
{168, 183, 176},
|
|
{168, 167, 183},
|
|
{184, 181, 176},
|
|
{183, 184, 176},
|
|
{180, 181, 185},
|
|
{180, 185, 182},
|
|
{186, 181, 184},
|
|
{186, 185, 181},
|
|
{184, 183, 187},
|
|
{185, 186, 188},
|
|
{186, 184, 189},
|
|
{189, 184, 187},
|
|
{190, 185, 188},
|
|
{182, 185, 190},
|
|
{186, 191, 188},
|
|
{191, 186, 189},
|
|
{188, 191, 190},
|
|
{187, 192, 189},
|
|
{191, 189, 192},
|
|
{187, 183, 193},
|
|
{183, 167, 193},
|
|
{194, 192, 187},
|
|
{193, 194, 187},
|
|
{195, 191, 192},
|
|
{196, 192, 194},
|
|
{192, 196, 195},
|
|
{197, 191, 195},
|
|
{190, 191, 197},
|
|
{196, 198, 195},
|
|
{198, 197, 195},
|
|
{199, 190, 197},
|
|
{190, 199, 182},
|
|
{197, 198, 200},
|
|
{201, 182, 199},
|
|
{182, 201, 179},
|
|
{197, 202, 199},
|
|
{202, 197, 200},
|
|
{203, 199, 202},
|
|
{199, 203, 201},
|
|
{202, 200, 203},
|
|
{204, 179, 201},
|
|
{201, 203, 204},
|
|
{179, 204, 138},
|
|
{205, 138, 204},
|
|
{204, 203, 205},
|
|
{138, 205, 136},
|
|
{200, 206, 203},
|
|
{203, 207, 205},
|
|
{206, 207, 203},
|
|
{136, 205, 208},
|
|
{205, 207, 209},
|
|
{205, 209, 208},
|
|
{206, 210, 207},
|
|
{211, 136, 208},
|
|
{120, 136, 211},
|
|
{120, 211, 117},
|
|
{208, 209, 212},
|
|
{211, 208, 212},
|
|
{207, 213, 209},
|
|
{213, 207, 210},
|
|
{214, 212, 209},
|
|
{214, 209, 213},
|
|
{211, 212, 215},
|
|
{212, 214, 216},
|
|
{216, 215, 212},
|
|
{211, 215, 217},
|
|
{117, 211, 217},
|
|
{216, 218, 215},
|
|
{215, 218, 217},
|
|
{117, 217, 219},
|
|
{218, 219, 217},
|
|
{219, 111, 117},
|
|
{111, 219, 112},
|
|
{219, 218, 220},
|
|
{219, 221, 112},
|
|
{220, 221, 219},
|
|
{218, 222, 220},
|
|
{221, 220, 222},
|
|
{222, 218, 216},
|
|
{112, 221, 223},
|
|
{223, 105, 112},
|
|
{223, 104, 105},
|
|
{224, 221, 222},
|
|
{223, 225, 104},
|
|
{104, 225, 66},
|
|
{226, 223, 221},
|
|
{226, 225, 223},
|
|
{226, 221, 224},
|
|
{66, 225, 67},
|
|
{226, 224, 227},
|
|
{227, 225, 226},
|
|
{222, 228, 224},
|
|
{224, 228, 227},
|
|
{216, 228, 222},
|
|
{216, 214, 228},
|
|
{214, 213, 228},
|
|
{67, 225, 229},
|
|
{229, 225, 227},
|
|
{229, 69, 67},
|
|
{229, 73, 69},
|
|
{74, 73, 229},
|
|
{227, 228, 230},
|
|
{229, 227, 230},
|
|
{213, 230, 228},
|
|
{231, 74, 229},
|
|
{230, 231, 229},
|
|
{232, 230, 213},
|
|
{230, 232, 231},
|
|
{210, 232, 213},
|
|
{74, 231, 233},
|
|
{233, 231, 232},
|
|
{233, 82, 74},
|
|
{233, 83, 82},
|
|
{234, 232, 210},
|
|
{232, 234, 233},
|
|
{235, 83, 233},
|
|
{235, 233, 234},
|
|
{234, 210, 236},
|
|
{236, 235, 234},
|
|
{210, 206, 236},
|
|
{206, 200, 236},
|
|
{235, 237, 83},
|
|
{86, 83, 237},
|
|
{237, 90, 86},
|
|
{90, 237, 238},
|
|
{238, 8, 90},
|
|
{237, 235, 239},
|
|
{8, 238, 240},
|
|
{240, 7, 8},
|
|
{241, 238, 237},
|
|
{240, 238, 241},
|
|
{237, 239, 241},
|
|
{239, 235, 242},
|
|
{235, 236, 242},
|
|
{239, 242, 243},
|
|
{242, 236, 243},
|
|
{241, 239, 243},
|
|
{236, 244, 243},
|
|
{241, 243, 245},
|
|
{244, 236, 246},
|
|
{246, 236, 200},
|
|
{245, 243, 247},
|
|
{247, 243, 244},
|
|
{245, 248, 241},
|
|
{245, 247, 248},
|
|
{240, 241, 248},
|
|
{247, 244, 249},
|
|
{246, 250, 244},
|
|
{244, 250, 249},
|
|
{200, 251, 246},
|
|
{250, 246, 251},
|
|
{251, 200, 198},
|
|
{251, 198, 196},
|
|
{252, 250, 251},
|
|
{252, 249, 250},
|
|
{196, 253, 251},
|
|
{251, 253, 252},
|
|
{249, 252, 253},
|
|
{253, 196, 194},
|
|
{254, 249, 253},
|
|
{253, 194, 254},
|
|
{249, 255, 247},
|
|
{249, 254, 255},
|
|
{255, 248, 247},
|
|
{256, 254, 194},
|
|
{194, 193, 256},
|
|
{255, 254, 257},
|
|
{256, 257, 254},
|
|
{256, 193, 258},
|
|
{257, 256, 258},
|
|
{258, 193, 259},
|
|
{167, 259, 193},
|
|
{260, 258, 259},
|
|
{259, 167, 261},
|
|
{260, 259, 261},
|
|
{167, 166, 261},
|
|
{166, 165, 261},
|
|
{262, 258, 260},
|
|
{262, 257, 258},
|
|
{260, 261, 263},
|
|
{261, 165, 264},
|
|
{261, 264, 263},
|
|
{264, 165, 162},
|
|
{147, 264, 162},
|
|
{148, 264, 147},
|
|
{146, 264, 148},
|
|
{264, 146, 265},
|
|
{146, 129, 265},
|
|
{129, 128, 265},
|
|
{126, 265, 128},
|
|
{266, 264, 265},
|
|
{265, 126, 266},
|
|
{266, 263, 264},
|
|
{126, 124, 123},
|
|
{123, 266, 126},
|
|
{266, 267, 263},
|
|
{267, 266, 123},
|
|
{263, 267, 260},
|
|
{267, 123, 122},
|
|
{267, 262, 260},
|
|
{122, 268, 267},
|
|
{262, 267, 268},
|
|
{268, 122, 119},
|
|
{268, 119, 116},
|
|
{268, 116, 115},
|
|
{268, 269, 262},
|
|
{115, 269, 268},
|
|
{257, 262, 269},
|
|
{270, 269, 115},
|
|
{257, 269, 270},
|
|
{270, 115, 110},
|
|
{270, 271, 257},
|
|
{270, 110, 271},
|
|
{271, 255, 257},
|
|
{271, 248, 255},
|
|
{110, 272, 271},
|
|
{248, 271, 272},
|
|
{272, 110, 107},
|
|
{107, 103, 272},
|
|
{272, 273, 248},
|
|
{273, 272, 103},
|
|
{240, 248, 273},
|
|
{100, 273, 103},
|
|
{273, 274, 240},
|
|
{273, 100, 274},
|
|
{240, 274, 7},
|
|
{2, 274, 100},
|
|
{0, 7, 274},
|
|
{274, 2, 0}
|
|
});
|
|
|
|
TArray<uint16> Materials;
|
|
for (int32 i = 0; i < Indices.Num(); ++i)
|
|
{
|
|
Materials.Emplace(0);
|
|
}
|
|
|
|
FTriangleMeshImplicitObjectPtr TriangleMesh( new FTriangleMeshImplicitObject(MoveTemp(TrimeshParticles), MoveTemp(Indices), MoveTemp(Materials)));
|
|
TImplicitObjectScaled<FTriangleMeshImplicitObject> ScaledTriangleMesh = TImplicitObjectScaled<FTriangleMeshImplicitObject>(TriangleMesh, FVec3(50,50,50));
|
|
|
|
const FVec3 X1 = { 0,0,-19.45 };
|
|
const FVec3 X2 = X1 + FVec3(0, 0, 38.9);
|
|
const FReal Radius = 25.895;
|
|
const FCapsule Capsule = FCapsule(X1, X2, Radius);
|
|
|
|
const FVec3 CapsuleToTrimeshTranslation = { 1818.55884, 27.8377075, -630.160645 };
|
|
const FRigidTransform3 CapsuleToTrimesh(CapsuleToTrimeshTranslation, FQuat::Identity);
|
|
|
|
const FVec3 TrimeshTranslation = { -1040.00000, 700.000000, 992.000000 };
|
|
const FRigidTransform3 TrimeshTransform(TrimeshTranslation, FQuat::Identity);
|
|
|
|
const FVec3 Dir(0, 0, -1);
|
|
const FReal Length = 159.100098;
|
|
|
|
FReal OutTime = -1;
|
|
FVec3 Normal(0.0);
|
|
FVec3 Position(0.0);
|
|
int32 FaceIndex = -1;
|
|
FVec3 FaceNormal(0.0);
|
|
bool bResult = ScaledTriangleMesh.LowLevelSweepGeom(Capsule, CapsuleToTrimesh, Dir, Length, OutTime, Position, Normal, FaceIndex, FaceNormal, 0.0f, true);
|
|
FVec3 WorldPosition = TrimeshTransform.TransformPositionNoScale(Position);
|
|
|
|
EXPECT_EQ(bResult, true);
|
|
EXPECT_EQ(FaceIndex, 415);
|
|
EXPECT_NEAR(WorldPosition.X, 763.85413, KINDA_SMALL_NUMBER);
|
|
EXPECT_NEAR(WorldPosition.Y, 728.80212, KINDA_SMALL_NUMBER);
|
|
EXPECT_NEAR(WorldPosition.Z, 303.77856, KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
struct FSphereSweepFixture : public testing::Test
|
|
{
|
|
struct FSweepResultData
|
|
{
|
|
bool bResult;
|
|
FReal TOI;
|
|
FVec3 Position, Normal, FaceNormal;
|
|
int32 FaceId;
|
|
};
|
|
|
|
FSweepResultData SweepQuerySphere(const FImplicitObject& TestObject, const FRigidTransform3& TestObjectTransform, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
const Chaos::FSphere Sphere(FVec3::ZeroVector, SphereRadius);
|
|
const FRigidTransform3 StartTM(SweepStart, TRotation<FReal, 3>::Identity);
|
|
const FVec3 NormalizedSweepDirection = SweepDirection.GetSafeNormal();
|
|
|
|
FSweepResultData Result;
|
|
Result.bResult = SweepQuery(TestObject, TestObjectTransform, Sphere, StartTM, NormalizedSweepDirection, SweepLength, Result.TOI, Result.Position, Result.Normal, Result.FaceId, Result.FaceNormal, 0.0, bComputeMTD);
|
|
return Result;
|
|
}
|
|
|
|
FSweepResultData SweepQuerySphere(const FImplicitObject& TestObject, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
return SweepQuerySphere(TestObject, FRigidTransform3(), SweepStart, SweepDirection, SweepLength);
|
|
}
|
|
|
|
FReal SphereRadius = 25;
|
|
bool bComputeMTD = true;
|
|
};
|
|
|
|
struct FTriangleMeshSweepFixture : public FSphereSweepFixture
|
|
{
|
|
struct FMeshInitData
|
|
{
|
|
FTriangleMeshImplicitObject::ParticlesType TrimeshParticles;
|
|
TArray<TVec3<int32>> Indices;
|
|
TArray<uint16> Materials;
|
|
|
|
void AutoBuildMaterials()
|
|
{
|
|
Materials.Empty();
|
|
for (int32 i = 0; i < Indices.Num(); ++i)
|
|
{
|
|
Materials.Emplace(0);
|
|
}
|
|
}
|
|
};
|
|
|
|
static FMeshInitData CreateSimpleTriInitData()
|
|
{
|
|
FMeshInitData Result;
|
|
Result.TrimeshParticles = FTriangleMeshImplicitObject::ParticlesType(
|
|
{
|
|
{0, 0, 0},
|
|
{100, 0, 0},
|
|
{100, 100, 0},
|
|
});
|
|
Result.Indices =
|
|
{
|
|
{0, 1, 2},
|
|
};
|
|
Result.AutoBuildMaterials();
|
|
return Result;
|
|
}
|
|
|
|
static FMeshInitData CreateSimpleQuadInitData()
|
|
{
|
|
FMeshInitData Result;
|
|
Result.TrimeshParticles = FTriangleMeshImplicitObject::ParticlesType(
|
|
{
|
|
{0, 0, 0},
|
|
{100, 0, 0},
|
|
{100, 100, 0},
|
|
{0, 100, 0},
|
|
});
|
|
Result.Indices =
|
|
{
|
|
{0, 1, 2},
|
|
{0, 2, 3},
|
|
};
|
|
Result.AutoBuildMaterials();
|
|
return Result;
|
|
}
|
|
|
|
FSweepResultData SweepSphere(const FTriangleMeshImplicitObject& TriangleMesh, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
const Chaos::FSphere Sphere(FVec3::ZeroVector, SphereRadius);
|
|
const FRigidTransform3 StartTM(SweepStart, TRotation<FReal, 3>::Identity);
|
|
const FVec3 NormalizedSweepDirection = SweepDirection.GetSafeNormal();
|
|
|
|
FSweepResultData Result;
|
|
Result.bResult = TriangleMesh.SweepGeom(Sphere, StartTM, NormalizedSweepDirection, SweepLength, Result.TOI, Result.Position, Result.Normal, Result.FaceId, Result.FaceNormal, 0.0, bComputeMTD);
|
|
return Result;
|
|
}
|
|
|
|
FSweepResultData SweepSphere(FMeshInitData& InitData, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
FTriangleMeshImplicitObject TriangleMesh(MoveTemp(InitData.TrimeshParticles), MoveTemp(InitData.Indices), MoveTemp(InitData.Materials), nullptr, nullptr, true);
|
|
return SweepSphere(TriangleMesh, SweepStart, SweepDirection, SweepLength);
|
|
}
|
|
};
|
|
|
|
TEST_F(FTriangleMeshSweepFixture, SphereWithInitialIntersectionOfTwoTriangles_SweepAgainstTriMesh_CorrectTriangleIsHit)
|
|
{
|
|
// Test a straight down sweep where the sphere has an initial intersection with both triangles.
|
|
FMeshInitData InitData = CreateSimpleQuadInitData();
|
|
FTriangleMeshImplicitObject TriangleMesh(MoveTemp(InitData.TrimeshParticles), MoveTemp(InitData.Indices), MoveTemp(InitData.Materials), nullptr, nullptr, true);
|
|
|
|
// Test where tri0 has the first TOI.
|
|
FSweepResultData Result = SweepSphere(TriangleMesh, FVec3(60, 50, 10), FVec3(0, 0, -1));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(60, 50, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 0);
|
|
|
|
// Test where tri1 has the first TOI.
|
|
Result = SweepSphere(TriangleMesh, FVec3(40, 50, 10), FVec3(0, 0, -1));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(40, 50, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 1);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshSweepFixture, SphereWithInitialIntersectionOfOneTriangle_SweepAgainstTriMesh_CorrectTriangleIsHit)
|
|
{
|
|
// Test a diagonal sweep where one triangle has an initial intersection and the other has a positive TOI.
|
|
FMeshInitData InitData = CreateSimpleQuadInitData();
|
|
FTriangleMeshImplicitObject TriangleMesh(MoveTemp(InitData.TrimeshParticles), MoveTemp(InitData.Indices), MoveTemp(InitData.Materials), nullptr, nullptr, true);
|
|
|
|
// Test where tri0 has the initial intersection.
|
|
FSweepResultData Result = SweepSphere(TriangleMesh, FVec3(90, 50, 10), FVec3(0, 0, -1));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(90, 50, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 0);
|
|
|
|
// Test where tri1 has the initial intersection.
|
|
Result = SweepSphere(TriangleMesh, FVec3(10, 50, 10), FVec3(0, 0, -1));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(10, 50, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 1);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshSweepFixture, SphereWithZeroLengthSweep_TestAllAxes_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FTriangleMeshImplicitObject TriangleMesh(MoveTemp(InitData.TrimeshParticles), MoveTemp(InitData.Indices), MoveTemp(InitData.Materials), nullptr, nullptr, true);
|
|
|
|
// Test each cardinal axis
|
|
FSweepResultData Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(-1, 0, 0), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(1, 0, 0), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, -1, 0), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, 1, 0), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, 0, -1), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, 0, 1), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
// Test the zero vector direction
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, 0, 0), 0);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
|
|
Result = SweepSphere(TriangleMesh, FVec3(20, 20, 0), FVec3(0, 0, 0), 1);
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
// All front-face hits (sweeping opposed to the normal) should generate valid hits.
|
|
TEST_F(FTriangleMeshSweepFixture, SphereInFront_SweepOpposedToNormal_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
const FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 0);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshSweepFixture, SphereInFrontWithInitialOverlap_SweepOpposedToNormal_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 0);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshSweepFixture, SphereBehindWithInitialOverlap_SweepOpposedToNormal_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, -10), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, -15, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, -1), KINDA_SMALL_NUMBER);
|
|
EXPECT_EQ(Result.FaceId, 0);
|
|
}
|
|
|
|
struct FTriangleMeshBackfaceSweepFixture : public FTriangleMeshSweepFixture
|
|
{
|
|
static constexpr FReal ValueWithinParallelEpsilon = UE_SMALL_NUMBER;
|
|
static constexpr FReal ValueOutsideParallelEpsilon = 4 * UE_KINDA_SMALL_NUMBER;
|
|
};
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereBehind_SweepOpposedToNormal_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, -50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
// All back-face hits (sweeping along the normal) should not generate a valid hit.
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereBehind_SweepAlongNormal_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereBehindWithInitialOverlap_SweepAlongNormal_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, -10), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereInFrontWithInitialOverlap_SweepAlongNormal_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereInFront_SweepAlongNormal_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
// Parallel checks are more interesting. If there is an initial overlap then no hit should be generated.
|
|
// This parallel checks uses an epsilon to determine the boundaries.
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereWithInitialOverlap_SweepExactlyParallel_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(1, 0, 0));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereWithInitialOverlap_SweepOpposedToNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(1, 0, ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereWithInitialOverlap_SweepOpposedToNormalOutsideParallelEpsilon_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(1, 0, ValueOutsideParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereWithInitialOverlap_SweepAlongNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(1, 0, -ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereWithInitialOverlap_SweepAlongNormalOutsideParallelEpsilon_HitIsExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(20, 20, 10), FVec3(1, 0, 4 * -ValueOutsideParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
// Need a few extra tests for parallel to validate that no initial overlap always returns false.
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereInAabbWithNoInitialOverlap_SweepExactlyParallel_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(0, 100, 0), FVec3(1, -1, 0));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereInAabbWithNoInitialOverlap_AlongNormalWithinPositiveEpsilon_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(0, 100, 0), FVec3(1, -1, ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FTriangleMeshBackfaceSweepFixture, SphereInAabbWithNoInitialOverlap_AlongNormalWithinNegativeEpsilon_HitIsNotExpected)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
FSweepResultData Result = SweepSphere(InitData, FVec3(0, 100, 0), FVec3(1, -1, -ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
// Some extra tests for negative scales
|
|
struct FScaledTriMeshSweepFixture : public FTriangleMeshBackfaceSweepFixture
|
|
{
|
|
static FMeshInitData CreateSimpleTriInitData()
|
|
{
|
|
FMeshInitData Result;
|
|
// Use a slightly different triangle mesh than above. This allows easy negation of the mesh without having to move the sweep's location.
|
|
Result.TrimeshParticles = FTriangleMeshImplicitObject::ParticlesType(
|
|
{
|
|
{-100, -100, 0},
|
|
{100, -100, 0},
|
|
{0, 100, 0},
|
|
});
|
|
Result.Indices =
|
|
{
|
|
{0, 1, 2},
|
|
};
|
|
Result.AutoBuildMaterials();
|
|
return Result;
|
|
}
|
|
|
|
FSweepResultData SweepSphere(const TImplicitObjectScaled<FTriangleMeshImplicitObject>& TriangleMesh, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
const Chaos::FSphere Sphere(FVec3::ZeroVector, SphereRadius);
|
|
const FRigidTransform3 StartTM(SweepStart, TRotation<FReal, 3>::Identity);
|
|
const FVec3 NormalizedSweepDirection = SweepDirection.GetSafeNormal();
|
|
|
|
FSweepResultData Result;
|
|
Result.bResult = SweepQuery(TriangleMesh, FRigidTransform3(), Sphere, StartTM, NormalizedSweepDirection, SweepLength, Result.TOI, Result.Position, Result.Normal, Result.FaceId, Result.FaceNormal, 0.0, true);
|
|
return Result;
|
|
}
|
|
|
|
FSweepResultData SweepSphere(FMeshInitData& InitData, const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
FTriangleMeshImplicitObject TriangleMesh(MoveTemp(InitData.TrimeshParticles), MoveTemp(InitData.Indices), MoveTemp(InitData.Materials), nullptr, nullptr, true);
|
|
FTriangleMeshBackfaceSweepFixture::SweepSphere(TriangleMesh, SweepStart, SweepDirection, SweepLength);
|
|
// Unfortunately, it is not possible to currently call FTriangleMeshImplicitObject::SweepGeom directly.
|
|
// There's code inside of TImplicitObjectScaled that negates some inputs values (the direction) that is necessary for the tests to work (follows the editor path).
|
|
TImplicitObjectScaled<FTriangleMeshImplicitObject> ScaledMesh(&TriangleMesh, TriMeshScale);
|
|
return SweepSphere(ScaledMesh, SweepStart, SweepDirection, SweepLength);
|
|
}
|
|
|
|
FSweepResultData SweepSphereVsSimpleTri(const FVec3& SweepStart, const FVec3& SweepDirection, const FReal SweepLength = 100)
|
|
{
|
|
FMeshInitData InitData = CreateSimpleTriInitData();
|
|
return SweepSphere(InitData, SweepStart, SweepDirection, SweepLength);
|
|
}
|
|
|
|
FVec3 TriMeshScale = FVec3(1, 1, 1);
|
|
};
|
|
|
|
// Test sweeps along the original front face
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXAxis_SweepInFrontOpposedToNormal_HitIsExpected)
|
|
{
|
|
// Negating the x axis should flip the winding order, but up is still the front face
|
|
TriMeshScale = FVec3(-1, 1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeYAxis_SweepInFrontOpposedToNormal_HitIsExpected)
|
|
{
|
|
// Negating the y axis should flip the winding order, but up is still the front face
|
|
TriMeshScale = FVec3(1, -1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeZAxis_SweepInBackAlongToNormal_HitIsNotExpected)
|
|
{
|
|
// Negating the z axis should cause down to be the front face
|
|
TriMeshScale = FVec3(1, 1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXYAxis_SweepInFrontOpposedToNormal_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, -1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, 1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXZAxis_SweepInFrontOpposedToNormal_HitIsNotExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, 1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeYZAxis_SweepInFrontOpposedToNormal_HitIsNotExpected)
|
|
{
|
|
TriMeshScale = FVec3(1, -1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXYZAxis_SweepInFrontOpposedToNormal_HitIsNotExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, -1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, 50), FVec3(0, 0, -1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
// Test sweeps along the original back face
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXAxis_SweepOnBackAlongNormal_HitIsNotExpected)
|
|
{
|
|
// Negating the x axis should flip the winding order, but up is still the front face
|
|
TriMeshScale = FVec3(-1, 1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeYAxis_SweepOnBackAlongNormal_HitIsNotExpected)
|
|
{
|
|
// Negating the y axis should flip the winding order, but up is still the front face
|
|
TriMeshScale = FVec3(1, -1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeZAxis_SweepOnBackAlongNormal_HitIsExpected)
|
|
{
|
|
// Negating the z axis should cause down to be the front face
|
|
TriMeshScale = FVec3(1, 1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, -1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXYAxis_SweepOnBackAlongNormal_HitIsNotExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, -1, 1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXZAxis_SweepOnBackAlongNormal_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, 1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, -1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeYZAxis_SweepOnBackAlongNormal_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(1, -1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, -1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXYZAxis_SweepOnBackAlongNormal_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, -1, -1);
|
|
const FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(20, 20, -50), FVec3(0, 0, 1));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 25, KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Position, FVec3(20, 20, 0), KINDA_SMALL_NUMBER);
|
|
EXPECT_VECTOR_NEAR(Result.Normal, FVec3(0, 0, -1), KINDA_SMALL_NUMBER);
|
|
}
|
|
|
|
// Test parallel sweeps
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXAxis_SphereWithInitialOverlap_SweepOpposedToNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, 1, 1);
|
|
FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(0, 0, 10), FVec3(1, 0, ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeZAxis_SphereWithInitialOverlap_SweepOpposedToNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(1, 1, -1);
|
|
FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(0, 0, 10), FVec3(1, 0, ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeXAxis_SphereWithInitialOverlap_SweepAlongNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(-1, 1, 1);
|
|
FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(0, 0, 10), FVec3(1, 0, -ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FScaledTriMeshSweepFixture, TriMeshWithNegativeZAxis_SphereWithInitialOverlap_SweepAlongNormalWithinParallelEpsilon_HitIsExpected)
|
|
{
|
|
TriMeshScale = FVec3(1, 1, -1);
|
|
FSweepResultData Result = SweepSphereVsSimpleTri(FVec3(0, 0, 10), FVec3(1, 0, -ValueWithinParallelEpsilon));
|
|
|
|
EXPECT_EQ(Result.bResult, true);
|
|
}
|
|
|
|
TEST_F(FSphereSweepFixture, TransformedUnionContainingNonUniformScaledObject_SweepSphere_ResultsAreExpected)
|
|
{
|
|
// This test is to catch a bug where a Transformed union with a scaled object would
|
|
// ensure because it attempted to go down the sweep as raycast path when there was a non-uniform scale.
|
|
bComputeMTD = false;
|
|
SphereRadius = 1;
|
|
|
|
|
|
// Create a union that has a scaled and non-scaled object
|
|
FImplicitObjectPtr SphereObjPtr = new FImplicitSphere3(FVec3(0, 0, 5), 1);
|
|
FImplicitObjectPtr ScaledBoxObjPtr = new TImplicitObjectScaled<FImplicitBox3>(new FImplicitBox3(FVec3(-1), FVec3(1)), FVec3(2, 1, 1));
|
|
TArray<FImplicitObjectPtr> Objects{ ScaledBoxObjPtr, SphereObjPtr };
|
|
FImplicitObjectPtr UnionObjectPtr = new FImplicitObjectUnion(MoveTemp(Objects));
|
|
// Build a transform around the union (this is necessary to produce the bug)
|
|
FRigidTransform3 ObjTransform(FVec3::Zero(), FRotation3::Identity, FVec3(1));
|
|
TImplicitObjectTransformed<FReal, 3> TestObject(UnionObjectPtr, ObjTransform);
|
|
|
|
// Test a few configurations to make sure we hit and don't hit where expected
|
|
FSweepResultData Result;
|
|
|
|
// To the left of the box
|
|
Result = SweepQuerySphere(TestObject, FVec3(-3.1, 20, 0), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, false);
|
|
|
|
// Should hit left edge of the box
|
|
Result = SweepQuerySphere(TestObject, FVec3(-2, 20, 0), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 18, KINDA_SMALL_NUMBER);
|
|
|
|
// Should hit right edge of the box
|
|
Result = SweepQuerySphere(TestObject, FVec3(2, 20, 0), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 18, KINDA_SMALL_NUMBER);
|
|
|
|
// To the right of the box
|
|
Result = SweepQuerySphere(TestObject, FVec3(3.1, 20, 0), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, false);
|
|
|
|
// Center of the sphere
|
|
Result = SweepQuerySphere(TestObject, FVec3(0, 20, 5), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, true);
|
|
EXPECT_NEAR(Result.TOI, 18, KINDA_SMALL_NUMBER);
|
|
|
|
// To the left of the sphere
|
|
Result = SweepQuerySphere(TestObject, FVec3(-2.1, 20, 5), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, false);
|
|
|
|
// To the right of the sphere
|
|
Result = SweepQuerySphere(TestObject, FVec3(2.1, 20, 5), FVec3(0, -1, 0));
|
|
EXPECT_EQ(Result.bResult, false);
|
|
}
|
|
}
|