+void Vehicle::turn_axles(float d)
+{
+ const vector<VehicleType::Axle> &axles = type.get_axles();
+ const vector<VehicleType::Bogie> &bogies = type.get_bogies();
+ for(unsigned i=0; i<axle_angles.size(); ++i)
+ for(unsigned j=0; j<axle_angles[i].size(); ++j)
+ {
+ const VehicleType::Axle &axle = (i==0 ? axles[j] : bogies[i-1].axles[j]);
+ axle_angles[i][j] += d*2/axle.wheel_dia;
+ }
+
+ update_rods();
+}
+
+void Vehicle::update_rods()
+{
+ const vector<VehicleType::Rod> &trods = type.get_rods();
+ for(unsigned i=0; i<trods.size(); ++i)
+ {
+ const VehicleType::Rod &rod = trods[i];
+ if(rod.pivot==VehicleType::Rod::BODY)
+ rods[i].position = rod.pivot_point;
+ else if(rod.pivot==VehicleType::Rod::AXLE)
+ {
+ const VehicleType::Axle &axle = type.get_axles()[rod.pivot_index];
+ float angle = axle_angles[0][rod.pivot_index];
+ float c = cos(angle);
+ float s = sin(angle);
+ const Point &pp = rod.pivot_point;
+ rods[i].position = Point(axle.position+pp.x*c+pp.z*s, pp.y, axle.wheel_dia/2+pp.z*c-pp.x*s);
+ }
+ else if(rod.pivot==VehicleType::Rod::ROD)
+ {
+ float angle = rods[rod.pivot_index].angle;
+ float c = cos(angle);
+ float s = sin(angle);
+ const Point &pos = rods[rod.pivot_index].position;
+ const Point &off = rod.pivot_point;
+ rods[i].position = Point(pos.x+off.x*c-off.z*s, pos.y+off.y, pos.z+off.z*c+off.x*s);
+ }
+
+ if(rod.connect_index>=0)
+ {
+ const VehicleType::Rod &crod = trods[rod.connect_index];
+ if(rod.limit==VehicleType::Rod::ROTATE && crod.limit==VehicleType::Rod::SLIDE_X)
+ {
+ float dx = (rods[rod.connect_index].position.x+rod.connect_offset.x)-rods[i].position.x;
+ float dz = (rods[rod.connect_index].position.z+rod.connect_offset.z)-rods[i].position.z;
+ float cd = sqrt(rod.connect_point.x*rod.connect_point.x+rod.connect_point.z*rod.connect_point.z);
+ float ca = atan2(rod.connect_point.z, rod.connect_point.x);
+ dx = sqrt(cd*cd-dz*dz)*(dx>0 ? 1 : -1);
+ rods[i].angle = atan2(dz, dx)-ca;
+ rods[rod.connect_index].position.x = rods[i].position.x+dx-rod.connect_offset.x;
+ }
+ else if(rod.limit==VehicleType::Rod::ROTATE && crod.limit==VehicleType::Rod::ROTATE)
+ {
+ float dx = rods[rod.connect_index].position.x-rods[i].position.x;
+ float dz = rods[rod.connect_index].position.z-rods[i].position.z;
+ float d = sqrt(dx*dx+dz*dz);
+ float cd1 = sqrt(rod.connect_point.x*rod.connect_point.x+rod.connect_point.z*rod.connect_point.z);
+ float cd2 = sqrt(rod.connect_offset.x*rod.connect_offset.x+rod.connect_offset.z*rod.connect_offset.z);
+ float a = (d*d+cd1*cd1-cd2*cd2)/(2*d);
+ float b = sqrt(cd1*cd1-a*a);
+ float sign = (dx*rod.connect_point.z-dz*rod.connect_point.x>0 ? 1 : -1);
+ float cx = (dx*a-dz*b*sign)/d;
+ float cz = (dz*a+dx*b*sign)/d;
+ float ca1 = atan2(rod.connect_point.z, rod.connect_point.x);
+ float ca2 = atan2(rod.connect_offset.z, rod.connect_offset.x);
+ rods[i].angle = atan2(cz, cx)-ca1;
+ rods[rod.connect_index].angle = atan2(cz-dz, cx-dx)-ca2;
+ }
+ }
+ }
+}
+