Vehicles/VehicleScripts/ArticulatedSteering.lua

Articulated steering allows to implement a steering mechanism that works with two different objects connected with a joint, similar to the Marmotta Vattenmask.

  25  ArticulatedSteering                     = ArticulatedSteering or {};

ArticulatedSteering:load(dataTable)

Load the configuration data of the joint and the steering values.

  29  function ArticulatedSteering:load(dataTable)
  30      if dataTable.articulatedSteering == nil then
  31          printf("Warning: Using vehicle script 'ArticulatedSteering', but the data table 'articulatedSteering' is missing (got a %s value, table expected)", type(dataTable.articulatedSteering));
  32          return;
  33      end;
  34  
  35      self.setArticulatedSteeringValue    = VehicleManager:newFunction("setArticulatedSteeringValue");
  36  
  37      self.getSteeringValue               = ArticulatedSteering.getSteeringValue;
  38  
  39      -- check whether all values are specified, and if not, output an error message
  40      if dataTable.articulatedSteering.steeringComponent == nil or dataTable.articulatedSteering.steeringComponent == "" then
  41          print("Error while loading vehicle '" .. tostring(self.templateName) .. "' articulated steering component. Make sure the component isn't set to nil or and isn't an empty string!");
  42          return;
  43      end;
  44  
  45      if dataTable.articulatedSteering.attachedComponent == nil or dataTable.articulatedSteering.attachedComponent == "" then
  46          print("Error while loading vehicle '" .. tostring(self.templateName) .. "' articulated steering attached component. Make sure the component is existingn't set to nil or and isn't an empty string!");
  47          return;
  48      end;
  49  
  50      -- identify the components linked by the joint
  51      self.steeringComponent              = self.components[dataTable.articulatedSteering.steeringComponent];
  52      self.attachedComponent              = self.components[dataTable.articulatedSteering.attachedComponent];
  53  
  54      self.invertSteering                 = getNoNil(dataTable.articulatedSteering.invertSteering, false);
  55      self.steeringMaxAngle               = getNoNil(dataTable.articulatedSteering.steeringMaxAngle, 45);
  56      self.steeringWheelBlocking          = getNoNil(dataTable.articulatedSteering.steeringWheelBlocking, false);
  57      
  58      -- set the pivot axis for the joint's position (0 -> locked | 1 -> limited | 2 -> free)
  59      self.motionAxis                     = {};
  60      if dataTable.articulatedSteering.motionAxis == nil or type(dataTable.articulatedSteering.motionAxis) ~= "table" then
  61          -- set angular motion to blocked by default
  62          self.motionAxis                 = Vector3:new(0, 0, 0);
  63      else 
  64          self.motionAxis                 = dataTable.articulatedSteering.motionAxis;
  65      end;
  66      Joint.setConfigurableJointMotionAxis(self.steeringComponent.id, self.motionAxis.x, self.motionAxis.y, self.motionAxis.z);
  67  
  68      -- set the pivot axis for the joint's rotations (0 -> locked | 1 -> limited | 2 -> free)
  69      self.angularMotionAxis              = {};
  70      if dataTable.articulatedSteering.angularMotionAxis == nil or type(dataTable.articulatedSteering.angularMotionAxis) ~= "table" then
  71          -- set angular motion to blocked by default
  72          self.angularMotionAxis          = Vector3:new(0, 0, 0);
  73      else 
  74          self.angularMotionAxis          = dataTable.articulatedSteering.angularMotionAxis;
  75      end;
  76      Joint.setConfigurableJointAngularMotionAxis(self.steeringComponent.id, self.angularMotionAxis.x, self.angularMotionAxis.y, self.angularMotionAxis.z);
  77  
  78      self.angularXDrive                  = dataTable.articulatedSteering.angularXDrive;
  79      self.angularYZDrive                 = dataTable.articulatedSteering.angularYZDrive;
  80      self.angularLimits                  = dataTable.articulatedSteering.angularLimits;
  81  
  82      if self.angularYZDrive ~= nil then
  83          Joint.setConfigurableJointYZDrive(self.steeringComponent.id, self.angularYZDrive.spring, self.angularYZDrive.damper);
  84      end;
  85      if self.angularXDrive ~= nil then
  86          Joint.setConfigurableJointXDrive(self.steeringComponent.id, self.angularXDrive.spring, self.angularXDrive.damper);
  87      end;
  88      if self.angularLimits ~= nil then
  89          Joint.setConfigurableJointLimits(self.steeringComponent.id, self.angularLimits);
  90      end;
  91  
  92      self.currentSteeringValue           = 0;
  93  end;
  94  

ArticulatedSteering:saveToTable(tbl)

Saves the current values of the articulated steering to the savegame.

  98  function ArticulatedSteering:saveToTable(tbl)
  99      if tbl == nil then return end;
 100      
 101      local _, ry1, _                 = getWorldRotation(self.steeringComponent.id);
 102      local _, ry2, _                 = getWorldRotation(self.attachedComponent.id);
 103      
 104      -- calculate the real steering value
 105      local realSteeringValue         = ry1 - ry2;
 106      tbl.articulatedSteeringValue    = realSteeringValue;
 107  end;

ArticulatedSteering:loadFromTable(tbl)

