public TriangleD[] GetMeshTrianglesD() { var triangles = new TriangleD[TriangleIndicies.Count / 3]; for (int i = 0; i < triangles.Length; i++) { var triangle = new TriangleD( Vertices[TriangleIndicies[i * 3 + 0]].ToVector3d(), Vertices[TriangleIndicies[i * 3 + 1]].ToVector3d(), Vertices[TriangleIndicies[i * 3 + 2]].ToVector3d() ); triangles[i] = triangle; } return(triangles); }
public static bool Intersects(this TriangleD triangle, SphereD sphere) { // from http://realtimecollisiondetection.net/bLog/?p=103 var A = triangle.a - sphere.center; var B = triangle.b - sphere.center; var C = triangle.c - sphere.center; var rr = sphere.radius * sphere.radius; var V = (B - A).Cross(C - A); var d = A.Dot(V); var e = V.Dot(V); var sep1 = (d * d > rr * e); var aa = A.Dot(A); var ab = A.Dot(B); var ac = A.Dot(C); var bb = B.Dot(B); var bc = B.Dot(C); var cc = C.Dot(C); var sep2 = (aa > rr) & (ab > aa) & (ac > aa); var sep3 = (bb > rr) & (ab > bb) & (bc > bb); var sep4 = (cc > rr) & (ac > cc) & (bc > cc); var AB = B - A; var BC = C - B; var CA = A - C; var d1 = ab - aa; var d2 = bc - bb; var d3 = ac - cc; var e1 = AB.Dot(AB); var e2 = BC.Dot(BC); var e3 = CA.Dot(CA); var Q1 = A * e1 - d1 * AB; var Q2 = B * e2 - d2 * BC; var Q3 = C * e3 - d3 * CA; var QC = C * e1 - Q1; var QA = A * e2 - Q2; var QB = B * e3 - Q3; var sep5 = (Q1.Dot(Q1) > rr * e1 * e1) & (Q1.Dot(QC) > 0); var sep6 = (Q2.Dot(Q2) > rr * e2 * e2) & (Q2.Dot(QA) > 0); var sep7 = (Q3.Dot(Q3) > rr * e3 * e3) & (Q3.Dot(QB) > 0); return(!(sep1 | sep2 | sep3 | sep4 | sep5 | sep6 | sep7)); // or this, but i failed to convert it into shere x triangle http://www.phatcode.net/articles.php?id=459 }
public static bool Intersects(this SphereD sphere, TriangleD triangle) => Intersects(triangle, sphere);
// Thomas Moller ray triangle intersection // or http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/ // release 0.054317 us // debug 0.602176 us public static RayDHitInfo CastRay(this RayD ray, TriangleD triangle) { // TODO /* * Zde doplòte kód pro testování existence prùseèíku parsku s trojúhelníkem. * Vypoètený parametr t spoleènì s trojúhelníkem triangle vložte ma konci této metody * do metody ray.closest_hit, napø. takto * * return ray.closest_hit( t, triangle ); * * Tato metoda vrátí true v pøípadì, že zadaný parametr t je menší než pøedchozí a zapíše * do paprsku i ukazatel na zasažený trojúhelník, pøes který (metoda target) je možno následnì zjistit * normálu (target.normal()) nebo materiál v bodì zásahu. */ const double ____EPSILON = 0.000001f; Vector3d V1 = triangle.a; Vector3d V2 = triangle.b; Vector3d V3 = triangle.c; Vector3d O = ray.origin; //RayD origin Vector3d D = ray.direction; //RayD direction Vector3d e1, e2; //Edge1, Edge2 Vector3d P, Q, T; double det, inv_det, u, v; double t; //Find vectors for two edges sharing V1 e1 = V2 - V1; e2 = V3 - V1; //Begin calculating determinant - also used to calculate u parameter P = D.Cross(e2); //if determinant is near zero, ray lies in plane of triangle det = e1.Dot(P); //NOT CULLING if (det > -____EPSILON && det < ____EPSILON) { return(RayDHitInfo.NoHit); } inv_det = 1.0f / det; //calculate distance from V1 to ray origin T = O - V1; //Calculate u parameter and test bound u = T.Dot(P) * inv_det; //The intersection lies outside of the triangle if (u < 0.0f || u > 1.0f) { return(RayDHitInfo.NoHit); } //Prepare to test v parameter Q = T.Cross(e1); //Calculate V parameter and test bound v = D.Dot(Q) * inv_det; //The intersection lies outside of the triangle if (v < 0.0f || u + v > 1.0f) { return(RayDHitInfo.NoHit); } t = e2.Dot(Q) * inv_det; if (t > ____EPSILON) { //ray intersection return(RayDHitInfo.HitAtRayDistance(t)); } return(RayDHitInfo.NoHit); // trojúhelník nenalezen }