public JointVehicleMotor ConnectWheel(VehiclePartEntity wheel, bool driving, bool powered) { wheel.SetFriction(2.5f); Vector3 left = Quaternion.Transform(new Vector3(-1, 0, 0), wheel.GetOrientation()); Vector3 up = Quaternion.Transform(new Vector3(0, 0, 1), wheel.GetOrientation()); JointSlider pointOnLineJoint = new JointSlider(this, wheel, -new Location(up)); JointLAxisLimit suspensionLimit = new JointLAxisLimit(this, wheel, 0f, 0.1f, wheel.GetPosition(), wheel.GetPosition(), -new Location(up)); JointPullPush spring = new JointPullPush(this, wheel, -new Location(up), true); BEPUphysics.CollisionRuleManagement.CollisionRules.AddRule(wheel.Body, this.Body, BEPUphysics.CollisionRuleManagement.CollisionRule.NoBroadPhase); // TODO: How necessary is this? Should we replicate this clientside? if (driving) { JointSpinner spinner = new JointSpinner(this, wheel, new Location(-left)); TheRegion.AddJoint(spinner); } else { JointSwivelHinge swivelhinge = new JointSwivelHinge(this, wheel, new Location(up), new Location(-left)); TheRegion.AddJoint(swivelhinge); } TheRegion.AddJoint(pointOnLineJoint); TheRegion.AddJoint(suspensionLimit); TheRegion.AddJoint(spring); if (powered) { JointVehicleMotor motor = new JointVehicleMotor(this, wheel, new Location(driving ? left : up), !driving); TheRegion.AddJoint(motor); return(motor); } return(null); }
public JointVehicleMotor ConnectWheel(VehiclePartEntity wheel, bool driving, bool powered, double susp) { TheRegion.AddJoint(new ConstWheelStepUp(wheel, wheel.StepHeight)); wheel.SetFriction(2.5f); Vector3 left = BEPUutilities.Quaternion.Transform(new Vector3(-1, 0, 0), wheel.GetOrientation()); Vector3 up = BEPUutilities.Quaternion.Transform(new Vector3(0, 0, 1), wheel.GetOrientation()); JointSlider pointOnLineJoint = new JointSlider(this, wheel, -new Location(up)); JointLAxisLimit suspensionLimit = new JointLAxisLimit(this, wheel, 0f, susp, wheel.GetPosition(), wheel.GetPosition(), -new Location(up)); JointPullPush spring = new JointPullPush(this, wheel, -new Location(up), true); if (driving) { JointSpinner spinner = new JointSpinner(this, wheel, new Location(-left)); TheRegion.AddJoint(spinner); } else { JointSwivelHinge swivelhinge = new JointSwivelHinge(this, wheel, new Location(up), new Location(-left)); TheRegion.AddJoint(swivelhinge); } TheRegion.AddJoint(pointOnLineJoint); TheRegion.AddJoint(suspensionLimit); TheRegion.AddJoint(spring); JointNoCollide jnc = new JointNoCollide(this, wheel); TheRegion.AddJoint(jnc); if (powered) { JointVehicleMotor motor = new JointVehicleMotor(this, wheel, new Location(driving ? left : up), !driving); TheRegion.AddJoint(motor); return(motor); } return(null); }
public override bool ParseBytesAndExecute(byte[] data) { int len = 1 + 8 + 8 + 8 + 24 + 4 + 4 + 4 + 4 + 24 + 4 + 4 + 4 + 4; if (data.Length < len) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad initial length!"); return(false); } byte type = data[0]; long EID1 = Utilities.BytesToLong(Utilities.BytesPartial(data, 1, 8)); long EID2 = Utilities.BytesToLong(Utilities.BytesPartial(data, 1 + 8, 8)); long JID = Utilities.BytesToLong(Utilities.BytesPartial(data, 1 + 8 + 8, 8)); if (TheClient.TheRegion.GetJoint(JID) != null) { // If we already know this joint, just keep on going. return(true); } Entity pe1 = TheClient.TheRegion.GetEntity(EID1); Entity pe2 = TheClient.TheRegion.GetEntity(EID2); if (pe1 == null) { SysConsole.Output(OutputType.WARNING, "Joint Packet: Invalid EID-1 " + EID1); return(false); } if (pe2 == null) { SysConsole.Output(OutputType.WARNING, "Joint Packet: Invalid EID-2 " + EID2); return(false); } Location pos1 = Location.FromDoubleBytes(data, 1 + 8 + 8 + 8); float qx1 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24, 4)); float qy1 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4, 4)); float qz1 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4 + 4, 4)); float qw1 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4 + 4 + 4, 4)); BEPUutilities.Quaternion quat1 = new BEPUutilities.Quaternion(qx1, qy1, qz1, qw1); pe1.SetPosition(pos1); pe1.SetOrientation(quat1); Location pos2 = Location.FromDoubleBytes(data, 1 + 8 + 8 + 8 + 24 + 4 + 4 + 4 + 4); float qx2 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 24 + 4 + 4 + 4 + 4, 4)); float qy2 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4 + 24 + 4 + 4 + 4 + 4, 4)); float qz2 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4 + 4 + 24 + 4 + 4 + 4 + 4, 4)); float qw2 = Utilities.BytesToFloat(Utilities.BytesPartial(data, 1 + 8 + 8 + 8 + 24 + 4 + 4 + 4 + 24 + 4 + 4 + 4 + 4, 4)); BEPUutilities.Quaternion quat2 = new BEPUutilities.Quaternion(qx2, qy2, qz2, qw2); pe1.SetPosition(pos1); pe1.SetOrientation(quat1); pe2.SetPosition(pos2); pe2.SetOrientation(quat2); if (type == 0) { if (data.Length != len + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location pos = Location.FromDoubleBytes(data, len); JointBallSocket jbs = new JointBallSocket((PhysicsEntity)pe1, (PhysicsEntity)pe2, pos) { JID = JID }; TheClient.TheRegion.AddJoint(jbs); return(true); } else if (type == 1) { if (data.Length != len + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location dir = Location.FromDoubleBytes(data, len); JointSlider js = new JointSlider((PhysicsEntity)pe1, (PhysicsEntity)pe2, dir) { JID = JID }; TheClient.TheRegion.AddJoint(js); return(true); } else if (type == 2) { if (data.Length != len + 4 + 4 + 24 + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } float min = Utilities.BytesToFloat(Utilities.BytesPartial(data, len, 4)); float max = Utilities.BytesToFloat(Utilities.BytesPartial(data, len + 4, 4)); Location ent1pos = Location.FromDoubleBytes(data, len + 4 + 4); Location ent2pos = Location.FromDoubleBytes(data, len + 4 + 4 + 24); JointDistance jd = new JointDistance((PhysicsEntity)pe1, (PhysicsEntity)pe2, min, max, ent1pos, ent2pos) { JID = JID }; TheClient.TheRegion.AddJoint(jd); return(true); } else if (type == 3) { if (data.Length != len + 24 + 1) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location axis = Location.FromDoubleBytes(data, len); bool mode = data[len + 24] == 1; JointPullPush jpp = new JointPullPush((PhysicsEntity)pe1, (PhysicsEntity)pe2, axis, mode) { JID = JID }; TheClient.TheRegion.AddJoint(jpp); return(true); } else if (type == 4) { if (data.Length != len) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } JointForceWeld jfw = new JointForceWeld(pe1, pe2) { JID = JID }; TheClient.TheRegion.AddJoint(jfw); return(true); } else if (type == 5) { if (data.Length != len + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location dir = Location.FromDoubleBytes(data, len); JointSpinner js = new JointSpinner((PhysicsEntity)pe1, (PhysicsEntity)pe2, dir) { JID = JID }; TheClient.TheRegion.AddJoint(js); return(true); } else if (type == 6) { if (data.Length != len + 24 + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location a1 = Location.FromDoubleBytes(data, len); Location a2 = Location.FromDoubleBytes(data, len + 24); JointTwist jt = new JointTwist((PhysicsEntity)pe1, (PhysicsEntity)pe2, a1, a2) { JID = JID }; TheClient.TheRegion.AddJoint(jt); return(true); } else if (type == 7) { if (data.Length != len) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } JointWeld jw = new JointWeld((PhysicsEntity)pe1, (PhysicsEntity)pe2) { JID = JID }; TheClient.TheRegion.AddJoint(jw); return(true); } else if (type == 8) { if (data.Length != len + 24 + 1) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location dir = Location.FromDoubleBytes(data, len); bool issteering = data[len + 24] == 1; JointVehicleMotor jm = new JointVehicleMotor((PhysicsEntity)pe1, (PhysicsEntity)pe2, dir, issteering) { JID = JID }; TheClient.TheRegion.AddJoint(jm); return(true); } else if (type == 9) { if (data.Length != len + 24 + 24 + 24 + 4 + 4) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location cpos1 = Location.FromDoubleBytes(data, len); Location cpos2 = Location.FromDoubleBytes(data, len + 24); Location axis = Location.FromDoubleBytes(data, len + 24 + 24); float min = Utilities.BytesToFloat(Utilities.BytesPartial(data, len + 24 + 24 + 24, 4)); float max = Utilities.BytesToFloat(Utilities.BytesPartial(data, len + 24 + 24 + 24 + 4, 4)); JointLAxisLimit jlal = new JointLAxisLimit((PhysicsEntity)pe1, (PhysicsEntity)pe2, min, max, cpos1, cpos2, axis) { JID = JID }; TheClient.TheRegion.AddJoint(jlal); return(true); } else if (type == 10) { if (data.Length != len + 24 + 24) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } Location hinge = Location.FromDoubleBytes(data, len); Location twist = Location.FromDoubleBytes(data, len + 24); JointSwivelHinge jlal = new JointSwivelHinge((PhysicsEntity)pe1, (PhysicsEntity)pe2, hinge, twist) { JID = JID }; TheClient.TheRegion.AddJoint(jlal); return(true); } else if (type == 11) { if (data.Length != len + 4) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } float height = Utilities.BytesToFloat(Utilities.BytesPartial(data, len, 4)); ConstWheelStepUp cwsu = new ConstWheelStepUp((PhysicsEntity)pe1, height) { JID = JID }; TheClient.TheRegion.AddJoint(cwsu); return(true); } else if (type == 12) { if (data.Length != len + 4 + 1) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } ConnectorBeam cb = new ConnectorBeam() { One = pe1, Two = pe2, color = System.Drawing.Color.FromArgb(Utilities.BytesToInt(Utilities.BytesPartial(data, len, 4))), JID = JID, type = (BeamType)data[len + 4] }; TheClient.TheRegion.AddJoint(cb); return(true); } else if (type == 13) { if (data.Length != len) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } JointFlyingDisc jfd = new JointFlyingDisc((PhysicsEntity)pe1) { JID = JID }; TheClient.TheRegion.AddJoint(jfd); return(true); } else if (type == 14) { if (data.Length != len) { SysConsole.Output(OutputType.WARNING, "Joint packet: Bad length!"); return(false); } JointNoCollide jnc = new JointNoCollide((PhysicsEntity)pe1, (PhysicsEntity)pe2) { JID = JID }; TheClient.TheRegion.AddJoint(jnc); return(true); } else { SysConsole.Output(OutputType.WARNING, "Unknown joint type " + type); return(false); } }
public void HandleWheels() { if (!hasWheels) { Model mod = TheServer.Models.GetModel(model); if (mod == null) // TODO: mod should return a cube when all else fails? { return; } Model3D scene = mod.Original; if (scene == null) // TODO: Scene should return a cube when all else fails? { return; } SetOrientation(Quaternion.Identity); List <Model3DNode> nodes = GetNodes(scene.RootNode); List <VehiclePartEntity> frontwheels = new List <VehiclePartEntity>(); for (int i = 0; i < nodes.Count; i++) { string name = nodes[i].Name.ToLowerFast(); if (name.Contains("wheel")) { Matrix mat = nodes[i].MatrixA; Model3DNode tnode = nodes[i].Parent; while (tnode != null) { mat = tnode.MatrixA * mat; tnode = tnode.Parent; } Location pos = GetPosition() + new Location(mat.M14, mat.M34, mat.M24) + offset; // NOTE: wtf happened to this matrix? VehiclePartEntity wheel = new VehiclePartEntity(TheRegion, "vehicles/" + vehName + "_wheel", true); wheel.SetPosition(pos); wheel.SetOrientation(Quaternion.Identity); wheel.Gravity = Gravity; wheel.CGroup = CGroup; wheel.SetMass(30); wheel.mode = ModelCollisionMode.CONVEXHULL; TheRegion.SpawnEntity(wheel); wheel.SetPosition(pos); if (name.After("wheel").StartsWith("f")) { SteeringMotors.Add(ConnectWheel(wheel, false, true)); frontwheels.Add(wheel); } else if (name.After("wheel").StartsWith("b")) { DrivingMotors.Add(ConnectWheel(wheel, true, true)); } else { ConnectWheel(wheel, true, false); } wheel.Body.ActivityInformation.Activate(); } } if (frontwheels.Count == 2) { JointSpinner js = new JointSpinner(frontwheels[0], frontwheels[1], new Location(1, 0, 0)); TheRegion.AddJoint(js); } hasWheels = true; } }
public void HandleWheels() { if (!hasWheels) { string wheelsModFront = SourceFile.GetString("vehicle.wheels.front.model"); string wheelsModBack = SourceFile.GetString("vehicle.wheels.back.model"); double wheelsSuspFront = SourceFile.GetDouble("vehicle.wheels.front.suspension", 0.1).Value; double wheelsSuspBack = SourceFile.GetDouble("vehicle.wheels.back.suspension", 0.1).Value; Model mod = TheServer.Models.GetModel(model); if (mod == null) // TODO: mod should return a cube when all else fails? { return; } Model3D scene = mod.Original; if (scene == null) // TODO: Scene should return a cube when all else fails? { return; } SetOrientation(BEPUutilities.Quaternion.Identity); // TODO: Track and reset orientation maybe? List <Model3DNode> nodes = GetNodes(scene.RootNode); List <VehiclePartEntity> frontwheels = new List <VehiclePartEntity>(); Location centerOfMass = Location.Zero; double mass = 0; for (int i = 0; i < nodes.Count; i++) { string name = nodes[i].Name.ToLowerFast(); if (name.Contains("wheel")) { Matrix mat = nodes[i].MatrixA; mat.Transpose(); Model3DNode tnode = nodes[i].Parent; while (tnode != null) { Matrix mb = tnode.MatrixA; mb.Transpose(); mat = mat * mb; tnode = tnode.Parent; } centerOfMass += (new Location(mat.M41, -mat.M43, mat.M42) + offset) * 30; // TODO: Arbitrary constant mass += 30; // TODO: Arbitrary constant } else if (name.Contains("flap")) { Matrix mat = nodes[i].MatrixA; mat.Transpose(); Model3DNode tnode = nodes[i].Parent; while (tnode != null) { Matrix mb = tnode.MatrixA; mb.Transpose(); mat = mat * mb; tnode = tnode.Parent; } centerOfMass += (new Location(mat.M41, -mat.M43, mat.M42) + offset) * 20; // TODO: Arbitrary constant mass += 20; // TODO: Arbitrary constant } } if (mass > 0) { centerOfMass /= mass; } Body.CollisionInformation.LocalPosition = -centerOfMass.ToBVector() - CenterOfMassOffset.ToBVector(); ForceNetwork(); for (int i = 0; i < nodes.Count; i++) { string name = nodes[i].Name.ToLowerFast(); if (name.Contains("wheel")) { Matrix mat = nodes[i].MatrixA; mat.Transpose(); Model3DNode tnode = nodes[i].Parent; while (tnode != null) { Matrix mb = tnode.MatrixA; mb.Transpose(); mat = mat * mb; tnode = tnode.Parent; } Location pos = GetPosition() + new Location(Body.CollisionInformation.LocalPosition) + new Location(mat.M41, -mat.M43, mat.M42) + offset; // TODO: matrix gone funky? VehiclePartEntity wheel = new VehiclePartEntity(TheRegion, (name.After("wheel").Contains("f") ? wheelsModFront : wheelsModBack), true); wheel.SetPosition(pos); wheel.SetOrientation(BEPUutilities.Quaternion.Identity); wheel.Gravity = Gravity; wheel.CGroup = CGroup; wheel.SetMass(30); // TODO: Arbitrary constant wheel.mode = ModelCollisionMode.CONVEXHULL; TheRegion.SpawnEntity(wheel); wheel.ForceNetwork(); wheel.SetPosition(pos); wheel.SetOrientation(BEPUutilities.Quaternion.Identity); if (name.After("wheel").Contains("f")) { SteeringMotors.Add(ConnectWheel(wheel, false, true, wheelsSuspFront)); frontwheels.Add(wheel); } else if (name.After("wheel").Contains("b")) { DrivingMotors.Add(ConnectWheel(wheel, true, true, wheelsSuspBack)); } else { ConnectWheel(wheel, true, false, wheelsSuspBack); } wheel.Body.ActivityInformation.Activate(); } else if (name.Contains("flap")) { Matrix mat = nodes[i].MatrixA; mat.Transpose(); Model3DNode tnode = nodes[i].Parent; while (tnode != null) { Matrix mb = tnode.MatrixA; mb.Transpose(); mat = mat * mb; tnode = tnode.Parent; } Location pos = GetPosition() + new Location(Body.CollisionInformation.LocalPosition) + new Location(mat.M41, -mat.M43, mat.M42) + offset; // TODO: matrix gone funky? FDSSection flapDat = SourceFile.GetSection("vehicle.flaps").GetSection(name.After("flap").Replace("_", "")); VehiclePartEntity flap = new VehiclePartEntity(TheRegion, flapDat.GetString("model"), true); flap.SetPosition(pos); flap.SetOrientation(BEPUutilities.Quaternion.Identity); flap.Gravity = Gravity; flap.CGroup = CGroup; flap.SetMass(20); flap.mode = ModelCollisionMode.CONVEXHULL; TheRegion.SpawnEntity(flap); flap.ForceNetwork(); flap.SetPosition(pos); flap.SetOrientation(BEPUutilities.Quaternion.Identity); ConnectFlap(flap, flapDat); } } if (frontwheels.Count == 2) { JointSpinner js = new JointSpinner(frontwheels[0], frontwheels[1], new Location(1, 0, 0)); TheRegion.AddJoint(js); } hasWheels = true; } }