+void Vehicle::turn_axles(float d)
+{
+ for(vector<Axle>::iterator i=axles.begin(); i!=axles.end(); ++i)
+ i->angle += d*2/i->type->wheel_dia;
+ for(vector<Bogie>::iterator i=bogies.begin(); i!=bogies.end(); ++i)
+ for(vector<Axle>::iterator j=i->axles.begin(); j!=i->axles.end(); ++j)
+ j->angle += d*2/j->type->wheel_dia;
+
+ update_rods();
+}
+
+void Vehicle::update_rods()
+{
+ for(vector<Rod>::iterator i=rods.begin(); i!=rods.end(); ++i)
+ {
+ if(i->type->pivot==VehicleType::Rod::BODY)
+ i->position = i->type->pivot_point;
+ else if(i->type->pivot==VehicleType::Rod::AXLE)
+ {
+ const Axle &axle = get_fixed_axle(i->type->pivot_index);
+ float c = cos(axle.angle);
+ float s = sin(axle.angle);
+ const Vector &pp = i->type->pivot_point;
+ i->position = Vector(axle.type->position+pp.x*c+pp.z*s, pp.y, axle.type->wheel_dia/2+pp.z*c-pp.x*s);
+ }
+ else if(i->type->pivot==VehicleType::Rod::ROD)
+ {
+ const Rod &prod = get_rod(i->type->pivot_index);
+ float c = cos(prod.angle);
+ float s = sin(prod.angle);
+ const Vector &pos = prod.position;
+ const Vector &off = i->type->pivot_point;
+ i->position = Vector(pos.x+off.x*c-off.z*s, pos.y+off.y, pos.z+off.z*c+off.x*s);
+ }
+
+ if(i->type->connect_index>=0)
+ {
+ Rod &crod = rods[i->type->connect_index];
+ if(i->type->limit==VehicleType::Rod::ROTATE && crod.type->limit==VehicleType::Rod::SLIDE_X)
+ {
+ float dx = (crod.position.x+i->type->connect_offset.x)-i->position.x;
+ float dz = (crod.position.z+i->type->connect_offset.z)-i->position.z;
+ float cd = sqrt(i->type->connect_point.x*i->type->connect_point.x+i->type->connect_point.z*i->type->connect_point.z);
+ float ca = atan2(i->type->connect_point.z, i->type->connect_point.x);
+ dx = sqrt(cd*cd-dz*dz)*(dx>0 ? 1 : -1);
+ i->angle = atan2(dz, dx)-ca;
+ crod.position.x = i->position.x+dx-i->type->connect_offset.x;
+ }
+ else if(i->type->limit==VehicleType::Rod::ROTATE && crod.type->limit==VehicleType::Rod::ROTATE)
+ {
+ float dx = crod.position.x-i->position.x;
+ float dz = crod.position.z-i->position.z;
+ float d = sqrt(dx*dx+dz*dz);
+ float cd1 = sqrt(i->type->connect_point.x*i->type->connect_point.x+i->type->connect_point.z*i->type->connect_point.z);
+ float cd2 = sqrt(i->type->connect_offset.x*i->type->connect_offset.x+i->type->connect_offset.z*i->type->connect_offset.z);
+ float a = (d*d+cd1*cd1-cd2*cd2)/(2*d);
+ float b = sqrt(cd1*cd1-a*a);
+ float sign = (dx*i->type->connect_point.z-dz*i->type->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(i->type->connect_point.z, i->type->connect_point.x);
+ float ca2 = atan2(i->type->connect_offset.z, i->type->connect_offset.x);
+ i->angle = atan2(cz, cx)-ca1;
+ crod.angle = atan2(cz-dz, cx-dx)-ca2;
+ }
+ }
+ }
+}
+