Loads the last position of the articulated steering from a savegame.

 111  function ArticulatedSteering:loadFromTable(tbl)
 112      if tbl == nil then return end;
 113      if tbl.articulatedSteeringValue ~= nil then
 114          self.currentSteeringValue   = tbl.articulatedSteeringValue;
 115          self:setArticulatedSteeringValue(self.steeringComponent.id, tbl.articulatedSteeringValue);
 116      end;
 117  end;

ArticulatedSteering:setArticulatedSteeringValue(steeringComponentId, steeringValue)

Sets the steering joint to a degree angle value.

 121  function ArticulatedSteering:setArticulatedSteeringValue(steeringComponentId, steeringValue)
 122      -- set steering rotation to joint
 123      Joint.setConfigurableJointTargetRotation(steeringComponentId, 0, steeringValue, 0);
 124  end;
 125  
 126  function ArticulatedSteering:getSteeringValue(invertSteering)
 127      local steeringValue             = InputMapper:getAxis(InputMapper.Axis_Vehicle_Steer) * self.steeringMaxAngle;
 128  
 129      -- check if we are supposed to invert the steering
 130      if invertSteering then
 131          steeringValue               = steeringValue * -1;
 132      end;
 133      return steeringValue;
 134  end;

ArticulatedSteering:update(dt)

Reads the player's steering inputs and maps them onto the articulated steering according to the steering values.

 138  function ArticulatedSteering:update(dt)
 139      local currentSteeringValue      = self:getSteeringValue(self.invertSteering);
 140  
 141      -- steering wheel blocking
 142      if self.steeringWheelBlocking and self.steeringWheelId ~= nil then
 143  
 144          local _, ry1, _             = getWorldRotation(self.steeringComponent.id);
 145          local _, ry2, _             = getWorldRotation(self.attachedComponent.id);
 146          
 147          -- calculate the real steering value
 148          local realSteeringValue     = ry1 - ry2;
 149          local steeringWheelAngle    = (self:getMaxVisualSteerAngle() * realSteeringValue) / self.steeringMaxAngle;
 150  
 151          -- update steering wheel, if steering wheel blocking is active
 152          if self.steeringWheelAxle == 1 then
 153              setRotationX(self.steeringWheelId, steeringWheelAngle);
 154          elseif self.steeringWheelAxle == 2 then
 155              setRotationY(self.steeringWheelId, steeringWheelAngle);
 156          else
 157              setRotationZ(self.steeringWheelId, steeringWheelAngle);
 158          end;
 159      end;
 160      self.currentSteeringValue               = currentSteeringValue;
 161  
 162      -- set the current steering value to the joint
 163      if self.isActive and self:getIsLocalPlayerEntered() then 
 164          self:setArticulatedSteeringValue(self.steeringComponent.id, currentSteeringValue);
 165      end;
 166  end;

ArticulatedSteering:setVehicleKinematic(isKinematic)

If the vehicle is set to kinematic, the joint angular motion will blocked.

 170  function ArticulatedSteering:setVehicleKinematic(isKinematic)
 171      if isKinematic == false then
 172          Joint.setConfigurableJointAngularMotionAxis(self.steeringComponent.id, self.angularMotionAxis.x, self.angularMotionAxis.y, self.angularMotionAxis.z);
 173      else 
 174          if g_isServer or g_isSingleplayer then
 175              Joint.setConfigurableJointAngularMotionAxis(self.steeringComponent.id, 0, 0, 0);
 176          end;
 177      end;
 178  end;

ArticulatedSteering:readResync()

Resynchronizes all variables when a new player joins the game. The data sent by writeResync will be received by readResync.

 182  function ArticulatedSteering:readResync()
 183      local currentSteeringValue          = streamReadFloat();
 184      self:setArticulatedSteeringValue(self.steeringComponent.id, currentSteeringValue);
 185  end;

ArticulatedSteering:writeResync()

Resynchronizes all variables when a new player joins the game. The data sent by writeResync will be received by readResync.

 189  function ArticulatedSteering:writeResync()
 190      streamWriteFloat(self.currentSteeringValue);
 191  end;

ArticulatedSteering:writeUpdate(isLocalPlayerEntered)

Sends a network packet each frame when the vehicle is updated. The data sent by writeUpdate will be received by readUpdate.

 195  function ArticulatedSteering:writeUpdate(isLocalPlayerEntered)
 196      if g_isClient and isLocalPlayerEntered then
 197          streamWriteFloat(self.currentSteeringValue);
 198      end;
 199  end;

ArticulatedSteering:readUpdate(connection, networkTime, isClientEntered)

Receives a network packet each frame when the vehicle is updated. The data sent by writeUpdate will be received by readUpdate.

 203  function ArticulatedSteering:readUpdate(connection, networkTime, isClientEntered)
 204      if isClientEntered then
 205          local currentSteeringValue          = streamReadFloat();
 206          self:setArticulatedSteeringValue(self.steeringComponent.id, currentSteeringValue);
 207      end;
 208  end;

All contents of this page may be used for modding use for Winter Resort Simulator - Season 2 only. Any use exceeding this regulation is not permitted.

Copyright (C) HR Innoways, 2021. All Rights Reserved.