Beispiel #1
0
 public CommandBinding(Command _source, Func<bool> enabled, params Command[] _destinations)
 {
     this.source = _source;
     this.source.AddBinding(this);
     this.destinations = _destinations;
     this.enabled = enabled;
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 public void Delete()
 {
     this.Enabled = false;
     this.source.RemoveBinding(this);
     this.source = null;
     this.destinations = null;
     this.enabled = null;
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 public CommandBinding(Command _source, params Action[] _destinations)
     : this(_source, () => true, _destinations)
 {
 }
Beispiel #7
0
        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;
                    }
                }
            });
        }
Beispiel #8
0
 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;
     }
 }
Beispiel #9
0
 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;
     }
 }
Beispiel #10
0
        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;
        }
Beispiel #11
0
        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;
                    }
                }
            });
        }