public MeshTriangle(MeshVertex vertex1, MeshVertex vertex2, MeshVertex vertex3) { this.Vertex1 = vertex1; this.Vertex2 = vertex2; this.Vertex3 = vertex3; this.visible = true; this.CurrentBarycentricCoordinate = BarycentricCoordinate.Zero; this.material = null; }
//From http://jgt.akpeters.com/papers/GuigueDevillers03/ray_triangle_intersection.html public bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); Vector3D vect0, vect1, nvect; float det, inv_det; vect0 = this.Vertex2.Position - this.Vertex1.Position; vect1 = this.Vertex3.Position - this.Vertex1.Position; Vector3D normalNonNormalized = vect0 ^ vect1; /* orientation of the ray with respect to the triangle's normal, also used to calculate output parameters*/ det = -(ray.Direction * normalNonNormalized); #if TEST_CULL /* define TEST_CULL if culling is desired */ if (det < MathUtil.Epsilon) return false; /* calculate vector from ray origin to this.vertex1 */ vect0 = this.Vertex1.Position - ray.Origin; /* vector used to calculate u and v parameters */ nvect = ray.Direction ^ vect0; /* calculate vector from ray origin to this.vertex2*/ vect1 = this.Vertex2.Position - ray.Origin; /* calculate unnormalized v parameter and test bounds */ float v = -(vect1 * nvect); if (v < 0.0 || v > det) return false; /* calculate vector from ray origin to this.vertex3*/ vect1 = this.Vertex3.Position - ray.Origin; /* calculate unnormalized v parameter and test bounds */ float u = vect1 * nvect; if (u < 0.0 || u + v > det) return false; /* calculate unormalized t parameter */ float t = -(vect0 * normalNonNormalized); inv_det = 1.0f / det; /* calculate u v t, ray intersects triangle */ u = u * inv_det; v = v * inv_det; t = t * inv_det; #else /* the non-culling branch */ /* if determinant is near zero, ray is parallel to the plane of triangle */ if (det.NearZero()) { return false; } /* calculate vector from ray origin to this.vertex1 */ vect0 = this.Vertex1.Position - ray.Origin; /* normal vector used to calculate u and v parameters */ nvect = ray.Direction ^ vect0; inv_det = 1.0f / det; /* calculate vector from ray origin to this.vertex2*/ vect1 = this.Vertex2.Position - ray.Origin; /* calculate v parameter and test bounds */ float v = -(vect1 * nvect) * inv_det; if (v < 0.0f || v > 1.0f) { return false; } /* calculate vector from ray origin to this.vertex3*/ vect1 = this.Vertex3.Position - ray.Origin; /* calculate v parameter and test bounds */ float u = (vect1 * nvect) * inv_det; if (u < 0.0f || u + v > 1.0f) { return false; } /* calculate t, ray intersects triangle */ float t = -(vect0 * normalNonNormalized) * inv_det; #endif //if (t < 100) // return false; // return 1; //if (t < 100) //FIXME: the correct is t < 0, but dont work, why? tell me you! =P //{ // return false; //} if (t >= 0) { intersect.TMin = t; intersect.Normal = Vector3D.Normal(this.Vertex1.Position, this.Vertex2.Position, this.Vertex3.Position); intersect.HitPoint = ray.Origin + (t * ray.Direction); this.CurrentBarycentricCoordinate = new BarycentricCoordinate(1.0f - (u + v), u, v); intersect.HitPrimitive = this; return true; } return false; }