public bool Intersects(ref Triangle t, CollisionContent cc) { return t.Intersects(cc, ref sphere); }
void AppendGeometry(MeshContent mc, Matrix x, Gather g) { int ta = 2; int tb = 1; if (SwapWindingOrder) { ta = 1; tb = 2; } int vBase = g.Vertices.Count; bool first = (g.Bounds.Lo == Vector3.Zero && g.Bounds.Hi == Vector3.Zero); foreach (Vector3 v in mc.Positions) { Vector3 vt = Vector3.Transform(v, x); g.Vertices.Add(vt); if (first) { first = false; g.Bounds.Set(vt, vt); } g.Bounds.Include(vt); } foreach (GeometryContent gc in mc.Geometry) { for (int i = 0, n = gc.Indices.Count - 2; i < n; i += 3) { Triangle t = new Triangle(); t.VertexA = gc.Indices[i] + vBase; t.VertexB = gc.Indices[i + ta] + vBase; t.VertexC = gc.Indices[i + tb] + vBase; t.Normal = Vector3.Cross(g.Vertices[t.VertexB] - g.Vertices[t.VertexA], g.Vertices[t.VertexC] - g.Vertices[t.VertexB]); if (t.Normal.Y < 0) { ++negYCount; } if (t.Normal.LengthSquared() > 1e-10f) { t.Normal.Normalize(); } else { context.Logger.LogImportantMessage("Normal is surprisingly short: {0} for tri {1}", t.Normal, i / 3); // set some normal; I don't really care if (t.Normal.X > 0) t.Normal = Vector3.Right; else if (t.Normal.X < 0) t.Normal = Vector3.Left; else if (t.Normal.Z > 0) t.Normal = Vector3.Backward; else if (t.Normal.Z < 0) t.Normal = Vector3.Forward; else if (t.Normal.Y < 0) t.Normal = Vector3.Down; else t.Normal = Vector3.Up; } // Assume the center of the bounding sphere is the center of the longest edge. // This is true for any triangle that is right-angled or blunt. The center will float la = (g.Vertices[t.VertexB] - g.Vertices[t.VertexA]).Length(); float lb = (g.Vertices[t.VertexC] - g.Vertices[t.VertexB]).Length(); float lc = (g.Vertices[t.VertexA] - g.Vertices[t.VertexC]).Length(); Vector3 c; if (la > lb) if (la > lc) c = (g.Vertices[t.VertexB] + g.Vertices[t.VertexA]) * 0.5f; else c = (g.Vertices[t.VertexA] + g.Vertices[t.VertexC]) * 0.5f; else if (lb > lc) c = (g.Vertices[t.VertexC] + g.Vertices[t.VertexB]) * 0.5f; else c = (g.Vertices[t.VertexA] + g.Vertices[t.VertexC]) * 0.5f; t.Distance = Vector3.Dot(t.Normal, c); g.Triangles.Add(t); float r = (g.Vertices[t.VertexA] - c).Length(); r = Math.Max(r, (g.Vertices[t.VertexB] - c).Length()); r = Math.Max(r, (g.Vertices[t.VertexC] - c).Length()); BoundingSphere bs = new BoundingSphere(c, r); // The center is somewhere inside for a triangle that is sharp. // Calculate an alternative center to get a better bounding sphere. if (la < lb) if (la < lc) c = (g.Vertices[t.VertexC] * 2 + g.Vertices[t.VertexB] + g.Vertices[t.VertexA]) * 0.25f; else c = (g.Vertices[t.VertexB] * 2 + g.Vertices[t.VertexC] + g.Vertices[t.VertexA]) * 0.25f; else if (lb < lc) c = (g.Vertices[t.VertexA] * 2 + g.Vertices[t.VertexB] + g.Vertices[t.VertexC]) * 0.25f; else c = (g.Vertices[t.VertexB] * 2 + g.Vertices[t.VertexC] + g.Vertices[t.VertexA]) * 0.25f; r = (g.Vertices[t.VertexA] - c).Length(); r = Math.Max(r, (g.Vertices[t.VertexB] - c).Length()); r = Math.Max(r, (g.Vertices[t.VertexC] - c).Length()); if (r < bs.Radius) { bs.Center = c; bs.Radius = r; } g.BoundingSpheres.Add(bs); } } }
public bool Intersects(ref Triangle t, CollisionContent cc) { float dd = collRayD; return t.Intersects(cc, ref collRay, ref dd); }