MCPcopy Create free account
hub / github.com/FlaxEngine/FlaxEngine / IntersectsItself

Method IntersectsItself

Source/Engine/Physics/Actors/Cloth.cpp:225–290  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

223}
224
225bool Cloth::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal)
226{
227#if MODEL_USE_PRECISE_MESH_INTERSECTS
228 if (!Actor::IntersectsItself(ray, distance, normal))
229 return false;
230#if WITH_CLOTH
231 if (_cloth)
232 {
233 // Precise per-triangle intersection
234 const ModelInstanceActor::MeshReference meshRef = GetMesh();
235 if (meshRef.Actor == nullptr)
236 return false;
237 MeshAccessor accessor;
238 MeshBufferType bufferTypes[1] = { MeshBufferType::Index };
239 if (accessor.LoadMesh(meshRef.Get(), false, ToSpan(bufferTypes, 1)))
240 return false;
241 auto indices = accessor.Index();
242 auto indicesData = indices.GetData();
243 PhysicsBackend::LockClothParticles(_cloth);
244 const Span<const Float4> particles = PhysicsBackend::GetClothParticles(_cloth);
245 const Transform transform = GetTransform();
246 const bool indices16bit = indices.GetFormat() == PixelFormat::R16_UInt;
247 const int32 trianglesCount = indices.GetCount() / 3;
248 bool result = false;
249 distance = MAX_Real;
250 for (int32 triangleIndex = 0; triangleIndex < trianglesCount; triangleIndex++)
251 {
252 const int32 index = triangleIndex * 3;
253 int32 i0, i1, i2;
254 if (indices16bit)
255 {
256 i0 = indicesData.Get<uint16>()[index];
257 i1 = indicesData.Get<uint16>()[index + 1];
258 i2 = indicesData.Get<uint16>()[index + 2];
259 }
260 else
261 {
262 i0 = indicesData.Get<uint32>()[index];
263 i1 = indicesData.Get<uint32>()[index + 1];
264 i2 = indicesData.Get<uint32>()[index + 2];
265 }
266 const Vector3 v0 = transform.LocalToWorld(Vector3(particles[i0]));
267 const Vector3 v1 = transform.LocalToWorld(Vector3(particles[i1]));
268 const Vector3 v2 = transform.LocalToWorld(Vector3(particles[i2]));
269 Real d;
270 if (CollisionsHelper::RayIntersectsTriangle(ray, v0, v1, v2, d) && d < distance)
271 {
272 result = true;
273 normal = Vector3::Normalize((v1 - v0) ^ (v2 - v0));
274 distance = d;
275
276 // Flip normal if needed as cloth is two-sided
277 const Vector3 hitPos = ray.GetPoint(d);
278 if (Vector3::DistanceSquared(hitPos + normal, ray.Position) > Math::Square(d))
279 normal = -normal;
280 }
281 }
282 PhysicsBackend::UnlockClothParticles(_cloth);

Callers

nothing calls this directly

Calls 13

GetMeshFunction · 0.85
SquareFunction · 0.85
GetPointMethod · 0.80
ToSpanFunction · 0.50
Vector3Class · 0.50
NormalizeFunction · 0.50
LoadMeshMethod · 0.45
GetMethod · 0.45
IndexMethod · 0.45
GetDataMethod · 0.45
GetFormatMethod · 0.45
GetCountMethod · 0.45

Tested by

no test coverage detected