Ejemplo n.º 1
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;
                    }
                }
            });
        }
Ejemplo n.º 2
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;
                    }
                }
            });
        }