private const double MOVEPERSTEPPERCENT = 1d; // this seems to be stable with 100%, if nessassary, drop it down a bit so that parts don't move as far each step #endregion //TODO: Make a better version, probably a combination of pulling in and separating public static void PullInCrude(out bool changed, PartSeparator_Part[] parts) { // Figure out the max radius double[] sizes = parts.Select(o => (o.Size.X + o.Size.Y + o.Size.Z) / 3d).ToArray(); double largestPart = sizes.Max(); double maxRadius = largestPart * 8d; double maxRadiusSquare = maxRadius * maxRadius; Point3D center = Math3D.GetCenter(parts.Select(o => Tuple.Create(o.Position, o.Mass)).ToArray()); changed = false; for (int cntr = 0; cntr < parts.Length; cntr++) { Vector3D offset = parts[cntr].Position - center; //NOTE: This is just going to the center of the part, it's not considering the extents of the part (this method IS called crude) if (offset.LengthSquared < maxRadiusSquare) { continue; } // Pull it straight in double difference = offset.Length - maxRadius; offset.Normalize(); offset *= difference * -1d; parts[cntr].Position += offset; //NOTE: I'm not going to change the center of mass changed = true; } }
public static CollisionHull[] Separate(out bool changed, PartSeparator_Part[] parts, World world) { changed = false; bool[] hasMoved = new bool[parts.Length]; // defaults to false CollisionHull[] hulls = parts. Select(o => o.CreateCollisionHull(world)). ToArray(); // Move the parts for (int cntr = 0; cntr < MAXSTEPS; cntr++) // execution will break out of this loop early if parts are no longer intersecting { Intersection[] intersections = GetIntersections(parts, hulls, hasMoved, world); if (intersections.Length == 0) { break; } DoStep(intersections, parts, hasMoved); changed = true; } // Ensure hulls are synced for (int cntr = 0; cntr < parts.Length; cntr++) { if (hasMoved[cntr]) { hulls[cntr].Dispose(); hulls[cntr] = parts[cntr].CreateCollisionHull(world); } } // Exit Function return hulls; }