/// <summary> /// Returns the Fixture that FixturePortal is attached to, or null if none exists. /// </summary> public static Fixture GetFixtureAttached(FixturePortal portal) { if (portal == null || portal.Parent == null) { return null; } Actor parent = portal.Parent as Actor; if (parent != null) { return GetFixtureEdgeCoord(parent, portal.Position).Fixture; } return null; }
/// <summary> /// Attach a portal to the nearest valid wall edge along a ray. /// </summary> /// <param name="portal">Portal that will potentially be attached to a wall edge.</param> /// <param name="ray">Portal ray cast. ray[0] is the begin point and ray[1] is the end point.</param> /// <returns>True if a valid edge was found, otherwise false.</returns> public static bool PortalPlace(FixturePortal portal, LineF ray) { WallCoord intersection = RayCast(portal.Scene, ray); if (intersection != null) { intersection = AdjustCoord(intersection, portal.Size); if (intersection != null) { portal.SetPosition(intersection.Wall, new PolygonCoord(intersection.EdgeIndex, intersection.EdgeT)); return true; } } return false; }
public Scene CreateSceneWithPortal(out Actor ground) { Scene scene = new Scene(); ground = CreateGround(scene); scene.World.ProcessChanges(); Fixture fixture = ground.Body.FixtureList[0]; FixturePortal portal = new FixturePortal(scene, ground, new PolygonCoord(0, 0.3f)); FloatPortal portalExit = new FloatPortal(scene); portalExit.Linked = portal; portal.Linked = portal; PortalCommon.UpdateWorldTransform(scene); FixtureExt.GetData(fixture).ProcessChanges(); return scene; }
public void StepTest9() { Scene scene = new Scene(); Actor actor = new Actor(scene, PolygonFactory.CreateRectangle(4, 1)); actor.SetVelocity(Transform2.CreateVelocity(new Vector2(0.1f, 0))); FloatPortal enter = new FloatPortal(scene); enter.SetTransform(new Transform2(new Vector2(2, 0))); FixturePortal exit = new FixturePortal(scene, actor, new PolygonCoord(0, 0.5f)); PortalCommon.UpdateWorldTransform(scene); SimulationStep.Step(scene.GetAll().OfType<IPortalCommon>(), scene.GetAll().OfType<IPortal>(), 1, null); Assert.IsTrue(PortalCommon.GetWorldTransform(exit) == exit.WorldTransform); }
public void StepTest8() { Scene scene = new Scene(); Actor actor = new Actor(scene, PolygonFactory.CreateRectangle(2, 2)); actor.SetTransform(new Transform2(new Vector2(1, 1))); Transform2 velocity = Transform2.CreateVelocity(new Vector2(0, 3)); actor.SetVelocity(velocity); FixturePortal fixture = new FixturePortal(scene, actor, new PolygonCoord(0, 0.5f)); /*FloatPortal enter = new FloatPortal(scene); enter.SetTransform(new Transform2(new Vector2(1, 2), 1, (float)Math.PI / 2)); //enter.SetVelocity(Transform2.CreateVelocity(new Vector2(1, 0))); FloatPortal exit = new FloatPortal(scene); exit.SetTransform(new Transform2(new Vector2(10, 10))); exit.SetVelocity(Transform2.CreateVelocity(new Vector2(10, 0))); enter.Linked = exit; exit.Linked = enter;*/ PortalCommon.UpdateWorldTransform(scene); Transform2 transformPrevious = fixture.WorldTransform.ShallowClone(); Transform2 actorPrevious = actor.WorldTransform.ShallowClone(); SimulationStep.Step(scene.GetAll().OfType<IPortalCommon>(), scene.GetAll().OfType<IPortal>(), 1, null); Transform2 expected = transformPrevious.Add(velocity); Assert.IsTrue(expected.AlmostEqual(fixture.WorldTransform)); }
public void StepTest5() { Scene scene = new Scene(); Actor p = new Actor(scene, PolygonFactory.CreateRectangle(2, 2)); Transform2 start = new Transform2(new Vector2(0, 0)); Transform2 velocity = Transform2.CreateVelocity(new Vector2(3, 0)); p.SetTransform(start); p.SetVelocity(velocity); FloatPortal enter = new FloatPortal(scene); enter.SetTransform(new Transform2(new Vector2(1, 0))); enter.SetVelocity(Transform2.CreateVelocity(new Vector2(1, 0))); FloatPortal exit = new FloatPortal(scene); exit.SetTransform(new Transform2(new Vector2(10, 10))); exit.SetVelocity(Transform2.CreateVelocity(new Vector2(10, 0))); enter.Linked = exit; exit.Linked = enter; FixturePortal child = new FixturePortal(scene, p, new PolygonCoord(0, 0.5f)); PortalCommon.UpdateWorldTransform(new IPortalCommon[] { p, enter, exit, child }); SimulationStep.Step(scene.GetAll().OfType<IPortalCommon>(), scene.GetAll().OfType<IPortal>(), 1, null); Assert.IsTrue(p.GetTransform().Position == new Vector2(19, 10)); Assert.IsTrue(p.GetVelocity().Position == new Vector2(8, 0)); }
/// <summary> /// Creates a Scene from an EditorScene. Scene is intended for gameplay use. /// </summary> public static Scene Export(EditorScene level, Controller controller) { Scene scene = new Scene(); /*if (level.GetAll().OfType<EditorPlayer>().Count() > 0) { Camera2 camera = new Camera2(scene); camera.SetTransform(new Transform2(new Vector2(), 10, 0)); scene.SetActiveCamera(camera); if (level.ActiveCamera != null) { camera.Aspect = level.ActiveCamera.Aspect; } } else*/ { if (level.ActiveCamera != null) { ControllerCamera camera = level.ActiveCamera.ShallowClone(); camera.Scene = scene; scene.SetActiveCamera(camera); } } #region create background Model background = Game.ModelFactory.CreatePlane(); background.Texture = level.Renderer.GetTexture("grid.png"); background.SetColor(new Vector3(1, 1, 0.5f)); background.Transform.Position = new Vector3(0, 0, -5f); float size = 50; background.Transform.Scale = new Vector3(size, size, size); background.TransformUv.Size = size; Entity back = new Entity(scene, new Vector2(0f, 0f)); back.Name = "Background"; back.AddModel(background); back.IsPortalable = false; #endregion Dictionary<EditorObject, SceneNode> dictionary = new Dictionary<EditorObject, SceneNode>(); AnimationDriver animation = new AnimationDriver(); scene.SceneObjectList.Add(animation); List<EditorObject> editorObjects = level.GetAll().OfType<EditorObject>().ToList(); foreach (EditorObject e in editorObjects) { if (e is EditorPortal) { EditorPortal cast = (EditorPortal)e; Entity entity = new Entity(scene); entity.IsPortalable = false; entity.AddModel(ModelFactory.CreatePortal()); entity.ModelList[0].Transform.Position += new Vector3(0, 0, -2); if (cast.OnEdge) { FixturePortal portal = new FixturePortal(scene); portal.Name = cast.Name; dictionary.Add(cast, portal); entity.SetParent(portal); } else { FloatPortal portal = new FloatPortal(scene); portal.Name = cast.Name; portal.SetTransform(cast.GetTransform()); dictionary.Add(cast, portal); entity.SetParent(portal); if (cast.AnimatedTransform != null) { animation.Add(portal, cast.AnimatedTransform); portal.SetTransform(cast.AnimatedTransform.GetTransform(0)); } else { portal.SetTransform(cast.GetTransform()); } } } else if (e is EditorEntity) { EditorEntity cast = (EditorEntity)e; Entity clone = new Entity(scene); clone.Name = cast.Name; clone.AddModelRange(cast.Models); dictionary.Add(cast, clone); if (cast.AnimatedTransform != null) { animation.Add(clone, cast.AnimatedTransform); clone.SetTransform(cast.AnimatedTransform.GetTransform(0)); } else { clone.SetTransform(cast.GetTransform()); } } else if (e is IWall) { EditorObject cast = e; Transform2 t = cast.GetTransform(); Actor actor = new Actor(scene, ((IWall)e).Vertices, t); actor.Name = cast.Name; Transform2 tEntity = new Transform2(); Entity entity = new Entity(scene, tEntity); entity.Name = cast.Name; entity.SetParent(actor); if (e is EditorWall) { EditorWall castWall = (EditorWall)e; actor.SetBodyType(BodyType.Static); //actor.Vertices = castWall.Vertices; entity.AddModel(Game.ModelFactory.CreatePolygon(castWall.Vertices)); //entity.AddModel(Game.ModelFactory.CreateActorDebug(actor)); dictionary.Add(castWall, actor); } else if (e is EditorActor) { //actor.SetVelocity(new Transform2(new Vector2(0.2f, 0))); EditorActor castActor = (EditorActor)e; //actor.Vertices = castActor.Vertices; entity.AddModel(castActor.GetActorModel(castActor)); //entity.AddModel(Game.ModelFactory.CreateActorDebug(actor)); dictionary.Add(castActor, actor); } else { Debug.Assert(false); } if (cast.AnimatedTransform != null) { animation.Add(actor, cast.AnimatedTransform); actor.SetTransform(cast.AnimatedTransform.GetTransform(0)); actor.SetBodyType(BodyType.Kinematic); } else { actor.SetTransform(cast.GetTransform()); } } else if (e is EditorPlayer) { EditorPlayer cast = (EditorPlayer)e; Player player = new Player(controller); Vector2[] polygon = PolygonFactory.CreateNGon(6, 0.5f, new Vector2()); Actor actor = new Actor(scene, polygon); player.SetActor(actor); actor.SetTransform(new Transform2(cast.GetWorldTransform().Position)); //player.Camera = (Camera2)scene.ActiveCamera; Entity entity = new Entity(scene, new Transform2()); entity.Name = cast.Name; entity.SetParent(actor); entity.AddModel(Game.ModelFactory.CreatePolygon(polygon)); scene.SceneObjectList.Add(player); dictionary.Add(cast, player.Actor); } else { Debug.Assert(false); } } foreach (EditorObject e in editorObjects) { SceneNode parent = e.Parent == null ? null : dictionary[e.Parent]; SceneNode clone = dictionary[e]; clone.SetParent(parent); if (clone is IPortal) { if (clone is FixturePortal) { FixturePortal cast = (FixturePortal)clone; cast.SetPosition((IWall)parent, ((EditorPortal)e).PolygonTransform, e.GetTransform().Size, e.GetTransform().MirrorX); Debug.Assert(((IWall)parent).Vertices.Count > 0); IPortal portalEditor = (IPortal)e; if (portalEditor.Linked != null) { cast.Linked = (IPortal)dictionary[(EditorPortal)portalEditor.Linked]; } } else if (clone is FloatPortal) { FloatPortal cast = (FloatPortal)clone; IPortal portalEditor = (IPortal)e; if (portalEditor.Linked != null) { cast.Linked = (IPortal)dictionary[(EditorPortal)portalEditor.Linked]; } } } } PortalCommon.UpdateWorldTransform(scene); return scene; }
public bool PartOfPortal(FixturePortal portal) { return PortalParents[0] == portal || PortalParents[1] == portal; }
private PolygonShape CreatePortalShape(FixturePortal portal, bool previousVertex) { Vector2[] verts = new Vector2[3]; PolygonShape shape = (PolygonShape)FixtureExt.GetFixtureAttached(portal).Shape; int i = 1; if (previousVertex) { i = 0; } int iNext = (i + 1) % 2; Transform2 t = portal.GetTransform(); t.MirrorX = false; t.Size = Math.Abs(t.Size); int index = (portal.Position.EdgeIndex + i) % Actor.Vertices.Count; verts[0] = Vector2Ext.Transform(Portal.GetVerts(portal)[iNext], t.GetMatrix()); verts[1] = Actor.GetFixtureContour(Actor)[index]; verts[2] = Vector2Ext.Transform(Portal.GetVerts(portal)[iNext] + new Vector2(-FixturePortal.EdgeMargin, 0), t.GetMatrix()); verts = MathExt.SetWinding(verts, false); return new PolygonShape(new FarseerPhysics.Common.Vertices(verts.Select(v => (Xna.Framework.Vector2)v)), 0); }
private PolygonShape CreatePortalShape(FixturePortal portal, FixturePortal portalNext) { Debug.Assert(portal.Position.EdgeIndex == portalNext.Position.EdgeIndex); Debug.Assert(portal.Position.EdgeT < portalNext.Position.EdgeT); Vector2[] verts = new Vector2[4]; { Transform2 t0 = portal.GetTransform(); t0.MirrorX = false; t0.Size = Math.Abs(t0.Size); verts[0] = Vector2Ext.Transform(Portal.GetVerts(portal)[0], t0.GetMatrix()); verts[1] = Vector2Ext.Transform(Portal.GetVerts(portal)[0] + new Vector2(-FixturePortal.EdgeMargin, 0), t0.GetMatrix()); } { Transform2 t1 = portalNext.GetTransform(); t1.MirrorX = false; t1.Size = Math.Abs(t1.Size); verts[2] = Vector2Ext.Transform(Portal.GetVerts(portalNext)[1] + new Vector2(-FixturePortal.EdgeMargin, 0), t1.GetMatrix()); verts[3] = Vector2Ext.Transform(Portal.GetVerts(portalNext)[1], t1.GetMatrix()); } verts = MathExt.SetWinding(verts, false); return new PolygonShape(new FarseerPhysics.Common.Vertices(verts.Select(v => (Xna.Framework.Vector2)v)), 0); }
public void ProcessChangesTest7() { Scene scene = new Scene(); Actor ground = new Actor(scene, PolygonFactory.CreateRectangle(4, 4)); FixturePortal portal0 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.3f)); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.7f)); portal0.Linked = portal0; portal1.Linked = portal1; portal0.MirrorX = true; portal1.MirrorX = true; portal0.Size = -1; PortalCommon.UpdateWorldTransform(scene); ProcessChangesAssert(ground); }
public void ProcessChangesTest0() { Scene scene = new Scene(); Actor ground = new Actor(scene, PolygonFactory.CreateRectangle(4, 4)); FixturePortal portal0 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.3f)); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.7f)); /*portal0.Linked = portal0; portal1.Linked = portal1;*/ Portal.SetLinked(portal0, portal1); PortalCommon.UpdateWorldTransform(scene); ProcessChangesAssert(ground); }
public void PortalParentTest6() { Scene scene = new Scene(); Actor ground = CreateGround(scene); FixturePortal portal0 = new FixturePortal(scene, ground, new PolygonCoord(1, 0.5f)); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.6f)); portal0.Linked = portal0; portal1.Linked = portal1; FixtureData userData = FixtureExt.GetData(ground.Body.FixtureList[0]); PortalCommon.UpdateWorldTransform(scene); userData.ProcessChanges(); Assert.IsFalse(userData.PartOfPortal(portal0)); Assert.IsFalse(userData.PartOfPortal(portal1)); Assert.IsTrue(ground.Body.FixtureList.Count == 5); for (int i = 1; i < ground.Body.FixtureList.Count; i++) { FixtureData childUserData = FixtureExt.GetData(ground.Body.FixtureList[i]); if (i < 3) { Assert.IsFalse(childUserData.PartOfPortal(portal0)); Assert.IsTrue(childUserData.PartOfPortal(portal1)); } else { Assert.IsTrue(childUserData.PartOfPortal(portal0)); Assert.IsFalse(childUserData.PartOfPortal(portal1)); } } }
public void PortalParentTest5() { Actor ground = null; Scene scene = CreateSceneWithPortal(out ground); FixturePortal portal0 = scene.GetPortalList().OfType<FixturePortal>().First(); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.6f)); FloatPortal portal2 = new FloatPortal(scene); //Make sure portal2 isn't sitting on top of the float portal linked to portal0. portal2.SetTransform(new Transform2(new Vector2(5, 0))); portal1.Linked = portal2; portal2.Linked = portal1; FixtureData userData = FixtureExt.GetData(ground.Body.FixtureList[0]); PortalCommon.UpdateWorldTransform(scene); userData.ProcessChanges(); FixtureData userData0 = FixtureExt.GetData(ground.Body.FixtureList[0]); Assert.IsFalse(userData0.PartOfPortal(portal0)); Assert.IsFalse(userData0.PartOfPortal(portal1)); FixtureData userData1 = FixtureExt.GetData(ground.Body.FixtureList[1]); Assert.IsTrue(userData1.PartOfPortal(portal0)); Assert.IsFalse(userData1.PartOfPortal(portal1)); FixtureData userData2 = FixtureExt.GetData(ground.Body.FixtureList[2]); Assert.IsTrue(userData2.PartOfPortal(portal0)); Assert.IsTrue(userData2.PartOfPortal(portal1)); FixtureData userData3 = FixtureExt.GetData(ground.Body.FixtureList[3]); Assert.IsFalse(userData3.PartOfPortal(portal0)); Assert.IsTrue(userData3.PartOfPortal(portal1)); }
public void PortalParentTest4() { Actor ground = null; Scene scene = CreateSceneWithPortal(out ground); FixturePortal portal0 = scene.GetPortalList().OfType<FixturePortal>().First(); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.6f)); FloatPortal portal2 = new FloatPortal(scene); //Make sure portal2 isn't sitting on top of the float portal linked to portal0. portal2.SetTransform(new Transform2(new Vector2(5, 0))); portal1.Linked = portal2; portal2.Linked = portal1; FixtureData userData = FixtureExt.GetData(ground.Body.FixtureList[0]); PortalCommon.UpdateWorldTransform(scene); userData.ProcessChanges(); PolygonShape shape; shape = (PolygonShape)ground.Body.FixtureList[0].Shape; Assert.IsTrue(shape.Vertices.Count == 5); shape = (PolygonShape)ground.Body.FixtureList[1].Shape; Assert.IsTrue(shape.Vertices.Count == 3); shape = (PolygonShape)ground.Body.FixtureList[2].Shape; Assert.IsTrue(shape.Vertices.Count == 4); shape = (PolygonShape)ground.Body.FixtureList[3].Shape; Assert.IsTrue(shape.Vertices.Count == 3); }
public void PortalParentTest3() { Actor ground = null; Scene scene = CreateSceneWithPortal(out ground); FixturePortal portal0 = scene.GetPortalList().OfType<FixturePortal>().First(); FixturePortal portal1 = new FixturePortal(scene, ground, new PolygonCoord(0, 0.6f)); FloatPortal portal2 = new FloatPortal(scene); //Make sure this portal isn't sitting on top of the float portal linked to portal0. portal2.SetTransform(new Transform2(new Vector2(5, 0))); portal1.Linked = portal2; portal2.Linked = portal1; FixtureData userData = FixtureExt.GetData(ground.Body.FixtureList[0]); PortalCommon.UpdateWorldTransform(scene); userData.ProcessChanges(); int parentCount = 0; foreach (Fixture f in ground.Body.FixtureList) { userData = FixtureExt.GetData(f); if (userData.IsPortalParentless() == false) { parentCount++; } } Assert.IsTrue(parentCount == 3); }