public override CollisionShape Clone() { CollisionSphere rv = new CollisionSphere(center, radius); rv.handle = this.handle; rv.timeStamp = this.timeStamp; return(rv); }
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(); }
// This method is the callback by which the forests controlled // by the scene manager tell us about SpeedTrees. private void AddTreeObstacles(SpeedTreeWrapper tree) { // If this tree didn't use to be in range but now is V3 vp = tree.TreePosition; Vector3 p = new Vector3(vp.x, vp.y, vp.z); // Find the tile in question int tileX, tileZ; WorldToTileCoords(p, out tileX, out tileZ); bool oir = InRange(tileXCenter, tileZCenter, tileX, tileZ); bool nir = InRange(newTileXCenter, newTileZCenter, tileX, tileZ); // if (MO.DoLog) // MO.Log(String.Format("For tree at {0}, testing !InRange({1},{2},{3},{4}) = {5} && InRange({6},{7},{8},{9}) = {10}", // MO.MeterString(p),tileXCenter, tileZCenter, tileX, tileZ, MO.Bool(!oir), // newTileXCenter, newTileZCenter, tileX, tileZ, MO.Bool(nir))); if (!oir && nir) { int tX = TileToArrayIndex(tileX, newTileXCenter); int tZ = TileToArrayIndex(tileZ, newTileZCenter); uint count = tree.CollisionObjectCount; long handle = ComposeHandle(tileX, tileZ); CollisionShape shape = null; if (MO.DoLog) { MO.Log(string.Format("Adding tree at {0}, tiles[{1},{2}] = {3}, tile coords[{4},{5}], obj. new count {6}", MO.MeterString(p), tX, tZ, tiles[tX,tZ], tileX, tileZ, count)); MO.Log(string.Format("Handle {0}, oldcenter {1}, newcenter {2}", MO.HandleString(handle), MO.MeterString(tileWorldCenter), MO.MeterString(newTileWorldCenter))); } float size = 0f; float variance = 0f; tree.GetTreeSize(ref size, ref variance); float scaleFactor = size / tree.OriginalSize; for (uint i=0; i<count; i++) { TreeCollisionObject tco = tree.CollisionObject(i); Vector3 cp = new Vector3(tco.position.x, tco.position.y, tco.position.z) * scaleFactor + p; Vector3 cd = new Vector3(tco.dimensions.x, tco.dimensions.y, tco.dimensions.z) * scaleFactor; switch ((CollisionObjectType)tco.type) { case CollisionObjectType.ColSphere: shape = new CollisionSphere(cp, cd.x); break; case CollisionObjectType.ColCylinder: // We treat it as a capsule, but we raise the // capsule up by the capRadius, and shorten // the segment by the double the capRadius Vector3 top = cp; top.y += cd.y - cd.x * 2f; cp.y += cd.x; shape = new CollisionCapsule(cp, top, cd.x); break; case CollisionObjectType.ColBox: Vector3 tp = cp; tp.x -= cd.x * .5f; tp.y -= cd.y * .5f; shape = new CollisionAABB(tp, tp + cd); break; } collisionAPI.AddCollisionShape(shape, handle); tiles[tX, tZ]++; objectsAdded++; if (MO.DoLog) { MO.Log(string.Format(" tiles[{0},{1}] = {2}, tile at [{3},{4}] after adding shape {5}", tX, tZ, tiles[tX, tZ], tileX, tileZ, shape.ToString())); } } } }
// Returns true if sphere s intersects OBB b, false otherwise. // The point p on the OBB closest to the sphere center is also returned public static bool TestSphereOBB(CollisionSphere s, CollisionOBB b, out Vector3 p) { return (SqDistPointOBB(s.center, b, out p) < s.radius * s.radius); }
private static void TestPhysics( string srcDir, string dstDir, string name ) { float OneMeter = 1000; PhysicsData pd = new PhysicsData(); Vector3 center = new Vector3( 10 * OneMeter, 1 * OneMeter, 1 * OneMeter ); Vector3[] obbAxes = new Vector3[ 3 ]; obbAxes[ 0 ] = new Vector3( 1, 0, -1 ); obbAxes[ 0 ].Normalize(); obbAxes[ 1 ] = Vector3.UnitY; obbAxes[ 2 ] = new Vector3( 1, 0, 1 ); obbAxes[ 2 ].Normalize(); Vector3 obbExtents = new Vector3( 2.5f * OneMeter, 1 * OneMeter, 1 * OneMeter ); CollisionOBB obb = new CollisionOBB( center, obbAxes, obbExtents ); pd.AddCollisionShape( "submesh01", obb ); CollisionAABB aabb = new CollisionAABB( center - obbExtents, center + obbExtents ); pd.AddCollisionShape( "submesh01", aabb ); CollisionSphere sphere = new CollisionSphere( center, 2 * OneMeter ); pd.AddCollisionShape( "submesh01", sphere ); Vector3 capExtents = new Vector3( -1 * OneMeter, 0, 0 ); CollisionCapsule capsule = new CollisionCapsule( center + capExtents, center - capExtents, .5f * OneMeter ); pd.AddCollisionShape( "submesh01", capsule ); PhysicsSerializer ps = new PhysicsSerializer(); ps.ExportPhysics( pd, name ); pd = new PhysicsData(); ps.ImportPhysics( pd, name ); foreach( string objectId in pd.GetCollisionObjects() ) { log.InfoFormat( "Collision shapes for: {0}", objectId ); List<CollisionShape> collisionShapes = pd.GetCollisionShapes( objectId ); foreach( CollisionShape shape in collisionShapes ) log.InfoFormat( "Shape: {0}", shape ); } }
// This method is the callback by which the forests controlled // by the scene manager tell us about SpeedTrees. private void AddTreeObstacles(SpeedTreeWrapper tree) { // If this tree didn't use to be in range but now is V3 vp = tree.TreePosition; Vector3 p = new Vector3(vp.x, vp.y, vp.z); // Find the tile in question int tileX, tileZ; WorldToTileCoords(p, out tileX, out tileZ); bool oir = InRange(tileXCenter, tileZCenter, tileX, tileZ); bool nir = InRange(newTileXCenter, newTileZCenter, tileX, tileZ); // if (MO.DoLog) // MO.Log(String.Format("For tree at {0}, testing !InRange({1},{2},{3},{4}) = {5} && InRange({6},{7},{8},{9}) = {10}", // MO.MeterString(p),tileXCenter, tileZCenter, tileX, tileZ, MO.Bool(!oir), // newTileXCenter, newTileZCenter, tileX, tileZ, MO.Bool(nir))); if (!oir && nir) { int tX = TileToArrayIndex(tileX, newTileXCenter); int tZ = TileToArrayIndex(tileZ, newTileZCenter); uint count = tree.CollisionObjectCount; long handle = ComposeHandle(tileX, tileZ); CollisionShape shape = null; if (MO.DoLog) { MO.Log(string.Format("Adding tree at {0}, tiles[{1},{2}] = {3}, tile coords[{4},{5}], obj. new count {6}", MO.MeterString(p), tX, tZ, tiles[tX, tZ], tileX, tileZ, count)); MO.Log(string.Format("Handle {0}, oldcenter {1}, newcenter {2}", MO.HandleString(handle), MO.MeterString(tileWorldCenter), MO.MeterString(newTileWorldCenter))); } float size = 0f; float variance = 0f; tree.GetTreeSize(ref size, ref variance); float scaleFactor = size / tree.OriginalSize; for (uint i = 0; i < count; i++) { TreeCollisionObject tco = tree.CollisionObject(i); Vector3 cp = new Vector3(tco.position.x, tco.position.y, tco.position.z) * scaleFactor + p; Vector3 cd = new Vector3(tco.dimensions.x, tco.dimensions.y, tco.dimensions.z) * scaleFactor; switch ((CollisionObjectType)tco.type) { case CollisionObjectType.ColSphere: shape = new CollisionSphere(cp, cd.x); break; case CollisionObjectType.ColCylinder: // We treat it as a capsule, but we raise the // capsule up by the capRadius, and shorten // the segment by the double the capRadius Vector3 top = cp; top.y += cd.y - cd.x * 2f; cp.y += cd.x; shape = new CollisionCapsule(cp, top, cd.x); break; case CollisionObjectType.ColBox: Vector3 tp = cp; tp.x -= cd.x * .5f; tp.y -= cd.y * .5f; shape = new CollisionAABB(tp, tp + cd); break; } collisionAPI.AddCollisionShape(shape, handle); tiles[tX, tZ]++; objectsAdded++; if (MO.DoLog) { MO.Log(string.Format(" tiles[{0},{1}] = {2}, tile at [{3},{4}] after adding shape {5}", tX, tZ, tiles[tX, tZ], tileX, tileZ, shape.ToString())); } } } }
public override CollisionShape Clone() { CollisionSphere rv = new CollisionSphere(center, radius); rv.handle = this.handle; rv.timeStamp = this.timeStamp; return rv; }
public void ReadSphere(string objectId, Matrix4 transform, XmlNode node, PhysicsData physicsData) { Vector3 scaleDelta = transform.Scale - Vector3.UnitScale; if (scaleDelta.Length > PhysicsSerializer.ScaleEpsilon) log.Error("Scale is not currently supported for sphere shapes"); float radius = 0; foreach (XmlNode childNode in node.ChildNodes) { switch (childNode.Name) { case "radius": radius = float.Parse(childNode.InnerText); break; default: DebugMessage(childNode); break; } } Vector3 center = unitConversion * transform.Translation; radius *= unitConversion; CollisionShape collisionShape = new CollisionSphere(center, radius); physicsData.AddCollisionShape(objectId, collisionShape); }