public TreadSegment(Vector3 segmentPosition, Entity body, TreadSegmentDescription treadSegmentDescription) { Entity = new Cylinder(segmentPosition, treadSegmentDescription.Width, treadSegmentDescription.Radius, treadSegmentDescription.Mass); Entity.Material.KineticFriction = treadSegmentDescription.Friction; Entity.Material.StaticFriction = treadSegmentDescription.Friction; Entity.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); //Preventing the occasional pointless collision pair can speed things up. CollisionRules.AddRule(Entity, body, CollisionRule.NoBroadPhase); //Connect the wheel to the body. SuspensionAxisJoint = new PointOnLineJoint(body, Entity, Entity.Position, Vector3.Down, Entity.Position); SuspensionLengthLimit = new LinearAxisLimit(body, Entity, Entity.Position, Entity.Position, Vector3.Down, -treadSegmentDescription.SuspensionLength, 0); //This linear axis motor will give the suspension its springiness by pushing the wheels outward. SuspensionSpring = new LinearAxisMotor(body, Entity, Entity.Position, Entity.Position, Vector3.Down); SuspensionSpring.Settings.Mode = MotorMode.Servomechanism; SuspensionSpring.Settings.Servo.Goal = 0; SuspensionSpring.Settings.Servo.SpringSettings.Stiffness = treadSegmentDescription.SuspensionStiffness; SuspensionSpring.Settings.Servo.SpringSettings.Damping = treadSegmentDescription.SuspensionDamping; SuspensionAngularJoint = new RevoluteAngularJoint(body, Entity, Vector3.Right); //Make the joint extremely rigid. There are going to be extreme conditions when the wheels get up to speed; //we don't want the forces involved to torque the wheel off the frame! SuspensionAngularJoint.SpringSettings.Damping *= Entity.Mass * 50; SuspensionAngularJoint.SpringSettings.Stiffness *= Entity.Mass * 50; //Motorize the wheel. Motor = new RevoluteMotor(body, Entity, Vector3.Left); Motor.Settings.VelocityMotor.Softness = treadSegmentDescription.MotorSoftness; Motor.Settings.MaximumForce = treadSegmentDescription.MotorMaximumForce; }
public Tank(Vector3 position) { Body = new Box(position, 4, (Fix64).5m, 5, 20); Body.CollisionInformation.LocalPosition = new Vector3(0, (Fix64).8m, 0); var treadDescription = new TreadSegmentDescription { Width = (Fix64)0.5m, Radius = (Fix64)0.5m, Mass = 1, Friction = (Fix64)2f, MotorSoftness = 0,//0.3m, MotorMaximumForce = 30, SuspensionDamping = 70, SuspensionStiffness = 300, SuspensionLength = 1 }; RightTread = new Tread(Body, new Vector3((Fix64)(-1.8m), (Fix64)(-.2m), (Fix64)(-2.1m)), 5, 1, treadDescription); LeftTread = new Tread(Body, new Vector3((Fix64)1.8m, (Fix64)(-.2m), (Fix64)(-2.1m)), 5, 1, treadDescription); Turret = new Turret(Body, new Vector3(0, (Fix64)1.5m, (Fix64)0.5m)); }
public Tank(Vector3 position) { Body = new Box(position, 4, .5f, 5, 20); Body.CollisionInformation.LocalPosition = new Vector3(0, .8f, 0); var treadDescription = new TreadSegmentDescription { Width = 0.5f, Radius = 0.5f, Mass = 1, Friction = 2f, MotorSoftness = 0,//0.3f, MotorMaximumForce = 30, SuspensionDamping = 70, SuspensionStiffness = 300, SuspensionLength = 1 }; RightTread = new Tread(Body, new Vector3(-1.8f, -.2f, -2.1f), 5, 1, treadDescription); LeftTread = new Tread(Body, new Vector3(1.8f, -.2f, -2.1f), 5, 1, treadDescription); Turret = new Turret(Body, new Vector3(0, 1.5f, 0.5f)); }
public Tank(Vector3 position) { Body = new Box(position, 4, .5f, 5, 20); Body.CollisionInformation.LocalPosition = new Vector3(0, .8f, 0); var treadDescription = new TreadSegmentDescription { Width = 0.5f, Radius = 0.5f, Mass = 1, Friction = 2f, MotorSoftness = 0,//0.3f, MotorMaximumForce = 30, SuspensionDamping = 70, SuspensionStiffness = 300, SuspensionLength = 1 }; RightTread = new Tread(Body, new Vector3(-1.8f, -.2f, -2.1f), 5, 1, treadDescription); LeftTread = new Tread(Body, new Vector3(1.8f, -.2f, -2.1f), 5, 1, treadDescription); Turret = new Turret(Body, new Vector3(0, 1.5f, 0.5f)); }
public Tread(Entity tankBody, Vector3 offsetToFrontOfTread, int segmentCount, Fix64 spacing, TreadSegmentDescription treadSegmentDescription) { Segments = new List <TreadSegment>(); Vector3 nextSegmentPosition = tankBody.Position + offsetToFrontOfTread; //The front of the tread includes the radius of the first segment. nextSegmentPosition.Z += treadSegmentDescription.Radius * (Fix64)0.5m; for (int i = 0; i < segmentCount; ++i) { Segments.Add(new TreadSegment(nextSegmentPosition, tankBody, treadSegmentDescription)); //The tread offset starts at the front of the vehicle and moves backward. nextSegmentPosition.Z += spacing; } //Don't let the tread segments rotate relative to each other. SegmentAngularBindings = new List <NoRotationJoint>(); for (int i = 1; i < segmentCount; ++i) { //Create constraints linking the segments together to ensure that the power of one motor is felt by other segments. SegmentAngularBindings.Add(new NoRotationJoint(Segments[i - 1].Entity, Segments[i].Entity)); //Don't let the tread segments collide. CollisionRules.AddRule(Segments[i - 1].Entity, Segments[i].Entity, CollisionRule.NoBroadPhase); } //Note: You can organize this in different ways. For example, you could have one motor which drives one wheel, which //in turn drives other wheels through these NoRotationJoints. //In such a one-motor model, it may be a good idea for stability to bind all wheels directly to the drive wheel with //NoRotationJoints rather than using a chain of one wheel to the next. //Per-wheel drive motors are used in this example just because it is slightly more intuitive at a glance. //Each segment is no different than the others. }
public TreadSegment(Vector3 segmentPosition, Entity body, TreadSegmentDescription treadSegmentDescription) { Entity = new Cylinder(segmentPosition, treadSegmentDescription.Width, treadSegmentDescription.Radius, treadSegmentDescription.Mass); Entity.Material.KineticFriction = treadSegmentDescription.Friction; Entity.Material.StaticFriction = treadSegmentDescription.Friction; Entity.Orientation = Quaternion.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2); //Preventing the occasional pointless collision pair can speed things up. CollisionRules.AddRule(Entity, body, CollisionRule.NoBroadPhase); //Connect the wheel to the body. SuspensionAxisJoint = new PointOnLineJoint(body, Entity, Entity.Position, Vector3.Down, Entity.Position); SuspensionLengthLimit = new LinearAxisLimit(body, Entity, Entity.Position, Entity.Position, Vector3.Down, -treadSegmentDescription.SuspensionLength, 0); //This linear axis motor will give the suspension its springiness by pushing the wheels outward. SuspensionSpring = new LinearAxisMotor(body, Entity, Entity.Position, Entity.Position, Vector3.Down); SuspensionSpring.Settings.Mode = MotorMode.Servomechanism; SuspensionSpring.Settings.Servo.Goal = 0; SuspensionSpring.Settings.Servo.SpringSettings.Stiffness = treadSegmentDescription.SuspensionStiffness; SuspensionSpring.Settings.Servo.SpringSettings.Damping = treadSegmentDescription.SuspensionDamping; SuspensionAngularJoint = new RevoluteAngularJoint(body, Entity, Vector3.Right); //Make the joint extremely rigid. There are going to be extreme conditions when the wheels get up to speed; //we don't want the forces involved to torque the wheel off the frame! SuspensionAngularJoint.SpringSettings.Damping *= Entity.Mass * 50; SuspensionAngularJoint.SpringSettings.Stiffness *= Entity.Mass * 50; //Motorize the wheel. Motor = new RevoluteMotor(body, Entity, Vector3.Left); Motor.Settings.VelocityMotor.Softness = treadSegmentDescription.MotorSoftness; Motor.Settings.MaximumForce = treadSegmentDescription.MotorMaximumForce; }
public Tread(Entity tankBody, Vector3 offsetToFrontOfTread, int segmentCount, float spacing, TreadSegmentDescription treadSegmentDescription) { Segments = new List<TreadSegment>(); Vector3 nextSegmentPosition = tankBody.Position + offsetToFrontOfTread; //The front of the tread includes the radius of the first segment. nextSegmentPosition.Z += treadSegmentDescription.Radius * 0.5f; for (int i = 0; i < segmentCount; ++i) { Segments.Add(new TreadSegment(nextSegmentPosition, tankBody, treadSegmentDescription)); //The tread offset starts at the front of the vehicle and moves backward. nextSegmentPosition.Z += spacing; } //Don't let the tread segments rotate relative to each other. SegmentAngularBindings = new List<NoRotationJoint>(); for (int i = 1; i < segmentCount; ++i) { //Create constraints linking the segments together to ensure that the power of one motor is felt by other segments. SegmentAngularBindings.Add(new NoRotationJoint(Segments[i - 1].Entity, Segments[i].Entity)); //Don't let the tread segments collide. CollisionRules.AddRule(Segments[i - 1].Entity, Segments[i].Entity, CollisionRule.NoBroadPhase); } //Note: You can organize this in different ways. For example, you could have one motor which drives one wheel, which //in turn drives other wheels through these NoRotationJoints. //In such a one-motor model, it may be a good idea for stability to bind all wheels directly to the drive wheel with //NoRotationJoints rather than using a chain of one wheel to the next. //Per-wheel drive motors are used in this example just because it is slightly more intuitive at a glance. //Each segment is no different than the others. }