private void FourCollisionsButton_Click(object sender, EventArgs e) { CollisionAPI API = new CollisionAPI(); // Create some obstacles, at 4 corners of a square List <CollisionShape> shapes = new List <CollisionShape>(); CollisionSphere sphere = new CollisionSphere(new Vector3(0f, 0f, 2f), 1f); shapes.Add(sphere); API.AddCollisionShape(sphere, 1); CollisionCapsule capsule = new CollisionCapsule(new Vector3(10f, 0f, 0f), new Vector3(10f, 0f, 4f), 1f); shapes.Add(capsule); API.AddCollisionShape(capsule, 2); // Now, an AABB CollisionAABB aabb = new CollisionAABB(new Vector3(9.5f, 9.5f, 0f), new Vector3(10.5f, 10.5f, 4f)); shapes.Add(aabb); API.AddCollisionShape(aabb, 3); CollisionOBB obb = new CollisionOBB(new Vector3(0f, 10f, 2), new Vector3[3] { new Vector3(1f, 0f, 0f), new Vector3(0f, 1f, 0f), new Vector3(0f, 0f, 1f) }, new Vector3(1f, 1f, 1f)); shapes.Add(obb); API.AddCollisionShape(obb, 4); FileStream f = new FileStream("C:\\Junk\\DumpSphereTree.txt", FileMode.Create, FileAccess.Write); StreamWriter writer = new StreamWriter(f); API.DumpSphereTree(writer); API.SphereTreeRoot.VerifySphereTree(); // Now a moving object capsule in the center of the square CollisionCapsule moCap = new CollisionCapsule(new Vector3(5f, 5f, 0f), new Vector3(5f, 5f, 4f), 1f); // Remember where the moving object started Vector3 start = moCap.center; // Move the moving object toward each of the obstacles foreach (CollisionShape s in shapes) { moCap.AddDisplacement(start - moCap.center); MoveToObject(writer, API, s, moCap); } writer.Close(); }
public void ReadCapsule(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData) { Quaternion rot = MathHelpers.GetRotation(transform); Matrix4 tmpTransform = rot.Inverse().ToRotationMatrix() * transform; Vector3 scaleDelta = tmpTransform.Scale - Vector3.UnitScale; if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon) { log.Error("Scale is not currently supported for capsule shapes"); } float height = 0; float[] radius = new float[2]; Vector3 halfExtents = Vector3.Zero; foreach (XmlNode childNode in node.ChildNodes) { switch (childNode.Name) { case "height": height = float.Parse(childNode.InnerText); break; case "radius": { string[] values = childNode.InnerText.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(values.Length == 2); for (int i = 0; i < 2; ++i) { radius[i] = float.Parse(values[i]); } } break; default: DebugMessage(childNode); break; } } // We only support capsules where the two radii match if (radius[0] != radius[1]) { log.Error("Different radii for capsules are not currently supported"); } Vector3 center = unitConversion * transform.Translation; Vector3 halfExtent = unitConversion * (.5f * height * (rot * Vector3.UnitY)); radius[0] *= unitConversion; radius[1] *= unitConversion; CollisionShape collisionShape; collisionShape = new CollisionCapsule(center - halfExtent, center + halfExtent, radius[0]); physicsData.AddCollisionShape(objectId, collisionShape); }
private static void TraceMOBottom(MovingObject mo, string description) { if (MO.DoLog) { CollisionShape obstacle = mo.parts[0].shape; CollisionCapsule moCapsule = null; if (obstacle is CollisionCapsule) { moCapsule = (CollisionCapsule)obstacle; } string rest = (moCapsule != null ? string.Format("mo bottom is {0}", moCapsule.bottomcenter - new Vector3(0f, moCapsule.capRadius, 0f)) : string.Format("obstacle {0}", obstacle)); MO.Log("{0}, {1}", description, rest); } }
private static bool NowColliding(MovingObject mo, string description) { CollisionParms parms = new CollisionParms(); bool colliding = collisionManager.CollideAfterAddingDisplacement(mo, Vector3.Zero, parms); CollisionShape obstacle = mo.parts[0].shape; CollisionCapsule moCapsule = null; if (obstacle is CollisionCapsule) { moCapsule = (CollisionCapsule)obstacle; } string rest = (moCapsule != null ? string.Format("mo bottom is {0}", moCapsule.bottomcenter - new Vector3(0f, moCapsule.capRadius, 0f)) : string.Format("obstacle {0}", obstacle)); if (MO.DoLog) { MO.Log("{0}, now colliding = {1}; {2}", description, colliding, rest); } log.DebugFormat("{0}, now colliding = {1}; {2}", description, colliding, rest); return(colliding); }
public XmlNode WriteShape(CollisionShape shape, XmlDocument document) { XmlNode node = document.CreateElement("shape"); if (shape is CollisionAABB) { CollisionAABB aabbShape = shape as CollisionAABB; // convert to meters (or other scaled unit) before writing out Vector3 center = shape.center / unitConversion; Vector3 halfExtent = (aabbShape.max - aabbShape.center) / unitConversion; XmlNode translate = WriteTranslate(center, document); node.AppendChild(translate); XmlNode boxNode = WriteBox(halfExtent, document); node.AppendChild(boxNode); } else if (shape is CollisionOBB) { CollisionOBB obbShape = shape as CollisionOBB; // convert to meters (or other scaled unit) before writing out Vector3 center = shape.center / unitConversion; Vector3 halfExtent = obbShape.extents / unitConversion; Quaternion rot = Quaternion.Identity; rot.FromAxes(obbShape.axes[0], obbShape.axes[1], obbShape.axes[2]); XmlNode rotate = WriteRotate(rot, document); node.AppendChild(rotate); XmlNode translate = WriteTranslate(center, document); node.AppendChild(translate); XmlNode boxNode = WriteBox(halfExtent, document); node.AppendChild(boxNode); } else if (shape is CollisionCapsule) { CollisionCapsule capsuleShape = shape as CollisionCapsule; // convert to meters (or other scaled unit) before writing out Vector3 center = shape.center / unitConversion; float height = capsuleShape.height / unitConversion; float radius = capsuleShape.capRadius / unitConversion; Vector3 halfExtent = capsuleShape.topcenter - capsuleShape.center; Quaternion rot = Vector3.UnitY.GetRotationTo(halfExtent); XmlNode rotate = WriteRotate(rot, document); node.AppendChild(rotate); XmlNode translate = WriteTranslate(center, document); node.AppendChild(translate); XmlNode capsuleNode = WriteCapsule(height, radius, document); node.AppendChild(capsuleNode); } else if (shape is CollisionSphere) { // convert to meters (or other scaled unit) before writing out Vector3 center = shape.center / unitConversion; float radius = shape.radius / unitConversion; XmlNode translate = WriteTranslate(center, document); node.AppendChild(translate); XmlNode sphereNode = WriteSphere(radius, document); node.AppendChild(sphereNode); } else { log.ErrorFormat("Unsupported collision shape: {0}", shape.GetType()); } return(node); }