public override void Simulate() { if (!Host.IsServer) { return; } using (Prediction.Off()) { if (!Input.Pressed(InputButton.Attack1)) { return; } var startPos = Owner.EyePosition; var dir = Owner.EyeRotation.Forward; var tr = Trace.Ray(startPos, startPos + dir * MaxTraceDistance) .Ignore(Owner) .Run(); if (!tr.Hit) { return; } if (!tr.Entity.IsValid()) { return; } var attached = !tr.Entity.IsWorld && tr.Body.IsValid() && tr.Body.PhysicsGroup != null && tr.Body.GetEntity().IsValid(); if (attached && tr.Entity is not Prop) { return; } CreateHitEffects(tr.EndPosition); if (tr.Entity is WheelEntity) { // TODO: Set properties return; } var ent = new WheelEntity { Position = tr.EndPosition, Rotation = Rotation.LookAt(tr.Normal) * Rotation.From(new Angles(0, 90, 0)), }; ent.SetModel("models/citizen_props/wheel01.vmdl"); ent.PhysicsBody.Mass = tr.Body.Mass; ent.Joint = PhysicsJoint.CreateHinge(ent.PhysicsBody, tr.Body, tr.EndPosition, tr.Normal); } }
private void ModulateWheelSpeed(float speed, WheelEntity wheel, float timeStep) { if (Math.Abs(speed) > 0.1) { if (speed > 0) { wheel.Wheel.AxleSpeed -= SpeedDelta * timeStep; } else { wheel.Wheel.AxleSpeed += SpeedDelta * timeStep; } } }
/// <summary> /// Builds the simulated robotic entity using local fields for position size, orientation /// </summary> /// <param name="device"></param> /// <param name="physicsEngine"></param> public void ProgrammaticallyBuildModel(xnagrfx.GraphicsDevice device, PhysicsEngine physicsEngine) { if (_chassisShape != null) { foreach (BoxShape shape in _chassisShape) { base.State.PhysicsPrimitives.Add(shape); } } base.CreateAndInsertPhysicsEntity(physicsEngine); // increase physics fidelity base.PhysicsEntity.SolverIterationCount = 64; // if we were created from xml the wheel entities would already be instantiated if (_leftFrontWheel != null && _rightFrontWheel != null && _leftRearWheel != null && _rightRearWheel != null) { return; } // front left wheel WheelShapeProperties w = new WheelShapeProperties("front left wheel", FrontWheelMass, FrontWheelRadius); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(LeftFrontWheelPosition); w.SuspensionTravel = _suspensionTravel; w.Suspension = new SpringProperties(10, 5, 0.5f); _leftFrontWheel = new WheelEntity(w); _leftFrontWheel.State.Name = State.Name + ":" + "Left front wheel"; _leftFrontWheel.State.Assets.Mesh = _frontWheelMesh; _leftFrontWheel.Parent = this; // front right wheel w = new WheelShapeProperties("front right wheel", FrontWheelMass, FrontWheelRadius); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(RightFrontWheelPosition); w.SuspensionTravel = _suspensionTravel; w.Suspension = new SpringProperties(10, 5, 0.5f); _rightFrontWheel = new WheelEntity(w); _rightFrontWheel.State.Name = State.Name + ":" + "Right front wheel"; _rightFrontWheel.State.Assets.Mesh = _frontWheelMesh; _rightFrontWheel.Parent = this; // rear left wheel w = new WheelShapeProperties("rear left wheel", RearWheelMass, RearWheelRadius); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(LeftRearWheelPosition); w.SuspensionTravel = _suspensionTravel; w.Suspension = new SpringProperties(10, 5, 0.5f); _leftRearWheel = new WheelEntity(w); _leftRearWheel.State.Name = State.Name + ":" + "Left rear wheel"; _leftRearWheel.State.Assets.Mesh = _rearWheelMesh; _leftRearWheel.Parent = this; // front right wheel w = new WheelShapeProperties("rear right wheel", RearWheelMass, RearWheelRadius); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(RightRearWheelPosition); w.SuspensionTravel = _suspensionTravel; w.Suspension = new SpringProperties(10, 5, 0.5f); _rightRearWheel = new WheelEntity(w); _rightRearWheel.State.Name = State.Name + ":" + "Right rear wheel"; _rightRearWheel.State.Assets.Mesh = _rearWheelMesh; _rightRearWheel.Parent = this; }
public override void OnPlayerControlTick() { if (!Host.IsServer) { return; } using (Prediction.Off()) { var input = Owner.Input; if (!input.Pressed(InputButton.Attack1)) { return; } var startPos = Owner.EyePos; var dir = Owner.EyeRot.Forward; var tr = Trace.Ray(startPos, startPos + dir * MaxTraceDistance) .Ignore(Owner) .Run(); if (!tr.Hit) { return; } if (!tr.Entity.IsValid()) { return; } var attached = !tr.Entity.IsWorld && tr.Body.IsValid() && tr.Body.PhysicsGroup != null && tr.Body.Entity.IsValid(); if (attached && tr.Entity is not Prop) { return; } CreateHitEffects(tr.EndPos); if (tr.Entity is WheelEntity) { // TODO: Set properties return; } var ent = new WheelEntity { WorldPos = tr.EndPos, WorldRot = Rotation.LookAt(tr.Normal) * Rotation.From(new Angles(0, 90, 0)), }; ent.SetModel("models/citizen_props/wheel01.vmdl"); ent.PhysicsBody.Mass = tr.Body.Mass; ent.Joint = PhysicsJoint.Revolute .From(ent.PhysicsBody) .To(tr.Body) .WithPivot(tr.EndPos) .WithBasis(Rotation.LookAt(tr.Normal) * Rotation.From(new Angles(90, 0, 0))) .Create(); } }
public void Save(WheelEntity item) { throw new NotImplementedException(); }
private void ConstructWheels() { // front left wheel WheelShapeProperties w = new WheelShapeProperties("front left wheel", FRONT_WHEEL_MASS, FRONT_WHEEL_RADIUS); // Set this flag on both wheels if you want to use axle speed instead of torque w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(LEFT_FRONT_WHEEL_POSITION); LeftWheel = new WheelEntity(w); LeftWheel.State.Name = State.Name + ":" + "Left wheel"; LeftWheel.State.Assets.Mesh = WheelMesh; LeftWheel.Parent = this; //LeftWheel.WheelShape.WheelState.Material = new MaterialProperties("wheel", 0.5f, 0f, 1f); // wheels must have zero friction material.The wheel model will do friction differently // front right wheel w = new WheelShapeProperties("front right wheel", FRONT_WHEEL_MASS, FRONT_WHEEL_RADIUS); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(RIGHT_FRONT_WHEEL_POSITION); RightWheel = new WheelEntity(w); RightWheel.State.Name = State.Name + ":" + "Right wheel"; RightWheel.State.Assets.Mesh = WheelMesh; RightWheel.MeshRotation = new Vector3(0, 180, 0); // flip the wheel mesh RightWheel.Parent = this; //RightWheel.WheelShape.WheelState.Material = LeftWheel.WheelShape.WheelState.Material; }
/// <summary> /// Builds the simulated robotic entity using local fields for positionm size, orientation /// </summary> /// <param name="device"></param> /// <param name="physicsEngine"></param> public void ProgrammaticallyBuildModel(xnagrfx.GraphicsDevice device, PhysicsEngine physicsEngine) { if (_casterWheelShape == null) { // add caster wheel as a basic sphere shape CasterWheelShape = new SphereShape( new SphereShapeProperties("rear wheel", 0.001f, new Pose(CASTER_WHEEL_POSITION), CASTER_WHEEL_RADIUS)); CasterWheelShape.State.Name = "Caster wheel"; // a fixed caster wheel has high friction when moving laterely, but low friction when it moves along the // body axis its aligned with. We use anisotropic friction to model this CasterWheelShape.State.Material = new MaterialProperties("small friction with anisotropy", 0.5f, 0.5f, 1); CasterWheelShape.State.Material.Advanced = new MaterialAdvancedProperties(); CasterWheelShape.State.Material.Advanced.AnisotropicDynamicFriction = 0.3f; CasterWheelShape.State.Material.Advanced.AnisotropicStaticFriction = 0.4f; CasterWheelShape.State.Material.Advanced.AnisotropyDirection = new Vector3(0, 0, 1); } base.State.PhysicsPrimitives.Add(_casterWheelShape); if (_chassisShape != null) base.State.PhysicsPrimitives.Add(_chassisShape); base.CreateAndInsertPhysicsEntity(physicsEngine); // increase physics fidelity base.PhysicsEntity.SolverIterationCount = 64; // if we were created from xml the wheel entities would already be instantiated if (_leftWheel != null && _rightWheel != null) return; // front left wheel WheelShapeProperties w = new WheelShapeProperties("front left wheel", FRONT_WHEEL_MASS, FRONT_WHEEL_RADIUS); // Set this flag on both wheels if you want to use axle speed instead of torque w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(LEFT_FRONT_WHEEL_POSITION); _leftWheel = new WheelEntity(w); _leftWheel.State.Name = State.Name + ":" + "Left wheel"; _leftWheel.State.Assets.Mesh = _wheelMesh; _leftWheel.Parent = this; //_leftWheel.WheelShape.WheelState.Material = new MaterialProperties("wheel", 0.5f, 0f, 1f); // wheels must have zero friction material.The wheel model will do friction differently // front right wheel w = new WheelShapeProperties("front right wheel", FRONT_WHEEL_MASS, FRONT_WHEEL_RADIUS); w.Flags |= WheelShapeBehavior.OverrideAxleSpeed; w.InnerRadius = 0.7f * w.Radius; w.LocalPose = new Pose(RIGHT_FRONT_WHEEL_POSITION); _rightWheel = new WheelEntity(w); _rightWheel.State.Name = State.Name + ":" + "Right wheel"; _rightWheel.State.Assets.Mesh = _wheelMesh; _rightWheel.Parent = this; //_rightWheel.WheelShape.WheelState.Material = _leftWheel.WheelShape.WheelState.Material; }
/// <summary> /// Rotations to ticks. /// </summary> /// <param name="wheel">The wheel entity.</param> /// <returns>The number of rotations converted to ticks</returns> private static int RotationsToTicks(WheelEntity wheel) { const double MetersPerEncoderTick = 0.01328; return((int)(wheel.Rotations * 2 * Math.PI * wheel.Wheel.State.Radius / MetersPerEncoderTick)); }