public CommandBinding(Command _source, Func<bool> enabled, params Command[] _destinations) { this.source = _source; this.source.AddBinding(this); this.destinations = _destinations; this.enabled = enabled; }
public CommandBinding(Command _source, Func<bool> enabled, params Action[] _destinations) { this.source = _source; this.source.AddBinding(this); this.destinations = _destinations.Select(x => new Command { Action = x }).ToArray(); this.enabled = enabled; }
public void Delete() { this.Enabled = false; this.source.RemoveBinding(this); this.source = null; this.destinations = null; this.enabled = null; }
public static void Bind(Entity result, Main main, Func<BEPUphysics.Entities.Entity, BEPUphysics.Entities.Entity, Vector3, Vector3, Vector3, ISpaceObject> createJoint, bool allowRotation, bool creating = false) { Transform mapTransform = result.GetOrCreate<Transform>("MapTransform"); Transform transform = result.GetOrCreate<Transform>("Transform"); Factory.Get<DynamicMapFactory>().InternalBind(result, main, creating, mapTransform); DynamicMap map = result.Get<DynamicMap>(); Property<Entity.Handle> parentMap = result.GetOrMakeProperty<Entity.Handle>("Parent"); Property<Map.Coordinate> coord = result.GetOrMakeProperty<Map.Coordinate>("Coord"); Property<Direction> dir = result.GetOrMakeProperty<Direction>("Direction", true); Action refreshMapTransform = delegate() { Entity parent = parentMap.Value.Target; if (parent != null) { if (!parent.Active) parent = null; else { Map staticMap = parent.Get<Map>(); coord.Value = staticMap.GetCoordinate(transform.Position); mapTransform.Position.Value = staticMap.GetAbsolutePosition(staticMap.GetRelativePosition(coord) - new Vector3(0.5f) + staticMap.Offset + map.Offset); if (!allowRotation) mapTransform.Orientation.Value = parent.Get<Transform>().Orientation; } } else mapTransform.Matrix.Value = transform.Matrix; }; if (main.EditorEnabled) result.Add(new NotifyBinding(refreshMapTransform, transform.Matrix, map.Offset)); ISpaceObject joint = null; CommandBinding jointDeleteBinding = null, physicsUpdateBinding = null; Action rebuildJoint = null; rebuildJoint = delegate() { if (joint != null) { if (joint.Space != null) main.Space.Remove(joint); result.Remove(jointDeleteBinding); if (physicsUpdateBinding != null) result.Remove(physicsUpdateBinding); physicsUpdateBinding = null; joint = null; jointDeleteBinding = null; } Entity parent = parentMap.Value.Target; if (main.EditorEnabled) { refreshMapTransform(); return; } if (parent != null) { if (!parent.Active) parent = null; else { Map staticMap = parent.Get<Map>(); map.PhysicsEntity.Position = mapTransform.Position; if (!allowRotation) map.PhysicsEntity.Orientation = mapTransform.Quaternion; if (dir != Direction.None && !main.EditorEnabled) { Vector3 relativeLineAnchor = staticMap.GetRelativePosition(coord) - new Vector3(0.5f) + staticMap.Offset + map.Offset; Vector3 lineAnchor = staticMap.GetAbsolutePosition(relativeLineAnchor); DynamicMap dynamicMap = parent.Get<DynamicMap>(); joint = createJoint(map.PhysicsEntity, dynamicMap == null ? null : dynamicMap.PhysicsEntity, map.PhysicsEntity.Position, staticMap.GetAbsoluteVector(dir.Value.GetVector()), lineAnchor); main.Space.Add(joint); map.PhysicsEntity.ActivityInformation.Activate(); if (dynamicMap != null) { physicsUpdateBinding = new CommandBinding(dynamicMap.PhysicsUpdated, rebuildJoint); result.Add(physicsUpdateBinding); } jointDeleteBinding = new CommandBinding(parent.Delete, delegate() { parentMap.Value = null; }); result.Add(jointDeleteBinding); } } } }; result.Add(new NotifyBinding(rebuildJoint, parentMap)); result.Add(new CommandBinding(result.Delete, delegate() { if (joint != null && joint.Space != null) { main.Space.Remove(joint); joint = null; } })); result.Add(new CommandBinding(map.OnSuspended, delegate() { if (joint != null && joint.Space != null) main.Space.Remove(joint); })); result.Add(new CommandBinding(map.OnResumed, delegate() { if (joint != null && joint.Space == null) main.Space.Add(joint); })); rebuildJoint(); Command rebuildJointCommand = new Command(); result.Add(new CommandBinding(rebuildJointCommand, rebuildJoint)); result.Add("RebuildJoint", rebuildJointCommand); if (main.EditorEnabled) JointFactory.attachEditorComponents(result, main); }
private static void attachEditorComponents(Entity result, Main main) { Transform transform = result.Get<Transform>(); Property<bool> selected = new Property<bool> { Value = false, Editable = false, Serialize = false }; result.Add("EditorSelected", selected); Property<Entity.Handle> parentMap = result.GetOrMakeProperty<Entity.Handle>("Parent"); Command<Entity> toggleEntityConnected = new Command<Entity> { Action = delegate(Entity entity) { parentMap.Value = entity; } }; result.Add("ToggleEntityConnected", toggleEntityConnected); LineDrawer connectionLines = new LineDrawer { Serialize = false }; connectionLines.Add(new Binding<bool>(connectionLines.Enabled, selected)); Color connectionLineColor = new Color(1.0f, 1.0f, 1.0f, 0.5f); Action recalculateLine = delegate() { connectionLines.Lines.Clear(); Entity parent = parentMap.Value.Target; if (parent != null) { connectionLines.Lines.Add(new LineDrawer.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(transform.Position, connectionLineColor), B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(parent.Get<Transform>().Position, connectionLineColor) }); } }; Model model = new Model(); model.Filename.Value = "Models\\cone"; model.Editable = false; model.Serialize = false; result.Add("DirectionModel", model); Property<Direction> dir = result.GetProperty<Direction>("Direction"); Transform mapTransform = result.Get<Transform>("MapTransform"); model.Add(new Binding<Matrix>(model.Transform, delegate() { Matrix m = Matrix.Identity; m.Translation = transform.Position; if (dir == Direction.None) m.Forward = m.Right = m.Up = Vector3.Zero; else { Vector3 normal = Vector3.TransformNormal(dir.Value.GetVector(), mapTransform.Matrix); m.Forward = -normal; if (normal.Equals(Vector3.Up)) m.Right = Vector3.Left; else if (normal.Equals(Vector3.Down)) m.Right = Vector3.Right; else m.Right = Vector3.Normalize(Vector3.Cross(normal, Vector3.Down)); m.Up = Vector3.Cross(normal, m.Left); } return m; }, transform.Matrix, mapTransform.Matrix)); NotifyBinding recalculateBinding = null; Action rebuildBinding = delegate() { if (recalculateBinding != null) { connectionLines.Remove(recalculateBinding); recalculateBinding = null; } if (parentMap.Value.Target != null) { recalculateBinding = new NotifyBinding(recalculateLine, parentMap.Value.Target.Get<Transform>().Matrix); connectionLines.Add(recalculateBinding); } recalculateLine(); }; connectionLines.Add(new NotifyBinding(rebuildBinding, parentMap)); connectionLines.Add(new NotifyBinding(recalculateLine, selected)); connectionLines.Add(new NotifyBinding(recalculateLine, () => selected, transform.Position)); result.Add(connectionLines); }
public CommandBinding(Command _source, params Action[] _destinations) : this(_source, () => true, _destinations) { }
public override void Bind(Entity result, Main main, bool creating = false) { Property<Direction> dir = result.GetOrMakeProperty<Direction>("Direction", true); Property<int> minimum = result.GetOrMakeProperty<int>("Minimum", true); Property<int> maximum = result.GetOrMakeProperty<int>("Maximum", true); Property<bool> locked = result.GetOrMakeProperty<bool>("Locked", true); Property<float> speed = result.GetOrMakeProperty<float>("Speed", true, 5); Property<float> maxForce = result.GetOrMakeProperty<float>("MaxForce", true); Property<float> damping = result.GetOrMakeProperty<float>("Damping", true); Property<float> stiffness = result.GetOrMakeProperty<float>("Stiffness", true); Property<int> goal = result.GetOrMakeProperty<int>("Goal", true); PrismaticJoint joint = null; Action setLimits = delegate() { if (joint != null) { int min = minimum, max = maximum; if (max > min) { joint.Limit.IsActive = true; joint.Limit.Minimum = minimum; joint.Limit.Maximum = maximum; } else joint.Limit.IsActive = false; } }; result.Add(new NotifyBinding(setLimits, minimum, maximum)); Action setMaxForce = delegate() { if (joint != null) { if (maxForce > 0.001f) joint.Motor.Settings.MaximumForce = maxForce * result.Get<DynamicMap>().PhysicsEntity.Mass; else joint.Motor.Settings.MaximumForce = float.MaxValue; } }; result.Add(new NotifyBinding(setMaxForce, maxForce)); Action setSpeed = delegate() { if (joint != null) joint.Motor.Settings.Servo.BaseCorrectiveSpeed = speed; }; result.Add(new NotifyBinding(setSpeed, speed)); Action setLocked = delegate() { if (joint != null) joint.Motor.IsActive = locked; }; result.Add(new NotifyBinding(setLocked, locked)); Action setGoal = delegate() { if (joint != null) joint.Motor.Settings.Servo.Goal = goal; }; result.Add(new NotifyBinding(setGoal, goal)); Action setDamping = delegate() { if (joint != null && damping != 0) joint.Motor.Settings.Servo.SpringSettings.DampingConstant = damping; }; result.Add(new NotifyBinding(setDamping, damping)); Action setStiffness = delegate() { if (joint != null && stiffness != 0) joint.Motor.Settings.Servo.SpringSettings.StiffnessConstant = stiffness; }; result.Add(new NotifyBinding(setStiffness, stiffness)); Func<BEPUphysics.Entities.Entity, BEPUphysics.Entities.Entity, Vector3, Vector3, Vector3, ISpaceObject> createJoint = delegate(BEPUphysics.Entities.Entity entity1, BEPUphysics.Entities.Entity entity2, Vector3 pos, Vector3 direction, Vector3 anchor) { joint = new PrismaticJoint(entity1, entity2, pos, -direction, anchor); joint.Motor.Settings.Mode = MotorMode.Servomechanism; setLimits(); setLocked(); setSpeed(); setMaxForce(); setGoal(); setDamping(); setStiffness(); return joint; }; JointFactory.Bind(result, main, createJoint, false, creating); result.Add("Forward", new Command { Action = delegate() { if (joint != null && locked) goal.Value = maximum; }, }); result.Add("Backward", new Command { Action = delegate() { if (joint != null && locked) goal.Value = minimum; }, }); Command hitMax = new Command(); result.Add("HitMax", hitMax); Command hitMin = new Command(); result.Add("HitMin", hitMin); bool lastLimitExceeded = false; result.Add(new Updater { delegate(float dt) { if (joint != null) { bool limitExceeded = joint.Limit.IsLimitExceeded; if (limitExceeded && !lastLimitExceeded) { if (joint.Limit.Error < 0) hitMin.Execute(); else hitMax.Execute(); } lastLimitExceeded = limitExceeded; } } }); }
public Command GetKeyUp(Keys key) { if (this.keyUpCommands.ContainsKey(key)) return this.keyUpCommands[key]; else { this.GetKey(key); Command command = new Command(); this.keyUpCommands.Add(key, command); return command; } }
public Command GetChord(Chord chord) { if (this.chords.ContainsKey(chord)) return this.chords[chord]; else { Command cmd = new Command(); this.chords.Add(chord, cmd); return cmd; } }
public override void AttachEditorComponents(Entity result, Main main) { Transform transform = result.Get<Transform>(); Zone zone = result.Get<Zone>(); Property<bool> selected = new Property<bool> { Value = false, Editable = false, Serialize = false }; result.Add("EditorSelected", selected); Command<Entity> toggleEntityConnected = new Command<Entity> { Action = delegate(Entity entity) { if (zone.ConnectedEntities.Contains(entity)) { zone.ConnectedEntities.Remove(entity); Zone z = entity.Get<Zone>(); if (z != null) z.Parent.Value = null; } else { zone.ConnectedEntities.Add(entity); Zone z = entity.Get<Zone>(); if (z != null) z.Parent.Value = result; } } }; result.Add("ToggleEntityConnected", toggleEntityConnected); LineDrawer connectionLines = new LineDrawer { Serialize = false }; connectionLines.Add(new Binding<bool>(connectionLines.Enabled, selected)); Color connectionLineColor = new Color(1.0f, 1.0f, 1.0f, 0.5f); ListBinding<LineDrawer.Line, Entity.Handle> connectionBinding = new ListBinding<LineDrawer.Line, Entity.Handle>(connectionLines.Lines, zone.ConnectedEntities, delegate(Entity.Handle entity) { if (entity.Target == null) return new LineDrawer.Line[] { }; else { return new[] { new LineDrawer.Line { A = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(transform.Position, connectionLineColor), B = new Microsoft.Xna.Framework.Graphics.VertexPositionColor(entity.Target.Get<Transform>().Position, connectionLineColor) } }; } }); result.Add(new NotifyBinding(delegate() { connectionBinding.OnChanged(null); }, selected)); result.Add(new NotifyBinding(delegate() { connectionBinding.OnChanged(null); }, () => selected, transform.Position)); connectionLines.Add(connectionBinding); result.Add(connectionLines); Model model = new Model(); model.Filename.Value = "Models\\sphere"; model.Color.Value = this.Color; model.IsInstanced.Value = false; model.Scale.Value = new Vector3(0.5f); model.Editable = false; model.Serialize = false; result.Add("EditorModel", model); model.Add(new Binding<Matrix, Vector3>(model.Transform, x => Matrix.CreateTranslation(x), transform.Position)); Property<Vector3> corner1 = new Property<Vector3> { Editable = false, Serialize = false, Value = zone.BoundingBox.Value.Min }; Property<Vector3> corner2 = new Property<Vector3> { Editable = false, Serialize = false, Value = zone.BoundingBox.Value.Max }; result.Add(new Binding<BoundingBox>(zone.BoundingBox, delegate() { Vector3 a = corner1, b = corner2; return new BoundingBox(new Vector3(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z)), new Vector3(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z))); }, corner1, corner2)); Transform cornerTransform1 = this.addCornerModel(result, selected); cornerTransform1.Add(new TwoWayBinding<Vector3, Vector3> ( corner1, x => Vector3.Transform(x, Matrix.Invert(transform.Matrix)), new[] { transform.Matrix }, cornerTransform1.Position, x => Vector3.Transform(x, transform.Matrix), new[] { transform.Matrix } )); Transform cornerTransform2 = this.addCornerModel(result, selected); cornerTransform2.Add(new TwoWayBinding<Vector3, Vector3> ( corner2, x => Vector3.Transform(x, Matrix.Invert(transform.Matrix)), new[] { transform.Matrix }, cornerTransform2.Position, x => Vector3.Transform(x, transform.Matrix), new[] { transform.Matrix } )); ModelAlpha box = new ModelAlpha(); box.Filename.Value = "Models\\alpha-box"; box.Color.Value = new Vector3(this.Color.X, this.Color.Y, this.Color.Z); box.Alpha.Value = 0.125f; box.IsInstanced.Value = false; box.Editable = false; box.Serialize = false; box.DrawOrder.Value = 11; // In front of water box.DisableCulling.Value = true; result.Add(box); box.Add(new Binding<Matrix>(box.Transform, delegate() { BoundingBox b = zone.BoundingBox; return Matrix.CreateScale(b.Max - b.Min) * Matrix.CreateTranslation((b.Min + b.Max) * 0.5f) * transform.Matrix; }, zone.BoundingBox, transform.Matrix)); box.Add(new Binding<bool>(box.Enabled, selected)); box.Add(new Binding<BoundingBox>(box.BoundingBox, zone.BoundingBox)); box.CullBoundingBox.Value = false; }
public override void Bind(Entity result, Main main, bool creating = false) { Property<Direction> dir = result.GetOrMakeProperty<Direction>("Direction", true); Property<float> minimum = result.GetOrMakeProperty<float>("Minimum", true); Property<float> maximum = result.GetOrMakeProperty<float>("Maximum", true); Property<bool> locked = result.GetOrMakeProperty<bool>("Locked", true); Property<bool> servo = result.GetOrMakeProperty<bool>("Servo", true, true); Property<float> speed = result.GetOrMakeProperty<float>("Speed", true, 5); Property<float> goal = result.GetOrMakeProperty<float>("Goal", true); RevoluteJoint joint = null; Action setLimits = delegate() { if (joint != null) { float min = minimum, max = maximum; if (max > min) { joint.Limit.IsActive = true; joint.Limit.MinimumAngle = minimum; joint.Limit.MaximumAngle = maximum; } else joint.Limit.IsActive = false; } }; result.Add(new NotifyBinding(setLimits, minimum, maximum)); Action setSpeed = delegate() { if (joint != null) { joint.Motor.Settings.Servo.BaseCorrectiveSpeed = joint.Motor.Settings.Servo.MaxCorrectiveVelocity = speed; joint.Motor.Settings.VelocityMotor.GoalVelocity = speed; } }; result.Add(new NotifyBinding(setSpeed, speed)); Action setGoal = delegate() { if (joint != null) joint.Motor.Settings.Servo.Goal = goal; }; result.Add(new NotifyBinding(setGoal, goal)); Action setLocked = delegate() { if (joint != null) joint.Motor.IsActive = locked; }; result.Add(new NotifyBinding(setLocked, locked)); DynamicMap map = result.Get<DynamicMap>(); Action setServo = delegate() { if (joint != null) joint.Motor.Settings.Mode = servo ? MotorMode.Servomechanism : MotorMode.VelocityMotor; }; result.Add(new NotifyBinding(setServo, servo)); Func<BEPUphysics.Entities.Entity, BEPUphysics.Entities.Entity, Vector3, Vector3, Vector3, ISpaceObject> createJoint = delegate(BEPUphysics.Entities.Entity entity1, BEPUphysics.Entities.Entity entity2, Vector3 pos, Vector3 direction, Vector3 anchor) { joint = new RevoluteJoint(entity1, entity2, pos, direction); float multiplier = Math.Max(1.0f, map.PhysicsEntity.Mass); joint.AngularJoint.SpringSettings.StiffnessConstant *= multiplier; joint.Limit.SpringSettings.StiffnessConstant *= multiplier; joint.Motor.Settings.Mode = MotorMode.Servomechanism; setLimits(); setLocked(); setSpeed(); setServo(); setGoal(); return joint; }; JointFactory.Bind(result, main, createJoint, true, creating); result.Add("On", new Command { Action = delegate() { if (joint != null && locked) servo.Value = false; }, }); result.Add("Off", new Command { Action = delegate() { if (joint != null && locked) { BEPUphysics.Constraints.JointBasis2D basis = joint.Motor.Basis; basis.RotationMatrix = joint.Motor.ConnectionA.OrientationMatrix; Vector3 localTestAxis = joint.Motor.LocalTestAxis; Vector3 worldTestAxis; BEPUutilities.Matrix3x3 orientationMatrix = joint.Motor.ConnectionB.OrientationMatrix; BEPUutilities.Matrix3x3.Transform(ref localTestAxis, ref orientationMatrix, out worldTestAxis); float y, x; Vector3 yAxis = Vector3.Cross(basis.PrimaryAxis, basis.XAxis); Vector3.Dot(ref worldTestAxis, ref yAxis, out y); x = Vector3.Dot(worldTestAxis, basis.XAxis); goal.Value = (float)Math.Atan2(y, x); servo.Value = true; } }, }); result.Add("Forward", new Command { Action = delegate() { if (joint != null && locked) joint.Motor.Settings.Servo.Goal = maximum; }, }); result.Add("Backward", new Command { Action = delegate() { if (joint != null && locked) joint.Motor.Settings.Servo.Goal = minimum; }, }); Command hitMax = new Command(); result.Add("HitMax", hitMax); Command hitMin = new Command(); result.Add("HitMin", hitMin); bool lastLimitExceeded = false; result.Add(new Updater { delegate(float dt) { if (joint != null) { bool limitExceeded = joint.Limit.IsLimitExceeded; if (limitExceeded && !lastLimitExceeded) { if (joint.Limit.Error.X > 0) hitMin.Execute(); else hitMax.Execute(); } lastLimitExceeded = limitExceeded; } } }); }